/*
 * mergeinfo.c:  Mergeinfo parsing and handling
 *
 * ====================================================================
 *    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 <assert.h>
#include <ctype.h>

#include "svn_path.h"
#include "svn_types.h"
#include "svn_ctype.h"
#include "svn_pools.h"
#include "svn_sorts.h"
#include "svn_error.h"
#include "svn_error_codes.h"
#include "svn_string.h"
#include "svn_mergeinfo.h"
#include "private/svn_fspath.h"
#include "private/svn_mergeinfo_private.h"
#include "private/svn_sorts_private.h"
#include "private/svn_string_private.h"
#include "private/svn_subr_private.h"
#include "svn_private_config.h"
#include "svn_hash.h"
#include "private/svn_dep_compat.h"

/* Return TRUE iff the forward revision range FIRST wholly contains the
 * forward revision range SECOND and (if CONSIDER_INHERITANCE is TRUE) has
 * the same inheritability. */
static svn_error_t *
range_contains(svn_boolean_t *result,
               const svn_merge_range_t *first, const svn_merge_range_t *second,
               svn_boolean_t consider_inheritance);


/* Attempt to combine two ranges, IN1 and IN2. If they are adjacent or
   overlapping, and their inheritability allows them to be combined, put
   the result in OUTPUT and return TRUE, otherwise return FALSE.

   CONSIDER_INHERITANCE determines how to account for the inheritability
   of IN1 and IN2 when trying to combine ranges.  If ranges with different
   inheritability are combined (CONSIDER_INHERITANCE must be FALSE for this
   to happen) the result is inheritable.  If both ranges are inheritable the
   result is inheritable.  And only if both ranges are non-inheritable
   the result is non-inheritable.

   Range overlapping detection algorithm from
   http://c2.com/cgi-bin/wiki/fullSearch?TestIfDateRangesOverlap
*/
static svn_boolean_t
combine_ranges(svn_merge_range_t *output,
               const svn_merge_range_t *in1,
               const svn_merge_range_t *in2,
               svn_boolean_t consider_inheritance)
{
  if (in1->start <= in2->end && in2->start <= in1->end)
    {
      if (!consider_inheritance
          || (consider_inheritance
              && (in1->inheritable == in2->inheritable)))
        {
          output->start = MIN(in1->start, in2->start);
          output->end = MAX(in1->end, in2->end);
          output->inheritable = (in1->inheritable || in2->inheritable);
          return TRUE;
        }
    }
  return FALSE;
}

/* pathname -> PATHNAME */
static svn_error_t *
parse_pathname(const char **input,
               const char *end,
               const char **pathname,
               apr_pool_t *pool)
{
  const char *curr = *input;
  const char *last_colon = NULL;

  /* A pathname may contain colons, so find the last colon before END
     or newline.  We'll consider this the divider between the pathname
     and the revisionlist. */
  while (curr < end && *curr != '\n')
    {
      if (*curr == ':')
        last_colon = curr;
      curr++;
    }

  if (!last_colon)
    return svn_error_create(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                            _("Pathname not terminated by ':'"));

  /* Tolerate relative repository paths, but convert them to absolute.
     ### Efficiency?  1 string duplication here, 2 in canonicalize. */
  *pathname = svn_fspath__canonicalize(apr_pstrndup(pool, *input,
                                                    last_colon - *input),
                                       pool);

  *input = last_colon;

  return SVN_NO_ERROR;
}

/* Return TRUE iff (svn_merge_range_t *) RANGE describes a valid, forward
 * revision range.
 *
 * Note: The smallest valid value of RANGE->start is 0 because it is an
 * exclusive endpoint, being one less than the revision number of the first
 * change described by the range, and the oldest possible change is "r1" as
 * there cannot be a change "r0". */
#define IS_VALID_FORWARD_RANGE(range) \
  (SVN_IS_VALID_REVNUM((range)->start) && ((range)->start < (range)->end))

/* Ways in which two svn_merge_range_t can intersect or adjoin, if at all. */
typedef enum intersection_type_t
{
  /* Ranges don't intersect and don't adjoin. */
  svn__no_intersection,

  /* Ranges are equal. */
  svn__equal_intersection,

  /* Ranges adjoin but don't overlap. */
  svn__adjoining_intersection,

  /* Ranges overlap but neither is a subset of the other. */
  svn__overlapping_intersection,

  /* One range is a proper subset of the other. */
  svn__proper_subset_intersection
} intersection_type_t;

/* Given ranges R1 and R2, both of which must be forward merge ranges,
   set *INTERSECTION_TYPE to describe how the ranges intersect, if they
   do at all.  The inheritance type of the ranges is not considered. */
static svn_error_t *
get_type_of_intersection(const svn_merge_range_t *r1,
                         const svn_merge_range_t *r2,
                         intersection_type_t *intersection_type)
{
  SVN_ERR_ASSERT(r1);
  SVN_ERR_ASSERT(r2);
  SVN_ERR_ASSERT(IS_VALID_FORWARD_RANGE(r1));
  SVN_ERR_ASSERT(IS_VALID_FORWARD_RANGE(r2));

  if (!(r1->start <= r2->end && r2->start <= r1->end))
    *intersection_type = svn__no_intersection;
  else if (r1->start == r2->start && r1->end == r2->end)
    *intersection_type = svn__equal_intersection;
  else if (r1->end == r2->start || r2->end == r1->start)
    *intersection_type = svn__adjoining_intersection;
  else if (r1->start <= r2->start && r1->end >= r2->end)
    *intersection_type = svn__proper_subset_intersection;
  else if (r2->start <= r1->start && r2->end >= r1->end)
    *intersection_type = svn__proper_subset_intersection;
  else
    *intersection_type = svn__overlapping_intersection;

  return SVN_NO_ERROR;
}

/* Modify or extend RANGELIST (a list of merge ranges) to incorporate
   NEW_RANGE. RANGELIST is a "rangelist" as defined in svn_mergeinfo.h.

   OVERVIEW

   Determine the minimal set of non-overlapping merge ranges required to
   represent the combination of RANGELIST and NEW_RANGE. The result depends
   on whether and how NEW_RANGE overlaps any merge range[*] in RANGELIST,
   and also on any differences in the inheritability of each range,
   according to the rules described below. Modify RANGELIST to represent
   this result, by adjusting the last range in it and/or appending one or
   two more ranges.

   ([*] Due to the simplifying assumption below, only the last range in
   RANGELIST is considered.)

   DETAILS

   If RANGELIST is not empty assume NEW_RANGE does not intersect with any
   range before the last one in RANGELIST.

   If RANGELIST is empty or NEW_RANGE does not intersect with the lastrange
   in RANGELIST, then append a copy of NEW_RANGE, allocated in RESULT_POOL,
   to RANGELIST.

   If NEW_RANGE intersects with the last range in RANGELIST then combine
   these two ranges as described below:

   If the intersecting ranges have the same inheritability then simply
   combine the ranges in place.  Otherwise, if the ranges intersect but
   differ in inheritability, then merge the ranges as dictated by
   CONSIDER_INHERITANCE:

   If CONSIDER_INHERITANCE is false then intersecting ranges are combined
   into a single range.  The inheritability of the resulting range is
   non-inheritable *only* if both ranges are non-inheritable, otherwise the
   combined range is inheritable, e.g.:

     Last range in        NEW_RANGE        RESULTING RANGES
     RANGELIST
     -------------        ---------        ----------------
     4-10*                6-13             4-13
     4-10                 6-13*            4-13
     4-10*                6-13*            4-13*

   If CONSIDER_INHERITANCE is true, then only the intersection between the
   two ranges is combined, with the inheritability of the resulting range
   non-inheritable only if both ranges were non-inheritable.  The
   non-intersecting portions are added as separate ranges allocated in
   RESULT_POOL, e.g.:

     Last range in        NEW_RANGE        RESULTING RANGES
     RANGELIST
     -------------        ---------        ----------------
     4-10*                6                4-5*, 6, 7-10*
     4-10*                6-12             4-5*, 6-12

   Note that the standard rules for rangelists still apply and overlapping
   ranges are not allowed.  So if the above would result in overlapping
   ranges of the same inheritance, the overlapping ranges are merged into a
   single range, e.g.:

     Last range in        NEW_RANGE        RESULTING RANGES
     RANGELIST
     -------------        ---------        ----------------
     4-10                 6*               4-10 (Not 4-5, 6, 7-10)

   When replacing the last range in RANGELIST, either allocate a new range in
   RESULT_POOL or modify the existing range in place.  Any new ranges added
   to RANGELIST are allocated in RESULT_POOL.
*/
static svn_error_t *
combine_with_lastrange(const svn_merge_range_t *new_range,
                       svn_rangelist_t *rangelist,
                       svn_boolean_t consider_inheritance,
                       apr_pool_t *result_pool)
{
  svn_merge_range_t *lastrange;
  svn_merge_range_t combined_range;

  /* We don't accept a NULL RANGELIST. */
  SVN_ERR_ASSERT(rangelist);

  if (rangelist->nelts > 0)
    lastrange = APR_ARRAY_IDX(rangelist, rangelist->nelts - 1, svn_merge_range_t *);
  else
    lastrange = NULL;

  if (!lastrange)
    {
      /* No *LASTRANGE so push NEW_RANGE onto RANGELIST and we are done. */
      APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) =
        svn_merge_range_dup(new_range, result_pool);
    }
  else if (combine_ranges(&combined_range, lastrange, new_range,
                     consider_inheritance))
    {
      *lastrange = combined_range;
    }
  else if (!consider_inheritance)
    {
      /* We are not considering inheritance so we can merge intersecting
         ranges of different inheritability.  Of course if the ranges
         don't intersect at all we simply push NEW_RANGE onto RANGELIST. */
      APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) =
            svn_merge_range_dup(new_range, result_pool);
    }
  else /* Considering inheritance */
    {
      /* If we are here then the ranges either don't intersect or do
          intersect but have differing inheritability.  Check for the
          first case as that is easy to handle. */
      intersection_type_t intersection_type;
      svn_boolean_t sorted = FALSE;

      SVN_ERR(get_type_of_intersection(new_range, lastrange,
                                        &intersection_type));

      switch (intersection_type)
        {
          case svn__no_intersection:
            /* NEW_RANGE and *LASTRANGE *really* don't intersect so
                just push NEW_RANGE onto RANGELIST. */
            APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) =
              svn_merge_range_dup(new_range, result_pool);
            sorted = (svn_sort_compare_ranges(&lastrange,
                                              &new_range) < 0);
            break;

          case svn__equal_intersection:
            /* They range are equal so all we do is force the
                inheritability of lastrange to true. */
            lastrange->inheritable = TRUE;
            sorted = TRUE;
            break;

          case svn__adjoining_intersection:
            /* They adjoin but don't overlap so just push NEW_RANGE
                onto RANGELIST. */
            APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) =
              svn_merge_range_dup(new_range, result_pool);
            sorted = (svn_sort_compare_ranges(&lastrange,
                                              &new_range) < 0);
            break;

          case svn__overlapping_intersection:
            /* They ranges overlap but neither is a proper subset of
                the other.  We'll end up pusing two new ranges onto
                RANGELIST, the intersecting part and the part unique to
                NEW_RANGE.*/
            {
              svn_merge_range_t *r1 = svn_merge_range_dup(lastrange,
                                                          result_pool);
              svn_merge_range_t *r2 = svn_merge_range_dup(new_range,
                                                          result_pool);

              /* Pop off *LASTRANGE to make our manipulations
                  easier. */
              apr_array_pop(rangelist);

              /* Ensure R1 is the older range. */
              if (r2->start < r1->start)
                {
                  /* Swap R1 and R2. */
                  *r2 = *r1;
                  *r1 = *new_range;
                }

              /* Absorb the intersecting ranges into the
                  inheritable range. */
              if (r1->inheritable)
                r2->start = r1->end;
              else
                r1->end = r2->start;

              /* Push everything back onto RANGELIST. */
              APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r1;
              sorted = (svn_sort_compare_ranges(&lastrange,
                                                &r1) < 0);
              APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r2;
              if (sorted)
                sorted = (svn_sort_compare_ranges(&r1, &r2) < 0);
              break;
            }

          default: /* svn__proper_subset_intersection */
            {
              /* One range is a proper subset of the other. */
              svn_merge_range_t *r1 = svn_merge_range_dup(lastrange,
                                                          result_pool);
              svn_merge_range_t *r2 = svn_merge_range_dup(new_range,
                                                          result_pool);
              svn_merge_range_t *r3 = NULL;

              /* Pop off *LASTRANGE to make our manipulations
                  easier. */
              apr_array_pop(rangelist);

              /* Ensure R1 is the superset. */
              if (r2->start < r1->start || r2->end > r1->end)
                {
                  /* Swap R1 and R2. */
                  *r2 = *r1;
                  *r1 = *new_range;
                }

              if (r1->inheritable)
                {
                  /* The simple case: The superset is inheritable, so
                      just combine r1 and r2. */
                  r1->start = MIN(r1->start, r2->start);
                  r1->end = MAX(r1->end, r2->end);
                  r2 = NULL;
                }
              else if (r1->start == r2->start)
                {
                  svn_revnum_t tmp_revnum;

                  /* *LASTRANGE and NEW_RANGE share an end point. */
                  tmp_revnum = r1->end;
                  r1->end = r2->end;
                  r2->inheritable = r1->inheritable;
                  r1->inheritable = TRUE;
                  r2->start = r1->end;
                  r2->end = tmp_revnum;
                }
              else if (r1->end == r2->end)
                {
                  /* *LASTRANGE and NEW_RANGE share an end point. */
                  r1->end = r2->start;
                  r2->inheritable = TRUE;
                }
              else
                {
                  /* NEW_RANGE and *LASTRANGE share neither start
                      nor end points. */
                  r3 = apr_pcalloc(result_pool, sizeof(*r3));
                  r3->start = r2->end;
                  r3->end = r1->end;
                  r3->inheritable = r1->inheritable;
                  r2->inheritable = TRUE;
                  r1->end = r2->start;
                }

              /* Push everything back onto RANGELIST. */
              APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r1;
              sorted = (svn_sort_compare_ranges(&lastrange, &r1) < 0);
              if (r2)
                {
                  APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r2;
                  if (sorted)
                    sorted = (svn_sort_compare_ranges(&r1, &r2) < 0);
                }
              if (r3)
                {
                  APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = r3;
                  if (sorted)
                    {
                      if (r2)
                        sorted = (svn_sort_compare_ranges(&r2,
                                                          &r3) < 0);
                      else
                        sorted = (svn_sort_compare_ranges(&r1,
                                                          &r3) < 0);
                    }
                }
              break;
            }
        }

      /* Some of the above cases might have put *RANGELIST out of
          order, so re-sort.*/
      if (!sorted)
        svn_sort__array(rangelist, svn_sort_compare_ranges);
    }

  return SVN_NO_ERROR;
}

/* Convert a single svn_merge_range_t *RANGE back into a string.  */
static svn_error_t *
range_to_string(char **s,
                const svn_merge_range_t *range,
                apr_pool_t *pool)
{
  const char *mark
    = range->inheritable ? "" : SVN_MERGEINFO_NONINHERITABLE_STR;

  if (range->start == range->end - 1)
    *s = apr_psprintf(pool, "%ld%s", range->end, mark);
  else if (range->start - 1 == range->end)
    *s = apr_psprintf(pool, "-%ld%s", range->start, mark);
  else if (range->start < range->end)
    *s = apr_psprintf(pool, "%ld-%ld%s", range->start + 1, range->end, mark);
  else if (range->start > range->end)
    *s = apr_psprintf(pool, "%ld-%ld%s", range->start, range->end + 1, mark);
  else
    {
      return svn_error_createf(SVN_ERR_ASSERTION_FAIL, NULL,
                               _("bad range {start=%ld,end=%ld,inheritable=%d}"),
                               range->start, range->end, range->inheritable);
    }

  return SVN_NO_ERROR;
}

/* Convert a single svn_merge_range_t *RANGE back into a string.  */
static char *
range_to_string_debug(const svn_merge_range_t *range,
                      apr_pool_t *pool)
{
  svn_error_t *err;
  char *s;

  err = range_to_string(&s, range, pool);
  if (err)
    {
      svn_error_clear(err);
      s = apr_psprintf(pool, _("bad range {start=%ld,end=%ld,inheritable=%d}"),
                       range->start, range->end, range->inheritable);
    }
  return s;
}

/* Helper for svn_mergeinfo_parse()
   Append revision ranges onto the array RANGELIST to represent the range
   descriptions found in the string *INPUT.  Read only as far as a newline
   or the position END, whichever comes first.  Set *INPUT to the position
   after the last character of INPUT that was used.

   revisionlist -> (revisionelement)(COMMA revisionelement)*
   revisionrange -> REVISION "-" REVISION("*")
   revisionelement -> revisionrange | REVISION("*")
*/
static svn_error_t *
parse_rangelist(const char **input, const char *end,
                svn_rangelist_t *rangelist,
                apr_pool_t *pool)
{
  const char *curr = *input;

  /* Eat any leading horizontal white-space before the rangelist. */
  while (curr < end && *curr != '\n' && isspace(*curr))
    curr++;

  if (*curr == '\n' || curr == end)
    {
      /* Empty range list. */
      *input = curr;
      return SVN_NO_ERROR;
    }

  while (curr < end && *curr != '\n')
    {
      /* Parse individual revisions or revision ranges. */
      svn_merge_range_t *mrange = apr_pcalloc(pool, sizeof(*mrange));
      svn_revnum_t firstrev;

      SVN_ERR(svn_revnum_parse(&firstrev, curr, &curr));
      if (*curr != '-' && *curr != '\n' && *curr != ',' && *curr != '*'
          && curr != end)
        return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                                 _("Invalid character '%c' found in revision "
                                   "list"), *curr);
      mrange->start = firstrev - 1;
      mrange->end = firstrev;
      mrange->inheritable = TRUE;

      if (firstrev == 0)
        return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                                 _("Invalid revision number '0' found in "
                                   "range list"));

      if (*curr == '-')
        {
          svn_revnum_t secondrev;

          curr++;
          SVN_ERR(svn_revnum_parse(&secondrev, curr, &curr));
          if (firstrev > secondrev)
            return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                                     _("Unable to parse reversed revision "
                                       "range '%ld-%ld'"),
                                       firstrev, secondrev);
          else if (firstrev == secondrev)
            return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                                     _("Unable to parse revision range "
                                       "'%ld-%ld' with same start and end "
                                       "revisions"), firstrev, secondrev);
          mrange->end = secondrev;
        }

      if (*curr == '\n' || curr == end)
        {
          APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = mrange;
          *input = curr;
          return SVN_NO_ERROR;
        }
      else if (*curr == ',')
        {
          APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = mrange;
          curr++;
        }
      else if (*curr == '*')
        {
          mrange->inheritable = FALSE;
          curr++;
          if (*curr == ',' || *curr == '\n' || curr == end)
            {
              APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = mrange;
              if (*curr == ',')
                {
                  curr++;
                }
              else
                {
                  *input = curr;
                  return SVN_NO_ERROR;
                }
            }
          else
            {
              return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                                       _("Invalid character '%c' found in "
                                         "range list"), *curr);
            }
        }
      else
        {
          return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                                   _("Invalid character '%c' found in "
                                     "range list"), *curr);
        }

    }
  if (*curr != '\n')
    return svn_error_create(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                            _("Range list parsing ended before hitting "
                              "newline"));
  *input = curr;
  return SVN_NO_ERROR;
}

svn_error_t *
svn_rangelist__parse(svn_rangelist_t **rangelist,
                     const char *str,
                     apr_pool_t *result_pool)
{
  const char *s = str;

  *rangelist = apr_array_make(result_pool, 1, sizeof(svn_merge_range_t *));
  SVN_ERR(parse_rangelist(&s, s + strlen(s), *rangelist, result_pool));
  return SVN_NO_ERROR;
}

svn_boolean_t
svn_rangelist__is_canonical(const svn_rangelist_t *rangelist)
{
  int i;
  svn_merge_range_t **ranges = (svn_merge_range_t **)rangelist->elts;

  /* Check for reversed and empty ranges */
  for (i = 0; i < rangelist->nelts; ++i)
    {
      if (ranges[i]->start >= ranges[i]->end)
        return FALSE;
    }

  /* Check for overlapping ranges */
  for (i = 0; i < rangelist->nelts - 1; ++i)
    {
      if (ranges[i]->end > ranges[i + 1]->start)
        return FALSE; /* Overlapping range */
      else if (ranges[i]->end == ranges[i+1]->start
               && ranges[i]->inheritable == ranges[i + 1]->inheritable)
        {
          return FALSE; /* Ranges should have been combined */
        }
    }

  return TRUE;
}

/* In-place combines adjacent ranges in a rangelist.
   SCRATCH_POOL is just used for providing error messages. */
svn_error_t *
svn_rangelist__canonicalize(svn_rangelist_t *rangelist,
                            apr_pool_t *scratch_pool)
{
  int i;
  svn_merge_range_t *range, *lastrange;

  if (svn_rangelist__is_canonical(rangelist))
    return SVN_NO_ERROR; /* Nothing to do */

  svn_sort__array(rangelist, svn_sort_compare_ranges);

  lastrange = APR_ARRAY_IDX(rangelist, 0, svn_merge_range_t *);

  for (i = 1; i < rangelist->nelts; i++)
    {
      range = APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
      if (lastrange->start <= range->end
          && range->start <= lastrange->end)
        {
          /* The ranges are adjacent or intersect. */

          /* svn_mergeinfo_parse promises to combine overlapping
             ranges as long as their inheritability is the same. */
          if (range->start < lastrange->end
              && range->inheritable != lastrange->inheritable)
            {
              return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                                       _("Unable to parse overlapping "
                                         "revision ranges '%s' and '%s' "
                                         "with different inheritance "
                                         "types"),
                                       range_to_string_debug(lastrange,
                                                             scratch_pool),
                                       range_to_string_debug(range,
                                                             scratch_pool));
            }

          /* Combine overlapping or adjacent ranges with the
             same inheritability. */
          if (lastrange->inheritable == range->inheritable)
            {
              lastrange->end = MAX(range->end, lastrange->end);
              SVN_ERR(svn_sort__array_delete2(rangelist, i, 1));
              i--;
            }
        }
      lastrange = APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
    }

  return SVN_NO_ERROR;
}

/* revisionline -> PATHNAME COLON revisionlist
 *
 * Parse one line of mergeinfo starting at INPUT, not reading beyond END,
 * into HASH. Allocate the new entry in HASH deeply from HASH's pool.
 */
static svn_error_t *
parse_revision_line(const char **input, const char *end, svn_mergeinfo_t hash,
                    apr_pool_t *scratch_pool)
{
  const char *pathname = "";
  apr_ssize_t klen;
  svn_rangelist_t *existing_rangelist;
  svn_rangelist_t *rangelist = apr_array_make(scratch_pool, 1,
                                              sizeof(svn_merge_range_t *));

  SVN_ERR(parse_pathname(input, end, &pathname, scratch_pool));

  if (*(*input) != ':')
    return svn_error_create(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                            _("Pathname not terminated by ':'"));

  *input = *input + 1;

  SVN_ERR(parse_rangelist(input, end, rangelist, scratch_pool));

  if (rangelist->nelts == 0)
      return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                               _("Mergeinfo for '%s' maps to an "
                                 "empty revision range"), pathname);
  if (*input != end && *(*input) != '\n')
    return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                             _("Could not find end of line in range list line "
                               "in '%s'"), *input);

  if (*input != end)
    *input = *input + 1;

  /* Sort the rangelist, combine adjacent ranges into single ranges, and
     make sure there are no overlapping ranges.  Luckily, most data in
     svn:mergeinfo will already be in normalized form and this will be quick.
   */
  SVN_ERR(svn_rangelist__canonicalize(rangelist, scratch_pool));

  /* Handle any funky mergeinfo with relative merge source paths that
     might exist due to issue #3547.  It's possible that this issue allowed
     the creation of mergeinfo with path keys that differ only by a
     leading slash, e.g. "trunk:4033\n/trunk:4039-4995".  In the event
     we encounter this we merge the rangelists together under a single
     absolute path key. */
  klen = strlen(pathname);
  existing_rangelist = apr_hash_get(hash, pathname, klen);
  if (existing_rangelist)
    SVN_ERR(svn_rangelist_merge2(rangelist, existing_rangelist,
                                 scratch_pool, scratch_pool));

  apr_hash_set(hash, apr_pstrmemdup(apr_hash_pool_get(hash), pathname, klen),
               klen, svn_rangelist_dup(rangelist, apr_hash_pool_get(hash)));

  return SVN_NO_ERROR;
}

/* top -> revisionline (NEWLINE revisionline)*
 *
 * Parse mergeinfo starting at INPUT, not reading beyond END, into HASH.
 * Allocate all the new entries in HASH deeply from HASH's pool.
 */
static svn_error_t *
parse_top(const char **input, const char *end, svn_mergeinfo_t hash,
          apr_pool_t *scratch_pool)
{
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);

  while (*input < end)
    {
      svn_pool_clear(iterpool);
      SVN_ERR(parse_revision_line(input, end, hash, iterpool));
    }
  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo_parse(svn_mergeinfo_t *mergeinfo,
                    const char *input,
                    apr_pool_t *pool)
{
  svn_error_t *err;

  *mergeinfo = svn_hash__make(pool);
  err = parse_top(&input, input + strlen(input), *mergeinfo, pool);

  /* Always return SVN_ERR_MERGEINFO_PARSE_ERROR as the topmost error. */
  if (err && err->apr_err != SVN_ERR_MERGEINFO_PARSE_ERROR)
    err = svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, err,
                            _("Could not parse mergeinfo string '%s'"),
                            input);
  return err;
}

static const char *
rangelist_to_string_debug(const svn_rangelist_t *rl,
                          apr_pool_t *pool)
{
  svn_string_t *rls;
  svn_error_t *err;

  err = svn_rangelist_to_string(&rls, rl, pool);
  if (err)
    {
      char *s = apr_psprintf(pool, _("<bad rangelist [%d ranges]: %s>"),
                             rl->nelts, err->message);
      svn_error_clear(err);
      return s;
    }
  return rls->data;
}

static svn_boolean_t
rangelist_is_sorted(const svn_rangelist_t *rangelist)
{
  int i;

  for (i = 1; i < rangelist->nelts; i++)
    {
      const svn_merge_range_t *lastrange
        = APR_ARRAY_IDX(rangelist, i-1, svn_merge_range_t *);
      const svn_merge_range_t *thisrange
        = APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);

      if (svn_sort_compare_ranges(&lastrange, &thisrange) > 0)
        return FALSE;
    }
  return TRUE;
}

/* Mergeinfo inheritance or absence in a rangelist interval */
enum rangelist_interval_kind_t { MI_NONE, MI_NON_INHERITABLE, MI_INHERITABLE };

/* A rangelist interval: like svn_merge_range_t but an interval can represent
 * a gap in the rangelist (kind = MI_NONE). */
typedef struct rangelist_interval_t
{
  svn_revnum_t start, end;
  enum rangelist_interval_kind_t kind;
} rangelist_interval_t;

/* Iterator for intervals in a rangelist. */
typedef struct rangelist_interval_iterator_t {
  /* iteration state: */
  const svn_rangelist_t *rl;  /* input */
  int i;  /* current interval is this range in RL or the gap before it */
  svn_boolean_t in_range;  /* current interval is range RL[I], not a gap? */

  /* current interval: */
  rangelist_interval_t interval;
} rangelist_interval_iterator_t;

/* Update IT->interval to match the current iteration state of IT.
 * Return the iterator, or NULL if the iteration has reached its end.
 */
static rangelist_interval_iterator_t *
rlii_update(rangelist_interval_iterator_t *it)
{
  const svn_merge_range_t *range
    = (it->i < it->rl->nelts
       ? APR_ARRAY_IDX(it->rl, it->i, void *) : NULL);

  if (!range)
    return NULL;

  if (!it->in_range)
    {
      it->interval.start
        = (it->i > 0
           ? APR_ARRAY_IDX(it->rl, it->i - 1, svn_merge_range_t *)->end
           : 0);
      it->interval.end = range->start;
      it->interval.kind = MI_NONE;
    }
  else
    {
      it->interval.start = range->start;
      it->interval.end = range->end;
      it->interval.kind
        = (range->inheritable ? MI_INHERITABLE : MI_NON_INHERITABLE);
    }
  return it;
}

/* Move to the next interval, which might be a zero-length interval.
 * Return IT, or return NULL at the end of iteration. */
static rangelist_interval_iterator_t *
rlii_next_any_interval(rangelist_interval_iterator_t *it)
{
  /* Should be called before iteration is finished. */
  if (it->i >= it->rl->nelts)
    return NULL;

  /* If we are in a range, move to the next pre-range gap;
   * else, move from this pre-range gap into this range. */
  if (it->in_range)
    it->i++;
  it->in_range = !it->in_range;
  return it;
}

/* Return an iterator pointing at the first non-zero-length interval in RL,
 * or NULL if there are none. */
static rangelist_interval_iterator_t *
rlii_first(const svn_rangelist_t *rl,
           apr_pool_t *pool)
{
  rangelist_interval_iterator_t *it = apr_palloc(pool, sizeof(*it));

  it->rl = rl;
  it->i = 0;
  it->in_range = FALSE;

  /* Update, and skip empty intervals */
  while ((it = rlii_update(it)) && it->interval.start == it->interval.end)
    {
      it = rlii_next_any_interval(it);
    }
  return it;
}

/* Move to the next non-empty interval.
 * Intervals will be generated in this sequence:
 *  (0,               MI_NONE,  RL[0]->start),  // i=0, !in_range
 *  (RL[0]->start,    MI_*      RL[0]->end),    // i=0, in_range
 *  (RL[0]->end,      MI_NONE,  RL[1]->start),
 *  (RL[1]->start,    MI_*      RL[1]->end),
 *  ...
 *  (RL[n-2]->end,    MI_NONE,  RL[n-1]->start),
 *  (RL[n-1]->start,  MI_*      RL[n-1]->end),
 * but excluding empty intervals.
 * Return IT, or return NULL at the end of iteration. */
static rangelist_interval_iterator_t *
rlii_next(rangelist_interval_iterator_t *it)
{
  it = rlii_next_any_interval(it);

  /* Update, and skip empty intervals */
  while ((it = rlii_update(it)) && it->interval.start == it->interval.end)
    {
      it = rlii_next_any_interval(it);
    }
  return it;
}

/* Rangelist builder. Accumulates consecutive intervals, combining them
 * when possible. */
typedef struct rangelist_builder_t {
  svn_rangelist_t *rl;  /* rangelist to build */
  rangelist_interval_t accu_interval;  /* current interval accumulator */
  apr_pool_t *pool;  /* from which to allocate ranges */
} rangelist_builder_t;

/* Return an initialized rangelist builder. */
static rangelist_builder_t *
rl_builder_new(svn_rangelist_t *rl,
               apr_pool_t *pool)
{
  rangelist_builder_t *b = apr_pcalloc(pool, sizeof(*b));

  b->rl = rl;
  /* b->accu_interval = {0, 0, RL_NONE} */
  b->pool = pool;
  return b;
}

/* Flush the last accumulated interval in the rangelist builder B. */
static void
rl_builder_flush(rangelist_builder_t *b)
{
  if (b->accu_interval.kind > MI_NONE)
    {
      svn_merge_range_t *mrange = apr_pcalloc(b->pool, sizeof(*mrange));
      mrange->start = b->accu_interval.start;
      mrange->end = b->accu_interval.end;
      mrange->inheritable = (b->accu_interval.kind == MI_INHERITABLE);
      APR_ARRAY_PUSH(b->rl, svn_merge_range_t *) = mrange;
    }
}

/* Add a new INTERVAL to the rangelist builder B. */
static void
rl_builder_add_interval(rangelist_builder_t *b,
                        const rangelist_interval_t *interval)
{
  SVN_ERR_ASSERT_NO_RETURN(interval->start < interval->end);
  SVN_ERR_ASSERT_NO_RETURN(interval->start == b->accu_interval.end);

  /* Extend the accumulating interval, or end it and start another? */
  if (interval->kind == b->accu_interval.kind)
    {
      b->accu_interval.end = interval->end;
    }
  else
    {
      /* Push the accumulated interval onto the building rangelist. */
      rl_builder_flush(b);
      /* Start accumulating a new interval */
      b->accu_interval = *interval;
    }
}

/* Set RL_OUT to the union (merge) of RL1 and RL2.
 * On entry, RL_OUT must be an empty rangelist.
 *
 * Each range added to RL_OUT will be either shallow-copied from RL1 or
 * allocated from RESULT_POOL.
 */
static svn_error_t *
rangelist_merge(svn_rangelist_t *rl_out,
                const svn_rangelist_t *rl1,
                const svn_rangelist_t *rl2,
                apr_pool_t *result_pool,
                apr_pool_t *scratch_pool)
{
  rangelist_interval_iterator_t *it[2];
  rangelist_builder_t *rl_builder = rl_builder_new(rl_out, result_pool);
  svn_revnum_t r_last = 0;

  /*SVN_ERR_ASSERT(svn_rangelist__is_canonical(rl1));*/
  /*SVN_ERR_ASSERT(svn_rangelist__is_canonical(rl2));*/
  SVN_ERR_ASSERT(rangelist_is_sorted(rl1));
  SVN_ERR_ASSERT(rangelist_is_sorted(rl2));
  SVN_ERR_ASSERT(rl_out->nelts == 0);

  /* Initialize the input iterators and the output generator */
  it[0] = rlii_first(rl1, scratch_pool);
  it[1] = rlii_first(rl2, scratch_pool);

  /* Keep choosing the next input revision (whether a start or end of a range)
   * at which to consider making an output transition. */
  while (it[0] || it[1])
    {
      svn_revnum_t r_next = !it[1] ? it[0]->interval.end
                            : !it[0] ? it[1]->interval.end
                            : MIN(it[0]->interval.end, it[1]->interval.end);
      rangelist_interval_t interval;

      interval.start = r_last;
      interval.end = r_next;
      interval.kind = !it[1] ? it[0]->interval.kind
                       : !it[0] ? it[1]->interval.kind
                       : MAX(it[0]->interval.kind, it[1]->interval.kind);

      /* Accumulate */
      SVN_ERR_ASSERT(interval.start < interval.end);
      rl_builder_add_interval(rl_builder, &interval);

      /* if we have used up either or both input intervals, increment them */
      if (it[0] && it[0]->interval.end <= r_next)
        it[0] = rlii_next(it[0]);
      if (it[1] && it[1]->interval.end <= r_next)
        it[1] = rlii_next(it[1]);

      r_last = interval.end;
    }
  rl_builder_flush(rl_builder);
  return SVN_NO_ERROR;
}

svn_error_t *
svn_rangelist_merge2(svn_rangelist_t *rangelist,
                     const svn_rangelist_t *chg,
                     apr_pool_t *result_pool,
                     apr_pool_t *scratch_pool)
{
  svn_error_t *err;
  svn_rangelist_t *rangelist_orig;

#ifdef SVN_DEBUG
  SVN_ERR_ASSERT(rangelist_is_sorted(rangelist));
  SVN_ERR_ASSERT(rangelist_is_sorted(chg));
#endif

  /* Move the original rangelist aside. A shallow copy suffices,
   * as rangelist_merge() won't modify its inputs. */
  rangelist_orig = apr_array_copy(scratch_pool, rangelist);
  apr_array_clear(rangelist);
  err = svn_error_trace(rangelist_merge(rangelist, rangelist_orig, chg,
                                        result_pool, scratch_pool));

#ifdef SVN_DEBUG
  if (err)
    {
      err = svn_error_createf(SVN_ERR_ASSERTION_FAIL, err,
              "svn_rangelist_merge2( %s / %s ): internal error",
              rangelist_to_string_debug(rangelist_orig, scratch_pool),
              rangelist_to_string_debug(chg, scratch_pool));
    }
  else if (! svn_rangelist__is_canonical(rangelist)
           && svn_rangelist__is_canonical(rangelist_orig)
           && svn_rangelist__is_canonical(chg))
    {
      err = svn_error_createf(SVN_ERR_ASSERTION_FAIL, NULL,
              "svn_rangelist_merge2( %s / %s ): canonical inputs, "
              "non-canonical result ( %s )",
              rangelist_to_string_debug(rangelist_orig, scratch_pool),
              rangelist_to_string_debug(chg, scratch_pool),
              rangelist_to_string_debug(rangelist, scratch_pool));
    }
#endif

  return err;
}

/* Set *RESULT to TRUE iff the forward revision ranges FIRST and SECOND overlap
 * and (if CONSIDER_INHERITANCE is TRUE) have the same inheritability. */
static svn_error_t *
range_intersect(svn_boolean_t *result,
                const svn_merge_range_t *first, const svn_merge_range_t *second,
                svn_boolean_t consider_inheritance)
{
  SVN_ERR_ASSERT(IS_VALID_FORWARD_RANGE(first));
  SVN_ERR_ASSERT(IS_VALID_FORWARD_RANGE(second));

  *result = (first->start + 1 <= second->end)
            && (second->start + 1 <= first->end)
            && (!consider_inheritance
                || (!(first->inheritable) == !(second->inheritable)));
  return SVN_NO_ERROR;
}

/* Set *RESULT to TRUE iff the forward revision range FIRST wholly contains the
 * forward revision range SECOND and (if CONSIDER_INHERITANCE is TRUE) has
 * the same inheritability. */
static svn_error_t *
range_contains(svn_boolean_t *result,
               const svn_merge_range_t *first, const svn_merge_range_t *second,
               svn_boolean_t consider_inheritance)
{
  SVN_ERR_ASSERT(IS_VALID_FORWARD_RANGE(first));
  SVN_ERR_ASSERT(IS_VALID_FORWARD_RANGE(second));

  *result = (first->start <= second->start) && (second->end <= first->end)
            && (!consider_inheritance
                || (!(first->inheritable) == !(second->inheritable)));
  return SVN_NO_ERROR;
}

/* Swap start and end fields of RANGE. */
static void
range_swap_endpoints(svn_merge_range_t *range)
{
  svn_revnum_t swap = range->start;
  range->start = range->end;
  range->end = swap;
}

svn_error_t *
svn_rangelist_reverse(svn_rangelist_t *rangelist, apr_pool_t *pool)
{
  int i;

  svn_sort__array_reverse(rangelist, pool);

  for (i = 0; i < rangelist->nelts; i++)
    {
      range_swap_endpoints(APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *));
    }

  return SVN_NO_ERROR;
}

void
svn_rangelist__set_inheritance(svn_rangelist_t *rangelist,
                               svn_boolean_t inheritable)
{
  if (rangelist)
    {
      int i;
      svn_merge_range_t *range;

      for (i = 0; i < rangelist->nelts; i++)
        {
          range = APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
          range->inheritable = inheritable;
        }
    }
  return;
}

void
svn_mergeinfo__set_inheritance(svn_mergeinfo_t mergeinfo,
                               svn_boolean_t inheritable,
                               apr_pool_t *scratch_pool)
{
  if (mergeinfo)
    {
      apr_hash_index_t *hi;

      for (hi = apr_hash_first(scratch_pool, mergeinfo);
           hi;
           hi = apr_hash_next(hi))
        {
          svn_rangelist_t *rangelist = apr_hash_this_val(hi);

          if (rangelist)
            svn_rangelist__set_inheritance(rangelist, inheritable);
        }
    }
  return;
}

/* If DO_REMOVE is true, then remove any overlapping ranges described by
   RANGELIST1 from RANGELIST2 and place the results in *OUTPUT.  When
   DO_REMOVE is true, RANGELIST1 is effectively the "eraser" and RANGELIST2
   the "whiteboard".

   If DO_REMOVE is false, then capture the intersection between RANGELIST1
   and RANGELIST2 and place the results in *OUTPUT.  The ordering of
   RANGELIST1 and RANGELIST2 doesn't matter when DO_REMOVE is false.

   If CONSIDER_INHERITANCE is true, then take the inheritance of the
   ranges in RANGELIST1 and RANGELIST2 into account when comparing them
   for intersection, see the doc string for svn_rangelist_intersect().

   If CONSIDER_INHERITANCE is false, then ranges with differing inheritance
   may intersect, but the resulting intersection is non-inheritable only
   if both ranges were non-inheritable, e.g.:

   RANGELIST1  RANGELIST2  CONSIDER     DO_REMOVE  *OUTPUT
                           INHERITANCE
   ----------  ------      -----------  ---------  -------

   90-420*     1-100       TRUE         FALSE      Empty Rangelist
   90-420      1-100*      TRUE         FALSE      Empty Rangelist
   90-420      1-100       TRUE         FALSE      90-100
   90-420*     1-100*      TRUE         FALSE      90-100*

   90-420*     1-100       FALSE        FALSE      90-100
   90-420      1-100*      FALSE        FALSE      90-100
   90-420      1-100       FALSE        FALSE      90-100
   90-420*     1-100*      FALSE        FALSE      90-100*

   Allocate the contents of *OUTPUT in POOL. */
static svn_error_t *
rangelist_intersect_or_remove(svn_rangelist_t **output,
                              const svn_rangelist_t *rangelist1,
                              const svn_rangelist_t *rangelist2,
                              svn_boolean_t do_remove,
                              svn_boolean_t consider_inheritance,
                              apr_pool_t *pool)
{
  int i1, i2, lasti2;
  svn_merge_range_t working_elt2;

  *output = apr_array_make(pool, 1, sizeof(svn_merge_range_t *));

  i1 = 0;
  i2 = 0;
  lasti2 = -1;  /* Initialized to a value that "i2" will never be. */

  while (i1 < rangelist1->nelts && i2 < rangelist2->nelts)
    {
      svn_merge_range_t *elt1, *elt2;
      svn_boolean_t elt1_contains_elt2, elt1_intersects_elt2;

      elt1 = APR_ARRAY_IDX(rangelist1, i1, svn_merge_range_t *);

      /* Instead of making a copy of the entire array of rangelist2
         elements, we just keep a copy of the current rangelist2 element
         that needs to be used, and modify our copy if necessary. */
      if (i2 != lasti2)
        {
          working_elt2 =
            *(APR_ARRAY_IDX(rangelist2, i2, svn_merge_range_t *));
          lasti2 = i2;
        }

      elt2 = &working_elt2;

      SVN_ERR(range_contains(&elt1_contains_elt2,
                             elt1, elt2, consider_inheritance));
      SVN_ERR(range_intersect(&elt1_intersects_elt2,
                              elt1, elt2, consider_inheritance));
      /* If the rangelist2 range is contained completely in the
         rangelist1, we increment the rangelist2.
         If the ranges intersect, and match exactly, we increment both
         rangelist1 and rangelist2.
         Otherwise, we have to generate a range for the left part of
         the removal of rangelist1 from rangelist2, and possibly change
         the rangelist2 to the remaining portion of the right part of
         the removal, to test against. */
      if (elt1_contains_elt2)
        {
          if (!do_remove)
            {
              svn_merge_range_t tmp_range;
              tmp_range.start = elt2->start;
              tmp_range.end = elt2->end;
              /* The intersection of two ranges is non-inheritable only
                 if both ranges are non-inheritable. */
              tmp_range.inheritable =
                (elt2->inheritable || elt1->inheritable);
              SVN_ERR(combine_with_lastrange(&tmp_range, *output,
                                             consider_inheritance,
                                             pool));
            }

          i2++;

          if (elt2->start == elt1->start && elt2->end == elt1->end)
            i1++;
        }
      else if (elt1_intersects_elt2)
        {
          if (elt2->start < elt1->start)
            {
              /* The rangelist2 range starts before the rangelist1 range. */
              svn_merge_range_t tmp_range;
              if (do_remove)
                {
                  /* Retain the range that falls before the rangelist1
                     start. */
                  tmp_range.start = elt2->start;
                  tmp_range.end = elt1->start;
                  tmp_range.inheritable = elt2->inheritable;
                }
              else
                {
                  /* Retain the range that falls between the rangelist1
                     start and rangelist2 end. */
                  tmp_range.start = elt1->start;
                  tmp_range.end = MIN(elt2->end, elt1->end);
                  /* The intersection of two ranges is non-inheritable only
                     if both ranges are non-inheritable. */
                  tmp_range.inheritable =
                    (elt2->inheritable || elt1->inheritable);
                }

              SVN_ERR(combine_with_lastrange(&tmp_range,
                                             *output, consider_inheritance,
                                             pool));
            }

          /* Set up the rest of the rangelist2 range for further
             processing.  */
          if (elt2->end > elt1->end)
            {
              /* The rangelist2 range ends after the rangelist1 range. */
              if (!do_remove)
                {
                  /* Partial overlap. */
                  svn_merge_range_t tmp_range;
                  tmp_range.start = MAX(elt2->start, elt1->start);
                  tmp_range.end = elt1->end;
                  /* The intersection of two ranges is non-inheritable only
                     if both ranges are non-inheritable. */
                  tmp_range.inheritable =
                    (elt2->inheritable || elt1->inheritable);
                  SVN_ERR(combine_with_lastrange(&tmp_range,
                                                 *output,
                                                 consider_inheritance,
                                                 pool));
                }

              working_elt2.start = elt1->end;
              working_elt2.end = elt2->end;
            }
          else
            i2++;
        }
      else  /* ranges don't intersect */
        {
          /* See which side of the rangelist2 the rangelist1 is on.  If it
             is on the left side, we need to move the rangelist1.

             If it is on past the rangelist2 on the right side, we
             need to output the rangelist2 and increment the
             rangelist2.  */
          if (svn_sort_compare_ranges(&elt1, &elt2) < 0)
            i1++;
          else
            {
              svn_merge_range_t *lastrange;

              if ((*output)->nelts > 0)
                lastrange = APR_ARRAY_IDX(*output, (*output)->nelts - 1,
                                          svn_merge_range_t *);
              else
                lastrange = NULL;

              if (do_remove && !(lastrange &&
                                 combine_ranges(lastrange, lastrange, elt2,
                                                consider_inheritance)))
                {
                  lastrange = svn_merge_range_dup(elt2, pool);
                  APR_ARRAY_PUSH(*output, svn_merge_range_t *) = lastrange;
                }
              i2++;
            }
        }
    }

  if (do_remove)
    {
      /* Copy the current rangelist2 element if we didn't hit the end
         of the rangelist2, and we still had it around.  This element
         may have been touched, so we can't just walk the rangelist2
         array, we have to use our copy.  This case only happens when
         we ran out of rangelist1 before rangelist2, *and* we had changed
         the rangelist2 element. */
      if (i2 == lasti2 && i2 < rangelist2->nelts)
        {
          SVN_ERR(combine_with_lastrange(&working_elt2, *output,
                                         consider_inheritance, pool));
          i2++;
        }

      /* Copy any other remaining untouched rangelist2 elements.  */
      for (; i2 < rangelist2->nelts; i2++)
        {
          svn_merge_range_t *elt = APR_ARRAY_IDX(rangelist2, i2,
                                                 svn_merge_range_t *);

          SVN_ERR(combine_with_lastrange(elt, *output,
                                         consider_inheritance, pool));
        }
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_rangelist_intersect(svn_rangelist_t **output,
                        const svn_rangelist_t *rangelist1,
                        const svn_rangelist_t *rangelist2,
                        svn_boolean_t consider_inheritance,
                        apr_pool_t *pool)
{
  return rangelist_intersect_or_remove(output, rangelist1, rangelist2, FALSE,
                                       consider_inheritance, pool);
}

svn_error_t *
svn_rangelist_remove(svn_rangelist_t **output,
                     const svn_rangelist_t *eraser,
                     const svn_rangelist_t *whiteboard,
                     svn_boolean_t consider_inheritance,
                     apr_pool_t *pool)
{
  return rangelist_intersect_or_remove(output, eraser, whiteboard, TRUE,
                                       consider_inheritance, pool);
}

svn_error_t *
svn_rangelist_diff(svn_rangelist_t **deleted, svn_rangelist_t **added,
                   const svn_rangelist_t *from, const svn_rangelist_t *to,
                   svn_boolean_t consider_inheritance,
                   apr_pool_t *pool)
{
  /* The following diagrams illustrate some common range delta scenarios:

     (from)           deleted
     r0 <===========(=========)============[=========]===========> rHEAD
     [to]                                    added

     (from)           deleted                deleted
     r0 <===========(=========[============]=========)===========> rHEAD
     [to]

     (from)           deleted
     r0 <===========(=========[============)=========]===========> rHEAD
     [to]                                    added

     (from)                                  deleted
     r0 <===========[=========(============]=========)===========> rHEAD
     [to]             added

     (from)
     r0 <===========[=========(============)=========]===========> rHEAD
     [to]             added                  added

     (from)  d                                  d             d
     r0 <===(=[=)=]=[==]=[=(=)=]=[=]=[=(===|===(=)==|=|==[=(=]=)=> rHEAD
     [to]        a   a    a   a   a   a                   a
  */

  /* The items that are present in from, but not in to, must have been
     deleted. */
  SVN_ERR(svn_rangelist_remove(deleted, to, from, consider_inheritance,
                               pool));
  /* The items that are present in to, but not in from, must have been
     added.  */
  return svn_rangelist_remove(added, from, to, consider_inheritance, pool);
}

struct mergeinfo_diff_baton
{
  svn_mergeinfo_t from;
  svn_mergeinfo_t to;
  svn_mergeinfo_t deleted;
  svn_mergeinfo_t added;
  svn_boolean_t consider_inheritance;
  apr_pool_t *pool;
};

/* This implements the 'svn_hash_diff_func_t' interface.
   BATON is of type 'struct mergeinfo_diff_baton *'.
*/
static svn_error_t *
mergeinfo_hash_diff_cb(const void *key, apr_ssize_t klen,
                       enum svn_hash_diff_key_status status,
                       void *baton)
{
  /* hash_a is FROM mergeinfo,
     hash_b is TO mergeinfo. */
  struct mergeinfo_diff_baton *cb = baton;
  svn_rangelist_t *from_rangelist, *to_rangelist;
  const char *path = key;
  if (status == svn_hash_diff_key_both)
    {
      /* Record any deltas (additions or deletions). */
      svn_rangelist_t *deleted_rangelist, *added_rangelist;
      from_rangelist = apr_hash_get(cb->from, path, klen);
      to_rangelist = apr_hash_get(cb->to, path, klen);
      SVN_ERR(svn_rangelist_diff(&deleted_rangelist, &added_rangelist,
                                 from_rangelist, to_rangelist,
                                 cb->consider_inheritance, cb->pool));
      if (cb->deleted && deleted_rangelist->nelts > 0)
        apr_hash_set(cb->deleted, apr_pstrmemdup(cb->pool, path, klen),
                     klen, deleted_rangelist);
      if (cb->added && added_rangelist->nelts > 0)
        apr_hash_set(cb->added, apr_pstrmemdup(cb->pool, path, klen),
                     klen, added_rangelist);
    }
  else if ((status == svn_hash_diff_key_a) && cb->deleted)
    {
      from_rangelist = apr_hash_get(cb->from, path, klen);
      apr_hash_set(cb->deleted, apr_pstrmemdup(cb->pool, path, klen), klen,
                   svn_rangelist_dup(from_rangelist, cb->pool));
    }
  else if ((status == svn_hash_diff_key_b) && cb->added)
    {
      to_rangelist = apr_hash_get(cb->to, path, klen);
      apr_hash_set(cb->added, apr_pstrmemdup(cb->pool, path, klen), klen,
                   svn_rangelist_dup(to_rangelist, cb->pool));
    }
  return SVN_NO_ERROR;
}

/* Record deletions and additions of entire range lists (by path
   presence), and delegate to svn_rangelist_diff() for delta
   calculations on a specific path.  */
static svn_error_t *
walk_mergeinfo_hash_for_diff(svn_mergeinfo_t from, svn_mergeinfo_t to,
                             svn_mergeinfo_t deleted, svn_mergeinfo_t added,
                             svn_boolean_t consider_inheritance,
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
{
  struct mergeinfo_diff_baton mdb;
  mdb.from = from;
  mdb.to = to;
  mdb.deleted = deleted;
  mdb.added = added;
  mdb.consider_inheritance = consider_inheritance;
  mdb.pool = result_pool;

  return svn_hash_diff(from, to, mergeinfo_hash_diff_cb, &mdb, scratch_pool);
}

svn_error_t *
svn_mergeinfo_diff2(svn_mergeinfo_t *deleted, svn_mergeinfo_t *added,
                    svn_mergeinfo_t from, svn_mergeinfo_t to,
                    svn_boolean_t consider_inheritance,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
{
  if (from && to == NULL)
    {
      *deleted = svn_mergeinfo_dup(from, result_pool);
      *added = svn_hash__make(result_pool);
    }
  else if (from == NULL && to)
    {
      *deleted = svn_hash__make(result_pool);
      *added = svn_mergeinfo_dup(to, result_pool);
    }
  else
    {
      *deleted = svn_hash__make(result_pool);
      *added = svn_hash__make(result_pool);

      if (from && to)
        {
          SVN_ERR(walk_mergeinfo_hash_for_diff(from, to, *deleted, *added,
                                               consider_inheritance,
                                               result_pool, scratch_pool));
        }
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo__equals(svn_boolean_t *is_equal,
                      svn_mergeinfo_t info1,
                      svn_mergeinfo_t info2,
                      svn_boolean_t consider_inheritance,
                      apr_pool_t *pool)
{
  apr_hash_index_t *hi;

  *is_equal = FALSE;

  /* special cases: at least one side has no merge info */
  if (info1 == NULL && info2 == NULL)
    {
      *is_equal = TRUE;
      return SVN_NO_ERROR;
    }

  if (info1 == NULL ||  info2 == NULL)
    return SVN_NO_ERROR;

  /* trivial case: different number of paths -> unequal */
  if (apr_hash_count(info1) != apr_hash_count(info2))
    return SVN_NO_ERROR;

  /* compare range lists for all paths */
  for (hi = apr_hash_first(pool, info1); hi; hi = apr_hash_next(hi))
    {
      const char *key;
      apr_ssize_t key_length;
      svn_rangelist_t *lhs, *rhs;
      int i;
      svn_rangelist_t *deleted, *added;

      /* get both path lists */
      apr_hash_this(hi, (const void**)&key, &key_length, (void **)&lhs);
      rhs = apr_hash_get(info2, key, key_length);

      /* missing on one side? */
      if (rhs == NULL)
        return SVN_NO_ERROR;

      /* quick compare: the range lists will often be a perfect match */
      if (lhs->nelts == rhs->nelts)
        {
          for (i = 0; i < lhs->nelts; ++i)
            {
              svn_merge_range_t *lrange
                = APR_ARRAY_IDX(lhs, i, svn_merge_range_t *);
              svn_merge_range_t *rrange
                = APR_ARRAY_IDX(rhs, i, svn_merge_range_t *);

              /* range mismatch? -> needs detailed comparison */
              if (   lrange->start != rrange->start
                  || lrange->end != rrange->end)
                break;

              /* inheritance mismatch? -> merge info differs */
              if (   consider_inheritance
                  && lrange->inheritable != rrange->inheritable)
                return SVN_NO_ERROR;
            }

          /* all ranges found to match -> next path */
          if (i == lhs->nelts)
            continue;
        }

      /* range lists differ but there are many ways to sort and aggregate
         revisions into ranges. Do a full diff on them. */
      SVN_ERR(svn_rangelist_diff(&deleted, &added, lhs, rhs,
                                  consider_inheritance, pool));
      if (deleted->nelts || added->nelts)
        return SVN_NO_ERROR;
    }

  /* no mismatch found */
  *is_equal = TRUE;
  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo_merge2(svn_mergeinfo_t mergeinfo,
                     svn_mergeinfo_t changes,
                     apr_pool_t *result_pool,
                     apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;
  apr_pool_t *iterpool;

  if (!apr_hash_count(changes))
    return SVN_NO_ERROR;

  iterpool = svn_pool_create(scratch_pool);
  for (hi = apr_hash_first(scratch_pool, changes); hi; hi = apr_hash_next(hi))
    {
      const char *key;
      apr_ssize_t klen;
      svn_rangelist_t *to_insert;
      svn_rangelist_t *target;

      /* get ranges to insert and the target ranges list of that insertion */
      apr_hash_this(hi, (const void**)&key, &klen, (void*)&to_insert);
      target = apr_hash_get(mergeinfo, key, klen);

      /* if range list exists, just expand on it.
       * Otherwise, add new hash entry. */
      if (target)
        {
          SVN_ERR(svn_rangelist_merge2(target, to_insert, result_pool,
                                       iterpool));
          svn_pool_clear(iterpool);
        }
      else
        apr_hash_set(mergeinfo, key, klen, to_insert);
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo_catalog_merge(svn_mergeinfo_catalog_t mergeinfo_cat,
                            svn_mergeinfo_catalog_t changes_cat,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
{
  int i = 0;
  int j = 0;
  apr_array_header_t *sorted_cat =
    svn_sort__hash(mergeinfo_cat, svn_sort_compare_items_as_paths,
                   scratch_pool);
  apr_array_header_t *sorted_changes =
    svn_sort__hash(changes_cat, svn_sort_compare_items_as_paths,
                   scratch_pool);

  while (i < sorted_cat->nelts && j < sorted_changes->nelts)
    {
      svn_sort__item_t cat_elt, change_elt;
      int res;

      cat_elt = APR_ARRAY_IDX(sorted_cat, i, svn_sort__item_t);
      change_elt = APR_ARRAY_IDX(sorted_changes, j, svn_sort__item_t);
      res = svn_sort_compare_items_as_paths(&cat_elt, &change_elt);

      if (res == 0) /* Both catalogs have mergeinfo for a given path. */
        {
          svn_mergeinfo_t mergeinfo = cat_elt.value;
          svn_mergeinfo_t changes_mergeinfo = change_elt.value;

          SVN_ERR(svn_mergeinfo_merge2(mergeinfo, changes_mergeinfo,
                                       result_pool, scratch_pool));
          apr_hash_set(mergeinfo_cat, cat_elt.key, cat_elt.klen, mergeinfo);
          i++;
          j++;
        }
      else if (res < 0) /* Only MERGEINFO_CAT has mergeinfo for this path. */
        {
          i++;
        }
      else /* Only CHANGES_CAT has mergeinfo for this path. */
        {
          apr_hash_set(mergeinfo_cat,
                       apr_pstrdup(result_pool, change_elt.key),
                       change_elt.klen,
                       svn_mergeinfo_dup(change_elt.value, result_pool));
          j++;
        }
    }

  /* Copy back any remaining elements from the CHANGES_CAT catalog. */
  for (; j < sorted_changes->nelts; j++)
    {
      svn_sort__item_t elt = APR_ARRAY_IDX(sorted_changes, j,
                                           svn_sort__item_t);
      apr_hash_set(mergeinfo_cat,
                   apr_pstrdup(result_pool, elt.key),
                   elt.klen,
                   svn_mergeinfo_dup(elt.value, result_pool));
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo_intersect2(svn_mergeinfo_t *mergeinfo,
                         svn_mergeinfo_t mergeinfo1,
                         svn_mergeinfo_t mergeinfo2,
                         svn_boolean_t consider_inheritance,
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;
  apr_pool_t *iterpool;

  *mergeinfo = apr_hash_make(result_pool);
  iterpool = svn_pool_create(scratch_pool);

  /* ### TODO(reint): Do we care about the case when a path in one
     ### mergeinfo hash has inheritable mergeinfo, and in the other
     ### has non-inheritable mergeinfo?  It seems like that path
     ### itself should really be an intersection, while child paths
     ### should not be... */
  for (hi = apr_hash_first(scratch_pool, mergeinfo1);
       hi; hi = apr_hash_next(hi))
    {
      const char *path = apr_hash_this_key(hi);
      svn_rangelist_t *rangelist1 = apr_hash_this_val(hi);
      svn_rangelist_t *rangelist2;

      svn_pool_clear(iterpool);
      rangelist2 = svn_hash_gets(mergeinfo2, path);
      if (rangelist2)
        {
          SVN_ERR(svn_rangelist_intersect(&rangelist2, rangelist1, rangelist2,
                                          consider_inheritance, iterpool));
          if (rangelist2->nelts > 0)
            svn_hash_sets(*mergeinfo, apr_pstrdup(result_pool, path),
                          svn_rangelist_dup(rangelist2, result_pool));
        }
    }
  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo_remove2(svn_mergeinfo_t *mergeinfo,
                      svn_mergeinfo_t eraser,
                      svn_mergeinfo_t whiteboard,
                      svn_boolean_t consider_inheritance,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
{
  *mergeinfo = apr_hash_make(result_pool);
  return walk_mergeinfo_hash_for_diff(whiteboard, eraser, *mergeinfo, NULL,
                                      consider_inheritance, result_pool,
                                      scratch_pool);
}

svn_error_t *
svn_rangelist_to_string(svn_string_t **output,
                        const svn_rangelist_t *rangelist,
                        apr_pool_t *pool)
{
  svn_stringbuf_t *buf = svn_stringbuf_create_empty(pool);

  if (rangelist->nelts > 0)
    {
      int i;
      svn_merge_range_t *range;
      char *s;

      /* Handle the elements that need commas at the end.  */
      for (i = 0; i < rangelist->nelts - 1; i++)
        {
          range = APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
          SVN_ERR(range_to_string(&s, range, pool));
          svn_stringbuf_appendcstr(buf, s);
          svn_stringbuf_appendcstr(buf, ",");
        }

      /* Now handle the last element, which needs no comma.  */
      range = APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
      SVN_ERR(range_to_string(&s, range, pool));
      svn_stringbuf_appendcstr(buf, s);
    }

  *output = svn_stringbuf__morph_into_string(buf);

  return SVN_NO_ERROR;
}

/* Converts a mergeinfo INPUT to an unparsed mergeinfo in OUTPUT.  If PREFIX
   is not NULL then prepend PREFIX to each line in OUTPUT.  If INPUT contains
   no elements, return the empty string.  If INPUT contains any merge source
   path keys that are relative then convert these to absolute paths in
   *OUTPUT.
 */
static svn_error_t *
mergeinfo_to_stringbuf(svn_stringbuf_t **output,
                       svn_mergeinfo_t input,
                       const char *prefix,
                       apr_pool_t *pool)
{
  *output = svn_stringbuf_create_empty(pool);

  if (apr_hash_count(input) > 0)
    {
      apr_array_header_t *sorted =
        svn_sort__hash(input, svn_sort_compare_items_as_paths, pool);
      int i;

      for (i = 0; i < sorted->nelts; i++)
        {
          svn_sort__item_t elt = APR_ARRAY_IDX(sorted, i, svn_sort__item_t);
          svn_string_t *revlist;

          SVN_ERR(svn_rangelist_to_string(&revlist, elt.value, pool));
          svn_stringbuf_appendcstr(
            *output,
            apr_psprintf(pool, "%s%s%s:%s",
                         prefix ? prefix : "",
                         *((const char *) elt.key) == '/' ? "" : "/",
                         (const char *) elt.key,
                         revlist->data));
          if (i < sorted->nelts - 1)
            svn_stringbuf_appendcstr(*output, "\n");
        }
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo_to_string(svn_string_t **output, svn_mergeinfo_t input,
                        apr_pool_t *pool)
{
  svn_stringbuf_t *mergeinfo_buf;

  SVN_ERR(mergeinfo_to_stringbuf(&mergeinfo_buf, input, NULL, pool));
  *output = svn_stringbuf__morph_into_string(mergeinfo_buf);
  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo_sort(svn_mergeinfo_t input, apr_pool_t *pool)
{
  apr_hash_index_t *hi;

  for (hi = apr_hash_first(pool, input); hi; hi = apr_hash_next(hi))
    {
      apr_array_header_t *rl = apr_hash_this_val(hi);

      svn_sort__array(rl, svn_sort_compare_ranges);
    }
  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo__canonicalize_ranges(svn_mergeinfo_t mergeinfo,
                                   apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;

  for (hi = apr_hash_first(scratch_pool, mergeinfo); hi; hi = apr_hash_next(hi))
    {
      apr_array_header_t *rl = apr_hash_this_val(hi);

      SVN_ERR(svn_rangelist__canonicalize(rl, scratch_pool));
    }

  return SVN_NO_ERROR;
}

svn_mergeinfo_catalog_t
svn_mergeinfo_catalog_dup(svn_mergeinfo_catalog_t mergeinfo_catalog,
                          apr_pool_t *pool)
{
  svn_mergeinfo_t new_mergeinfo_catalog = apr_hash_make(pool);
  apr_hash_index_t *hi;

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

      svn_hash_sets(new_mergeinfo_catalog, apr_pstrdup(pool, key),
                    svn_mergeinfo_dup(val, pool));
    }

  return new_mergeinfo_catalog;
}

svn_mergeinfo_t
svn_mergeinfo_dup(svn_mergeinfo_t mergeinfo, apr_pool_t *pool)
{
  svn_mergeinfo_t new_mergeinfo = svn_hash__make(pool);
  apr_hash_index_t *hi;

  for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
    {
      const char *path = apr_hash_this_key(hi);
      apr_ssize_t pathlen = apr_hash_this_key_len(hi);
      svn_rangelist_t *rangelist = apr_hash_this_val(hi);

      apr_hash_set(new_mergeinfo, apr_pstrmemdup(pool, path, pathlen), pathlen,
                   svn_rangelist_dup(rangelist, pool));
    }

  return new_mergeinfo;
}

svn_error_t *
svn_mergeinfo_inheritable2(svn_mergeinfo_t *output,
                           svn_mergeinfo_t mergeinfo,
                           const char *path,
                           svn_revnum_t start,
                           svn_revnum_t end,
                           svn_boolean_t inheritable,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;
  svn_mergeinfo_t inheritable_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);
      apr_ssize_t keylen = apr_hash_this_key_len(hi);
      svn_rangelist_t *rangelist = apr_hash_this_val(hi);
      svn_rangelist_t *inheritable_rangelist;

      if (!path || svn_path_compare_paths(path, key) == 0)
        SVN_ERR(svn_rangelist_inheritable2(&inheritable_rangelist, rangelist,
                                           start, end, inheritable,
                                           result_pool, scratch_pool));
      else
        inheritable_rangelist = svn_rangelist_dup(rangelist, result_pool);

      /* Only add this rangelist if some ranges remain.  A rangelist with
         a path mapped to an empty rangelist is not syntactically valid */
      if (inheritable_rangelist->nelts)
        apr_hash_set(inheritable_mergeinfo,
                     apr_pstrmemdup(result_pool, key, keylen), keylen,
                     inheritable_rangelist);
    }
  *output = inheritable_mergeinfo;
  return SVN_NO_ERROR;
}


svn_error_t *
svn_rangelist_inheritable2(svn_rangelist_t **inheritable_rangelist,
                           const svn_rangelist_t *rangelist,
                           svn_revnum_t start,
                           svn_revnum_t end,
                           svn_boolean_t inheritable,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
{
  *inheritable_rangelist = apr_array_make(result_pool, 1,
                                          sizeof(svn_merge_range_t *));
  if (rangelist->nelts)
    {
      if (!SVN_IS_VALID_REVNUM(start)
          || !SVN_IS_VALID_REVNUM(end)
          || end < start)
        {
          /* We want all (non-inheritable or inheritable) ranges removed. */
          int i;

          for (i = 0; i < rangelist->nelts; i++)
            {
              svn_merge_range_t *range = APR_ARRAY_IDX(rangelist, i,
                                                       svn_merge_range_t *);
              if (range->inheritable == inheritable)
                {
                  APR_ARRAY_PUSH(*inheritable_rangelist, svn_merge_range_t *)
                    = svn_merge_range_dup(range, result_pool);
                }
            }
        }
      else
        {
          /* We want only the (non-inheritable or inheritable) ranges
             bound by START and END removed. */
          svn_rangelist_t *ranges_inheritable =
            svn_rangelist__initialize(start, end, inheritable, scratch_pool);

          if (rangelist->nelts)
            SVN_ERR(svn_rangelist_remove(inheritable_rangelist,
                                         ranges_inheritable,
                                         rangelist,
                                         TRUE,
                                         result_pool));
        }
    }
  return SVN_NO_ERROR;
}

svn_boolean_t
svn_mergeinfo__remove_empty_rangelists(svn_mergeinfo_t mergeinfo,
                                       apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;
  svn_boolean_t removed_some_ranges = FALSE;

  if (mergeinfo)
    {
      for (hi = apr_hash_first(scratch_pool, mergeinfo); hi;
           hi = apr_hash_next(hi))
        {
          const char *path = apr_hash_this_key(hi);
          svn_rangelist_t *rangelist = apr_hash_this_val(hi);

          if (rangelist->nelts == 0)
            {
              svn_hash_sets(mergeinfo, path, NULL);
              removed_some_ranges = TRUE;
            }
        }
    }
  return removed_some_ranges;
}

svn_error_t *
svn_mergeinfo__remove_prefix_from_catalog(svn_mergeinfo_catalog_t *out_catalog,
                                          svn_mergeinfo_catalog_t in_catalog,
                                          const char *prefix_path,
                                          apr_pool_t *pool)
{
  apr_hash_index_t *hi;

  SVN_ERR_ASSERT(prefix_path[0] == '/');

  *out_catalog = apr_hash_make(pool);

  for (hi = apr_hash_first(pool, in_catalog); hi; hi = apr_hash_next(hi))
    {
      const char *original_path = apr_hash_this_key(hi);
      svn_mergeinfo_t value = apr_hash_this_val(hi);
      const char *new_path;

      new_path = svn_fspath__skip_ancestor(prefix_path, original_path);
      SVN_ERR_ASSERT(new_path);

      svn_hash_sets(*out_catalog, new_path, value);
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo__add_prefix_to_catalog(svn_mergeinfo_catalog_t *out_catalog,
                                     svn_mergeinfo_catalog_t in_catalog,
                                     const char *prefix_path,
                                     apr_pool_t *result_pool,
                                     apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;

  *out_catalog = apr_hash_make(result_pool);

  for (hi = apr_hash_first(scratch_pool, in_catalog);
       hi;
       hi = apr_hash_next(hi))
    {
      const char *original_path = apr_hash_this_key(hi);
      svn_mergeinfo_t value = apr_hash_this_val(hi);

      if (original_path[0] == '/')
        original_path++;

      svn_hash_sets(*out_catalog,
                    svn_dirent_join(prefix_path, original_path, result_pool),
                    value);
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo__add_suffix_to_mergeinfo(svn_mergeinfo_t *out_mergeinfo,
                                       svn_mergeinfo_t mergeinfo,
                                       const char *suffix_relpath,
                                       apr_pool_t *result_pool,
                                       apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;

  SVN_ERR_ASSERT(suffix_relpath && svn_relpath_is_canonical(suffix_relpath));

  *out_mergeinfo = apr_hash_make(result_pool);

  for (hi = apr_hash_first(scratch_pool, mergeinfo);
       hi;
       hi = apr_hash_next(hi))
    {
      const char *fspath = apr_hash_this_key(hi);
      svn_rangelist_t *rangelist = apr_hash_this_val(hi);

      svn_hash_sets(*out_mergeinfo,
                    svn_fspath__join(fspath, suffix_relpath, result_pool),
                    rangelist);
    }

  return SVN_NO_ERROR;
}

/* Deep-copy an array of pointers to simple objects.
 *
 * Return a duplicate in POOL of the array ARRAY of pointers to objects
 * of size OBJECT_SIZE bytes. Duplicate each object bytewise.
 */
static apr_array_header_t *
ptr_array_dup(const apr_array_header_t *array,
              size_t object_size,
              apr_pool_t *pool)
{
  apr_array_header_t *new_array = apr_array_make(pool, array->nelts,
                                                 sizeof(void *));

  /* allocate target range buffer with a single operation */
  char *copy = apr_palloc(pool, object_size * array->nelts);

  /* for efficiency, directly address source and target reference buffers */
  void **source = (void **)(array->elts);
  void **target = (void **)(new_array->elts);
  int i;

  /* copy ranges iteratively and link them into the target range list */
  for (i = 0; i < array->nelts; i++)
    {
      target[i] = &copy[i * object_size];
      memcpy(target[i], source[i], object_size);
    }
  new_array->nelts = array->nelts;

  return new_array;
}

svn_rangelist_t *
svn_rangelist_dup(const svn_rangelist_t *rangelist, apr_pool_t *pool)
{
  return ptr_array_dup(rangelist, sizeof(svn_merge_range_t), pool);
}

svn_merge_range_t *
svn_merge_range_dup(const svn_merge_range_t *range, apr_pool_t *pool)
{
  svn_merge_range_t *new_range = apr_pmemdup(pool, range, sizeof(*new_range));
  return new_range;
}

svn_boolean_t
svn_merge_range_contains_rev(const svn_merge_range_t *range, svn_revnum_t rev)
{
  assert(SVN_IS_VALID_REVNUM(range->start));
  assert(SVN_IS_VALID_REVNUM(range->end));
  assert(range->start != range->end);

  if (range->start < range->end)
    return rev > range->start && rev <= range->end;
  else
    return rev > range->end && rev <= range->start;
}

svn_error_t *
svn_mergeinfo__catalog_to_formatted_string(svn_string_t **output,
                                           svn_mergeinfo_catalog_t catalog,
                                           const char *key_prefix,
                                           const char *val_prefix,
                                           apr_pool_t *pool)
{
  svn_stringbuf_t *output_buf = NULL;

  if (catalog && apr_hash_count(catalog))
    {
      int i;
      apr_array_header_t *sorted_catalog =
        svn_sort__hash(catalog, svn_sort_compare_items_as_paths, pool);

      output_buf = svn_stringbuf_create_empty(pool);
      for (i = 0; i < sorted_catalog->nelts; i++)
        {
          svn_sort__item_t elt =
            APR_ARRAY_IDX(sorted_catalog, i, svn_sort__item_t);
          const char *path1;
          svn_mergeinfo_t mergeinfo;
          svn_stringbuf_t *mergeinfo_output_buf;

          path1 = elt.key;
          mergeinfo = elt.value;
          if (key_prefix)
            svn_stringbuf_appendcstr(output_buf, key_prefix);
          svn_stringbuf_appendcstr(output_buf, path1);
          svn_stringbuf_appendcstr(output_buf, "\n");
          SVN_ERR(mergeinfo_to_stringbuf(&mergeinfo_output_buf, mergeinfo,
                                         val_prefix ? val_prefix : "", pool));
          svn_stringbuf_appendstr(output_buf, mergeinfo_output_buf);
          svn_stringbuf_appendcstr(output_buf, "\n");
        }
    }
#ifdef SVN_DEBUG
  else if (!catalog)
    {
      output_buf = svn_stringbuf_create(key_prefix ? key_prefix : "", pool);
      svn_stringbuf_appendcstr(output_buf, _("NULL mergeinfo catalog\n"));
    }
  else if (apr_hash_count(catalog) == 0)
    {
      output_buf = svn_stringbuf_create(key_prefix ? key_prefix : "", pool);
      svn_stringbuf_appendcstr(output_buf, _("empty mergeinfo catalog\n"));
    }
#endif

  /* If we have an output_buf, convert it to an svn_string_t;
     otherwise, return a new string containing only a newline
     character.  */
  if (output_buf)
    *output = svn_stringbuf__morph_into_string(output_buf);
  else
    *output = svn_string_create("\n", pool);

  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo__get_range_endpoints(svn_revnum_t *youngest_rev,
                                   svn_revnum_t *oldest_rev,
                                   svn_mergeinfo_t mergeinfo,
                                   apr_pool_t *pool)
{
  *youngest_rev = *oldest_rev = SVN_INVALID_REVNUM;
  if (mergeinfo)
    {
      apr_hash_index_t *hi;

      for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
        {
          svn_rangelist_t *rangelist = apr_hash_this_val(hi);

          if (rangelist->nelts)
            {
              svn_merge_range_t *range = APR_ARRAY_IDX(rangelist,
                                                       rangelist->nelts - 1,
                                                       svn_merge_range_t *);
              if (!SVN_IS_VALID_REVNUM(*youngest_rev)
                  || (range->end > *youngest_rev))
                *youngest_rev = range->end;

              range = APR_ARRAY_IDX(rangelist, 0, svn_merge_range_t *);
              if (!SVN_IS_VALID_REVNUM(*oldest_rev)
                  || (range->start < *oldest_rev))
                *oldest_rev = range->start;
            }
        }
    }
  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo__filter_catalog_by_ranges(svn_mergeinfo_catalog_t *filtered_cat,
                                        svn_mergeinfo_catalog_t catalog,
                                        svn_revnum_t youngest_rev,
                                        svn_revnum_t oldest_rev,
                                        svn_boolean_t include_range,
                                        apr_pool_t *result_pool,
                                        apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;

  *filtered_cat = apr_hash_make(result_pool);
  for (hi = apr_hash_first(scratch_pool, catalog);
       hi;
       hi = apr_hash_next(hi))
    {
      const char *path = apr_hash_this_key(hi);
      svn_mergeinfo_t mergeinfo = apr_hash_this_val(hi);
      svn_mergeinfo_t filtered_mergeinfo;

      SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(&filtered_mergeinfo,
                                                        mergeinfo,
                                                        youngest_rev,
                                                        oldest_rev,
                                                        include_range,
                                                        result_pool,
                                                        scratch_pool));
      if (apr_hash_count(filtered_mergeinfo))
        svn_hash_sets(*filtered_cat,
                      apr_pstrdup(result_pool, path), filtered_mergeinfo);
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo__filter_mergeinfo_by_ranges(svn_mergeinfo_t *filtered_mergeinfo,
                                          svn_mergeinfo_t mergeinfo,
                                          svn_revnum_t youngest_rev,
                                          svn_revnum_t oldest_rev,
                                          svn_boolean_t include_range,
                                          apr_pool_t *result_pool,
                                          apr_pool_t *scratch_pool)
{
  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(oldest_rev));
  SVN_ERR_ASSERT(oldest_rev < youngest_rev);

  *filtered_mergeinfo = apr_hash_make(result_pool);

  if (mergeinfo)
    {
      apr_hash_index_t *hi;
      svn_rangelist_t *filter_rangelist =
        svn_rangelist__initialize(oldest_rev, youngest_rev, TRUE,
                                  scratch_pool);

      for (hi = apr_hash_first(scratch_pool, mergeinfo);
           hi;
           hi = apr_hash_next(hi))
        {
          const char *path = apr_hash_this_key(hi);
          svn_rangelist_t *rangelist = apr_hash_this_val(hi);

          if (rangelist->nelts)
            {
              svn_rangelist_t *new_rangelist;

              SVN_ERR(rangelist_intersect_or_remove(
                        &new_rangelist, filter_rangelist, rangelist,
                        ! include_range, FALSE, result_pool));

              if (new_rangelist->nelts)
                svn_hash_sets(*filtered_mergeinfo,
                              apr_pstrdup(result_pool, path), new_rangelist);
            }
        }
    }
  return SVN_NO_ERROR;
}

svn_error_t *
svn_mergeinfo__adjust_mergeinfo_rangelists(svn_mergeinfo_t *adjusted_mergeinfo,
                                           svn_mergeinfo_t mergeinfo,
                                           svn_revnum_t offset,
                                           apr_pool_t *result_pool,
                                           apr_pool_t *scratch_pool)
{
  apr_hash_index_t *hi;
  *adjusted_mergeinfo = apr_hash_make(result_pool);

  if (mergeinfo)
    {
      for (hi = apr_hash_first(scratch_pool, mergeinfo);
           hi;
           hi = apr_hash_next(hi))
        {
          int i;
          const char *path = apr_hash_this_key(hi);
          svn_rangelist_t *rangelist = apr_hash_this_val(hi);
          svn_rangelist_t *adjusted_rangelist =
            apr_array_make(result_pool, rangelist->nelts,
                           sizeof(svn_merge_range_t *));

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

              if (range->start + offset > 0 && range->end + offset > 0)
                {
                  range->start = range->start + offset;
                  range->end = range->end + offset;
                  APR_ARRAY_PUSH(adjusted_rangelist, svn_merge_range_t *) =
                    range;
                }
            }

          if (adjusted_rangelist->nelts)
            svn_hash_sets(*adjusted_mergeinfo, apr_pstrdup(result_pool, path),
                          adjusted_rangelist);
        }
    }
  return SVN_NO_ERROR;
}

svn_boolean_t
svn_mergeinfo__is_noninheritable(svn_mergeinfo_t mergeinfo,
                                 apr_pool_t *scratch_pool)
{
  if (mergeinfo)
    {
      apr_hash_index_t *hi;

      for (hi = apr_hash_first(scratch_pool, mergeinfo);
           hi;
           hi = apr_hash_next(hi))
        {
          svn_rangelist_t *rangelist = apr_hash_this_val(hi);
          int i;

          for (i = 0; i < rangelist->nelts; i++)
            {
              svn_merge_range_t *range = APR_ARRAY_IDX(rangelist, i,
                                                       svn_merge_range_t *);
              if (!range->inheritable)
                return TRUE;
            }
        }
    }
  return FALSE;
}

svn_rangelist_t *
svn_rangelist__initialize(svn_revnum_t start,
                          svn_revnum_t end,
                          svn_boolean_t inheritable,
                          apr_pool_t *result_pool)
{
  svn_rangelist_t *rangelist =
    apr_array_make(result_pool, 1, sizeof(svn_merge_range_t *));
  svn_merge_range_t *range = apr_pcalloc(result_pool, sizeof(*range));

  range->start = start;
  range->end = end;
  range->inheritable = inheritable;
  APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = range;
  return rangelist;
}

svn_error_t *
svn_mergeinfo__mergeinfo_from_segments(svn_mergeinfo_t *mergeinfo_p,
                                       const apr_array_header_t *segments,
                                       apr_pool_t *pool)
{
  svn_mergeinfo_t mergeinfo = apr_hash_make(pool);
  int i;

  /* Translate location segments into merge sources and ranges. */
  for (i = 0; i < segments->nelts; i++)
    {
      svn_location_segment_t *segment =
        APR_ARRAY_IDX(segments, i, svn_location_segment_t *);
      svn_rangelist_t *path_ranges;
      svn_merge_range_t *range;
      const char *source_path;

      /* No path segment?  Skip it. */
      if (! segment->path)
        continue;

      /* Prepend a leading slash to our path. */
      source_path = apr_pstrcat(pool, "/", segment->path, SVN_VA_NULL);

      /* See if we already stored ranges for this path.  If not, make
         a new list.  */
      path_ranges = svn_hash_gets(mergeinfo, source_path);
      if (! path_ranges)
        path_ranges = apr_array_make(pool, 1, sizeof(range));

      /* A svn_location_segment_t may have legitimately describe only
         revision 0, but there is no corresponding representation for
         this in a svn_merge_range_t. */
      if (segment->range_start == 0 && segment->range_end == 0)
        continue;

      /* Build a merge range, push it onto the list of ranges, and for
         good measure, (re)store it in the hash. */
      range = apr_pcalloc(pool, sizeof(*range));
      range->start = MAX(segment->range_start - 1, 0);
      range->end = segment->range_end;
      range->inheritable = TRUE;
      APR_ARRAY_PUSH(path_ranges, svn_merge_range_t *) = range;
      svn_hash_sets(mergeinfo, source_path, path_ranges);
    }

  *mergeinfo_p = mergeinfo;
  return SVN_NO_ERROR;
}

svn_error_t *
svn_rangelist__merge_many(svn_rangelist_t *merged_rangelist,
                          svn_mergeinfo_t merge_history,
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
{
  if (apr_hash_count(merge_history))
    {
      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
      apr_hash_index_t *hi;

      for (hi = apr_hash_first(scratch_pool, merge_history);
           hi;
           hi = apr_hash_next(hi))
        {
          svn_rangelist_t *subtree_rangelist = apr_hash_this_val(hi);

          svn_pool_clear(iterpool);
          SVN_ERR(svn_rangelist_merge2(merged_rangelist, subtree_rangelist,
                                       result_pool, iterpool));
        }
      svn_pool_destroy(iterpool);
    }
  return SVN_NO_ERROR;
}


const char *
svn_inheritance_to_word(svn_mergeinfo_inheritance_t inherit)
{
  switch (inherit)
    {
    case svn_mergeinfo_inherited:
      return "inherited";
    case svn_mergeinfo_nearest_ancestor:
      return "nearest-ancestor";
    default:
      return "explicit";
    }
}

svn_mergeinfo_inheritance_t
svn_inheritance_from_word(const char *word)
{
  if (strcmp(word, "inherited") == 0)
    return svn_mergeinfo_inherited;
  if (strcmp(word, "nearest-ancestor") == 0)
    return svn_mergeinfo_nearest_ancestor;
  return svn_mergeinfo_explicit;
}
