emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] feature/noverlay 8d7bdfa: Provide a new tree data-structur


From: Andreas Politz
Subject: [Emacs-diffs] feature/noverlay 8d7bdfa: Provide a new tree data-structure for overlays.
Date: Wed, 4 Oct 2017 16:34:21 -0400 (EDT)

branch: feature/noverlay
commit 8d7bdfa3fca076b34aaf86548d3243bee11872ad
Author: Andreas Politz <address@hidden>
Commit: Andreas Politz <address@hidden>

    Provide a new tree data-structure for overlays.
    
    * src/itree.c
    (interval_generator_narrow, interval_generator_next)
    (interval_node_init, interval_node_begin)
    (interval_node_end, interval_node_set_region)
    (interval_tree_create, interval_tree_clear)
    (interval_tree_init, interval_tree_destroy)
    (interval_tree_size, interval_tree_insert)
    (interval_tree_contains, interval_tree_remove)
    (interval_tree_validate, interval_tree_iter_start)
    (interval_tree_iter_finish, interval_tree_iter_next)
    (interval_tree_iter_ensure_space, interval_tree_max_height)
    (interval_tree_insert_gap, interval_tree_delete_gap)
    (interval_generator_create, interval_generator_reset)
    (interval_generator_ensure_space, interval_node_intersects)
    (interval_generator_next, interval_generator_narrow)
    (interval_generator_destroy, interval_stack_create)
    (interval_stack_destroy, interval_stack_clear)
    (interval_stack_ensure_space, interval_stack_push)
    (interval_stack_push_flagged, interval_stack_pop)
    (interval_tree_update_limit, interval_tree_inherit_offset)
    (interval_tree_propagate_limit, interval_tree_rotate_left)
    (interval_tree_rotate_right, interval_tree_insert_fix)
    (interval_tree_remove_fix, interval_tree_transplant)
    (interval_tree_subtree_min): New file and new functions.
    
    * src/itree.h: New file.
    
    * configure.ac: Create Makefile for manual overlay tests.
    
    * src/Makefile.in: Add itree.o target.
    
    * src/alloc.c (build_overlay, mark_overlay, mark_buffer)
    (sweep_misc, sweep_buffers): Adapt to new tree data-structure.
    
    * src/buffer.c (overlays_in, overlays_at): Remove unused arguments
    prev_ptr and change_req, adapt to new data-structure and reuse
    code.
    (copy_overlays, drop_overlays, delete_all_overlays)
    (reset_buffer, kill-buffer, buffer-swap-text, next_overlay_change)
    (previous_overlay_change, mouse_face_overlay_overlaps)
    (disable_line_numbers_overlay_at_eob, overlay_touches_p)
    (overlay_strings, adjust_overlays_for_insert)
    (adjust_overlays_for_delete, overlayp, make-overlay, move-overlay)
    (delete-overlay, overlay-start, overlay-end, overlay-buffer)
    (overlay-properties, overlays-at, overlays-in)
    (next-overlay-change, previous-overlay-change, overlay-put)
    (overlay-get, report_overlay_modification, evaporate_overlays)
    (init_buffer_once): Adapt to changes and tree data-structure.
    (overlay-lists, overlay-recenter): Funtions are now obsolete, but
    kept anyway.
    (set_buffer_overlays_before, set_buffer_overlays_after)
    (recenter_overlay_lists,fix_start_end_in_overlays,fix_overlays_before)
    (unchain_overlay,): Removed functions of the old list
    data-structure.
    (swap_buffer_overlays, make_sortvec_item): New functions.
    (sort_overlays): Adapt to changes and tree data-structure.
    (sortvec): Moved to buffer.h .
    (make_lispy_interval_node, overlay_tree, overlay-tree)
    [ITREE_DEBUG]: New debugging functions.
    
    * src/buffer.h (overlays_before, overlays_after): Removed struct
    member of the list data-structure.
    (overlays): Added tree struct member.
    (sortvec): Moved here from buffer.c .
    (GET_OVERLAYS_AT): Adapt to changes.
    (set_buffer_intervals, OVERLAY_START, OVERLAY_END, OVERLAY_PLIST):
    Adapt to tree data-structure.
    (OVERLAY_POSITION): Removed macro of the list data-structure.
    (OVERLAY_REAR_ADVANCE_P, OVERLAY_FRONT_ADVANCE_P): New macros.
    (overlay_start, overlay_end)
    (set_overlay_region, maybe_alloc_buffer_overlays)
    (free_buffer_overlays, add_buffer_overlay)
    (remove_buffer_overlay, buffer_overlay_iter_start)
    (buffer_overlay_iter_next, buffer_overlay_iter_finish)
    (buffer_overlay_iter_narrow): New functions.
    (compare_overlays, make_sortvec_item): Export functions.
    
    * src/editfns.c (overlays_around): Reuse overlays_in.
    (get-pos-property): Adapt to tree data-structure.
    (transpose-regions): Remove call to deleted function.
    
    * src/fileio.c: (insert-file-contents): Remove
    references to deleted struct member.
    
    * src/fns.c (internal_equal): Adapt to tree data-structure.
    
    * src/indent.c (check_display_width): Adapt to tree
    data-structure.
    (skip_invisible): Remove call to deleted function.
    
    * src/insdel.c (adjust_markers_for_insert): Remove calls to
    deleted functions.
    
    * src/intervals.c (adjust_for_invis_intang): Adapt to tree
    data-structure.
    
    * src/keyboard.c (adjust_point_for_property): Adapt to tree
    data-structure.
    
    * src/lisp.h (Lisp_Overlay): Modified struct layout.
    
    * src/print.c (temp_output_buffer_setup, print_object): Adapt to
    tree data-structure.
    
    * src/textprop.c (get_char_property_and_overlay): Adapt to tree
    data-structure.  Take advantage of the new data-structure.
    
    * src/window.h (overlay_matches_window): New function.
    
    * src/xdisp.h (next_overlay_change): Removed function.  Use
    next-overlay-change, which does not use xmalloc anymore.
    (handle_single_display_spec, load_overlay_strings)
    (back_to_previous_visible_line_start, note_mouse_highlight): Adapt
    to tree data-structure.
    (move_it_to, display_line): Remove calls to deleted functions.
    
    * src/xfaces.c (face_at_buffer_position): Adapt to changes and
    tree data-structure.
    
    * test/src/buffer-tests.el: Many tests regarding overlays added.
    
    * test/manual/noverlay/itree-tests.c: New file with tests of the
    tree data-structure on the C level.
    * test/manual/noverlay/Makefile.in: New file.
    * test/manual/noverlay/check-sanitize.sh: New file.
    * test/manual/noverlay/emacs-compat.h: New file.
    * test/manual/noverlay/.gitignore: New file.
    
    * test/manual/noverlay/overlay-perf.el: New file providing
    performance tests.
    * test/manual/noverlay/many-errors.h: New file.
---
 configure.ac                           |    1 +
 src/Makefile.in                        |    1 +
 src/alloc.c                            |   49 +-
 src/buffer.c                           | 1458 ++-----
 src/buffer.h                           |  161 +-
 src/editfns.c                          |   56 +-
 src/fileio.c                           |    3 +-
 src/fns.c                              |    7 +-
 src/indent.c                           |    5 +-
 src/insdel.c                           |   12 -
 src/intervals.c                        |    4 +-
 src/itree.c                            | 1138 +++++
 src/itree.h                            |   88 +
 src/keyboard.c                         |    4 +-
 src/lisp.h                             |   19 +-
 src/print.c                            |   12 +-
 src/textprop.c                         |   52 +-
 src/window.h                           |   10 +
 src/xdisp.c                            |  167 +-
 src/xfaces.c                           |   17 +-
 test/manual/noverlay/.gitignore        |    1 +
 test/manual/noverlay/Makefile.in       |   32 +
 test/manual/noverlay/check-sanitize.sh |   11 +
 test/manual/noverlay/emacs-compat.h    |   52 +
 test/manual/noverlay/itree-tests.c     | 1381 ++++++
 test/manual/noverlay/many-errors.py    | 2480 +++++++++++
 test/manual/noverlay/overlay-perf.el   |  764 ++++
 test/src/buffer-tests.el               | 7519 ++++++++++++++++++++++++++++++++
 28 files changed, 14157 insertions(+), 1347 deletions(-)

diff --git a/configure.ac b/configure.ac
index eba95e2..76cf557 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5495,6 +5495,7 @@ if test -f "$srcdir/$opt_makefile.in"; then
   dnl Again, it's best not to use a variable.  Though you can add
   dnl ", [], [opt_makefile='$opt_makefile']" and it should work.
   AC_CONFIG_FILES([test/Makefile])
+  AC_CONFIG_FILES([test/manual/noverlay/Makefile])
 fi
 
 
diff --git a/src/Makefile.in b/src/Makefile.in
index 9a8c9c8..8a8df03 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -395,6 +395,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o 
$(XMENU_OBJ) window.o \
        $(XWIDGETS_OBJ) \
        profiler.o decompress.o \
        thread.o systhread.o \
+       itree.o \
        $(if $(HYBRID_MALLOC),sheap.o) \
        $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
        $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ)
diff --git a/src/alloc.c b/src/alloc.c
index 2e6399e..15a6fc4 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -43,6 +43,7 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include "frame.h"
 #include "blockinput.h"
 #include "termhooks.h"         /* For struct terminal.  */
+#include "itree.h"
 #ifdef HAVE_WINDOW_SYSTEM
 #include TERM_HEADER
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -3835,16 +3836,19 @@ free_save_value (Lisp_Object save)
 /* Return a Lisp_Misc_Overlay object with specified START, END and PLIST.  */
 
 Lisp_Object
-build_overlay (Lisp_Object start, Lisp_Object end, Lisp_Object plist)
+build_overlay (ptrdiff_t begin, ptrdiff_t end,
+               bool front_advance, bool rear_advance,
+               Lisp_Object plist)
 {
-  register Lisp_Object overlay;
+  Lisp_Object ov = allocate_misc (Lisp_Misc_Overlay);
+  struct interval_node *node = xmalloc (sizeof (*node));
 
-  overlay = allocate_misc (Lisp_Misc_Overlay);
-  OVERLAY_START (overlay) = start;
-  OVERLAY_END (overlay) = end;
-  set_overlay_plist (overlay, plist);
-  XOVERLAY (overlay)->next = NULL;
-  return overlay;
+  interval_node_init (node, begin, end, front_advance,
+                      rear_advance, ov);
+  XOVERLAY (ov)->interval = node;
+  XOVERLAY (ov)->buffer = NULL;
+  set_overlay_plist (ov, plist);
+  return ov;
 }
 
 DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0,
@@ -6280,16 +6284,10 @@ mark_compiled (struct Lisp_Vector *ptr)
 /* Mark the chain of overlays starting at PTR.  */
 
 static void
-mark_overlay (struct Lisp_Overlay *ptr)
+mark_overlay (struct Lisp_Overlay *ov)
 {
-  for (; ptr && !ptr->gcmarkbit; ptr = ptr->next)
-    {
-      ptr->gcmarkbit = 1;
-      /* These two are always markers and can be marked fast.  */
-      XMARKER (ptr->start)->gcmarkbit = 1;
-      XMARKER (ptr->end)->gcmarkbit = 1;
-      mark_object (ptr->plist);
-    }
+  ov->gcmarkbit = 1;
+  mark_object (ov->plist);
 }
 
 /* Mark Lisp_Objects and special pointers in BUFFER.  */
@@ -6308,8 +6306,15 @@ mark_buffer (struct buffer *buffer)
      a special way just before the sweep phase, and after stripping
      some of its elements that are not needed any more.  */
 
-  mark_overlay (buffer->overlays_before);
-  mark_overlay (buffer->overlays_after);
+  if (buffer->overlays)
+    {
+      struct interval_node *node;
+      buffer_overlay_iter_start (buffer, PTRDIFF_MIN, PTRDIFF_MAX, 
ITREE_ASCENDING);
+
+      while ((node = buffer_overlay_iter_next (buffer)))
+        mark_overlay (XOVERLAY (node->data));
+      buffer_overlay_iter_finish (buffer);
+    }
 
   /* If this is an indirect buffer, mark its base buffer.  */
   if (buffer->base_buffer && !VECTOR_MARKED_P (buffer->base_buffer))
@@ -7090,6 +7095,11 @@ sweep_misc (void)
                 unchain_marker (&mblk->markers[i].m.u_marker);
               else if (mblk->markers[i].m.u_any.type == Lisp_Misc_Finalizer)
                 unchain_finalizer (&mblk->markers[i].m.u_finalizer);
+              else if (mblk->markers[i].m.u_any.type == Lisp_Misc_Overlay)
+                {
+                  xfree (mblk->markers[i].m.u_overlay.interval);
+                  mblk->markers[i].m.u_overlay.interval = NULL;
+                }
 #ifdef HAVE_MODULES
              else if (mblk->markers[i].m.u_any.type == Lisp_Misc_User_Ptr)
                {
@@ -7145,6 +7155,7 @@ sweep_buffers (void)
     if (!VECTOR_MARKED_P (buffer))
       {
         *bprev = buffer->next;
+        free_buffer_overlays (buffer);
         lisp_free (buffer);
       }
     else
diff --git a/src/buffer.c b/src/buffer.c
index 76670b8..21c040a 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -44,6 +44,7 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include "keymap.h"
 #include "frame.h"
 #include "xwidget.h"
+#include "itree.h"
 
 #ifdef WINDOWSNT
 #include "w32heap.h"           /* for mmap_* */
@@ -120,7 +121,7 @@ static Lisp_Object QSFundamental;   /* A string 
"Fundamental".  */
 
 static void alloc_buffer_text (struct buffer *, ptrdiff_t);
 static void free_buffer_text (struct buffer *b);
-static struct Lisp_Overlay * copy_overlays (struct buffer *, struct 
Lisp_Overlay *);
+static void copy_overlays (struct buffer *, struct buffer *);
 static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t);
 static Lisp_Object buffer_lisp_local_variables (struct buffer *, bool);
 
@@ -600,51 +601,30 @@ even if it is dead.  The return value is never nil.  */)
 }
 
 
-/* Return a list of overlays which is a copy of the overlay list
-   LIST, but for buffer B.  */
+/* Copy overlays of buffer FROM to buffer TO.  */
 
-static struct Lisp_Overlay *
-copy_overlays (struct buffer *b, struct Lisp_Overlay *list)
+static void
+copy_overlays (struct buffer *from, struct buffer *to)
 {
-  struct Lisp_Overlay *result = NULL, *tail = NULL;
+  eassert (to && ! to->overlays);
 
-  for (; list; list = list->next)
-    {
-      Lisp_Object overlay, start, end;
-      struct Lisp_Marker *m;
-
-      eassert (MARKERP (list->start));
-      m = XMARKER (list->start);
-      start = build_marker (b, m->charpos, m->bytepos);
-      XMARKER (start)->insertion_type = m->insertion_type;
-
-      eassert (MARKERP (list->end));
-      m = XMARKER (list->end);
-      end = build_marker (b, m->charpos, m->bytepos);
-      XMARKER (end)->insertion_type = m->insertion_type;
-
-      overlay = build_overlay (start, end, Fcopy_sequence (list->plist));
-      if (tail)
-       tail = tail->next = XOVERLAY (overlay);
-      else
-       result = tail = XOVERLAY (overlay);
-    }
-
-  return result;
-}
+  struct interval_node *node;
 
-/* Set an appropriate overlay of B.  */
+  if (! from->overlays)
+    return;
 
-static void
-set_buffer_overlays_before (struct buffer *b, struct Lisp_Overlay *o)
-{
-  b->overlays_before = o;
-}
+  buffer_overlay_iter_start (from, PTRDIFF_MIN, PTRDIFF_MAX, ITREE_ASCENDING);
 
-static void
-set_buffer_overlays_after (struct buffer *b, struct Lisp_Overlay *o)
-{
-  b->overlays_after = o;
+  while ((node = buffer_overlay_iter_next (from)))
+    {
+      Lisp_Object ov = node->data;
+      Lisp_Object copy = build_overlay (node->begin, node->end,
+                                        node->front_advance,
+                                        node->rear_advance,
+                                        Fcopy_sequence (OVERLAY_PLIST (ov)));
+      add_buffer_overlay (to, XOVERLAY (copy));
+    }
+  buffer_overlay_iter_finish (from);
 }
 
 /* Clone per-buffer values of buffer FROM.
@@ -681,8 +661,7 @@ clone_per_buffer_values (struct buffer *from, struct buffer 
*to)
 
   memcpy (to->local_flags, from->local_flags, sizeof to->local_flags);
 
-  set_buffer_overlays_before (to, copy_overlays (to, from->overlays_before));
-  set_buffer_overlays_after (to, copy_overlays (to, from->overlays_after));
+  copy_overlays (from, to);
 
   /* Get (a copy of) the alist of Lisp-level local variables of FROM
      and install that in TO.  */
@@ -867,17 +846,16 @@ CLONE nil means the indirect buffer's state is reset to 
default values.  */)
   return buf;
 }
 
-/* Mark OV as no longer associated with B.  */
+/* Mark OV as no longer associated with its buffer.  */
 
 static void
-drop_overlay (struct buffer *b, struct Lisp_Overlay *ov)
+drop_overlay (struct Lisp_Overlay *ov)
 {
-  eassert (b == XBUFFER (Fmarker_buffer (ov->start)));
-  modify_overlay (b, marker_position (ov->start),
-                 marker_position (ov->end));
-  unchain_marker (XMARKER (ov->start));
-  unchain_marker (XMARKER (ov->end));
+  if (! ov->buffer)
+    return;
 
+  modify_overlay (ov->buffer, overlay_start (ov), overlay_end (ov));
+  remove_buffer_overlay (ov->buffer, ov);
 }
 
 /* Delete all overlays of B and reset its overlay lists.  */
@@ -885,26 +863,20 @@ drop_overlay (struct buffer *b, struct Lisp_Overlay *ov)
 void
 delete_all_overlays (struct buffer *b)
 {
-  struct Lisp_Overlay *ov, *next;
+  struct interval_node *node;
 
-  /* FIXME: Since each drop_overlay will scan BUF_MARKERS to unlink its
-     markers, we have an unneeded O(N^2) behavior here.  */
-  for (ov = b->overlays_before; ov; ov = next)
-    {
-      drop_overlay (b, ov);
-      next = ov->next;
-      ov->next = NULL;
-    }
+  if (! b->overlays)
+    return;
 
-  for (ov = b->overlays_after; ov; ov = next)
+  buffer_overlay_iter_start (b, PTRDIFF_MIN, PTRDIFF_MAX, ITREE_ASCENDING);
+  while ((node = buffer_overlay_iter_next (b)))
     {
-      drop_overlay (b, ov);
-      next = ov->next;
-      ov->next = NULL;
+      modify_overlay (b, node->begin, node->end);
+      /* Where are the nodes freed ? --ap */
+      XOVERLAY (node->data)->buffer = NULL;
     }
-
-  set_buffer_overlays_before (b, NULL);
-  set_buffer_overlays_after (b, NULL);
+  buffer_overlay_iter_finish (b);
+  interval_tree_clear (b->overlays);
 }
 
 /* Reinitialize everything about a buffer except its name and contents
@@ -932,9 +904,7 @@ reset_buffer (register struct buffer *b)
   b->auto_save_failure_time = 0;
   bset_auto_save_file_name (b, Qnil);
   bset_read_only (b, Qnil);
-  set_buffer_overlays_before (b, NULL);
-  set_buffer_overlays_after (b, NULL);
-  b->overlay_center = BEG;
+  b->overlays = NULL;
   bset_mark_active (b, Qnil);
   bset_point_before_scroll (b, Qnil);
   bset_file_format (b, Qnil);
@@ -1843,10 +1813,8 @@ cleaning up all windows currently displaying the buffer 
to be killed. */)
 
       /* Perhaps we should explicitly free the interval tree here...  */
     }
-  /* Since we've unlinked the markers, the overlays can't be here any more
-     either.  */
-  b->overlays_before = NULL;
-  b->overlays_after = NULL;
+  delete_all_overlays (b);
+  free_buffer_overlays (b);
 
   /* Reset the local variables, so that this buffer's local values
      won't be protected from GC.  They would be protected
@@ -2254,6 +2222,31 @@ advance_to_char_boundary (ptrdiff_t byte_pos)
   return byte_pos;
 }
 
+static void
+swap_buffer_overlays (struct buffer *buffer, struct buffer *other)
+{
+  struct interval_node *node;
+
+  if (buffer->overlays)
+    {
+      buffer_overlay_iter_start  (buffer, PTRDIFF_MIN, PTRDIFF_MAX, 
ITREE_ASCENDING);
+      while ((node = buffer_overlay_iter_next (buffer)))
+        XOVERLAY (node->data)->buffer = other;
+      buffer_overlay_iter_finish (buffer);
+    }
+  if (other->overlays)
+    {
+      buffer_overlay_iter_start (other, PTRDIFF_MIN, PTRDIFF_MAX, 
ITREE_ASCENDING);
+      while ((node = buffer_overlay_iter_next (other)))
+        XOVERLAY (node->data)->buffer = buffer;
+      buffer_overlay_iter_finish (other);
+    }
+  /* Swap the interval trees. */
+  void *tmp = buffer->overlays;
+  buffer->overlays = other->overlays;
+  other->overlays = tmp;
+}
+
 DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
        1, 1, 0,
        doc: /* Swap the text between current buffer and BUFFER.
@@ -2324,9 +2317,6 @@ results, see Info node `(elisp)Swapping Text'.  */)
   swapfield (bidi_paragraph_cache, struct region_cache *);
   current_buffer->prevent_redisplay_optimizations_p = 1;
   other_buffer->prevent_redisplay_optimizations_p = 1;
-  swapfield (overlays_before, struct Lisp_Overlay *);
-  swapfield (overlays_after, struct Lisp_Overlay *);
-  swapfield (overlay_center, ptrdiff_t);
   swapfield_ (undo_list, Lisp_Object);
   swapfield_ (mark, Lisp_Object);
   swapfield_ (enable_multibyte_characters, Lisp_Object);
@@ -2349,6 +2339,7 @@ results, see Info node `(elisp)Swapping Text'.  */)
   current_buffer->text->end_unchanged = current_buffer->text->gpt;
   other_buffer->text->beg_unchanged = other_buffer->text->gpt;
   other_buffer->text->end_unchanged = other_buffer->text->gpt;
+  swap_buffer_overlays (current_buffer, other_buffer);
   {
     struct Lisp_Marker *m;
     for (m = BUF_MARKERS (current_buffer); m; m = m->next)
@@ -2763,285 +2754,160 @@ swap_out_buffer_local_variables (struct buffer *b)
        }
     }
 }
+
 
-/* Find all the overlays in the current buffer that contain position POS.
+/* Find all the overlays in the current buffer that overlap the range
+   [BEG, END).
+
+   If EMPTY is true, include empty overlays in that range and also at
+   END, provided END denotes the position at the end of the buffer.
+
    Return the number found, and store them in a vector in *VEC_PTR.
    Store in *LEN_PTR the size allocated for the vector.
    Store in *NEXT_PTR the next position after POS where an overlay starts,
-     or ZV if there are no more overlays between POS and ZV.
-   Store in *PREV_PTR the previous position before POS where an overlay ends,
-     or where an overlay starts which ends at or after POS;
-     or BEGV if there are no such overlays from BEGV to POS.
-   NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
+     or ZV if there are no more overlays.
+   NEXT_PTR may be 0, meaning don't store that info.
 
    *VEC_PTR and *LEN_PTR should contain a valid vector and size
    when this function is called.
 
-   If EXTEND, make the vector bigger if necessary.
-   If not, never extend the vector,
-   and store only as many overlays as will fit.
+   If EXTEND, make the vector bigger if necessary.  If not, never
+   extend the vector, and store only as many overlays as will fit.
    But still return the total number of overlays.
-
-   If CHANGE_REQ, any position written into *PREV_PTR or
-   *NEXT_PTR is guaranteed to be not equal to POS, unless it is the
-   default (BEGV or ZV).  */
+*/
 
 ptrdiff_t
-overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr,
-            ptrdiff_t *len_ptr,
-            ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, bool change_req)
+overlays_in (ptrdiff_t beg, ptrdiff_t end, bool extend,
+            Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,  bool empty,
+             ptrdiff_t *next_ptr)
 {
-  Lisp_Object overlay, start, end;
-  struct Lisp_Overlay *tail;
   ptrdiff_t idx = 0;
   ptrdiff_t len = *len_ptr;
-  Lisp_Object *vec = *vec_ptr;
   ptrdiff_t next = ZV;
-  ptrdiff_t prev = BEGV;
-  bool inhibit_storing = 0;
-
-  for (tail = current_buffer->overlays_before; tail; tail = tail->next)
-    {
-      ptrdiff_t startpos, endpos;
+  Lisp_Object *vec = *vec_ptr;
 
-      XSETMISC (overlay, tail);
+  struct interval_node *node;
 
-      start = OVERLAY_START (overlay);
-      end = OVERLAY_END (overlay);
-      endpos = OVERLAY_POSITION (end);
-      if (endpos < pos)
-       {
-         if (prev < endpos)
-           prev = endpos;
-         break;
-       }
-      startpos = OVERLAY_POSITION (start);
-      /* This one ends at or after POS
-        so its start counts for PREV_PTR if it's before POS.  */
-      if (prev < startpos && startpos < pos)
-       prev = startpos;
-      if (endpos == pos)
-       continue;
-      if (startpos <= pos)
-       {
-         if (idx == len)
-           {
-             /* The supplied vector is full.
-                Either make it bigger, or don't store any more in it.  */
-             if (extend)
-               {
-                 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
-                                sizeof *vec);
-                 *vec_ptr = vec;
-                 len = *len_ptr;
-               }
-             else
-               inhibit_storing = 1;
-           }
+  if (! current_buffer->overlays)
+    return idx;
 
-         if (!inhibit_storing)
-           vec[idx] = overlay;
-         /* Keep counting overlays even if we can't return them all.  */
-         idx++;
-       }
-      else if (startpos < next)
-       next = startpos;
-    }
+  buffer_overlay_iter_start (current_buffer, beg,
+                             /* Find empty OV at Z ? */
+                             (end >= Z && empty) ? Z + 1 : ZV,
+                             ITREE_ASCENDING);
 
-  for (tail = current_buffer->overlays_after; tail; tail = tail->next)
+  while ((node = buffer_overlay_iter_next (current_buffer)))
     {
-      ptrdiff_t startpos, endpos;
-
-      XSETMISC (overlay, tail);
-
-      start = OVERLAY_START (overlay);
-      end = OVERLAY_END (overlay);
-      startpos = OVERLAY_POSITION (start);
-      if (pos < startpos)
-       {
-         if (startpos < next)
-           next = startpos;
-         break;
-       }
-      endpos = OVERLAY_POSITION (end);
-      if (pos < endpos)
-       {
-         if (idx == len)
-           {
-             if (extend)
-               {
-                 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
-                                sizeof *vec);
-                 *vec_ptr = vec;
-                 len = *len_ptr;
-               }
-             else
-               inhibit_storing = 1;
-           }
+      if (node->begin > end)
+        {
+          next = min (next, node->begin);
+          break;
+        }
+      else if (node->begin == end)
+        {
+          next = node->begin;
+          if ((! empty || end < Z) && beg < end)
+            break;
+        }
 
-         if (!inhibit_storing)
-           vec[idx] = overlay;
-         idx++;
+      if (! empty && node->begin == node->end)
+        continue;
 
-         if (startpos < pos && startpos > prev)
-           prev = startpos;
-       }
-      else if (endpos < pos && endpos > prev)
-       prev = endpos;
-      else if (endpos == pos && startpos > prev
-              && (!change_req || startpos < pos))
-       prev = startpos;
+      if (extend && idx == len)
+        {
+          vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+                         sizeof *vec);
+          *vec_ptr = vec;
+          len = *len_ptr;
+        }
+      if (idx < len)
+        vec[idx] = node->data;
+      /* Keep counting overlays even if we can't return them all.  */
+      idx++;
     }
-
+  buffer_overlay_iter_finish (current_buffer);
   if (next_ptr)
-    *next_ptr = next;
-  if (prev_ptr)
-    *prev_ptr = prev;
+    *next_ptr = next ? next : ZV;
+
   return idx;
 }
-
-/* Find all the overlays in the current buffer that overlap the range
-   BEG-END, or are empty at BEG, or are empty at END provided END
-   denotes the position at the end of the current buffer.
 
-   Return the number found, and store them in a vector in *VEC_PTR.
-   Store in *LEN_PTR the size allocated for the vector.
-   Store in *NEXT_PTR the next position after POS where an overlay starts,
-     or ZV if there are no more overlays.
-   Store in *PREV_PTR the previous position before POS where an overlay ends,
-     or BEGV if there are no previous overlays.
-   NEXT_PTR and/or PREV_PTR may be 0, meaning don't store that info.
+/* Find all non-empty overlays in the current buffer that contain
+   position POS.
 
-   *VEC_PTR and *LEN_PTR should contain a valid vector and size
-   when this function is called.
+   See overlays_in for the meaning of the arguments.
+  */
 
-   If EXTEND, make the vector bigger if necessary.
-   If not, never extend the vector,
-   and store only as many overlays as will fit.
-   But still return the total number of overlays.  */
+ptrdiff_t
+overlays_at (ptrdiff_t pos, bool extend,
+             Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
+             ptrdiff_t *next_ptr)
+{
+  return overlays_in (pos, pos + 1, extend, vec_ptr, len_ptr, false, next_ptr);
+}
 
-static ptrdiff_t
-overlays_in (EMACS_INT beg, EMACS_INT end, bool extend,
-            Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
-            ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr)
+ptrdiff_t
+next_overlay_change (ptrdiff_t pos)
 {
-  Lisp_Object overlay, ostart, oend;
-  struct Lisp_Overlay *tail;
-  ptrdiff_t idx = 0;
-  ptrdiff_t len = *len_ptr;
-  Lisp_Object *vec = *vec_ptr;
   ptrdiff_t next = ZV;
-  ptrdiff_t prev = BEGV;
-  bool inhibit_storing = 0;
-  bool end_is_Z = end == Z;
+  struct interval_node *node;
 
-  for (tail = current_buffer->overlays_before; tail; tail = tail->next)
-    {
-      ptrdiff_t startpos, endpos;
+  if (! current_buffer->overlays)
+    return next;
 
-      XSETMISC (overlay, tail);
-
-      ostart = OVERLAY_START (overlay);
-      oend = OVERLAY_END (overlay);
-      endpos = OVERLAY_POSITION (oend);
-      if (endpos < beg)
-       {
-         if (prev < endpos)
-           prev = endpos;
-         break;
-       }
-      startpos = OVERLAY_POSITION (ostart);
-      /* Count an interval if it overlaps the range, is empty at the
-        start of the range, or is empty at END provided END denotes the
-        end of the buffer.  */
-      if ((beg < endpos && startpos < end)
-         || (startpos == endpos
-             && (beg == endpos || (end_is_Z && endpos == end))))
-       {
-         if (idx == len)
-           {
-             /* The supplied vector is full.
-                Either make it bigger, or don't store any more in it.  */
-             if (extend)
-               {
-                 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
-                                sizeof *vec);
-                 *vec_ptr = vec;
-                 len = *len_ptr;
-               }
-             else
-               inhibit_storing = 1;
-           }
-
-         if (!inhibit_storing)
-           vec[idx] = overlay;
-         /* Keep counting overlays even if we can't return them all.  */
-         idx++;
-       }
-      else if (startpos < next)
-       next = startpos;
+  buffer_overlay_iter_start (current_buffer, pos, ZV, ITREE_ASCENDING);
+  while ((node = buffer_overlay_iter_next (current_buffer)))
+    {
+      if (node->begin > pos)
+        {
+          /* If we reach this branch, node->begin must be the least upper bound
+             of pos, because the search is limited to [pos,next) . */
+          eassert (node->begin < next);
+          next = node->begin;
+          break;
+        }
+      else if (node->begin < node->end && node->end < next)
+        {
+          next = node->end;
+          buffer_overlay_iter_narrow (current_buffer, pos, next);
+        }
     }
+  buffer_overlay_iter_finish (current_buffer);
 
-  for (tail = current_buffer->overlays_after; tail; tail = tail->next)
-    {
-      ptrdiff_t startpos, endpos;
+  return next;
+}
 
-      XSETMISC (overlay, tail);
+ptrdiff_t
+previous_overlay_change (ptrdiff_t pos)
+{
+  struct interval_node *node;
+  ptrdiff_t prev = BEGV;
 
-      ostart = OVERLAY_START (overlay);
-      oend = OVERLAY_END (overlay);
-      startpos = OVERLAY_POSITION (ostart);
-      if (end < startpos)
-       {
-         if (startpos < next)
-           next = startpos;
-         break;
-       }
-      endpos = OVERLAY_POSITION (oend);
-      /* Count an interval if it overlaps the range, is empty at the
-        start of the range, or is empty at END provided END denotes the
-        end of the buffer.  */
-      if ((beg < endpos && startpos < end)
-         || (startpos == endpos
-             && (beg == endpos || (end_is_Z && endpos == end))))
-       {
-         if (idx == len)
-           {
-             if (extend)
-               {
-                 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
-                                sizeof *vec);
-                 *vec_ptr = vec;
-                 len = *len_ptr;
-               }
-             else
-               inhibit_storing = 1;
-           }
+  if (! current_buffer->overlays)
+    return prev;
 
-         if (!inhibit_storing)
-           vec[idx] = overlay;
-         idx++;
-       }
-      else if (endpos < beg && endpos > prev)
-       prev = endpos;
+  buffer_overlay_iter_start (current_buffer, BEGV, pos, ITREE_DESCENDING);
+  while ((node = buffer_overlay_iter_next (current_buffer)))
+    {
+      if (node->end < pos)
+        prev = node->end;
+      else
+        prev = max (prev, node->begin);
+      buffer_overlay_iter_narrow (current_buffer, prev, pos);
     }
+  buffer_overlay_iter_finish (current_buffer);
 
-  if (next_ptr)
-    *next_ptr = next;
-  if (prev_ptr)
-    *prev_ptr = prev;
-  return idx;
+  return prev;
 }
 
-
 /* Return true if there exists an overlay with a non-nil
    `mouse-face' property overlapping OVERLAY.  */
 
 bool
 mouse_face_overlay_overlaps (Lisp_Object overlay)
 {
-  ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay));
-  ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay));
+  ptrdiff_t start = OVERLAY_START (overlay);
+  ptrdiff_t end = OVERLAY_END (overlay);
   ptrdiff_t n, i, size;
   Lisp_Object *v, tem;
   Lisp_Object vbuf[10];
@@ -3049,11 +2915,11 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
 
   size = ARRAYELTS (vbuf);
   v = vbuf;
-  n = overlays_in (start, end, 0, &v, &size, NULL, NULL);
+  n = overlays_in (start, end, 0, &v, &size, true, NULL);
   if (n > size)
     {
       SAFE_NALLOCA (v, 1, n);
-      overlays_in (start, end, 0, &v, &n, NULL, NULL);
+      overlays_in (start, end, 0, &v, &n, true, NULL);
     }
 
   for (i = 0; i < n; ++i)
@@ -3095,52 +2961,34 @@ disable_line_numbers_overlay_at_eob (void)
 }
 
 
-/* Fast function to just test if we're at an overlay boundary.  */
+/* Fast function to just test if we're at an overlay boundary.
+
+   Returns true if some overlay starts or ends (or both) at POS,
+*/
 bool
 overlay_touches_p (ptrdiff_t pos)
 {
-  Lisp_Object overlay;
-  struct Lisp_Overlay *tail;
-
-  for (tail = current_buffer->overlays_before; tail; tail = tail->next)
-    {
-      ptrdiff_t endpos;
+  struct interval_node *node;
+  bool result = false;
 
-      XSETMISC (overlay ,tail);
-      eassert (OVERLAYP (overlay));
+  if (! current_buffer->overlays)
+    return false;
 
-      endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
-      if (endpos < pos)
-       break;
-      if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos)
-       return 1;
-    }
+  /* We need to find overlays ending in pos, as well as empty ones at
+     pos. */
+  buffer_overlay_iter_start (current_buffer,
+                             pos - 1, pos + 1, ITREE_DESCENDING);
 
-  for (tail = current_buffer->overlays_after; tail; tail = tail->next)
-    {
-      ptrdiff_t startpos;
+  while (! result && (node = buffer_overlay_iter_next (current_buffer)))
+    result = (node->begin == pos || node->end == pos);
 
-      XSETMISC (overlay, tail);
-      eassert (OVERLAYP (overlay));
+  buffer_overlay_iter_finish (current_buffer);
 
-      startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
-      if (pos < startpos)
-       break;
-      if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
-       return 1;
-    }
-  return 0;
+  return result;
 }
-
-struct sortvec
-{
-  Lisp_Object overlay;
-  ptrdiff_t beg, end;
-  EMACS_INT priority;
-  EMACS_INT spriority;         /* Secondary priority.  */
-};
 
-static int
+
+int
 compare_overlays (const void *v1, const void *v2)
 {
   const struct sortvec *s1 = v1;
@@ -3169,6 +3017,33 @@ compare_overlays (const void *v1, const void *v2)
     return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1;
 }
 
+void
+make_sortvec_item (struct sortvec *item, Lisp_Object overlay)
+{
+  Lisp_Object tem;
+  /* This overlay is good and counts: put it into sortvec.  */
+  item->overlay = overlay;
+  item->beg = OVERLAY_START (overlay);
+  item->end = OVERLAY_END (overlay);
+  tem = Foverlay_get (overlay, Qpriority);
+  if (NILP (tem))
+    {
+      item->priority = 0;
+      item->spriority = 0;
+    }
+  else if (INTEGERP (tem))
+    {
+      item->priority = XINT (tem);
+      item->spriority = 0;
+    }
+  else if (CONSP (tem))
+    {
+      Lisp_Object car = XCAR (tem);
+      Lisp_Object cdr = XCDR (tem);
+      item->priority  = INTEGERP (car) ? XINT (car) : 0;
+      item->spriority = INTEGERP (cdr) ? XINT (cdr) : 0;
+    }
+}
 /* Sort an array of overlays by priority.  The array is modified in place.
    The return value is the new size; this may be smaller than the original
    size if some of the overlays were invalid or were window-specific.  */
@@ -3185,47 +3060,18 @@ sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t 
noverlays, struct window *w)
 
   for (i = 0, j = 0; i < noverlays; i++)
     {
-      Lisp_Object tem;
       Lisp_Object overlay;
 
       overlay = overlay_vec[i];
       if (OVERLAYP (overlay)
-         && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0
-         && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0)
+         && OVERLAY_START (overlay) > 0
+         && OVERLAY_END (overlay) > 0)
        {
-         /* If we're interested in a specific window, then ignore
-            overlays that are limited to some other window.  */
-         if (w)
-           {
-             Lisp_Object window;
-
-             window = Foverlay_get (overlay, Qwindow);
-             if (WINDOWP (window) && XWINDOW (window) != w)
-               continue;
-           }
-
-         /* This overlay is good and counts: put it into sortvec.  */
-         sortvec[j].overlay = overlay;
-         sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
-         sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
-         tem = Foverlay_get (overlay, Qpriority);
-         if (NILP (tem))
-           {
-             sortvec[j].priority = 0;
-             sortvec[j].spriority = 0;
-           }
-         else if (INTEGERP (tem))
-           {
-             sortvec[j].priority = XINT (tem);
-             sortvec[j].spriority = 0;
-           }
-         else if (CONSP (tem))
-           {
-             Lisp_Object car = XCAR (tem);
-             Lisp_Object cdr = XCDR (tem);
-             sortvec[j].priority  = INTEGERP (car) ? XINT (car) : 0;
-             sortvec[j].spriority = INTEGERP (cdr) ? XINT (cdr) : 0;
-           }
+          /* If we're interested in a specific window, then ignore
+             overlays that are limited to some other window.  */
+          if (w && ! overlay_matches_window (w, overlay))
+            continue;
+          make_sortvec_item (sortvec + j, overlay);
          j++;
        }
     }
@@ -3340,68 +3186,44 @@ ptrdiff_t
 overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
 {
   Lisp_Object overlay, window, str;
-  struct Lisp_Overlay *ov;
-  ptrdiff_t startpos, endpos;
+  ptrdiff_t obegin, oend;
   bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
+  struct interval_node *node;
 
   overlay_heads.used = overlay_heads.bytes = 0;
   overlay_tails.used = overlay_tails.bytes = 0;
-  for (ov = current_buffer->overlays_before; ov; ov = ov->next)
+
+  buffer_overlay_iter_start (current_buffer,
+                             pos - 1, pos + 1, ITREE_DESCENDING);
+  while ((node  = buffer_overlay_iter_next (current_buffer)))
     {
-      XSETMISC (overlay, ov);
+      overlay = node->data;
       eassert (OVERLAYP (overlay));
 
-      startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
-      endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
-      if (endpos < pos)
-       break;
-      if (endpos != pos && startpos != pos)
+      obegin = node->begin;
+      oend = node->end;
+
+      if (oend != pos && obegin != pos)
        continue;
       window = Foverlay_get (overlay, Qwindow);
       if (WINDOWP (window) && XWINDOW (window) != w)
        continue;
-      if (startpos == pos
+      if (obegin == pos
          && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
        record_overlay_string (&overlay_heads, str,
-                              (startpos == endpos
+                              (obegin == oend
                                ? Foverlay_get (overlay, Qafter_string)
                                : Qnil),
                               Foverlay_get (overlay, Qpriority),
-                              endpos - startpos);
-      else if (endpos == pos
+                              oend - obegin);
+      else if (oend == pos
          && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
        record_overlay_string (&overlay_tails, str, Qnil,
                               Foverlay_get (overlay, Qpriority),
-                              endpos - startpos);
+                              oend - obegin);
     }
-  for (ov = current_buffer->overlays_after; ov; ov = ov->next)
-    {
-      XSETMISC (overlay, ov);
-      eassert (OVERLAYP (overlay));
+  buffer_overlay_iter_finish (current_buffer);
 
-      startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
-      endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
-      if (startpos > pos)
-       break;
-      if (endpos != pos && startpos != pos)
-       continue;
-      window = Foverlay_get (overlay, Qwindow);
-      if (WINDOWP (window) && XWINDOW (window) != w)
-       continue;
-      if (startpos == pos
-         && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
-       record_overlay_string (&overlay_heads, str,
-                              (startpos == endpos
-                               ? Foverlay_get (overlay, Qafter_string)
-                               : Qnil),
-                              Foverlay_get (overlay, Qpriority),
-                              endpos - startpos);
-      else if (endpos == pos
-              && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
-       record_overlay_string (&overlay_tails, str, Qnil,
-                              Foverlay_get (overlay, Qpriority),
-                              endpos - startpos);
-    }
   if (overlay_tails.used > 1)
     qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr),
           cmp_for_strings);
@@ -3456,385 +3278,26 @@ overlay_strings (ptrdiff_t pos, struct window *w, 
unsigned char **pstr)
     }
   return 0;
 }
-
-/* Shift overlays in BUF's overlay lists, to center the lists at POS.  */
-
-void
-recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
-{
-  Lisp_Object overlay, beg, end;
-  struct Lisp_Overlay *prev, *tail, *next;
-
-  /* See if anything in overlays_before should move to overlays_after.  */
-
-  /* We don't strictly need prev in this loop; it should always be nil.
-     But we use it for symmetry and in case that should cease to be true
-     with some future change.  */
-  prev = NULL;
-  for (tail = buf->overlays_before; tail; prev = tail, tail = next)
-    {
-      next = tail->next;
-      XSETMISC (overlay, tail);
-      eassert (OVERLAYP (overlay));
-
-      beg = OVERLAY_START (overlay);
-      end = OVERLAY_END (overlay);
-
-      if (OVERLAY_POSITION (end) > pos)
-       {
-         /* OVERLAY needs to be moved.  */
-         ptrdiff_t where = OVERLAY_POSITION (beg);
-         struct Lisp_Overlay *other, *other_prev;
-
-         /* Splice the cons cell TAIL out of overlays_before.  */
-         if (prev)
-           prev->next = next;
-         else
-           set_buffer_overlays_before (buf, next);
-
-         /* Search thru overlays_after for where to put it.  */
-         other_prev = NULL;
-         for (other = buf->overlays_after; other;
-              other_prev = other, other = other->next)
-           {
-             Lisp_Object otherbeg, otheroverlay;
-
-             XSETMISC (otheroverlay, other);
-             eassert (OVERLAYP (otheroverlay));
-
-             otherbeg = OVERLAY_START (otheroverlay);
-             if (OVERLAY_POSITION (otherbeg) >= where)
-               break;
-           }
-
-         /* Add TAIL to overlays_after before OTHER.  */
-         tail->next = other;
-         if (other_prev)
-           other_prev->next = tail;
-         else
-           set_buffer_overlays_after (buf, tail);
-         tail = prev;
-       }
-      else
-       /* We've reached the things that should stay in overlays_before.
-          All the rest of overlays_before must end even earlier,
-          so stop now.  */
-       break;
-    }
-
-  /* See if anything in overlays_after should be in overlays_before.  */
-  prev = NULL;
-  for (tail = buf->overlays_after; tail; prev = tail, tail = next)
-    {
-      next = tail->next;
-      XSETMISC (overlay, tail);
-      eassert (OVERLAYP (overlay));
-
-      beg = OVERLAY_START (overlay);
-      end = OVERLAY_END (overlay);
-
-      /* Stop looking, when we know that nothing further
-        can possibly end before POS.  */
-      if (OVERLAY_POSITION (beg) > pos)
-       break;
-
-      if (OVERLAY_POSITION (end) <= pos)
-       {
-         /* OVERLAY needs to be moved.  */
-         ptrdiff_t where = OVERLAY_POSITION (end);
-         struct Lisp_Overlay *other, *other_prev;
-
-         /* Splice the cons cell TAIL out of overlays_after.  */
-         if (prev)
-           prev->next = next;
-         else
-           set_buffer_overlays_after (buf, next);
-
-         /* Search thru overlays_before for where to put it.  */
-         other_prev = NULL;
-         for (other = buf->overlays_before; other;
-              other_prev = other, other = other->next)
-           {
-             Lisp_Object otherend, otheroverlay;
-
-             XSETMISC (otheroverlay, other);
-             eassert (OVERLAYP (otheroverlay));
-
-             otherend = OVERLAY_END (otheroverlay);
-             if (OVERLAY_POSITION (otherend) <= where)
-               break;
-           }
-
-         /* Add TAIL to overlays_before before OTHER.  */
-         tail->next = other;
-         if (other_prev)
-           other_prev->next = tail;
-         else
-           set_buffer_overlays_before (buf, tail);
-         tail = prev;
-       }
-    }
-
-  buf->overlay_center = pos;
-}
 
+
 void
 adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length)
 {
   /* After an insertion, the lists are still sorted properly,
      but we may need to update the value of the overlay center.  */
-  if (current_buffer->overlay_center >= pos)
-    current_buffer->overlay_center += length;
+  if (! current_buffer->overlays)
+    return;
+  interval_tree_insert_gap (current_buffer->overlays, pos, length);
 }
 
 void
 adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length)
 {
-  if (current_buffer->overlay_center < pos)
-    /* The deletion was to our right.  No change needed; the before- and
-       after-lists are still consistent.  */
-    ;
-  else if (current_buffer->overlay_center - pos > length)
-    /* The deletion was to our left.  We need to adjust the center value
-       to account for the change in position, but the lists are consistent
-       given the new value.  */
-    current_buffer->overlay_center -= length;
-  else
-    /* We're right in the middle.  There might be things on the after-list
-       that now belong on the before-list.  Recentering will move them,
-       and also update the center point.  */
-    recenter_overlay_lists (current_buffer, pos);
-}
-
-/* Fix up overlays that were garbled as a result of permuting markers
-   in the range START through END.  Any overlay with at least one
-   endpoint in this range will need to be unlinked from the overlay
-   list and reinserted in its proper place.
-   Such an overlay might even have negative size at this point.
-   If so, we'll make the overlay empty. */
-void
-fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
-{
-  Lisp_Object overlay;
-  struct Lisp_Overlay *before_list;
-  struct Lisp_Overlay *after_list;
-  /* These are either nil, indicating that before_list or after_list
-     should be assigned, or the cons cell the cdr of which should be
-     assigned.  */
-  struct Lisp_Overlay *beforep = NULL, *afterp = NULL;
-  /* 'Parent', likewise, indicates a cons cell or
-     current_buffer->overlays_before or overlays_after, depending
-     which loop we're in.  */
-  struct Lisp_Overlay *tail, *parent;
-  ptrdiff_t startpos, endpos;
-
-  /* This algorithm shifts links around instead of consing and GCing.
-     The loop invariant is that before_list (resp. after_list) is a
-     well-formed list except that its last element, the CDR of beforep
-     (resp. afterp) if beforep (afterp) isn't nil or before_list
-     (after_list) if it is, is still uninitialized.  So it's not a bug
-     that before_list isn't initialized, although it may look
-     strange.  */
-  for (parent = NULL, tail = current_buffer->overlays_before; tail;)
-    {
-      XSETMISC (overlay, tail);
-
-      endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
-      startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
-
-      /* If the overlay is backwards, make it empty.  */
-      if (endpos < startpos)
-       {
-         startpos = endpos;
-         Fset_marker (OVERLAY_START (overlay), make_number (startpos),
-                      Qnil);
-       }
-
-      if (endpos < start)
-       break;
-
-      if (endpos < end
-         || (startpos >= start && startpos < end))
-       {
-         /* Add it to the end of the wrong list.  Later on,
-            recenter_overlay_lists will move it to the right place.  */
-         if (endpos < current_buffer->overlay_center)
-           {
-             if (!afterp)
-               after_list = tail;
-             else
-               afterp->next = tail;
-             afterp = tail;
-           }
-         else
-           {
-             if (!beforep)
-               before_list = tail;
-             else
-               beforep->next = tail;
-             beforep = tail;
-           }
-         if (!parent)
-           set_buffer_overlays_before (current_buffer, tail->next);
-         else
-           parent->next = tail->next;
-         tail = tail->next;
-       }
-      else
-       parent = tail, tail = parent->next;
-    }
-  for (parent = NULL, tail = current_buffer->overlays_after; tail;)
-    {
-      XSETMISC (overlay, tail);
-
-      startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
-      endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
-
-      /* If the overlay is backwards, make it empty.  */
-      if (endpos < startpos)
-       {
-         startpos = endpos;
-         Fset_marker (OVERLAY_START (overlay), make_number (startpos),
-                      Qnil);
-       }
-
-      if (startpos >= end)
-       break;
-
-      if (startpos >= start
-         || (endpos >= start && endpos < end))
-       {
-         if (endpos < current_buffer->overlay_center)
-           {
-             if (!afterp)
-               after_list = tail;
-             else
-               afterp->next = tail;
-             afterp = tail;
-           }
-         else
-           {
-             if (!beforep)
-               before_list = tail;
-             else
-               beforep->next = tail;
-             beforep = tail;
-           }
-         if (!parent)
-           set_buffer_overlays_after (current_buffer, tail->next);
-         else
-           parent->next = tail->next;
-         tail = tail->next;
-       }
-      else
-       parent = tail, tail = parent->next;
-    }
-
-  /* Splice the constructed (wrong) lists into the buffer's lists,
-     and let the recenter function make it sane again.  */
-  if (beforep)
-    {
-      beforep->next = current_buffer->overlays_before;
-      set_buffer_overlays_before (current_buffer, before_list);
-    }
-
-  if (afterp)
-    {
-      afterp->next = current_buffer->overlays_after;
-      set_buffer_overlays_after (current_buffer, after_list);
-    }
-  recenter_overlay_lists (current_buffer, current_buffer->overlay_center);
-}
-
-/* We have two types of overlay: the one whose ending marker is
-   after-insertion-marker (this is the usual case) and the one whose
-   ending marker is before-insertion-marker.  When `overlays_before'
-   contains overlays of the latter type and the former type in this
-   order and both overlays end at inserting position, inserting a text
-   increases only the ending marker of the latter type, which results
-   in incorrect ordering of `overlays_before'.
-
-   This function fixes ordering of overlays in the slot
-   `overlays_before' of the buffer *BP.  Before the insertion, `point'
-   was at PREV, and now is at POS.  */
-
-void
-fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos)
-{
-  /* If parent is nil, replace overlays_before; otherwise, parent->next.  */
-  struct Lisp_Overlay *tail = bp->overlays_before, *parent = NULL, *right_pair;
-  Lisp_Object tem;
-  ptrdiff_t end UNINIT;
-
-  /* After the insertion, the several overlays may be in incorrect
-     order.  The possibility is that, in the list `overlays_before',
-     an overlay which ends at POS appears after an overlay which ends
-     at PREV.  Since POS is greater than PREV, we must fix the
-     ordering of these overlays, by moving overlays ends at POS before
-     the overlays ends at PREV.  */
-
-  /* At first, find a place where disordered overlays should be linked
-     in.  It is where an overlay which end before POS exists. (i.e. an
-     overlay whose ending marker is after-insertion-marker if disorder
-     exists).  */
-  while (tail
-        && (XSETMISC (tem, tail),
-            (end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos))
-    {
-      parent = tail;
-      tail = tail->next;
-    }
-
-  /* If we don't find such an overlay,
-     or the found one ends before PREV,
-     or the found one is the last one in the list,
-     we don't have to fix anything.  */
-  if (!tail || end < prev || !tail->next)
+  if (! current_buffer->overlays)
     return;
-
-  right_pair = parent;
-  parent = tail;
-  tail = tail->next;
-
-  /* Now, end position of overlays in the list TAIL should be before
-     or equal to PREV.  In the loop, an overlay which ends at POS is
-     moved ahead to the place indicated by the CDR of RIGHT_PAIR.  If
-     we found an overlay which ends before PREV, the remaining
-     overlays are in correct order.  */
-  while (tail)
-    {
-      XSETMISC (tem, tail);
-      end = OVERLAY_POSITION (OVERLAY_END (tem));
-
-      if (end == pos)
-       {                       /* This overlay is disordered. */
-         struct Lisp_Overlay *found = tail;
-
-         /* Unlink the found overlay.  */
-         tail = found->next;
-         parent->next = tail;
-         /* Move an overlay at RIGHT_PLACE to the next of the found one,
-            and link it into the right place.  */
-         if (!right_pair)
-           {
-             found->next = bp->overlays_before;
-             set_buffer_overlays_before (bp, found);
-           }
-         else
-           {
-             found->next = right_pair->next;
-             right_pair->next = found;
-           }
-       }
-      else if (end == prev)
-       {
-         parent = tail;
-         tail = tail->next;
-       }
-      else                     /* No more disordered overlay. */
-       break;
-    }
+  interval_tree_delete_gap (current_buffer->overlays, pos, length);
 }
+
 
 DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0,
        doc: /* Return t if OBJECT is an overlay.  */)
@@ -3853,10 +3316,11 @@ for the front of the overlay advance when text is 
inserted there
 The fifth arg REAR-ADVANCE, if non-nil, makes the marker
 for the rear of the overlay advance when text is inserted there
 \(which means the text *is* included in the overlay).  */)
-  (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer,
+  (Lisp_Object begin, Lisp_Object end, Lisp_Object buffer,
    Lisp_Object front_advance, Lisp_Object rear_advance)
 {
-  Lisp_Object overlay;
+  Lisp_Object ov;
+  ptrdiff_t obegin, oend;
   struct buffer *b;
 
   if (NILP (buffer))
@@ -3864,53 +3328,35 @@ for the rear of the overlay advance when text is 
inserted there
   else
     CHECK_BUFFER (buffer);
 
-  if (MARKERP (beg) && !EQ (Fmarker_buffer (beg), buffer))
-    signal_error ("Marker points into wrong buffer", beg);
+  b = XBUFFER (buffer);
+  if (! BUFFER_LIVE_P (b))
+    error ("Attempt to create overlay in a dead buffer");
+
+  if (MARKERP (begin) && !EQ (Fmarker_buffer (begin), buffer))
+    signal_error ("Marker points into wrong buffer", begin);
   if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer))
     signal_error ("Marker points into wrong buffer", end);
 
-  CHECK_NUMBER_COERCE_MARKER (beg);
+  CHECK_NUMBER_COERCE_MARKER (begin);
   CHECK_NUMBER_COERCE_MARKER (end);
 
-  if (XINT (beg) > XINT (end))
+  if (XINT (begin) > XINT (end))
     {
       Lisp_Object temp;
-      temp = beg; beg = end; end = temp;
+      temp = begin; begin = end; end = temp;
     }
 
-  b = XBUFFER (buffer);
-
-  beg = Fset_marker (Fmake_marker (), beg, buffer);
-  end = Fset_marker (Fmake_marker (), end, buffer);
-
-  if (!NILP (front_advance))
-    XMARKER (beg)->insertion_type = 1;
-  if (!NILP (rear_advance))
-    XMARKER (end)->insertion_type = 1;
-
-  overlay = build_overlay (beg, end, Qnil);
-
-  /* Put the new overlay on the wrong list.  */
-  end = OVERLAY_END (overlay);
-  if (OVERLAY_POSITION (end) < b->overlay_center)
-    {
-      eassert (b->overlays_after || (XOVERLAY (overlay)->next == NULL));
-      XOVERLAY (overlay)->next = b->overlays_after;
-      set_buffer_overlays_after (b, XOVERLAY (overlay));
-    }
-  else
-    {
-      eassert (b->overlays_before || (XOVERLAY (overlay)->next == NULL));
-      XOVERLAY (overlay)->next = b->overlays_before;
-      set_buffer_overlays_before (b, XOVERLAY (overlay));
-    }
-  /* This puts it in the right list, and in the right order.  */
-  recenter_overlay_lists (b, b->overlay_center);
+  obegin = clip_to_bounds (BEG, XINT (begin), b->text->z);
+  oend = clip_to_bounds (obegin, XINT (end), b->text->z);
+  ov = build_overlay (obegin, oend,
+                      ! NILP (front_advance),
+                      ! NILP (rear_advance), Qnil);
+  add_buffer_overlay (b, XOVERLAY (ov));
 
   /* We don't need to redisplay the region covered by the overlay, because
      the overlay has no properties at the moment.  */
 
-  return overlay;
+  return ov;
 }
 
 /* Mark a section of BUF as needing redisplay because of overlays changes.  */
@@ -3932,35 +3378,6 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, 
ptrdiff_t end)
   ++BUF_OVERLAY_MODIFF (buf);
 }
 
-/* Remove OVERLAY from LIST.  */
-
-static struct Lisp_Overlay *
-unchain_overlay (struct Lisp_Overlay *list, struct Lisp_Overlay *overlay)
-{
-  register struct Lisp_Overlay *tail, **prev = &list;
-
-  for (tail = list; tail; prev = &tail->next, tail = *prev)
-    if (tail == overlay)
-      {
-       *prev = overlay->next;
-       overlay->next = NULL;
-       break;
-      }
-  return list;
-}
-
-/* Remove OVERLAY from both overlay lists of B.  */
-
-static void
-unchain_both (struct buffer *b, Lisp_Object overlay)
-{
-  struct Lisp_Overlay *ov = XOVERLAY (overlay);
-
-  set_buffer_overlays_before (b, unchain_overlay (b->overlays_before, ov));
-  set_buffer_overlays_after (b, unchain_overlay (b->overlays_after, ov));
-  eassert (XOVERLAY (overlay)->next == NULL);
-}
-
 DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
        doc: /* Set the endpoints of OVERLAY to BEG and END in BUFFER.
 If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.
@@ -3976,7 +3393,7 @@ buffer.  */)
 
   CHECK_OVERLAY (overlay);
   if (NILP (buffer))
-    buffer = Fmarker_buffer (OVERLAY_START (overlay));
+    buffer = Foverlay_buffer (overlay);
   if (NILP (buffer))
     XSETBUFFER (buffer, current_buffer);
   CHECK_BUFFER (buffer);
@@ -4000,25 +3417,28 @@ buffer.  */)
 
   specbind (Qinhibit_quit, Qt);
 
-  obuffer = Fmarker_buffer (OVERLAY_START (overlay));
+  obuffer = Foverlay_buffer (overlay);
   b = XBUFFER (buffer);
 
   if (!NILP (obuffer))
     {
       ob = XBUFFER (obuffer);
 
-      o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
-      o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
-
-      unchain_both (ob, overlay);
+      o_beg = OVERLAY_START (overlay);
+      o_end = OVERLAY_END (overlay);
     }
 
+  if (! EQ (buffer, obuffer))
+    {
+      if (! NILP (obuffer))
+        remove_buffer_overlay (XBUFFER (obuffer), XOVERLAY (overlay));
+      add_buffer_overlay (XBUFFER (buffer), XOVERLAY (overlay));
+    }
   /* Set the overlay boundaries, which may clip them.  */
-  Fset_marker (OVERLAY_START (overlay), beg, buffer);
-  Fset_marker (OVERLAY_END (overlay), end, buffer);
+  set_overlay_region (XOVERLAY (overlay), XINT (beg), XINT (end));
 
-  n_beg = marker_position (OVERLAY_START (overlay));
-  n_end = marker_position (OVERLAY_END (overlay));
+  n_beg = OVERLAY_START (overlay);
+  n_end = OVERLAY_END (overlay);
 
   /* If the overlay has changed buffers, do a thorough redisplay.  */
   if (!EQ (buffer, obuffer))
@@ -4046,22 +3466,6 @@ buffer.  */)
   if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate)))
     return unbind_to (count, Fdelete_overlay (overlay));
 
-  /* Put the overlay into the new buffer's overlay lists, first on the
-     wrong list.  */
-  if (n_end < b->overlay_center)
-    {
-      XOVERLAY (overlay)->next = b->overlays_after;
-      set_buffer_overlays_after (b, XOVERLAY (overlay));
-    }
-  else
-    {
-      XOVERLAY (overlay)->next = b->overlays_before;
-      set_buffer_overlays_before (b, XOVERLAY (overlay));
-    }
-
-  /* This puts it in the right list, and in the right order.  */
-  recenter_overlay_lists (b, b->overlay_center);
-
   return unbind_to (count, overlay);
 }
 
@@ -4069,21 +3473,18 @@ DEFUN ("delete-overlay", Fdelete_overlay, 
Sdelete_overlay, 1, 1, 0,
        doc: /* Delete the overlay OVERLAY from its buffer.  */)
   (Lisp_Object overlay)
 {
-  Lisp_Object buffer;
   struct buffer *b;
   ptrdiff_t count = SPECPDL_INDEX ();
 
   CHECK_OVERLAY (overlay);
 
-  buffer = Fmarker_buffer (OVERLAY_START (overlay));
-  if (NILP (buffer))
+  b = OVERLAY_BUFFER (overlay);
+  if (! b)
     return Qnil;
 
-  b = XBUFFER (buffer);
   specbind (Qinhibit_quit, Qt);
 
-  unchain_both (b, overlay);
-  drop_overlay (b, XOVERLAY (overlay));
+  drop_overlay (XOVERLAY (overlay));
 
   /* When deleting an overlay with before or after strings, turn off
      display optimizations for the affected buffer, on the basis that
@@ -4114,8 +3515,10 @@ DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 
1, 1, 0,
   (Lisp_Object overlay)
 {
   CHECK_OVERLAY (overlay);
+  if (! OVERLAY_BUFFER (overlay))
+    return Qnil;
 
-  return (Fmarker_position (OVERLAY_START (overlay)));
+  return make_number (OVERLAY_START (overlay));
 }
 
 DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
@@ -4123,8 +3526,10 @@ DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 
0,
   (Lisp_Object overlay)
 {
   CHECK_OVERLAY (overlay);
+  if (! OVERLAY_BUFFER (overlay))
+    return Qnil;
 
-  return (Fmarker_position (OVERLAY_END (overlay)));
+  return make_number (OVERLAY_END (overlay));
 }
 
 DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
@@ -4132,9 +3537,16 @@ DEFUN ("overlay-buffer", Foverlay_buffer, 
Soverlay_buffer, 1, 1, 0,
 Return nil if OVERLAY has been deleted.  */)
   (Lisp_Object overlay)
 {
+  Lisp_Object buffer;
+
   CHECK_OVERLAY (overlay);
 
-  return Fmarker_buffer (OVERLAY_START (overlay));
+  if (! OVERLAY_BUFFER (overlay))
+    return Qnil;
+
+  XSETBUFFER (buffer, OVERLAY_BUFFER (overlay));
+
+  return buffer;
 }
 
 DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0,
@@ -4145,7 +3557,7 @@ OVERLAY.  */)
 {
   CHECK_OVERLAY (overlay);
 
-  return Fcopy_sequence (XOVERLAY (overlay)->plist);
+  return Fcopy_sequence (OVERLAY_PLIST (overlay));
 }
 
 
@@ -4169,8 +3581,7 @@ If SORTED is non-nil, then sort them by decreasing 
priority.  */)
 
   /* Put all the overlays we want in a vector in overlay_vec.
      Store the length in len.  */
-  noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
-                          NULL, NULL, 0);
+  noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, NULL);
 
   if (!NILP (sorted))
     noverlays = sort_overlays (overlay_vec, noverlays,
@@ -4213,8 +3624,7 @@ end of the buffer.  */)
 
   /* Put all the overlays we want in a vector in overlay_vec.
      Store the length in len.  */
-  noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len,
-                          NULL, NULL);
+  noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len, 
true, NULL);
 
   /* Make a list of them all.  */
   result = Flist (noverlays, overlay_vec);
@@ -4230,39 +3640,12 @@ If there are no overlay boundaries from POS to 
(point-max),
 the value is (point-max).  */)
   (Lisp_Object pos)
 {
-  ptrdiff_t i, len, noverlays;
-  ptrdiff_t endpos;
-  Lisp_Object *overlay_vec;
-
   CHECK_NUMBER_COERCE_MARKER (pos);
 
   if (!buffer_has_overlays ())
     return make_number (ZV);
 
-  len = 10;
-  overlay_vec = xmalloc (len * sizeof *overlay_vec);
-
-  /* Put all the overlays we want in a vector in overlay_vec.
-     Store the length in len.
-     endpos gets the position where the next overlay starts.  */
-  noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
-                          &endpos, 0, 1);
-
-  /* If any of these overlays ends before endpos,
-     use its ending point instead.  */
-  for (i = 0; i < noverlays; i++)
-    {
-      Lisp_Object oend;
-      ptrdiff_t oendpos;
-
-      oend = OVERLAY_END (overlay_vec[i]);
-      oendpos = OVERLAY_POSITION (oend);
-      if (oendpos < endpos)
-       endpos = oendpos;
-    }
-
-  xfree (overlay_vec);
-  return make_number (endpos);
+  return make_number (next_overlay_change (XINT (pos)));
 }
 
 DEFUN ("previous-overlay-change", Fprevious_overlay_change,
@@ -4272,32 +3655,15 @@ If there are no overlay boundaries from (point-min) to 
POS,
 the value is (point-min).  */)
   (Lisp_Object pos)
 {
-  ptrdiff_t prevpos;
-  Lisp_Object *overlay_vec;
-  ptrdiff_t len;
 
   CHECK_NUMBER_COERCE_MARKER (pos);
 
   if (!buffer_has_overlays ())
     return make_number (BEGV);
 
-  /* At beginning of buffer, we know the answer;
-     avoid bug subtracting 1 below.  */
-  if (XINT (pos) == BEGV)
-    return pos;
-
-  len = 10;
-  overlay_vec = xmalloc (len * sizeof *overlay_vec);
-
-  /* Put all the overlays we want in a vector in overlay_vec.
-     Store the length in len.
-     prevpos gets the position of the previous change.  */
-  overlays_at (XINT (pos), 1, &overlay_vec, &len,
-              0, &prevpos, 1);
-
-  xfree (overlay_vec);
-  return make_number (prevpos);
+  return make_number (previous_overlay_change (XINT (pos)));
 }
+
 
 /* These functions are for debugging overlays.  */
 
@@ -4307,24 +3673,21 @@ The car has all the overlays before the overlay center;
 the cdr has all the overlays after the overlay center.
 Recentering overlays moves overlays between these lists.
 The lists you get are copies, so that changing them has no effect.
-However, the overlays you get are the real objects that the buffer uses.  */)
+However, the overlays you get are the real objects that the buffer uses. */)
   (void)
 {
-  struct Lisp_Overlay *ol;
-  Lisp_Object before = Qnil, after = Qnil, tmp;
+  Lisp_Object overlays = Qnil;
 
-  for (ol = current_buffer->overlays_before; ol; ol = ol->next)
-    {
-      XSETMISC (tmp, ol);
-      before = Fcons (tmp, before);
-    }
-  for (ol = current_buffer->overlays_after; ol; ol = ol->next)
+  if (current_buffer->overlays)
     {
-      XSETMISC (tmp, ol);
-      after = Fcons (tmp, after);
-    }
+      struct interval_node *node;
 
-  return Fcons (Fnreverse (before), Fnreverse (after));
+      buffer_overlay_iter_start (current_buffer, BEG, Z, ITREE_DESCENDING);
+      while ((node = buffer_overlay_iter_next (current_buffer)))
+        overlays = Fcons (node->data, overlays);
+      buffer_overlay_iter_finish (current_buffer);
+    }
+  return Fcons (overlays, Qnil);
 }
 
 DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
@@ -4333,11 +3696,8 @@ That makes overlay lookup faster for positions near POS 
(but perhaps slower
 for positions far away from POS).  */)
   (Lisp_Object pos)
 {
-  ptrdiff_t p;
   CHECK_NUMBER_COERCE_MARKER (pos);
-
-  p = clip_to_bounds (PTRDIFF_MIN, XINT (pos), PTRDIFF_MAX);
-  recenter_overlay_lists (current_buffer, p);
+  /* Noop */
   return Qnil;
 }
 
@@ -4354,12 +3714,13 @@ DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 
0,
 VALUE will be returned.*/)
   (Lisp_Object overlay, Lisp_Object prop, Lisp_Object value)
 {
-  Lisp_Object tail, buffer;
+  Lisp_Object tail;
+  struct buffer *b;
   bool changed;
 
   CHECK_OVERLAY (overlay);
 
-  buffer = Fmarker_buffer (OVERLAY_START (overlay));
+  b = OVERLAY_BUFFER (overlay);
 
   for (tail = XOVERLAY (overlay)->plist;
        CONSP (tail) && CONSP (XCDR (tail));
@@ -4375,15 +3736,14 @@ VALUE will be returned.*/)
   set_overlay_plist
     (overlay, Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist)));
  found:
-  if (! NILP (buffer))
+  if (b)
     {
       if (changed)
-       modify_overlay (XBUFFER (buffer),
-                       marker_position (OVERLAY_START (overlay)),
-                       marker_position (OVERLAY_END   (overlay)));
+       modify_overlay (b, OVERLAY_START (overlay),
+                        OVERLAY_END (overlay));
       if (EQ (prop, Qevaporate) && ! NILP (value)
-         && (OVERLAY_POSITION (OVERLAY_START (overlay))
-             == OVERLAY_POSITION (OVERLAY_END (overlay))))
+         && (OVERLAY_START (overlay)
+              == OVERLAY_END (overlay)))
        Fdelete_overlay (overlay);
     }
 
@@ -4441,14 +3801,9 @@ void
 report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
                             Lisp_Object arg1, Lisp_Object arg2, Lisp_Object 
arg3)
 {
-  Lisp_Object prop, overlay;
-  struct Lisp_Overlay *tail;
   /* True if this change is an insertion.  */
   bool insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end));
 
-  overlay = Qnil;
-  tail = NULL;
-
   /* We used to run the functions as soon as we found them and only register
      them in last_overlay_modification_hooks for the purpose of the `after'
      case.  But running elisp code as we traverse the list of overlays is
@@ -4459,68 +3814,35 @@ report_overlay_modification (Lisp_Object start, 
Lisp_Object end, bool after,
 
   if (!after)
     {
+      struct interval_node *node;
+      EMACS_INT begin_arg = XFASTINT (start);
+      EMACS_INT end_arg = XFASTINT (end);
       /* We are being called before a change.
         Scan the overlays to find the functions to call.  */
       last_overlay_modification_hooks_used = 0;
-      for (tail = current_buffer->overlays_before; tail; tail = tail->next)
-       {
-         ptrdiff_t startpos, endpos;
-         Lisp_Object ostart, oend;
-
-         XSETMISC (overlay, tail);
-
-         ostart = OVERLAY_START (overlay);
-         oend = OVERLAY_END (overlay);
-         endpos = OVERLAY_POSITION (oend);
-         if (XFASTINT (start) > endpos)
-           break;
-         startpos = OVERLAY_POSITION (ostart);
-         if (insertion && (XFASTINT (start) == startpos
-                           || XFASTINT (end) == startpos))
-           {
-             prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
-             if (!NILP (prop))
-               add_overlay_mod_hooklist (prop, overlay);
-           }
-         if (insertion && (XFASTINT (start) == endpos
-                           || XFASTINT (end) == endpos))
-           {
-             prop = Foverlay_get (overlay, Qinsert_behind_hooks);
-             if (!NILP (prop))
-               add_overlay_mod_hooklist (prop, overlay);
-           }
-         /* Test for intersecting intervals.  This does the right thing
-            for both insertion and deletion.  */
-         if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
-           {
-             prop = Foverlay_get (overlay, Qmodification_hooks);
-             if (!NILP (prop))
-               add_overlay_mod_hooklist (prop, overlay);
-           }
-       }
 
-      for (tail = current_buffer->overlays_after; tail; tail = tail->next)
+      if (! current_buffer->overlays)
+        return;
+      buffer_overlay_iter_start (current_buffer,
+                                 begin_arg - (insertion ? 1 : 0),
+                                 end_arg + (insertion ? 1 : 0),
+                                 ITREE_ASCENDING);
+      while ((node = buffer_overlay_iter_next (current_buffer)))
        {
-         ptrdiff_t startpos, endpos;
-         Lisp_Object ostart, oend;
-
-         XSETMISC (overlay, tail);
-
-         ostart = OVERLAY_START (overlay);
-         oend = OVERLAY_END (overlay);
-         startpos = OVERLAY_POSITION (ostart);
-         endpos = OVERLAY_POSITION (oend);
-         if (XFASTINT (end) < startpos)
-           break;
-         if (insertion && (XFASTINT (start) == startpos
-                           || XFASTINT (end) == startpos))
+          Lisp_Object overlay = node->data;
+         ptrdiff_t obegin = OVERLAY_START (overlay);
+         ptrdiff_t oend = OVERLAY_END (overlay);
+          Lisp_Object prop;
+
+         if (insertion && (begin_arg == obegin
+                           || end_arg == obegin))
            {
              prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
              if (!NILP (prop))
                add_overlay_mod_hooklist (prop, overlay);
            }
-         if (insertion && (XFASTINT (start) == endpos
-                           || XFASTINT (end) == endpos))
+         if (insertion && (begin_arg == oend
+                           || end_arg == oend))
            {
              prop = Foverlay_get (overlay, Qinsert_behind_hooks);
              if (!NILP (prop))
@@ -4528,15 +3850,15 @@ report_overlay_modification (Lisp_Object start, 
Lisp_Object end, bool after,
            }
          /* Test for intersecting intervals.  This does the right thing
             for both insertion and deletion.  */
-         if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
+         if (! insertion || (end_arg > obegin && begin_arg < oend))
            {
              prop = Foverlay_get (overlay, Qmodification_hooks);
              if (!NILP (prop))
                add_overlay_mod_hooklist (prop, overlay);
            }
        }
+      buffer_overlay_iter_finish (current_buffer);
     }
-
   {
     /* Call the functions recorded in last_overlay_modification_hooks.
        First copy the vector contents, in case some of these hooks
@@ -4558,7 +3880,7 @@ report_overlay_modification (Lisp_Object start, 
Lisp_Object end, bool after,
           function is never called to record the overlay modification
           hook functions in the last_overlay_modification_hooks
           array, so anything we find there is not ours.  */
-       if (XMARKER (OVERLAY_START (ovl))->buffer != current_buffer)
+       if (OVERLAY_BUFFER (ovl) != current_buffer)
          return;
       }
 
@@ -4598,34 +3920,22 @@ call_overlay_mod_hooks (Lisp_Object list, Lisp_Object 
overlay, bool after,
 void
 evaporate_overlays (ptrdiff_t pos)
 {
-  Lisp_Object overlay, hit_list;
-  struct Lisp_Overlay *tail;
+  Lisp_Object hit_list;
+  struct interval_node *node;
+
+  if (! current_buffer->overlays)
+    return;
 
   hit_list = Qnil;
-  if (pos <= current_buffer->overlay_center)
-    for (tail = current_buffer->overlays_before; tail; tail = tail->next)
-      {
-       ptrdiff_t endpos;
-       XSETMISC (overlay, tail);
-       endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
-       if (endpos < pos)
-         break;
-       if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos
-           && ! NILP (Foverlay_get (overlay, Qevaporate)))
-         hit_list = Fcons (overlay, hit_list);
-      }
-  else
-    for (tail = current_buffer->overlays_after; tail; tail = tail->next)
-      {
-       ptrdiff_t startpos;
-       XSETMISC (overlay, tail);
-       startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
-       if (startpos > pos)
-         break;
-       if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos
-           && ! NILP (Foverlay_get (overlay, Qevaporate)))
-         hit_list = Fcons (overlay, hit_list);
-      }
+  buffer_overlay_iter_start (current_buffer, pos, pos, ITREE_ASCENDING);
+
+  while ((node = buffer_overlay_iter_next (current_buffer)))
+    {
+      if (node->end == pos
+          && ! NILP (Foverlay_get (node->data, Qevaporate)))
+        hit_list = Fcons (node->data, hit_list);
+    }
+  buffer_overlay_iter_finish (current_buffer);
   for (; CONSP (hit_list); hit_list = XCDR (hit_list))
     Fdelete_overlay (XCAR (hit_list));
 }
@@ -5212,9 +4522,7 @@ init_buffer_once (void)
   bset_mark_active (&buffer_defaults, Qnil);
   bset_file_format (&buffer_defaults, Qnil);
   bset_auto_save_file_format (&buffer_defaults, Qt);
-  set_buffer_overlays_before (&buffer_defaults, NULL);
-  set_buffer_overlays_after (&buffer_defaults, NULL);
-  buffer_defaults.overlay_center = BEG;
+  buffer_defaults.overlays = NULL;
 
   XSETFASTINT (BVAR (&buffer_defaults, tab_width), 8);
   bset_truncate_lines (&buffer_defaults, Qnil);
@@ -5434,6 +4742,48 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, 
const char *namestring,
     emacs_abort ();
 }
 
+#ifdef ITREE_DEBUG
+static Lisp_Object
+make_lispy_interval_node (const struct interval_node *node)
+{
+  return listn (CONSTYPE_HEAP, 12,
+                intern (":begin"),
+                make_number (node->begin),
+                intern (":end"),
+                make_number (node->end),
+                intern (":limit"),
+                make_number (node->limit),
+                intern (":offset"),
+                make_number (node->offset),
+                intern (":rear-advance"),
+                node->rear_advance ? Qt : Qnil,
+                intern (":front-advance"),
+                node->front_advance ? Qt : Qnil);
+}
+
+static Lisp_Object
+overlay_tree (const struct interval_tree *tree,
+              const struct interval_node *node)
+{
+  if (node == &tree->nil)
+    return Qnil;
+  return list3 (make_lispy_interval_node (node),
+                overlay_tree (tree, node->left),
+                overlay_tree (tree, node->right));
+}
+
+DEFUN ("overlay-tree", Foverlay_tree, Soverlay_tree, 0, 1, 0,
+       doc: /* Get the overlay tree for BUFFER.  */)
+     (Lisp_Object buffer)
+{
+  struct buffer *b = decode_buffer (buffer);
+  if (! b->overlays)
+    return Qnil;
+  return overlay_tree (b->overlays, b->overlays->root);
+}
+#endif
+
+
 
 /* Initialize the buffer routines.  */
 void
@@ -6303,6 +5653,10 @@ Functions running this hook are, `get-buffer-create',
   defsubr (&Srestore_buffer_modified_p);
 
   Fput (intern_c_string ("erase-buffer"), Qdisabled, Qt);
+
+#ifdef ITREE_DEBUG
+  defsubr (&Soverlay_tree);
+#endif
 }
 
 void
diff --git a/src/buffer.h b/src/buffer.h
index ac7c5a5..ef31ad1 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -26,6 +26,7 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 
 #include "character.h"
 #include "lisp.h"
+#include "itree.h"
 
 INLINE_HEADER_BEGIN
 
@@ -877,16 +878,8 @@ struct buffer
   /* Non-zero whenever the narrowing is changed in this buffer.  */
   bool_bf clip_changed : 1;
 
-  /* List of overlays that end at or before the current center,
-     in order of end-position.  */
-  struct Lisp_Overlay *overlays_before;
-
-  /* List of overlays that end after  the current center,
-     in order of start-position.  */
-  struct Lisp_Overlay *overlays_after;
-
-  /* Position where the overlay lists are centered.  */
-  ptrdiff_t overlay_center;
+  /* The inveral tree containing this buffer's overlays. */
+  struct interval_tree *overlays;
 
   /* Changes in the buffer are recorded here for undo, and t means
      don't record anything.  This information belongs to the base
@@ -896,6 +889,14 @@ struct buffer
   Lisp_Object undo_list_;
 };
 
+struct sortvec
+{
+  Lisp_Object overlay;
+  ptrdiff_t beg, end;
+  EMACS_INT priority;
+  EMACS_INT spriority;         /* Secondary priority.  */
+};
+
 INLINE bool
 BUFFERP (Lisp_Object a)
 {
@@ -1109,8 +1110,11 @@ extern void delete_all_overlays (struct buffer *);
 extern void reset_buffer (struct buffer *);
 extern void compact_buffer (struct buffer *);
 extern void evaporate_overlays (ptrdiff_t);
-extern ptrdiff_t overlays_at (EMACS_INT, bool, Lisp_Object **,
-                             ptrdiff_t *, ptrdiff_t *, ptrdiff_t *, bool);
+extern ptrdiff_t overlays_at (ptrdiff_t, bool, Lisp_Object **, ptrdiff_t *, 
ptrdiff_t *);
+extern ptrdiff_t overlays_in (ptrdiff_t, ptrdiff_t, bool, Lisp_Object **,
+                              ptrdiff_t *,  bool, ptrdiff_t *);
+extern ptrdiff_t previous_overlay_change (ptrdiff_t);
+extern ptrdiff_t next_overlay_change (ptrdiff_t);
 extern ptrdiff_t sort_overlays (Lisp_Object *, ptrdiff_t, struct window *);
 extern void recenter_overlay_lists (struct buffer *, ptrdiff_t);
 extern ptrdiff_t overlay_strings (ptrdiff_t, struct window *, unsigned char 
**);
@@ -1162,18 +1166,16 @@ record_unwind_current_buffer (void)
    If NEXTP is non-NULL, return next overlay there.
    See overlay_at arg CHANGE_REQ for meaning of CHRQ arg.  */
 
-#define GET_OVERLAYS_AT(posn, overlays, noverlays, nextp, chrq)                
\
+#define GET_OVERLAYS_AT(posn, overlays, noverlays, next)                \
   do {                                                                 \
     ptrdiff_t maxlen = 40;                                             \
     SAFE_NALLOCA (overlays, 1, maxlen);                                        
\
-    (noverlays) = overlays_at (posn, false, &(overlays), &maxlen,      \
-                              nextp, NULL, chrq);                      \
+    (noverlays) = overlays_at (posn, false, &(overlays), &maxlen, next); \
     if ((noverlays) > maxlen)                                          \
       {                                                                        
\
        maxlen = noverlays;                                             \
        SAFE_NALLOCA (overlays, 1, maxlen);                             \
-       (noverlays) = overlays_at (posn, false, &(overlays), &maxlen,   \
-                                  nextp, NULL, chrq);                  \
+       (noverlays) = overlays_at (posn, false, &(overlays), &maxlen, next); \
       }                                                                        
\
   } while (false)
 
@@ -1208,7 +1210,8 @@ set_buffer_intervals (struct buffer *b, INTERVAL i)
 INLINE bool
 buffer_has_overlays (void)
 {
-  return current_buffer->overlays_before || current_buffer->overlays_after;
+  return current_buffer->overlays
+    && (interval_tree_size (current_buffer->overlays) > 0);
 }
 
 /* Return character code of multi-byte form at byte position POS.  If POS
@@ -1248,23 +1251,124 @@ buffer_window_count (struct buffer *b)
 
 /* Overlays */
 
-/* Return the marker that stands for where OV starts in the buffer.  */
+INLINE ptrdiff_t
+overlay_start (struct Lisp_Overlay *ov)
+{
+  if (! ov->buffer)
+    return -1;
+  return interval_node_begin (ov->buffer->overlays, ov->interval);
+}
+
+INLINE ptrdiff_t
+overlay_end (struct Lisp_Overlay *ov)
+{
+  if (! ov->buffer)
+    return -1;
+  return interval_node_end (ov->buffer->overlays, ov->interval);
+}
+
+INLINE void
+set_overlay_region (struct Lisp_Overlay *ov, ptrdiff_t begin, ptrdiff_t end)
+{
+  eassert (ov->buffer);
+  begin = clip_to_bounds (BEG, begin, ov->buffer->text->z);
+  end = clip_to_bounds (begin, end, ov->buffer->text->z);
+  interval_node_set_region (ov->buffer->overlays, ov->interval, begin, end);
+}
+
+INLINE void
+maybe_alloc_buffer_overlays (struct buffer *b)
+{
+  if (! b->overlays)
+    b->overlays = interval_tree_create ();
+}
+
+/* FIXME: Actually this does not free any overlay, but the tree
+   only. --ap */
+
+INLINE void
+free_buffer_overlays (struct buffer *b)
+{
+  eassert (! b->overlays || 0 == interval_tree_size (b->overlays));
+  if (b->overlays)
+    {
+      interval_tree_destroy (b->overlays);
+      b->overlays = NULL;
+    }
+}
+
+INLINE void
+add_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov)
+{
+  eassert (! ov->buffer);
+  maybe_alloc_buffer_overlays (b);
+  ov->buffer = b;
+  interval_tree_insert (b->overlays, ov->interval);
+}
+
+INLINE void
+remove_buffer_overlay (struct buffer *b, struct Lisp_Overlay *ov)
+{
+  eassert (b->overlays);
+  eassert (ov->buffer == b);
+  interval_tree_remove (ov->buffer->overlays, ov->interval);
+  ov->buffer = NULL;
+}
+
+INLINE void
+buffer_overlay_iter_start (struct buffer *b, ptrdiff_t begin, ptrdiff_t end,
+                           enum interval_tree_order order)
+{
+  if (b->overlays)
+    interval_tree_iter_start (b->overlays, begin, end, order);
+}
+
+INLINE struct interval_node*
+buffer_overlay_iter_next (struct buffer *b)
+{
+  if (! b->overlays)
+    return NULL;
+  return interval_tree_iter_next (b->overlays);
+}
+
+INLINE void
+buffer_overlay_iter_finish (struct buffer *b)
+{
+  if (b->overlays)
+    interval_tree_iter_finish (b->overlays);
+}
+
+INLINE void
+buffer_overlay_iter_narrow (struct buffer *b, ptrdiff_t begin, ptrdiff_t end)
+{
+  if (b->overlays)
+    interval_tree_iter_narrow (b->overlays, begin, end);
+}
 
-#define OVERLAY_START(OV) XOVERLAY (OV)->start
+/* Return the start of OV in its buffer, or -1 if OV is not associated
+   with any buffer.  */
 
-/* Return the marker that stands for where OV ends in the buffer.  */
+#define OVERLAY_START(OV) (overlay_start (XOVERLAY (OV)))
 
-#define OVERLAY_END(OV) XOVERLAY (OV)->end
+/* Return the end of OV in its buffer, or -1. */
+
+#define OVERLAY_END(OV) (overlay_end (XOVERLAY (OV)))
 
 /* Return the plist of overlay OV.  */
 
-#define OVERLAY_PLIST(OV) XOVERLAY (OV)->plist
+#define OVERLAY_PLIST(OV) (XOVERLAY (OV)->plist)
+
+/* Return the buffer of overlay OV. */
+
+#define OVERLAY_BUFFER(OV) (XOVERLAY (OV)->buffer)
 
-/* Return the actual buffer position for the marker P.
-   We assume you know which buffer it's pointing into.  */
+/* Return true, if OV's rear-advance is set. */
 
-#define OVERLAY_POSITION(P) \
- (MARKERP (P) ? marker_position (P) : (emacs_abort (), 0))
+#define OVERLAY_REAR_ADVANCE_P(OV) (XOVERLAY (OV)->interval->rear_advance)
+
+/* Return true, if OV's front-advance is set. */
+
+#define OVERLAY_FRONT_ADVANCE_P(OV) (XOVERLAY (OV)->interval->front_advance)
 
 
 /***********************************************************************
@@ -1405,4 +1509,7 @@ lowercasep (int c)
 
 INLINE_HEADER_END
 
+int compare_overlays (const void *v1, const void *v2);
+void make_sortvec_item (struct sortvec *item, Lisp_Object overlay);
+
 #endif /* EMACS_BUFFER_H */
diff --git a/src/editfns.c b/src/editfns.c
index 4dcf7cb..8628b1b 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -457,51 +457,9 @@ If you set the marker not to point anywhere, the buffer 
will have no mark.  */)
    of length LEN.  */
 
 static ptrdiff_t
-overlays_around (EMACS_INT pos, Lisp_Object *vec, ptrdiff_t len)
+overlays_around (ptrdiff_t pos, Lisp_Object *vec, ptrdiff_t len)
 {
-  Lisp_Object overlay, start, end;
-  struct Lisp_Overlay *tail;
-  ptrdiff_t startpos, endpos;
-  ptrdiff_t idx = 0;
-
-  for (tail = current_buffer->overlays_before; tail; tail = tail->next)
-    {
-      XSETMISC (overlay, tail);
-
-      end = OVERLAY_END (overlay);
-      endpos = OVERLAY_POSITION (end);
-      if (endpos < pos)
-         break;
-      start = OVERLAY_START (overlay);
-      startpos = OVERLAY_POSITION (start);
-      if (startpos <= pos)
-       {
-         if (idx < len)
-           vec[idx] = overlay;
-         /* Keep counting overlays even if we can't return them all.  */
-         idx++;
-       }
-    }
-
-  for (tail = current_buffer->overlays_after; tail; tail = tail->next)
-    {
-      XSETMISC (overlay, tail);
-
-      start = OVERLAY_START (overlay);
-      startpos = OVERLAY_POSITION (start);
-      if (pos < startpos)
-       break;
-      end = OVERLAY_END (overlay);
-      endpos = OVERLAY_POSITION (end);
-      if (pos <= endpos)
-       {
-         if (idx < len)
-           vec[idx] = overlay;
-         idx++;
-       }
-    }
-
-  return idx;
+  return overlays_in (pos - 1, pos, false, &vec, &len, false, NULL);
 }
 
 DEFUN ("get-pos-property", Fget_pos_property, Sget_pos_property, 2, 3, 0,
@@ -561,11 +519,10 @@ at POSITION.  */)
          if (!NILP (tem))
            {
              /* Check the overlay is indeed active at point.  */
-             Lisp_Object start = OVERLAY_START (ol), finish = OVERLAY_END (ol);
-             if ((OVERLAY_POSITION (start) == posn
-                  && XMARKER (start)->insertion_type == 1)
-                 || (OVERLAY_POSITION (finish) == posn
-                     && XMARKER (finish)->insertion_type == 0))
+             if ((OVERLAY_START (ol) == posn
+                  && OVERLAY_FRONT_ADVANCE_P (ol))
+                 || (OVERLAY_END (ol) == posn
+                     && ! OVERLAY_REAR_ADVANCE_P (ol)))
                ; /* The overlay will not cover a char inserted at point.  */
              else
                {
@@ -5385,7 +5342,6 @@ Transposing beyond buffer boundaries is an error.  */)
       transpose_markers (start1, end1, start2, end2,
                         start1_byte, start1_byte + len1_byte,
                         start2_byte, start2_byte + len2_byte);
-      fix_start_end_in_overlays (start1, end2);
     }
   else
     {
diff --git a/src/fileio.c b/src/fileio.c
index 1137027..6b22b29 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3656,8 +3656,7 @@ by calling `format-decode', which see.  */)
                  bset_read_only (buf, Qnil);
                  bset_filename (buf, Qnil);
                  bset_undo_list (buf, Qt);
-                 eassert (buf->overlays_before == NULL);
-                 eassert (buf->overlays_after == NULL);
+                 eassert (buf->overlays == NULL);
 
                  set_buffer_internal (buf);
                  Ferase_buffer ();
diff --git a/src/fns.c b/src/fns.c
index 2311a6e..9f41103 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2240,10 +2240,9 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum 
equal_kind equal_kind,
        return false;
       if (OVERLAYP (o1))
        {
-         if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2),
-                              equal_kind, depth + 1, ht)
-             || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2),
-                                 equal_kind, depth + 1, ht))
+         if (OVERLAY_START (o1) != OVERLAY_START (o2)
+             || OVERLAY_END (o1) != OVERLAY_END (o2)
+              || OVERLAY_BUFFER (o1) != OVERLAY_BUFFER (o2))
            return false;
          o1 = XOVERLAY (o1)->plist;
          o2 = XOVERLAY (o2)->plist;
diff --git a/src/indent.c b/src/indent.c
index 26507b5..8ac7c6e 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -225,9 +225,6 @@ skip_invisible (ptrdiff_t pos, ptrdiff_t *next_boundary_p, 
ptrdiff_t to, Lisp_Ob
   XSETFASTINT (position, pos);
   XSETBUFFER (buffer, current_buffer);
 
-  /* Give faster response for overlay lookup near POS.  */
-  recenter_overlay_lists (current_buffer, pos);
-
   /* We must not advance farther than the next overlay change.
      The overlay change might change the invisible property;
      or there might be overlay strings to be displayed there.  */
@@ -501,7 +498,7 @@ check_display_width (ptrdiff_t pos, ptrdiff_t col, 
ptrdiff_t *endpos)
        {
          ptrdiff_t start;
          if (OVERLAYP (overlay))
-           *endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+           *endpos = OVERLAY_END (overlay);
          else
            get_property_and_range (pos, Qdisplay, &val, &start, endpos, Qnil);
 
diff --git a/src/insdel.c b/src/insdel.c
index 5dfc628..3e9f0c9 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -276,7 +276,6 @@ adjust_markers_for_insert (ptrdiff_t from, ptrdiff_t 
from_byte,
                           ptrdiff_t to, ptrdiff_t to_byte, bool before_markers)
 {
   struct Lisp_Marker *m;
-  bool adjusted = 0;
   ptrdiff_t nchars = to - from;
   ptrdiff_t nbytes = to_byte - from_byte;
 
@@ -292,8 +291,6 @@ adjust_markers_for_insert (ptrdiff_t from, ptrdiff_t 
from_byte,
            {
              m->bytepos = to_byte;
              m->charpos = to;
-             if (m->insertion_type)
-               adjusted = 1;
            }
        }
       else if (m->bytepos > from_byte)
@@ -302,15 +299,6 @@ adjust_markers_for_insert (ptrdiff_t from, ptrdiff_t 
from_byte,
          m->charpos += nchars;
        }
     }
-
-  /* Adjusting only markers whose insertion-type is t may result in
-     - disordered start and end in overlays, and
-     - disordered overlays in the slot `overlays_before' of current_buffer.  */
-  if (adjusted)
-    {
-      fix_start_end_in_overlays (from, to);
-      fix_overlays_before (current_buffer, from, to);
-    }
 }
 
 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
diff --git a/src/intervals.c b/src/intervals.c
index e711212..3db80eb 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -1810,8 +1810,8 @@ adjust_for_invis_intang (ptrdiff_t pos, ptrdiff_t 
test_offs, ptrdiff_t adj,
             == (test_offs == 0 ? 1 : -1))
          /* Invisible property is from an overlay.  */
          : (test_offs == 0
-            ? XMARKER (OVERLAY_START (invis_overlay))->insertion_type == 0
-            : XMARKER (OVERLAY_END (invis_overlay))->insertion_type == 1)))
+            ? ! OVERLAY_FRONT_ADVANCE_P (invis_overlay)
+            : OVERLAY_REAR_ADVANCE_P (invis_overlay))))
     pos += adj;
 
   return pos;
diff --git a/src/itree.c b/src/itree.c
new file mode 100644
index 0000000..0c10100
--- /dev/null
+++ b/src/itree.c
@@ -0,0 +1,1138 @@
+/* This file implements an efficient interval data-structure.
+
+Copyright (C) 2017 Andreas Politz (address@hidden)
+
+This file is not part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <math.h>
+#include "lisp.h"
+#include "itree.h"
+
+/*
+   Intervals of the form [BEGIN, END), are stored as nodes inside a RB
+   tree, sorted by BEGIN .  The core operation of this tree (besides
+   insert, remove, etc.) is finding all intervals intersecting with
+   some given interval.  In order to perform this operation
+   efficiently, every node stores a third value called LIMIT. (See
+   https://en.wikipedia.org/wiki/Interval_tree#Augmented_tree and its
+   source Introduction to Algorithms (Section 14.3), Cormen et al. .)
+
+   ==== Finding intervals ====
+
+   If we search for all intervals intersecting with (X, Y], we look at
+   some node and test whether
+
+   NODE.BEGIN > Y
+
+   Due to the invariant of the search tree, we know, that we may
+   safely prune NODE's right subtree if this test succeeds, since all
+   intervals begin strictly after Y.
+
+   But we can not make such an assumptions about the left tree, since
+   all we know is that the intervals in this subtree must start before
+   or at NODE.BEGIN.  So we can't tell, whether they end before X or
+   not.  To solve this problem we add another attribute to each node,
+   called LIMIT.
+
+   The LIMIT of a node is the largest END value occurring in the nodes
+   subtree (including the node itself).  Thus, we may look at the left
+   child of some NODE and test whether
+
+   NODE.left.LIMIT < X
+
+   and this tells us, if all intervals in the left subtree of NODE end
+   before X and if they can be pruned.
+
+   Conversely, if this inequality is false, the left subtree must
+   contain at least one intersecting interval, giving a resulting time
+   complexity of O(K*log(N)) for this operation, where K is the size
+   of the result set and N the size of the tree.
+
+   ==== Adjusting intervals ====
+
+   Since this data-structure will be used for overlays in an Emacs
+   buffer, a second core operation implements the ability to insert or
+   delete gaps in resp. from the tree.  This models the insertion
+   resp. deletion of text in a buffer and the effects it may have on
+   the positions of overlays.
+
+   Consider this: Something gets inserted at position P into a buffer
+   and assume that all overlays occur strictly after P.  Ordinarily,
+   we would have to iterate all overlays and increment their BEGIN and
+   END values accordingly (the insertion of text pushes them back).
+   In order to avoid this, we introduce yet another node attribute,
+   called OFFSET.
+
+   The OFFSET of some some subtree, represented by its root, is the
+   amount of shift that needs to be applied to its BEGIN, END and
+   LIMIT values, in order to get to the real values.  Coming back to
+   the example, all we would need to do in this case, is to increment
+   the OFFSET of the tree's root, without any traversal of the tree
+   itself.
+
+   As a consequence, the real values of BEGIN, END and LIMIT of some
+   NODE need to be computed by incrementing them by the sum of NODE's
+   OFFSET and all of its ancestors offsets.  Therefore, we store a
+   counter (otick) inside every node and also the tree, by which we
+   remember the fact, that a node's path to the root has no offsets
+   applied (i.e. its values are up to date).  This is the case if some
+   node's value differs from the tree's one, the later of which is
+   incremented whenever some node's offset has changed.
+*/
+
+static struct interval_node *interval_tree_validate(struct interval_tree *, 
struct interval_node *);
+static void interval_generator_ensure_space(struct interval_generator *);
+static bool interval_node_intersects(const struct interval_node *, ptrdiff_t, 
ptrdiff_t);
+static int interval_tree_max_height(const struct interval_tree *);
+static struct interval_stack *interval_stack_create(intmax_t);
+static void interval_stack_destroy(struct interval_stack *);
+static void interval_stack_clear(struct interval_stack *);
+static void interval_stack_ensure_space(struct interval_stack *, intmax_t);
+static void interval_stack_push(struct interval_stack *, struct interval_node 
*);
+static void interval_stack_push_flagged(struct interval_stack *, struct 
interval_node *, bool);
+static struct interval_node *interval_stack_pop(struct interval_stack *);
+static void interval_tree_update_limit(const struct interval_tree *, struct 
interval_node *);
+static void interval_tree_inherit_offset(const struct interval_tree *, struct 
interval_node *);
+static void interval_tree_propagate_limit(const struct interval_tree *, struct 
interval_node *);
+static void interval_tree_rotate_left(struct interval_tree *, struct 
interval_node *);
+static void interval_tree_rotate_right(struct interval_tree *, struct 
interval_node *);
+static void interval_tree_insert_fix(struct interval_tree *, struct 
interval_node *);
+static void interval_tree_remove_fix(struct interval_tree *, struct 
interval_node *);
+static void interval_tree_transplant(struct interval_tree *, struct 
interval_node *, struct interval_node *);
+static struct interval_node *interval_tree_subtree_min(const struct 
interval_tree *, struct interval_node *);
+static struct interval_generator* interval_generator_create (struct 
interval_tree *);
+static void interval_generator_destroy (struct interval_generator *);
+static void interval_generator_reset (struct interval_generator *,
+                               ptrdiff_t, ptrdiff_t,
+                               enum interval_tree_order);
+static void
+interval_generator_narrow (struct interval_generator *g,
+                             ptrdiff_t begin, ptrdiff_t end);
+static inline struct interval_node*
+interval_generator_next (struct interval_generator *g);
+static inline void interval_tree_iter_ensure_space(struct interval_tree *);
+
+
+
+/* 
+------------------------------------------------------------------------------------+
 */
+
+/* Simple dynamic array. */
+struct interval_stack
+{
+  struct interval_node **nodes;
+  size_t size;
+  size_t length;
+};
+
+/* State used when iterating interval. */
+struct interval_generator
+{
+  struct interval_tree *tree;
+  struct interval_stack *stack;
+  ptrdiff_t begin;
+  ptrdiff_t end;
+  enum interval_tree_order order;
+};
+
+
+
+/* 
+===================================================================================+
+ * | Tree operations
+ * 
+===================================================================================+
 */
+
+/* Initialize an allocated node. */
+
+void
+interval_node_init (struct interval_node *node,
+                    ptrdiff_t begin, ptrdiff_t end,
+                    bool front_advance, bool rear_advance,
+                    Lisp_Object data)
+{
+  node->begin = begin;
+  node->end = max (begin, end);
+  node->front_advance = front_advance;
+  node->rear_advance = rear_advance;
+  node->data = data;
+}
+
+/* Return NODE's begin value, computing it if necessary. */
+
+ptrdiff_t
+interval_node_begin (struct interval_tree *tree,
+                     struct interval_node *node)
+{
+  interval_tree_validate (tree, node);
+  return node->begin;
+}
+
+/* Return NODE's end value, computing it if necessary. */
+
+ptrdiff_t
+interval_node_end (struct interval_tree *tree,
+                   struct interval_node *node)
+{
+  interval_tree_validate (tree, node);
+  return node->end;
+}
+
+/* Safely modify a node's interval. */
+
+void
+interval_node_set_region (struct interval_tree *tree,
+                          struct interval_node *node,
+                          ptrdiff_t begin, ptrdiff_t end)
+{
+  interval_tree_validate (tree, node);
+  if (begin != node->begin)
+    {
+      interval_tree_remove (tree, node);
+      node->begin = min (begin, PTRDIFF_MAX - 1);
+      node->end = max (node->begin, end);
+      interval_tree_insert (tree, node);
+    }
+  else if (end != node->end)
+    {
+      node->end = max (node->begin, end);
+      interval_tree_propagate_limit (tree, node);
+    }
+}
+
+/* Allocate an interval_tree. Free with interval_tree_destroy. */
+
+struct interval_tree*
+interval_tree_create (void)
+{
+  struct interval_tree *tree = xmalloc (sizeof (*tree));
+  interval_tree_clear (tree);
+  tree->iter = interval_generator_create (tree);
+  return tree;
+}
+
+/* Reset the tree TREE to its empty state. */
+
+void
+interval_tree_clear (struct interval_tree *tree)
+{
+  struct interval_node *nil = &tree->nil;
+  nil->left = nil->right = nil->parent = nil;
+  nil->offset = nil->otick = 0;
+  nil->begin = PTRDIFF_MIN;
+  nil->end = PTRDIFF_MIN;
+  nil->limit = PTRDIFF_MIN;     /* => max(x, nil.limit) = x */
+  nil->color = ITREE_BLACK;
+  tree->root = nil;
+  tree->otick = 1;
+  tree->size = 0;
+  tree->iter_running = 0;
+}
+
+#ifdef ITREE_TESTING
+/* Initialize a pre-allocated tree (presumably on the stack). */
+
+static void
+interval_tree_init (struct interval_tree *tree)
+{
+  interval_tree_clear (tree);
+  tree->iter = interval_generator_create (tree);
+}
+#endif
+
+/* Release a tree, freeing its allocated memory. */
+void
+interval_tree_destroy (struct interval_tree *tree)
+{
+  if (! tree)
+    return;
+  if (tree->iter)
+    interval_generator_destroy (tree->iter);
+  xfree (tree);
+}
+
+/* Return the number of nodes in TREE.  */
+
+intmax_t
+interval_tree_size (struct interval_tree *tree)
+{
+  return tree->size;
+}
+
+/* Insert a NODE into the TREE.
+
+   Note, that inserting a node twice results in undefined behaviour.
+*/
+
+void
+interval_tree_insert (struct interval_tree *tree, struct interval_node *node)
+{
+  eassert (node && node->begin <= node->end && node != &tree->nil);
+
+  struct interval_node *parent = &tree->nil;
+  struct interval_node *child = tree->root;
+  ptrdiff_t offset = 0;
+
+  /* Find the insertion point, accumulate node's offset and update
+     ancestors limit values. */
+  while (child != &tree->nil)
+    {
+      parent = child;
+      offset += child->offset;
+      child->limit = max (child->limit, node->end - offset);
+      /* This suggests that nodes in the right subtree are strictly
+         greater.  But this is not true due to later rotations. */
+      child = node->begin <= child->begin ? child->left : child->right;
+    }
+
+  /* Insert the node */
+  if (parent == &tree->nil)
+    tree->root = node;
+  else if (node->begin <= parent->begin)
+    parent->left = node;
+  else
+    parent->right = node;
+
+  /* Init the node */
+  node->parent = parent;
+  node->left = &tree->nil;
+  node->right = &tree->nil;
+  node->color = ITREE_RED;
+  node->offset = offset;
+  node->limit = node->end;
+  node->otick = tree->otick - 1;
+
+  /* Fix/update the tree */
+  ++tree->size;
+  interval_tree_insert_fix (tree, node);
+  interval_tree_iter_ensure_space (tree);
+}
+
+/* Return true, if NODE is a member of TREE. */
+
+bool
+interval_tree_contains (struct interval_tree *tree, struct interval_node *node)
+{
+  struct interval_node *other;
+
+  interval_tree_iter_start (tree, node->begin, PTRDIFF_MAX, ITREE_ASCENDING);
+  while ((other = interval_tree_iter_next (tree)))
+    if (other == node)
+      break;
+
+  interval_tree_iter_finish (tree);
+  return other == node;
+}
+
+/* Remove NODE from TREE and return it. NODE must exist in TREE.*/
+
+struct interval_node*
+interval_tree_remove (struct interval_tree *tree, struct interval_node *node)
+{
+  eassert (interval_tree_contains (tree, node));
+
+  struct interval_node *broken = NULL;
+
+  interval_tree_inherit_offset (tree, node);
+  if (node->left == &tree->nil || node->right == &tree->nil)
+    {
+      struct interval_node *subst =
+        (node->right == &tree->nil) ? node->left : node->right;
+      if (node->color == ITREE_BLACK)
+        broken = subst;
+      interval_tree_transplant (tree, subst, node);
+      interval_tree_propagate_limit (tree, subst);
+    }
+  else
+    {
+      struct interval_node *min = interval_tree_subtree_min (tree, 
node->right);
+      struct interval_node *min_right = min->right;
+
+      if (min->color == ITREE_BLACK)
+        broken = min->right;
+      if (min->parent == node)
+        min_right->parent = min; /* set parent, if min_right = nil */
+      else
+        {
+          interval_tree_transplant (tree, min->right, min);
+          min->right = node->right;
+          min->right->parent = min;
+        }
+      interval_tree_inherit_offset (tree, min);
+      interval_tree_transplant (tree, min, node);
+      min->left = node->left;
+      min->left->parent = min;
+      min->color = node->color;
+      interval_tree_propagate_limit (tree, min_right);
+      interval_tree_propagate_limit (tree, min);
+    }
+
+  if (broken)
+    interval_tree_remove_fix (tree, broken);
+
+  node->right = node->left = node->parent = NULL;
+  --tree->size;
+
+  eassert (tree->size == 0 || (tree->size > 0 && tree->root != &tree->nil));
+
+  return node;
+}
+
+static struct interval_node*
+interval_tree_validate (struct interval_tree *tree, struct interval_node *node)
+{
+
+  if (tree->otick == node->otick || node == &tree->nil)
+    return node;
+  if (node != tree->root)
+    interval_tree_validate (tree, node->parent);
+
+  interval_tree_inherit_offset (tree, node);
+  return node;
+}
+
+/* Start a generator iterating all intervals in [BEGIN,END) in the
+   given ORDER. Only one iterator per tree can be running at any
+   time.
+*/
+
+void
+interval_tree_iter_start (struct interval_tree *tree,
+                          ptrdiff_t begin, ptrdiff_t end,
+                          enum interval_tree_order order)
+{
+  if (tree->iter_running)
+    emacs_abort ();
+  interval_generator_reset (tree->iter, begin, end, order);
+  tree->iter_running = 1;
+}
+
+/* Limit the search interval of the iterator to the given values.  The
+   interval can only shrink, but never grow.*/
+
+inline void
+interval_tree_iter_narrow(struct interval_tree *tree,
+                               ptrdiff_t begin, ptrdiff_t end)
+{
+  if (! tree->iter_running)
+    emacs_abort ();
+  interval_generator_narrow (tree->iter, begin, end);
+}
+
+/* Stop using the iterator. */
+
+void
+interval_tree_iter_finish (struct interval_tree *tree)
+{
+  if (! tree->iter_running)
+    emacs_abort ();
+  tree->iter_running = 0;
+}
+
+/* Return the next node of the iterator in the order given when it was
+   started; or NULL if there are no more nodes. */
+
+inline struct interval_node*
+interval_tree_iter_next (struct interval_tree *tree)
+{
+  if (! tree->iter_running)
+    emacs_abort ();
+  return interval_generator_next (tree->iter);
+}
+
+/* Ensure that the tree's iterator does not need to allocate space
+   until the tree grows in size. */
+
+static inline void
+interval_tree_iter_ensure_space (struct interval_tree *tree)
+{
+  interval_generator_ensure_space (tree->iter);
+}
+
+static int
+interval_tree_max_height (const struct interval_tree *tree)
+{
+  return 2 * log (tree->size + 1) / log (2) + 0.5;
+}
+
+
+/* 
+===================================================================================+
+ * | Insert/Delete Gaps
+ * 
+===================================================================================+
 */
+
+/* Insert a gap at POS of length LENGTH expanding all intervals
+   intersecting it, while respecting their rear_advance and
+   front_advance setting. */
+
+void
+interval_tree_insert_gap (struct interval_tree *tree, ptrdiff_t pos, ptrdiff_t 
length)
+{
+  if (length <= 0 || tree->size == 0)
+    return;
+
+  /* FIXME: Don't allocate generator/stack anew every time. */
+
+  /* Nodes with front_advance starting at pos may mess up the tree
+     order, so we need to remove them first. */
+  struct interval_stack *saved = interval_stack_create (0);
+  struct interval_node *node = NULL;
+  interval_tree_iter_start (tree, pos, pos + 1, ITREE_PRE_ORDER);
+  while ((node = interval_tree_iter_next (tree)))
+    {
+      if (node->begin == pos && node->front_advance
+          && (node->begin != node->end || node->rear_advance))
+        interval_stack_push (saved, node);
+    }
+  interval_tree_iter_finish (tree);
+  for (int i = 0; i < saved->length; ++i)
+    interval_tree_remove (tree, saved->nodes[i]);
+
+
+  /* We can't use a generator here, because we can't effectively
+     narrow AND shift some subtree at the same time. */
+  const int size = interval_tree_max_height (tree) + 1;
+  struct interval_stack *stack = interval_stack_create (size);
+  interval_stack_push (stack, tree->root);
+  while ((node = interval_stack_pop (stack)))
+    {
+      /* Process in pre-order. */
+      interval_tree_inherit_offset (tree, node);
+      if (node->right != &tree->nil)
+        {
+          if (node->begin > pos)
+            {
+              /* All nodes in this subtree are shifted by length. */
+              node->right->offset += length;
+              ++tree->otick;
+            }
+          else
+            interval_stack_push (stack, node->right);
+        }
+      if (node->left != &tree->nil && pos <= node->left->limit)
+        interval_stack_push (stack, node->left);
+
+      /* node->begin == pos implies no front-advance. */
+      if (node->begin > pos)
+        node->begin += length;
+      if (node->end > pos || (node->end == pos && node->rear_advance))
+        {
+          node->end += length;
+          interval_tree_propagate_limit (tree, node);
+        }
+    }
+  interval_stack_destroy (stack);
+
+  /* Reinsert nodes starting at POS having front-advance. */
+  while ((node = interval_stack_pop (saved)))
+    {
+      node->begin += length;
+      if (node->end != pos || node->rear_advance)
+        node->end += length;
+      interval_tree_insert (tree, node);
+    }
+
+  interval_stack_destroy (saved);
+}
+
+/* Delete a gap at POS of length LENGTH, contracting all intervals
+   intersecting it. */
+
+void
+interval_tree_delete_gap (struct interval_tree *tree, ptrdiff_t pos, ptrdiff_t 
length)
+{
+  if (length <= 0 || tree->size == 0)
+    return;
+
+  /* FIXME: Don't allocate stack anew every time. */
+
+  /* Can't use the generator here, because by decrementing begin, we
+     might unintentionally bring shifted nodes back into our search
+     space. */
+  const int size = interval_tree_max_height (tree) + 1;
+  struct interval_stack *stack = interval_stack_create (size);
+  struct interval_node *node;
+
+  interval_stack_push (stack, tree->root);
+  while ((node = interval_stack_pop (stack)))
+    {
+      interval_tree_inherit_offset (tree, node);
+      if (node->right != &tree->nil)
+        {
+          if (node->begin > pos + length)
+            {
+              /* Shift right subtree to the left. */
+              node->right->offset -= length;
+              ++tree->otick;
+            }
+          else
+            interval_stack_push (stack, node->right);
+        }
+      if (node->left != &tree->nil && pos <= node->left->limit)
+        interval_stack_push (stack, node->left);
+
+      if (pos < node->begin)
+        node->begin = max (pos, node->begin - length);
+      if (node->end > pos)
+        {
+          node->end = max (pos , node->end - length);
+          interval_tree_propagate_limit (tree, node);
+        }
+    }
+  interval_stack_destroy (stack);
+}
+
+
+
+/* 
+===================================================================================+
+ * | Generator
+ * 
+===================================================================================+
 */
+
+/* Allocate a new generator for TREE. */
+
+static struct interval_generator*
+interval_generator_create  (struct interval_tree *tree)
+{
+  struct interval_generator *g = xmalloc (sizeof *g);
+  const int size = interval_tree_max_height (tree) + 1;
+
+  g->stack = interval_stack_create (size);
+  g->tree = tree;
+  interval_generator_reset (g, 1, 0, 0);
+  return g;
+}
+
+/* Reset generator G such that it iterates over intervals intersecting
+   with [BEGIN, END) in the given ORDER. */
+
+void
+interval_generator_reset (struct interval_generator *g,
+                          ptrdiff_t begin, ptrdiff_t end,
+                          enum interval_tree_order order)
+{
+  if (! g) return;
+
+  g->begin = begin;
+  g->end = end;
+  g->order = order;
+  interval_stack_clear (g->stack);
+  if (begin <= end  && g->tree->size > 0)
+    interval_stack_push_flagged (g->stack, g->tree->root, false);
+}
+
+/* Allocate enough space for the tree of G in its current shape. */
+
+static inline void
+interval_generator_ensure_space (struct interval_generator *g)
+{
+  interval_stack_ensure_space (g->stack, interval_tree_max_height (g->tree) + 
1);
+}
+
+/* Return true, if NODE's interval intersects with [BEGIN, END). */
+
+static inline bool
+interval_node_intersects (const struct interval_node *node,
+                          ptrdiff_t begin, ptrdiff_t end)
+{
+  return (begin < node->end && node->begin < end)
+    || (node->begin == node->end && begin == node->begin);
+}
+
+/* Return the next node of G, or NULL if there is none. */
+
+inline struct interval_node*
+interval_generator_next (struct interval_generator *g)
+{
+  if (! g) return NULL;
+
+  struct interval_node * const nil = &g->tree->nil;
+  struct interval_node *node;
+
+  do {
+    node = interval_stack_pop (g->stack);
+
+    while (node && ! node->visited)
+      {
+        struct interval_node * const left = node->left;
+        struct interval_node * const right = node->right;
+
+        interval_tree_inherit_offset (g->tree, node);
+        switch (g->order)
+          {
+          case ITREE_ASCENDING:
+            if (right != nil && node->begin <= g->end)
+              interval_stack_push_flagged (g->stack, right, false);
+            if (interval_node_intersects (node, g->begin, g->end))
+              interval_stack_push_flagged (g->stack, node, true);
+            /* Node's children may still be off-set and we need to add it. */
+            if (left != nil && g->begin <= left->limit + left->offset)
+              interval_stack_push_flagged (g->stack, left, false);
+            break;
+          case ITREE_DESCENDING:
+            if (left != nil && g->begin <= left->limit + left->offset)
+              interval_stack_push_flagged (g->stack, left, false);
+            if (interval_node_intersects (node, g->begin, g->end))
+              interval_stack_push_flagged (g->stack, node, true);
+            if (right != nil && node->begin <= g->end)
+              interval_stack_push_flagged (g->stack, right, false);
+            break;
+          case ITREE_PRE_ORDER:
+            if (right != nil && node->begin <= g->end)
+              interval_stack_push_flagged (g->stack, right, false);
+            if (left != nil && g->begin <= left->limit + left->offset)
+              interval_stack_push_flagged (g->stack, left, false);
+            if (interval_node_intersects (node, g->begin, g->end))
+              interval_stack_push_flagged (g->stack, node, true);
+            break;
+          }
+        node = interval_stack_pop (g->stack);
+      }
+    /* Node may have been invalidated by interval_generator_narrow
+       after it was pushed: Check if it still intersects. */
+  } while (node && ! interval_node_intersects (node, g->begin, g->end));
+
+  return node;
+}
+
+/* Limit G to the new interval [BEGIN, END), which must be a subset of
+   the current one.  I.E. it can't grow on either side. */
+
+static inline void
+interval_generator_narrow (struct interval_generator *g,
+                           ptrdiff_t begin, ptrdiff_t end)
+{
+  g->begin =  max (begin, g->begin);
+  g->end =  min (end, g->end);
+}
+
+/* Free the memory allocated for G. */
+
+void
+interval_generator_destroy (struct interval_generator *g)
+{
+  if (! g) return;
+  if (g->stack)
+    interval_stack_destroy (g->stack);
+  xfree (g);
+}
+
+
+/* 
+===================================================================================+
+ * | Stack
+ * 
+===================================================================================+
 */
+
+/* This is just a simple dynamic array with stack semantics. */
+
+static struct interval_stack*
+interval_stack_create (intmax_t initial_size)
+{
+  struct interval_stack *stack = xmalloc (sizeof (struct interval_stack));
+  stack->size = max (0, initial_size);
+  stack->nodes = xmalloc (stack->size * sizeof (struct interval_node*));
+  stack->length = 0;
+  return stack;
+}
+
+static void
+interval_stack_destroy (struct interval_stack *stack)
+{
+  if (! stack)
+    return;
+  if (stack->nodes)
+    xfree (stack->nodes);
+  xfree (stack);
+}
+
+static void
+interval_stack_clear (struct interval_stack *stack)
+{
+  stack->length = 0;
+}
+
+static inline void
+interval_stack_ensure_space (struct interval_stack *stack, intmax_t nelements)
+{
+  if (nelements > stack->size)
+    {
+      stack->size = (nelements + 1) * 2;
+      stack->nodes = xrealloc (stack->nodes, stack->size * sizeof 
(*stack->nodes));
+    }
+}
+
+static inline void
+interval_stack_push (struct interval_stack *stack, struct interval_node *node)
+{
+  interval_stack_ensure_space (stack, stack->length + 1);
+  stack->nodes[stack->length] = node;
+  stack->length++;
+}
+
+/* Push NODE on the STACK, while settings its visited flag to FLAG. */
+
+static inline void
+interval_stack_push_flagged (struct interval_stack *stack,
+                             struct interval_node *node, bool flag)
+{
+  interval_stack_push (stack, node);
+  node->visited = flag;
+}
+
+static inline struct interval_node*
+interval_stack_pop (struct interval_stack *stack)
+{
+  if (stack->length == 0)
+    return NULL;
+  return stack->nodes[--stack->length];
+}
+
+
+/* 
+===================================================================================+
+ * | Internal Functions
+ * 
+===================================================================================+
 */
+
+/* Update NODE's limit attribute according to its children. */
+
+static void
+interval_tree_update_limit (const struct interval_tree *tree,
+                            struct interval_node *node)
+{
+  if (node == &tree->nil)
+    return;
+
+  node->limit = max (node->end, max (node->left->limit + node->left->offset,
+                                     node->right->limit + 
node->right->offset));
+}
+
+/* Apply NODE's offset to its begin, end and limit values and
+   propagate it to its children.
+
+   Does nothing, if NODE is clean, i.e. NODE.otick = tree.otick .
+*/
+
+static void
+interval_tree_inherit_offset (const struct interval_tree *tree,
+                              struct interval_node *node)
+{
+
+  if (node->otick == tree->otick)
+    return;
+
+  node->begin += node->offset;
+  node->end += node->offset;
+  node->limit += node->offset;
+  if (node->left != &tree->nil)
+    node->left->offset += node->offset;
+  if (node->right != &tree->nil)
+    node->right->offset += node->offset;
+  node->offset = 0;
+  if (node == tree->root || node->parent->otick == tree->otick)
+    node->otick = tree->otick;
+}
+
+/* Update limit of NODE and its ancestors.  Stop when it becomes
+   stable, i.e. new_limit = old_limit.
+
+   NODE may also be the nil node, in which case its parent is
+   used. (This feature is due to the RB algorithm.)
+*/
+
+static void
+interval_tree_propagate_limit (const struct interval_tree *tree,
+                               struct interval_node *node)
+{
+  if (node == &tree->nil)
+    node = node->parent;
+  if (node == &tree->nil)
+    return;
+
+  while (1) {
+    ptrdiff_t newlimit = max (node->end, max (node->left->limit + 
node->left->offset,
+                                              node->right->limit + 
node->right->offset));
+    if (newlimit == node->limit)
+      break;
+    node->limit = newlimit;
+    if (node == tree->root)
+      break;
+    node = node->parent;
+  }
+}
+
+/* Perform the familiar left-rotation on node NODE. */
+
+static void
+interval_tree_rotate_left (struct interval_tree *tree, struct interval_node 
*node)
+{
+  eassert (node->right != &tree->nil);
+
+  struct interval_node *right = node->right;
+
+  interval_tree_inherit_offset (tree, node);
+  interval_tree_inherit_offset (tree, right);
+
+  /* Turn right's left subtree into node's right subtree.  */
+  node->right = right->left;
+  if (right->left != &tree->nil)
+    right->left->parent = node;
+
+  /* right's parent was node's parent.  */
+  if (right != &tree->nil)
+    right->parent = node->parent;
+
+  /* Get the parent to point to right instead of node.  */
+  if (node != tree->root)
+    {
+      if (node == node->parent->left)
+       node->parent->left = right;
+      else
+       node->parent->right = right;
+    }
+  else
+    tree->root = right;
+
+  /* Put node on right's left.  */
+  right->left = node;
+  if (node != &tree->nil)
+    node->parent = right;
+
+  /* Order matters here. */
+  interval_tree_update_limit (tree, node);
+  interval_tree_update_limit (tree, right);
+}
+
+/* Perform the familiar right-rotation on node NODE. */
+
+static void
+interval_tree_rotate_right (struct interval_tree *tree, struct interval_node 
*node)
+{
+  eassert (tree && node && node->left != &tree->nil);
+
+  struct interval_node *left = node->left;
+
+  interval_tree_inherit_offset (tree, node);
+  interval_tree_inherit_offset (tree, left);
+
+  node->left = left->right;
+  if (left->right != &tree->nil)
+    left->right->parent = node;
+
+  if (left != &tree->nil)
+    left->parent = node->parent;
+  if (node != tree->root)
+    {
+      if (node == node->parent->right)
+       node->parent->right = left;
+      else
+       node->parent->left = left;
+    }
+  else
+    tree->root = left;
+
+  left->right = node;
+  if (node != &tree->nil)
+    node->parent = left;
+
+  interval_tree_update_limit (tree, left);
+  interval_tree_update_limit (tree, node);
+}
+
+/* Repair the tree after an insertion.  Part of the RB-Tree
+   algorithm. */
+
+static void
+interval_tree_insert_fix (struct interval_tree *tree, struct interval_node 
*node)
+{
+  while (node->parent->color == ITREE_RED)
+    {
+      /* NODE is red and its parent is red.  This is a violation of
+        red-black tree property #3.  */
+
+      if (node->parent == node->parent->parent->left)
+       {
+         /* We're on the left side of our grandparent, and OTHER is
+            our "uncle".  */
+         struct interval_node *uncle = node->parent->parent->right;
+
+         if (uncle->color == ITREE_RED) /* case 1.a */
+           {
+             /* Uncle and parent are red but should be black because
+                NODE is red.  Change the colors accordingly and
+                proceed with the grandparent.  */
+             node->parent->color = ITREE_BLACK;
+             uncle->color = ITREE_BLACK;
+             node->parent->parent->color = ITREE_RED;
+             node = node->parent->parent;
+            }
+         else
+           {
+             /* Parent and uncle have different colors; parent is
+                red, uncle is black.  */
+             if (node == node->parent->right) /* case 2.a */
+               {
+                 node = node->parent;
+                 interval_tree_rotate_left (tree, node);
+                }
+              /* case 3.a */
+             node->parent->color = ITREE_BLACK;
+             node->parent->parent->color = ITREE_RED;
+             interval_tree_rotate_right (tree, node->parent->parent);
+            }
+        }
+      else
+       {
+         /* This is the symmetrical case of above.  */
+         struct interval_node *uncle = node->parent->parent->left;
+
+         if (uncle->color == ITREE_RED) /* case 1.b */
+           {
+             node->parent->color = ITREE_BLACK;
+             uncle->color = ITREE_BLACK;
+             node->parent->parent->color = ITREE_RED;
+             node = node->parent->parent;
+            }
+         else
+           {
+             if (node == node->parent->left) /* case 2.b */
+               {
+                 node = node->parent;
+                 interval_tree_rotate_right (tree, node);
+               }
+              /* case 3.b */
+             node->parent->color = ITREE_BLACK;
+             node->parent->parent->color = ITREE_RED;
+             interval_tree_rotate_left (tree, node->parent->parent);
+            }
+        }
+    }
+
+  /* The root may have been changed to red due to the algorithm.  Set
+     it to black so that property #5 is satisfied.  */
+  tree->root->color = ITREE_BLACK;
+}
+
+/* Repair the tree after a deletion.  Part of the RB-Tree
+   algorithm. */
+
+static void
+interval_tree_remove_fix (struct interval_tree *tree, struct interval_node 
*node)
+{
+  while (node != tree->root && node->color == ITREE_BLACK)
+    {
+      if (node == node->parent->left)
+       {
+         struct interval_node *other = node->parent->right;
+
+         if (other->color == ITREE_RED) /* case 1.a */
+           {
+             other->color = ITREE_BLACK;
+             node->parent->color = ITREE_RED;
+             interval_tree_rotate_left (tree, node->parent);
+             other = node->parent->right;
+            }
+
+         if (other->left->color == ITREE_BLACK /* 2.a */
+              && other->right->color == ITREE_BLACK)
+           {
+             other->color = ITREE_RED;
+             node = node->parent;
+            }
+         else
+           {
+             if (other->right->color == ITREE_BLACK) /* 3.a */
+               {
+                 other->left->color = ITREE_BLACK;
+                 other->color = ITREE_RED;
+                 interval_tree_rotate_right (tree, other);
+                 other = node->parent->right;
+                }
+             other->color = node->parent->color; /* 4.a */
+             node->parent->color = ITREE_BLACK;
+             other->right->color = ITREE_BLACK;
+             interval_tree_rotate_left (tree, node->parent);
+             node = tree->root;
+            }
+        }
+      else
+       {
+         struct interval_node *other = node->parent->left;
+
+         if (other->color == ITREE_RED) /* 1.b */
+           {
+             other->color = ITREE_BLACK;
+             node->parent->color = ITREE_RED;
+             interval_tree_rotate_right (tree, node->parent);
+             other = node->parent->left;
+            }
+
+         if (other->right->color == ITREE_BLACK /* 2.b */
+              && other->left->color == ITREE_BLACK)
+           {
+             other->color = ITREE_RED;
+             node = node->parent;
+            }
+         else
+           {
+             if (other->left->color == ITREE_BLACK) /* 3.b */
+               {
+                 other->right->color = ITREE_BLACK;
+                 other->color = ITREE_RED;
+                 interval_tree_rotate_left (tree, other);
+                 other = node->parent->left;
+                }
+
+             other->color = node->parent->color; /* 4.b */
+             node->parent->color = ITREE_BLACK;
+             other->left->color = ITREE_BLACK;
+             interval_tree_rotate_right (tree, node->parent);
+             node = tree->root;
+            }
+        }
+    }
+
+  node->color = ITREE_BLACK;
+}
+
+/* Link node SOURCE in DEST's place. */
+
+static void
+interval_tree_transplant (struct interval_tree *tree, struct interval_node 
*source,
+                          struct interval_node *dest)
+{
+  eassert (tree && source && dest && dest != &tree->nil);
+
+  if (dest == tree->root)
+    tree->root = source;
+  else if (dest == dest->parent->left)
+    dest->parent->left = source;
+  else
+    dest->parent->right = source;
+
+  source->parent = dest->parent;
+}
+
+
+static struct interval_node*
+interval_tree_subtree_min (const struct interval_tree *tree, struct 
interval_node *node)
+{
+  if (node == &tree->nil)
+    return node;
+  while (node->left != &tree->nil)
+    node = node->left;
+  return node;
+}
+
+
+/* 
+===================================================================================+
+ * | Debugging
+ * 
+===================================================================================+
 */
+
+/* See Foverlay_tree in buffer.c */
diff --git a/src/itree.h b/src/itree.h
new file mode 100644
index 0000000..d35c5af
--- /dev/null
+++ b/src/itree.h
@@ -0,0 +1,88 @@
+/* This file implements an efficient interval data-structure.
+
+Copyright (C) 2017 Andreas Politz (address@hidden)
+
+This file is not part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef ITREE_H
+#define ITREE_H
+#include <config.h>
+#include <stddef.h>
+#include <inttypes.h>
+
+/* The tree and node structs are mainly here, so they can be allocated.
+
+   NOTE: The only time where it is safe to modify node.begin and
+   node.end directly, is while the node is not part of any tree.
+
+   NOTE: It is safe to read node.begin and node.end directly, if the
+   node came from a generator, because it validates the nodes it
+   returns as a side-effect.
+*/
+
+struct interval_node;
+struct interval_node
+{
+  enum { ITREE_RED, ITREE_BLACK } color;
+  struct interval_node *parent;
+  struct interval_node *left;
+  struct interval_node *right;
+  ptrdiff_t begin;             /* The beginning of this interval. */
+  ptrdiff_t end;               /* The end of the interval. */
+  ptrdiff_t limit;             /* The maximum end in this subtree. */
+  ptrdiff_t offset;            /* The amount of shift to apply to this 
subtree. */
+  uintmax_t otick;              /* offset modified tick */
+  Lisp_Object data;             /* Exclusively used by the client. */
+  bool_bf visited;              /* For traversal via generator. */
+  bool_bf rear_advance : 1;     /* Same as for marker and overlays.  */
+  bool_bf front_advance : 1;    /* Same as for marker and overlays.  */
+};
+
+struct interval_tree
+{
+  struct interval_node *root;
+  struct interval_node nil;    /* The tree's version of NULL. */
+  uintmax_t otick;              /* offset tick, compared with node's otick. */
+  intmax_t size;                /* Number of nodes in the tree. */
+  struct interval_generator *iter;
+  bool_bf iter_running;
+};
+
+enum interval_tree_order {
+  ITREE_ASCENDING = 0,
+  ITREE_DEFLT_ORDER = 0,
+  ITREE_DESCENDING,
+  ITREE_PRE_ORDER,
+};
+
+void interval_node_init(struct interval_node *, ptrdiff_t, ptrdiff_t, bool, 
bool, Lisp_Object);
+ptrdiff_t interval_node_begin(struct interval_tree *, struct interval_node *);
+ptrdiff_t interval_node_end(struct interval_tree *, struct interval_node *);
+void interval_node_set_region(struct interval_tree *, struct interval_node *, 
ptrdiff_t, ptrdiff_t);
+struct interval_tree *interval_tree_create(void);
+void interval_tree_destroy(struct interval_tree *);
+intmax_t interval_tree_size(struct interval_tree *);
+void interval_tree_clear(struct interval_tree *);
+void interval_tree_insert(struct interval_tree *, struct interval_node *);
+bool interval_tree_contains(struct interval_tree *, struct interval_node *);
+struct interval_node *interval_tree_remove(struct interval_tree *, struct 
interval_node *);
+void interval_tree_iter_start(struct interval_tree *, ptrdiff_t, ptrdiff_t, 
enum interval_tree_order);
+void interval_tree_iter_narrow(struct interval_tree *, ptrdiff_t, ptrdiff_t);
+void interval_tree_iter_finish(struct interval_tree *);
+struct interval_node *interval_tree_iter_next(struct interval_tree *);
+void interval_tree_insert_gap(struct interval_tree *, ptrdiff_t, ptrdiff_t);
+void interval_tree_delete_gap(struct interval_tree *, ptrdiff_t, ptrdiff_t);
+#endif
diff --git a/src/keyboard.c b/src/keyboard.c
index e8701b8..60cdaba 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1668,8 +1668,8 @@ adjust_point_for_property (ptrdiff_t last_pt, bool 
modified)
          && display_prop_intangible_p (val, overlay, PT, PT_BYTE)
          && (!OVERLAYP (overlay)
              ? get_property_and_range (PT, Qdisplay, &val, &beg, &end, Qnil)
-             : (beg = OVERLAY_POSITION (OVERLAY_START (overlay)),
-                end = OVERLAY_POSITION (OVERLAY_END (overlay))))
+             : (beg = OVERLAY_START (overlay),
+                end = OVERLAY_END (overlay)))
          && (beg < PT /* && end > PT   <- It's always the case.  */
              || (beg <= PT && STRINGP (val) && SCHARS (val) == 0)))
        {
diff --git a/src/lisp.h b/src/lisp.h
index 680c25d..222a999 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2217,15 +2217,14 @@ struct Lisp_Overlay
    - next fields of start and end markers (singly linked list of markers).
    I.e. 9words plus 2 bits, 3words of which are for external linked lists.
 */
-  {
-    ENUM_BF (Lisp_Misc_Type) type : 16;        /* = Lisp_Misc_Overlay */
-    bool_bf gcmarkbit : 1;
-    unsigned spacer : 15;
-    struct Lisp_Overlay *next;
-    Lisp_Object start;
-    Lisp_Object end;
-    Lisp_Object plist;
-  };
+{
+  ENUM_BF (Lisp_Misc_Type) type : 16;  /* = Lisp_Misc_Overlay */
+  bool_bf gcmarkbit : 1;
+  unsigned spacer : 15;
+  Lisp_Object plist;
+  struct buffer *buffer;        /* eassert (live buffer || NULL). */
+  struct interval_node *interval;
+};
 
 /* Number of bits needed to store one of the values
    SAVE_UNUSED..SAVE_OBJECT.  */
@@ -3704,7 +3703,7 @@ extern Lisp_Object make_save_funcptr_ptr_obj (void (*) 
(void), void *,
                                              Lisp_Object);
 extern Lisp_Object make_save_memory (Lisp_Object *, ptrdiff_t);
 extern void free_save_value (Lisp_Object);
-extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
+extern Lisp_Object build_overlay (ptrdiff_t, ptrdiff_t, bool, bool, 
Lisp_Object);
 extern void free_marker (Lisp_Object);
 extern void free_cons (struct Lisp_Cons *);
 extern void init_alloc_once (void);
diff --git a/src/print.c b/src/print.c
index f280616..a07baa3 100644
--- a/src/print.c
+++ b/src/print.c
@@ -548,8 +548,7 @@ temp_output_buffer_setup (const char *bufname)
   bset_read_only (current_buffer, Qnil);
   bset_filename (current_buffer, Qnil);
   bset_undo_list (current_buffer, Qt);
-  eassert (current_buffer->overlays_before == NULL);
-  eassert (current_buffer->overlays_after == NULL);
+  eassert (current_buffer->overlays == NULL);
   bset_enable_multibyte_characters
     (current_buffer, BVAR (&buffer_defaults, enable_multibyte_characters));
   specbind (Qinhibit_read_only, Qt);
@@ -2074,7 +2073,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, 
bool escapeflag)
              obj = XCDR (obj);
              if (!(i & 1))
                halftail = XCDR (halftail);
-         }
+            }
 
          /* OBJ non-nil here means it's the end of a dotted list.  */
          if (!NILP (obj))
@@ -2114,15 +2113,14 @@ print_object (Lisp_Object obj, Lisp_Object 
printcharfun, bool escapeflag)
 
        case Lisp_Misc_Overlay:
          print_c_string ("#<overlay ", printcharfun);
-         if (! XMARKER (OVERLAY_START (obj))->buffer)
+         if (! OVERLAY_BUFFER (obj))
            print_c_string ("in no buffer", printcharfun);
          else
            {
              int len = sprintf (buf, "from %"pD"d to %"pD"d in ",
-                                marker_position (OVERLAY_START (obj)),
-                                marker_position (OVERLAY_END   (obj)));
+                                 OVERLAY_START (obj), OVERLAY_END (obj));
              strout (buf, len, len, printcharfun);
-             print_string (BVAR (XMARKER (OVERLAY_START (obj))->buffer, name),
+             print_string (BVAR (OVERLAY_BUFFER (obj), name),
                            printcharfun);
            }
          printchar ('>', printcharfun);
diff --git a/src/textprop.c b/src/textprop.c
index 513780c..aebb652 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -617,36 +617,42 @@ get_char_property_and_overlay (Lisp_Object position, 
register Lisp_Object prop,
     }
   if (BUFFERP (object))
     {
-      ptrdiff_t noverlays;
-      Lisp_Object *overlay_vec;
-      struct buffer *obuf = current_buffer;
+      struct buffer *b = XBUFFER (object);
+      struct interval_node *node;
+      struct sortvec items[2];
+      struct sortvec *result = NULL;
+      Lisp_Object result_tem = Qnil;
 
-      if (XINT (position) < BUF_BEGV (XBUFFER (object))
-         || XINT (position) > BUF_ZV (XBUFFER (object)))
+      if (XINT (position) < BUF_BEGV (b) || XINT (position) > BUF_ZV (b))
        xsignal1 (Qargs_out_of_range, position);
 
-      set_buffer_temp (XBUFFER (object));
-
-      USE_SAFE_ALLOCA;
-      GET_OVERLAYS_AT (XINT (position), overlay_vec, noverlays, NULL, false);
-      noverlays = sort_overlays (overlay_vec, noverlays, w);
-
-      set_buffer_temp (obuf);
+      buffer_overlay_iter_start(b, XINT (position), XINT (position) + 1,
+                                ITREE_ASCENDING);
 
       /* Now check the overlays in order of decreasing priority.  */
-      while (--noverlays >= 0)
+      while ((node = buffer_overlay_iter_next (b)))
        {
-         Lisp_Object tem = Foverlay_get (overlay_vec[noverlays], prop);
-         if (!NILP (tem))
-           {
-             if (overlay)
-               /* Return the overlay we got the property from.  */
-               *overlay = overlay_vec[noverlays];
-             SAFE_FREE ();
-             return tem;
-           }
+         Lisp_Object tem = Foverlay_get (node->data, prop);
+          struct sortvec *this;
+
+         if (NILP (tem) || (w && ! overlay_matches_window (w, node->data)))
+           continue;
+
+          this = (result == items ? items + 1 : items);
+          make_sortvec_item (this, node->data);
+          if (! result || (compare_overlays (result, this) < 0))
+            {
+              result = this;
+              result_tem = tem;
+            }
        }
-      SAFE_FREE ();
+      buffer_overlay_iter_finish (b);
+      if (result)
+        {
+          if (overlay)
+            *overlay = result->overlay;
+          return result_tem;
+        }
     }
 
   if (overlay)
diff --git a/src/window.h b/src/window.h
index df7c23f..324d30b 100644
--- a/src/window.h
+++ b/src/window.h
@@ -1128,6 +1128,16 @@ output_cursor_to (struct window *w, int vpos, int hpos, 
int y, int x)
   w->output_cursor.y = y;
 }
 
+/* Return true, if overlay OV's properties should have an effect in
+   window W. */
+INLINE bool
+overlay_matches_window (const struct window *w, Lisp_Object ov)
+{
+  eassert (OVERLAYP (ov));
+  Lisp_Object  window = Foverlay_get (ov, Qwindow);
+  return (! WINDOWP (window) || XWINDOW (window) == w);
+}
+
 INLINE_HEADER_END
 
 #endif /* not WINDOW_H_INCLUDED */
diff --git a/src/xdisp.c b/src/xdisp.c
index 86164eb..b3b9eca 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -873,7 +873,6 @@ static enum move_it_result
 static void get_visually_first_element (struct it *);
 static void compute_stop_pos (struct it *);
 static int face_before_or_after_it_pos (struct it *, bool);
-static ptrdiff_t next_overlay_change (ptrdiff_t);
 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
                                Lisp_Object, struct text_pos *, ptrdiff_t, 
bool);
 static int handle_single_display_spec (struct it *, Lisp_Object, Lisp_Object,
@@ -3606,39 +3605,6 @@ compute_stop_pos (struct it *it)
               && it->stop_charpos >= IT_CHARPOS (*it)));
 }
 
-
-/* Return the position of the next overlay change after POS in
-   current_buffer.  Value is point-max if no overlay change
-   follows.  This is like `next-overlay-change' but doesn't use
-   xmalloc.  */
-
-static ptrdiff_t
-next_overlay_change (ptrdiff_t pos)
-{
-  ptrdiff_t i, noverlays;
-  ptrdiff_t endpos;
-  Lisp_Object *overlays;
-  USE_SAFE_ALLOCA;
-
-  /* Get all overlays at the given position.  */
-  GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, true);
-
-  /* If any of these overlays ends before endpos,
-     use its ending point instead.  */
-  for (i = 0; i < noverlays; ++i)
-    {
-      Lisp_Object oend;
-      ptrdiff_t oendpos;
-
-      oend = OVERLAY_END (overlays[i]);
-      oendpos = OVERLAY_POSITION (oend);
-      endpos = min (endpos, oendpos);
-    }
-
-  SAFE_FREE ();
-  return endpos;
-}
-
 /* How many characters forward to search for a display property or
    display string.  Searching too far forward makes the bidi display
    sluggish, especially in small windows.  */
@@ -5071,7 +5037,7 @@ handle_single_display_spec (struct it *it, Lisp_Object 
spec, Lisp_Object object,
         overlay's display string/image twice.  */
       if (!NILP (overlay))
        {
-         ptrdiff_t ovendpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+         ptrdiff_t ovendpos = OVERLAY_END (overlay);
 
          /* Some borderline-sane Lisp might call us with the current
             buffer narrowed so that overlay-end is outside the
@@ -5785,13 +5751,14 @@ static void
 load_overlay_strings (struct it *it, ptrdiff_t charpos)
 {
   Lisp_Object overlay, window, str, invisible;
-  struct Lisp_Overlay *ov;
   ptrdiff_t start, end;
   ptrdiff_t n = 0, i, j;
   int invis;
   struct overlay_entry entriesbuf[20];
   ptrdiff_t size = ARRAYELTS (entriesbuf);
   struct overlay_entry *entries = entriesbuf;
+  struct interval_node *node;
+
   USE_SAFE_ALLOCA;
 
   if (charpos <= 0)
@@ -5823,83 +5790,47 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
     }                                                                  \
   while (false)
 
-  /* Process overlay before the overlay center.  */
-  for (ov = current_buffer->overlays_before; ov; ov = ov->next)
+  if (current_buffer->overlays)
     {
-      XSETMISC (overlay, ov);
-      eassert (OVERLAYP (overlay));
-      start = OVERLAY_POSITION (OVERLAY_START (overlay));
-      end = OVERLAY_POSITION (OVERLAY_END (overlay));
-
-      if (end < charpos)
-       break;
-
-      /* Skip this overlay if it doesn't start or end at IT's current
-        position.  */
-      if (end != charpos && start != charpos)
-       continue;
-
-      /* Skip this overlay if it doesn't apply to IT->w.  */
-      window = Foverlay_get (overlay, Qwindow);
-      if (WINDOWP (window) && XWINDOW (window) != it->w)
-       continue;
-
-      /* If the text ``under'' the overlay is invisible, both before-
-        and after-strings from this overlay are visible; start and
-        end position are indistinguishable.  */
-      invisible = Foverlay_get (overlay, Qinvisible);
-      invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
-
-      /* If overlay has a non-empty before-string, record it.  */
-      if ((start == charpos || (end == charpos && invis != 0))
-         && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
-         && SCHARS (str))
-       RECORD_OVERLAY_STRING (overlay, str, false);
-
-      /* If overlay has a non-empty after-string, record it.  */
-      if ((end == charpos || (start == charpos && invis != 0))
-         && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
-         && SCHARS (str))
-       RECORD_OVERLAY_STRING (overlay, str, true);
-    }
-
-  /* Process overlays after the overlay center.  */
-  for (ov = current_buffer->overlays_after; ov; ov = ov->next)
-    {
-      XSETMISC (overlay, ov);
-      eassert (OVERLAYP (overlay));
-      start = OVERLAY_POSITION (OVERLAY_START (overlay));
-      end = OVERLAY_POSITION (OVERLAY_END (overlay));
-
-      if (start > charpos)
-       break;
-
-      /* Skip this overlay if it doesn't start or end at IT's current
-        position.  */
-      if (end != charpos && start != charpos)
-       continue;
-
-      /* Skip this overlay if it doesn't apply to IT->w.  */
-      window = Foverlay_get (overlay, Qwindow);
-      if (WINDOWP (window) && XWINDOW (window) != it->w)
-       continue;
-
-      /* If the text ``under'' the overlay is invisible, it has a zero
-        dimension, and both before- and after-strings apply.  */
-      invisible = Foverlay_get (overlay, Qinvisible);
-      invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
-
-      /* If overlay has a non-empty before-string, record it.  */
-      if ((start == charpos || (end == charpos && invis != 0))
-         && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
-         && SCHARS (str))
-       RECORD_OVERLAY_STRING (overlay, str, false);
-
-      /* If overlay has a non-empty after-string, record it.  */
-      if ((end == charpos || (start == charpos && invis != 0))
-         && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
-         && SCHARS (str))
-       RECORD_OVERLAY_STRING (overlay, str, true);
+      buffer_overlay_iter_start (current_buffer,
+                                 charpos - 1, charpos + 1, ITREE_DESCENDING);
+      /* Process overlays.  */
+      while ((node = buffer_overlay_iter_next (current_buffer)))
+        {
+          overlay = node->data;
+          eassert (OVERLAYP (overlay));
+          start = node->begin;
+          end = node->end;
+
+          /* Skip this overlay if it doesn't start or end at IT's current
+             position.  */
+          if (end != charpos && start != charpos)
+            continue;
+
+          /* Skip this overlay if it doesn't apply to IT->w.  */
+          window = Foverlay_get (overlay, Qwindow);
+          if (WINDOWP (window) && XWINDOW (window) != it->w)
+            continue;
+
+          /* If the text ``under'' the overlay is invisible, both before-
+             and after-strings from this overlay are visible; start and
+             end position are indistinguishable.  */
+          invisible = Foverlay_get (overlay, Qinvisible);
+          invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
+
+          /* If overlay has a non-empty before-string, record it.  */
+          if ((start == charpos || (end == charpos && invis != 0))
+              && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
+              && SCHARS (str))
+            RECORD_OVERLAY_STRING (overlay, str, false);
+
+          /* If overlay has a non-empty after-string, record it.  */
+          if ((end == charpos || (start == charpos && invis != 0))
+              && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
+              && SCHARS (str))
+            RECORD_OVERLAY_STRING (overlay, str, true);
+        }
+      buffer_overlay_iter_finish (current_buffer);
     }
 
 #undef RECORD_OVERLAY_STRING
@@ -6463,7 +6394,7 @@ back_to_previous_visible_line_start (struct it *it)
            && !NILP (val = get_char_property_and_overlay
                      (make_number (pos), Qdisplay, Qnil, &overlay))
            && (OVERLAYP (overlay)
-               ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
+               ? (beg = OVERLAY_START (overlay))
                : get_property_and_range (pos, Qdisplay, &val, &beg, &end, 
Qnil)))
          {
            RESTORE_IT (it, it, it2data);
@@ -9568,7 +9499,6 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int 
to_x, int to_y, int to_vpos
        }
 
       /* Reset/increment for the next run.  */
-      recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
       it->current_x = line_start_x;
       line_start_x = 0;
       it->hpos = 0;
@@ -21212,13 +21142,6 @@ display_line (struct it *it, int cursor_vpos)
   row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
   it->starts_in_middle_of_char_p = false;
 
-  /* Arrange the overlays nicely for our purposes.  Usually, we call
-     display_line on only one line at a time, in which case this
-     can't really hurt too much, or we call it on lines which appear
-     one after another in the buffer, in which case all calls to
-     recenter_overlay_lists but the first will be pretty cheap.  */
-  recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
-
   /* If we are going to display the cursor's line, account for the
      hscroll of that line.  We subtract the window's min_hscroll,
      because that was already accounted for in init_iterator.  */
@@ -31212,7 +31135,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
       if (BUFFERP (object))
        {
          /* Put all the overlays we want in a vector in overlay_vec.  */
-         GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, false);
+         GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL);
          /* Sort overlays into increasing priority order.  */
          noverlays = sort_overlays (overlay_vec, noverlays, w);
        }
diff --git a/src/xfaces.c b/src/xfaces.c
index b309c16..b178872 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -5931,8 +5931,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
   USE_SAFE_ALLOCA;
   {
     ptrdiff_t next_overlay;
-
-    GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay, false);
+    GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay);
     if (next_overlay < endpos)
       endpos = next_overlay;
   }
@@ -5975,7 +5974,6 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
     {
       for (prop = Qnil, i = noverlays - 1; i >= 0 && NILP (prop); --i)
        {
-         Lisp_Object oend;
          ptrdiff_t oendpos;
 
          prop = Foverlay_get (overlay_vec[i], propname);
@@ -5988,8 +5986,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
              merge_face_ref (f, prop, attrs, true, 0);
            }
 
-         oend = OVERLAY_END (overlay_vec[i]);
-         oendpos = OVERLAY_POSITION (oend);
+         oendpos = OVERLAY_END (overlay_vec[i]);
          if (oendpos < endpos)
            endpos = oendpos;
        }
@@ -5998,18 +5995,16 @@ face_at_buffer_position (struct window *w, ptrdiff_t 
pos,
     {
       for (i = 0; i < noverlays; i++)
        {
-         Lisp_Object oend;
          ptrdiff_t oendpos;
 
          prop = Foverlay_get (overlay_vec[i], propname);
          if (!NILP (prop))
            merge_face_ref (f, prop, attrs, true, 0);
 
-         oend = OVERLAY_END (overlay_vec[i]);
-         oendpos = OVERLAY_POSITION (oend);
-         if (oendpos < endpos)
-           endpos = oendpos;
-       }
+          oendpos = OVERLAY_END (overlay_vec[i]);
+          if (oendpos < endpos)
+            endpos = oendpos;
+        }
     }
 
   *endptr = endpos;
diff --git a/test/manual/noverlay/.gitignore b/test/manual/noverlay/.gitignore
new file mode 100644
index 0000000..ca7fc45
--- /dev/null
+++ b/test/manual/noverlay/.gitignore
@@ -0,0 +1 @@
+itree-tests
diff --git a/test/manual/noverlay/Makefile.in b/test/manual/noverlay/Makefile.in
new file mode 100644
index 0000000..beef1db
--- /dev/null
+++ b/test/manual/noverlay/Makefile.in
@@ -0,0 +1,32 @@
+PROGRAM = itree-tests
+LIBS = check
+top_srcdir = @top_srcdir@
+CFLAGS += -O0 -g3 $(shell pkg-config --cflags $(LIBS)) -I $(top_srcdir)/src
+LDFLAGS += $(shell pkg-config --libs $(LIBS)) -lm
+OBJECTS = itree-tests.o
+CC = gcc
+EMACS ?= ../../../src/emacs
+
+.PHONY: all check have-libcheck
+
+all: check
+
+have-libcheck:
+       pkg-config --cflags $(LIBS)
+
+check: have-libcheck $(PROGRAM)
+       ./check-sanitize.sh ./$(PROGRAM)
+
+itree-tests.o: emacs-compat.h itree-tests.c $(top_srcdir)/src/itree.c 
$(top_srcdir)/src/itree.h
+
+$(PROGRAM): $(OBJECTS)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) -o $(PROGRAM)
+
+perf:
+       -$(EMACS) -Q -l ./overlay-perf.el -f perf-run-batch
+
+clean:
+       rm -f -- $(OBJECTS) $(PROGRAM)
+
+distclean: clean
+       rm -f -- Makefile
diff --git a/test/manual/noverlay/check-sanitize.sh 
b/test/manual/noverlay/check-sanitize.sh
new file mode 100755
index 0000000..03eedce
--- /dev/null
+++ b/test/manual/noverlay/check-sanitize.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+prog=$1
+shift
+
+[ -z "$prog" ] && {
+    echo "usage:$(basename $0) CHECK_PRGOGRAM";
+    exit 1;
+}
+
+"$prog" "$@" | sed -e 's/^\([^:]\+\):\([0-9]\+\):[PFE]:[^:]*:\([^:]*\):[^:]*: 
*\(.*\)/\1:\2:\3:\4/'
diff --git a/test/manual/noverlay/emacs-compat.h 
b/test/manual/noverlay/emacs-compat.h
new file mode 100644
index 0000000..812f8e4
--- /dev/null
+++ b/test/manual/noverlay/emacs-compat.h
@@ -0,0 +1,52 @@
+#ifndef TEST_COMPAT_H
+#define TEST_COMPAT_H
+
+#include <stdio.h>
+#include <limits.h>
+
+typedef int Lisp_Object;
+
+void *
+xmalloc (size_t size)
+{
+  return malloc (size);
+}
+
+void
+xfree (void *ptr)
+{
+  free (ptr);
+}
+
+void *
+xrealloc (void *block, size_t size)
+{
+  return realloc (block, size);
+}
+
+void
+emacs_abort ()
+{
+  fprintf (stderr, "Aborting...\n");
+  exit (1);
+}
+
+#ifndef eassert
+#define eassert(cond)                                                   \
+  do {                                                                  \
+    if (! (cond)) {                                                     \
+      fprintf (stderr, "\n%s:%d:eassert condition failed: %s\n",        \
+               __FILE__, __LINE__ ,#cond);                              \
+      exit (1);                                                         \
+    }                                                                   \
+  } while (0)
+#endif
+
+#ifndef max
+#define max(x,y) ((x) >= (y) ? (x) : (y))
+#endif
+#ifndef min
+#define min(x,y) ((x) <= (y) ? (x) : (y))
+#endif
+
+#endif
diff --git a/test/manual/noverlay/itree-tests.c 
b/test/manual/noverlay/itree-tests.c
new file mode 100644
index 0000000..a318389
--- /dev/null
+++ b/test/manual/noverlay/itree-tests.c
@@ -0,0 +1,1381 @@
+#include <config.h>
+#include <check.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "emacs-compat.h"
+
+#define EMACS_LISP_H            /* lisp.h inclusion guard */
+#define ITREE_DEBUG 1
+#define ITREE_TESTING
+#include "itree.c"
+
+/* Basic tests of the interval_tree data-structure. */
+
+/* 
+===================================================================================+
+ * | Insert
+ * 
+===================================================================================+
 */
+
+/* The graphs below display the trees after each insertion (as they
+   should be).  See the source code for the different cases
+   applied. */
+
+#define N_50 (n[0])
+#define N_30 (n[1])
+#define N_20 (n[2])
+#define N_10 (n[3])
+#define N_15 (n[4])
+#define N_05 (n[5])
+
+#define DEF_TEST_SETUP()                        \
+  struct interval_tree tree;                    \
+  struct interval_node n[6];                    \
+  interval_tree_init (&tree);                   \
+  const int values[] = {50, 30, 20, 10, 15, 5}; \
+  for (int i = 0; i < 6; ++i)                   \
+    {                                           \
+      n[i].begin = values[i];                   \
+      n[i].end = values[i];                     \
+    }
+
+START_TEST (test_insert_1)
+{
+  /*
+   *                 [50]
+   */
+
+  DEF_TEST_SETUP ();
+  interval_tree_insert (&tree, &N_50);
+  ck_assert (N_50.color == ITREE_BLACK);
+  ck_assert (&N_50 == tree.root);
+}
+END_TEST
+
+START_TEST (test_insert_2)
+{
+  /*
+   *                 [50]
+   *                /
+   *              (30)
+   */
+
+  DEF_TEST_SETUP ();
+  interval_tree_insert (&tree, &N_50);
+  interval_tree_insert (&tree, &N_30);
+  ck_assert (N_50.color == ITREE_BLACK);
+  ck_assert (N_30.color == ITREE_RED);
+  ck_assert (&N_50 == tree.root);
+  ck_assert (N_30.parent == &N_50);
+  ck_assert (N_50.left == &N_30);
+  ck_assert (N_50.right == &tree.nil);
+  ck_assert (N_30.left == &tree.nil);
+  ck_assert (N_30.right == &tree.nil);
+}
+END_TEST
+
+START_TEST (test_insert_3)
+{
+  /* case 3.a
+   *                [30]
+   *               /    \
+   *             (20)   (50)
+   */
+
+  DEF_TEST_SETUP ();
+  interval_tree_insert (&tree, &N_50);
+  interval_tree_insert (&tree, &N_30);
+  interval_tree_insert (&tree, &N_20);
+  ck_assert (N_50.color == ITREE_RED);
+  ck_assert (N_30.color == ITREE_BLACK);
+  ck_assert (N_20.color == ITREE_RED);
+  ck_assert (&N_30 == tree.root);
+  ck_assert (N_50.parent == &N_30);
+  ck_assert (N_30.right == &N_50);
+  ck_assert (N_30.left == &N_20);
+  ck_assert (N_20.left == &tree.nil);
+  ck_assert (N_20.right == &tree.nil);
+  ck_assert (N_20.parent == &N_30);
+}
+END_TEST
+
+START_TEST (test_insert_4)
+{
+  /* 1.a
+   *                [30]
+   *               /    \
+   *             [20]   [50]
+   *             /
+   *           (10)
+   */
+
+  DEF_TEST_SETUP ();
+  interval_tree_insert (&tree, &N_50);
+  interval_tree_insert (&tree, &N_30);
+  interval_tree_insert (&tree, &N_20);
+  interval_tree_insert (&tree, &N_10);
+  ck_assert (N_50.color == ITREE_BLACK);
+  ck_assert (N_30.color == ITREE_BLACK);
+  ck_assert (N_20.color == ITREE_BLACK);
+  ck_assert (N_10.color == ITREE_RED);
+  ck_assert (&N_30 == tree.root);
+  ck_assert (N_50.parent == &N_30);
+  ck_assert (N_30.right == &N_50);
+  ck_assert (N_30.left == &N_20);
+  ck_assert (N_20.left == &N_10);
+  ck_assert (N_20.right == &tree.nil);
+  ck_assert (N_20.parent == &N_30);
+  ck_assert (N_10.parent == &N_20);
+  ck_assert (N_20.left == &N_10);
+  ck_assert (N_10.right == &tree.nil);
+}
+END_TEST
+
+START_TEST (test_insert_5)
+{
+  /* 2.a
+   *                [30]
+   *               /    \
+   *             [15]   [50]
+   *             /  \
+   *           (10) (20)
+   */
+
+  DEF_TEST_SETUP ();
+  interval_tree_insert (&tree, &N_50);
+  interval_tree_insert (&tree, &N_30);
+  interval_tree_insert (&tree, &N_20);
+  interval_tree_insert (&tree, &N_10);
+  interval_tree_insert (&tree, &N_15);
+  ck_assert (N_50.color == ITREE_BLACK);
+  ck_assert (N_30.color == ITREE_BLACK);
+  ck_assert (N_20.color == ITREE_RED);
+  ck_assert (N_10.color == ITREE_RED);
+  ck_assert (N_15.color == ITREE_BLACK);
+  ck_assert (&N_30 == tree.root);
+  ck_assert (N_50.parent == &N_30);
+  ck_assert (N_30.right == &N_50);
+  ck_assert (N_30.left == &N_15);
+  ck_assert (N_20.left == &tree.nil);
+  ck_assert (N_20.right == &tree.nil);
+  ck_assert (N_20.parent == &N_15);
+  ck_assert (N_10.parent == &N_15);
+  ck_assert (N_20.left == &tree.nil);
+  ck_assert (N_10.right == &tree.nil);
+  ck_assert (N_15.right == &N_20);
+  ck_assert (N_15.left == &N_10);
+  ck_assert (N_15.parent == &N_30);
+
+}
+END_TEST
+
+START_TEST (test_insert_6)
+{
+  /* 1.a
+   *                [30]
+   *               /    \
+   *             (15)   [50]
+   *             /  \
+   *           [10] [20]
+   *           /
+   *         (5)
+   */
+
+  DEF_TEST_SETUP ();
+  interval_tree_insert (&tree, &N_50);
+  interval_tree_insert (&tree, &N_30);
+  interval_tree_insert (&tree, &N_20);
+  interval_tree_insert (&tree, &N_10);
+  interval_tree_insert (&tree, &N_15);
+  interval_tree_insert (&tree, &N_05);
+  ck_assert (N_50.color == ITREE_BLACK);
+  ck_assert (N_30.color == ITREE_BLACK);
+  ck_assert (N_20.color == ITREE_BLACK);
+  ck_assert (N_10.color == ITREE_BLACK);
+  ck_assert (N_15.color == ITREE_RED);
+  ck_assert (N_05.color == ITREE_RED);
+  ck_assert (&N_30 == tree.root);
+  ck_assert (N_50.parent == &N_30);
+  ck_assert (N_30.right == &N_50);
+  ck_assert (N_30.left == &N_15);
+  ck_assert (N_20.left == &tree.nil);
+  ck_assert (N_20.right == &tree.nil);
+  ck_assert (N_20.parent == &N_15);
+  ck_assert (N_10.parent == &N_15);
+  ck_assert (N_20.left == &tree.nil);
+  ck_assert (N_10.right == &tree.nil);
+  ck_assert (N_15.right == &N_20);
+  ck_assert (N_15.left == &N_10);
+  ck_assert (N_15.parent == &N_30);
+  ck_assert (N_05.parent == &N_10);
+  ck_assert (N_10.left == &N_05);
+  ck_assert (N_05.right == &tree.nil);
+}
+END_TEST
+
+#undef N_50
+#undef N_30
+#undef N_20
+#undef N_10
+#undef N_15
+#undef N_05
+#undef DEF_TEST_SETUP
+
+
+
+/* These are the mirror cases to the above ones.  */
+
+#define N_50 (n[0])
+#define N_70 (n[1])
+#define N_80 (n[2])
+#define N_90 (n[3])
+#define N_85 (n[4])
+#define N_95 (n[5])
+
+#define DEF_TEST_SETUP()                                \
+  struct interval_tree tree;                            \
+  struct interval_node n[6];                            \
+  interval_tree_init (&tree);                           \
+  const int values[] = {50, 70, 80, 90, 85, 95};        \
+  for (int i = 0; i < 6; ++i)                           \
+    {                                                   \
+      n[i].begin = values[i];                           \
+      n[i].end = values[i];                             \
+    }
+
+START_TEST (test_insert_7)
+{
+  /*
+   *                 [50]
+   */
+
+  DEF_TEST_SETUP ();
+  interval_tree_insert (&tree, &N_50);
+  ck_assert (N_50.color == ITREE_BLACK);
+  ck_assert (&N_50 == tree.root);
+}
+END_TEST
+
+START_TEST (test_insert_8)
+{
+  /*
+   *                 [50]
+   *                    \
+   *                   (70)
+   */
+
+  DEF_TEST_SETUP ();
+  interval_tree_insert (&tree, &N_50);
+  interval_tree_insert (&tree, &N_70);
+  ck_assert (N_50.color == ITREE_BLACK);
+  ck_assert (N_70.color == ITREE_RED);
+  ck_assert (&N_50 == tree.root);
+  ck_assert (N_70.parent == &N_50);
+  ck_assert (N_50.right == &N_70);
+  ck_assert (N_50.left == &tree.nil);
+  ck_assert (N_70.right == &tree.nil);
+  ck_assert (N_70.left == &tree.nil);
+}
+END_TEST
+
+START_TEST (test_insert_9)
+{
+  /* 3.a
+   *                [70]
+   *               /    \
+   *             (50)   (80)
+   */
+
+  DEF_TEST_SETUP ();
+  interval_tree_insert (&tree, &N_50);
+  interval_tree_insert (&tree, &N_70);
+  interval_tree_insert (&tree, &N_80);
+  ck_assert (N_50.color == ITREE_RED);
+  ck_assert (N_70.color == ITREE_BLACK);
+  ck_assert (N_80.color == ITREE_RED);
+  ck_assert (&N_70 == tree.root);
+  ck_assert (N_50.parent == &N_70);
+  ck_assert (N_70.right == &N_80);
+  ck_assert (N_70.left == &N_50);
+  ck_assert (N_80.right == &tree.nil);
+  ck_assert (N_80.left == &tree.nil);
+  ck_assert (N_80.parent == &N_70);
+}
+END_TEST
+
+START_TEST (test_insert_10)
+{
+  /* 1.b
+   *                [70]
+   *               /    \
+   *             [50]   [80]
+   *                      \
+   *                      (90)
+   */
+
+  DEF_TEST_SETUP ();
+  interval_tree_insert (&tree, &N_50);
+  interval_tree_insert (&tree, &N_70);
+  interval_tree_insert (&tree, &N_80);
+  interval_tree_insert (&tree, &N_90);
+  ck_assert (N_50.color == ITREE_BLACK);
+  ck_assert (N_70.color == ITREE_BLACK);
+  ck_assert (N_80.color == ITREE_BLACK);
+  ck_assert (N_90.color == ITREE_RED);
+  ck_assert (&N_70 == tree.root);
+  ck_assert (N_50.parent == &N_70);
+  ck_assert (N_70.right == &N_80);
+  ck_assert (N_70.left == &N_50);
+  ck_assert (N_80.right == &N_90);
+  ck_assert (N_80.left == &tree.nil);
+  ck_assert (N_80.parent == &N_70);
+  ck_assert (N_90.parent == &N_80);
+  ck_assert (N_80.right == &N_90);
+  ck_assert (N_90.left == &tree.nil);
+}
+END_TEST
+
+START_TEST (test_insert_11)
+{
+  /* 2.b
+   *                [70]
+   *               /    \
+   *             [50]   [85]
+   *                    /  \
+   *                  (80) (90)
+   */
+
+  DEF_TEST_SETUP ();
+  interval_tree_insert (&tree, &N_50);
+  interval_tree_insert (&tree, &N_70);
+  interval_tree_insert (&tree, &N_80);
+  interval_tree_insert (&tree, &N_90);
+  interval_tree_insert (&tree, &N_85);
+  ck_assert (N_50.color == ITREE_BLACK);
+  ck_assert (N_70.color == ITREE_BLACK);
+  ck_assert (N_80.color == ITREE_RED);
+  ck_assert (N_90.color == ITREE_RED);
+  ck_assert (N_85.color == ITREE_BLACK);
+  ck_assert (&N_70 == tree.root);
+  ck_assert (N_50.parent == &N_70);
+  ck_assert (N_70.right == &N_85);
+  ck_assert (N_70.left == &N_50);
+  ck_assert (N_80.right == &tree.nil);
+  ck_assert (N_80.left == &tree.nil);
+  ck_assert (N_80.parent == &N_85);
+  ck_assert (N_90.parent == &N_85);
+  ck_assert (N_80.right == &tree.nil);
+  ck_assert (N_90.left == &tree.nil);
+  ck_assert (N_85.right == &N_90);
+  ck_assert (N_85.left == &N_80);
+  ck_assert (N_85.parent == &N_70);
+
+}
+END_TEST
+
+START_TEST (test_insert_12)
+{
+  /* 1.b
+   *                [70]
+   *               /    \
+   *             [50]   (85)
+   *                    /  \
+   *                  [80] [90]
+   *                         \
+   *                        (95)
+   */
+
+  DEF_TEST_SETUP ();
+  interval_tree_insert (&tree, &N_50);
+  interval_tree_insert (&tree, &N_70);
+  interval_tree_insert (&tree, &N_80);
+  interval_tree_insert (&tree, &N_90);
+  interval_tree_insert (&tree, &N_85);
+  interval_tree_insert (&tree, &N_95);
+  ck_assert (N_50.color == ITREE_BLACK);
+  ck_assert (N_70.color == ITREE_BLACK);
+  ck_assert (N_80.color == ITREE_BLACK);
+  ck_assert (N_90.color == ITREE_BLACK);
+  ck_assert (N_85.color == ITREE_RED);
+  ck_assert (N_95.color == ITREE_RED);
+  ck_assert (&N_70 == tree.root);
+  ck_assert (N_50.parent == &N_70);
+  ck_assert (N_70.right == &N_85);
+  ck_assert (N_70.left == &N_50);
+  ck_assert (N_80.right == &tree.nil);
+  ck_assert (N_80.left == &tree.nil);
+  ck_assert (N_80.parent == &N_85);
+  ck_assert (N_90.parent == &N_85);
+  ck_assert (N_80.right == &tree.nil);
+  ck_assert (N_90.left == &tree.nil);
+  ck_assert (N_85.right == &N_90);
+  ck_assert (N_85.left == &N_80);
+  ck_assert (N_85.parent == &N_70);
+  ck_assert (N_95.parent == &N_90);
+  ck_assert (N_90.right == &N_95);
+  ck_assert (N_95.left == &tree.nil);
+}
+END_TEST
+
+#undef N_50
+#undef N_70
+#undef N_80
+#undef N_90
+#undef N_85
+#undef N_95
+#undef DEF_TEST_SETUP
+
+struct interval_tree*
+test_get_tree4 (struct interval_node **n)
+{
+  static struct interval_tree tree;
+  static struct interval_node nodes[4];
+  memset (&tree, 0, sizeof (struct interval_tree));
+  memset (&nodes, 0, 4 * sizeof (struct interval_node));
+  interval_tree_init (&tree);
+  for (int i = 0; i < 4; ++i)
+    {
+      nodes[i].begin = 10 * (i + 1);
+      nodes[i].end = nodes[i].begin;
+      interval_tree_insert (&tree, &nodes[i]);
+    }
+  *n = nodes;
+  return &tree;
+}
+
+static void
+shuffle (int *index, int n)
+{
+  for (int i = n - 1; i >= 0; --i)
+    {
+      int j = random () % (i + 1);
+      int h = index[j];
+      index[j] = index[i];
+      index[i] = h;
+    }
+}
+
+#define N_10 (nodes[0])
+#define N_20 (nodes[1])
+#define N_30 (nodes[2])
+#define N_40 (nodes[3])
+
+START_TEST (test_insert_13)
+{
+  struct interval_node *nodes = NULL;
+  struct interval_tree *tree = test_get_tree4 (&nodes);
+
+
+  ck_assert (tree->root == &N_20);
+  ck_assert (N_20.left == &N_10);
+  ck_assert (N_20.right == &N_30);
+  ck_assert (N_30.right == &N_40);
+  ck_assert (N_10.color == ITREE_BLACK);
+  ck_assert (N_20.color == ITREE_BLACK);
+  ck_assert (N_30.color == ITREE_BLACK);
+  ck_assert (N_40.color == ITREE_RED);
+}
+END_TEST
+
+START_TEST (test_insert_14)
+{
+  struct interval_tree tree;
+  struct interval_node nodes[3];
+
+  nodes[0].begin = nodes[1].begin = nodes[2].begin = 10;
+  nodes[0].end = nodes[1].end = nodes[2].end = 10;
+
+  for (int i = 0; i < 3; ++i)
+    interval_tree_insert (&tree, &nodes[i]);
+  for (int i = 0; i < 3; ++i)
+    ck_assert (interval_tree_contains (&tree, &nodes[i]));
+}
+END_TEST
+
+
+
+
+/* 
+===================================================================================+
+ * | Remove
+ * 
+===================================================================================+
 */
+
+#define A (nodes[0])
+#define B (nodes[1])
+#define C (nodes[2])
+#define D (nodes[3])
+#define E (nodes[4])
+
+/* Creating proper test trees for the formal tests via insertions is
+   way to tedious, so we just fake it and only test the
+   fix-routine. */
+#define DEF_TEST_SETUP()                                        \
+    struct interval_tree tree;                                  \
+    struct interval_node nodes[5];                              \
+    interval_tree_init (&tree);                                 \
+    tree.root = &B;                                             \
+    A.parent = &B; B.parent = &tree.nil; C.parent = &D;         \
+    D.parent = &B; E.parent = &D;                               \
+    A.left = A.right = C.left = C.right = &tree.nil;            \
+    E.left = E.right = &tree.nil;                               \
+    B.left = &A; B.right = &D; D.left = &C; D.right = &E        \
+
+/* 1.a -> 2.a
+ *                [B]
+ *               /    \
+ *             [A]    (D)
+ *                    /  \
+ *                 [C]   [E]
+ */
+
+
+START_TEST (test_remove_1)
+{
+  DEF_TEST_SETUP ();
+  B.color = A.color = C.color = E.color = ITREE_BLACK;
+  D.color = ITREE_RED;
+  interval_tree_remove_fix (&tree, &A);
+
+  ck_assert (A.color == ITREE_BLACK);
+  ck_assert (B.color == ITREE_BLACK);
+  ck_assert (C.color == ITREE_RED);
+  ck_assert (D.color == ITREE_BLACK);
+  ck_assert (E.color == ITREE_BLACK);
+  ck_assert (A.parent == &B);
+  ck_assert (B.left == &A);
+  ck_assert (B.right == &C);
+  ck_assert (C.parent == &B);
+  ck_assert (E.parent == &D);
+  ck_assert (D.right == &E);
+  ck_assert (D.left == &B);
+  ck_assert (tree.root == &D);
+}
+END_TEST
+
+/* 2.a */
+START_TEST (test_remove_2)
+{
+  DEF_TEST_SETUP ();
+  B.color = D.color = A.color = C.color = E.color = ITREE_BLACK;
+  interval_tree_remove_fix (&tree, &A);
+
+  ck_assert (A.color == ITREE_BLACK);
+  ck_assert (B.color == ITREE_BLACK);
+  ck_assert (C.color == ITREE_BLACK);
+  ck_assert (D.color == ITREE_RED);
+  ck_assert (E.color == ITREE_BLACK);
+  ck_assert (A.parent == &B);
+  ck_assert (B.left == &A);
+  ck_assert (B.right == &D);
+  ck_assert (C.parent == &D);
+  ck_assert (E.parent == &D);
+  ck_assert (tree.root == &B);
+}
+END_TEST
+
+/* 3.a -> 4.a*/
+START_TEST (test_remove_3)
+{
+  DEF_TEST_SETUP ();
+  D.color = A.color = E.color = ITREE_BLACK;
+  B.color = C.color = ITREE_RED;
+  interval_tree_remove_fix (&tree, &A);
+
+  ck_assert (A.color == ITREE_BLACK);
+  ck_assert (B.color == ITREE_BLACK);
+  ck_assert (C.color == ITREE_BLACK);
+  ck_assert (D.color == ITREE_BLACK);
+  ck_assert (E.color == ITREE_BLACK);
+  ck_assert (A.parent == &B);
+  ck_assert (B.left == &A);
+  ck_assert (B.right == &tree.nil);
+  ck_assert (&C == tree.root);
+  ck_assert (C.left == &B);
+  ck_assert (C.right == &D);
+  ck_assert (E.parent == &D);
+  ck_assert (D.left == &tree.nil);
+
+}
+END_TEST
+
+/* 4.a */
+START_TEST (test_remove_4)
+{
+  DEF_TEST_SETUP ();
+  B.color = C.color = E.color = ITREE_RED;
+  A.color = D.color = ITREE_BLACK;
+  interval_tree_remove_fix (&tree, &A);
+
+  ck_assert (A.color == ITREE_BLACK);
+  ck_assert (B.color == ITREE_BLACK);
+  ck_assert (C.color == ITREE_RED);
+  ck_assert (D.color == ITREE_BLACK);
+  ck_assert (E.color == ITREE_BLACK);
+  ck_assert (A.parent == &B);
+  ck_assert (B.left == &A);
+  ck_assert (B.right == &C);
+  ck_assert (C.parent == &B);
+  ck_assert (E.parent == &D);
+  ck_assert (tree.root == &D);
+}
+END_TEST
+
+
+#undef A
+#undef B
+#undef C
+#undef D
+#undef E
+#undef DEF_TEST_SETUP
+
+
+
+/* These are the mirrored cases. */
+
+#define A (nodes[0])
+#define B (nodes[1])
+#define C (nodes[2])
+#define D (nodes[3])
+#define E (nodes[4])
+
+#define DEF_TEST_SETUP()                                        \
+    struct interval_tree tree;                                  \
+    struct interval_node nodes[5];                              \
+    interval_tree_init (&tree);                                 \
+    tree.root = &B;                                             \
+    A.parent = &B; B.parent = &tree.nil; C.parent = &D;         \
+    D.parent = &B; E.parent = &D;                               \
+    A.right = A.left = C.right = C.left = &tree.nil;            \
+    E.right = E.left = &tree.nil;                               \
+    B.right = &A; B.left = &D; D.right = &C; D.left = &E        \
+
+/* 1.b -> 2.b
+ *                [B]
+ *               /    \
+ *             [A]    (D)
+ *                    /  \
+ *                 [C]   [E]
+ */
+
+
+START_TEST (test_remove_5)
+{
+  DEF_TEST_SETUP ();
+  B.color = A.color = C.color = E.color = ITREE_BLACK;
+  D.color = ITREE_RED;
+  interval_tree_remove_fix (&tree, &A);
+
+  ck_assert (A.color == ITREE_BLACK);
+  ck_assert (B.color == ITREE_BLACK);
+  ck_assert (C.color == ITREE_RED);
+  ck_assert (D.color == ITREE_BLACK);
+  ck_assert (E.color == ITREE_BLACK);
+  ck_assert (A.parent == &B);
+  ck_assert (B.right == &A);
+  ck_assert (B.left == &C);
+  ck_assert (C.parent == &B);
+  ck_assert (E.parent == &D);
+  ck_assert (D.left == &E);
+  ck_assert (D.right == &B);
+  ck_assert (tree.root == &D);
+}
+END_TEST
+
+/* 2.b */
+START_TEST (test_remove_6)
+{
+  DEF_TEST_SETUP ();
+  B.color = D.color = A.color = C.color = E.color = ITREE_BLACK;
+  interval_tree_remove_fix (&tree, &A);
+
+  ck_assert (A.color == ITREE_BLACK);
+  ck_assert (B.color == ITREE_BLACK);
+  ck_assert (C.color == ITREE_BLACK);
+  ck_assert (D.color == ITREE_RED);
+  ck_assert (E.color == ITREE_BLACK);
+  ck_assert (A.parent == &B);
+  ck_assert (B.right == &A);
+  ck_assert (B.left == &D);
+  ck_assert (C.parent == &D);
+  ck_assert (E.parent == &D);
+  ck_assert (tree.root == &B);
+}
+END_TEST
+
+/* 3.b -> 4.b*/
+START_TEST (test_remove_7)
+{
+  DEF_TEST_SETUP ();
+  D.color = A.color = E.color = ITREE_BLACK;
+  B.color = C.color = ITREE_RED;
+  interval_tree_remove_fix (&tree, &A);
+
+  ck_assert (A.color == ITREE_BLACK);
+  ck_assert (B.color == ITREE_BLACK);
+  ck_assert (C.color == ITREE_BLACK);
+  ck_assert (D.color == ITREE_BLACK);
+  ck_assert (E.color == ITREE_BLACK);
+  ck_assert (A.parent == &B);
+  ck_assert (B.right == &A);
+  ck_assert (B.left == &tree.nil);
+  ck_assert (&C == tree.root);
+  ck_assert (C.right == &B);
+  ck_assert (C.left == &D);
+  ck_assert (E.parent == &D);
+  ck_assert (D.right == &tree.nil);
+
+}
+END_TEST
+
+/* 4.b */
+START_TEST (test_remove_8)
+{
+  DEF_TEST_SETUP ();
+  B.color = C.color = E.color = ITREE_RED;
+  A.color = D.color = ITREE_BLACK;
+  interval_tree_remove_fix (&tree, &A);
+
+  ck_assert (A.color == ITREE_BLACK);
+  ck_assert (B.color == ITREE_BLACK);
+  ck_assert (C.color == ITREE_RED);
+  ck_assert (D.color == ITREE_BLACK);
+  ck_assert (E.color == ITREE_BLACK);
+  ck_assert (A.parent == &B);
+  ck_assert (B.right == &A);
+  ck_assert (B.left == &C);
+  ck_assert (C.parent == &B);
+  ck_assert (E.parent == &D);
+  ck_assert (tree.root == &D);
+}
+END_TEST
+
+
+#undef A
+#undef B
+#undef C
+#undef D
+#undef E
+#undef DEF_TEST_SETUP
+
+
+START_TEST (test_remove_9)
+{
+  struct interval_node *nodes = NULL;
+  struct interval_tree *tree = test_get_tree4 (&nodes);
+
+  ck_assert (tree->root == &N_20);
+  ck_assert (N_20.left == &N_10);
+  ck_assert (N_20.right == &N_30);
+  ck_assert (N_30.right == &N_40);
+  ck_assert (N_20.color == ITREE_BLACK);
+  ck_assert (N_10.color == ITREE_BLACK);
+  ck_assert (N_30.color == ITREE_BLACK);
+  ck_assert (N_40.color == ITREE_RED);
+
+  interval_tree_remove (tree, &N_10);
+
+  ck_assert (tree->root == &N_30);
+  ck_assert (N_30.parent == &tree->nil);
+  ck_assert (N_30.left == &N_20);
+  ck_assert (N_30.right == &N_40);
+  ck_assert (N_20.color == ITREE_BLACK);
+  ck_assert (N_30.color == ITREE_BLACK);
+  ck_assert (N_40.color == ITREE_BLACK);
+}
+END_TEST
+
+#define N 3
+
+START_TEST (test_remove_10)
+{
+  struct interval_tree tree;
+  struct interval_node nodes[N];
+  int index[N];
+
+  srand (42);
+  interval_tree_init (&tree);
+  for (int i = 0; i < N; ++i)
+    {
+      nodes[i].begin = (i + 1) * 10;
+      nodes[i].end = nodes[i].begin + 1;
+      index[i] = i;
+    }
+  shuffle (index, N);
+  for (int i = 0; i < N; ++i)
+    interval_tree_insert (&tree, &nodes[index[i]]);
+
+  shuffle (index, N);
+  for (int i = 0; i < N; ++i)
+    {
+      ck_assert (interval_tree_contains (&tree, &nodes[index[i]]));
+      interval_tree_remove (&tree, &nodes[index[i]]);
+    }
+  ck_assert (tree.root == &tree.nil);
+  ck_assert (tree.size == 0);
+}
+END_TEST
+
+
+/* 
+===================================================================================+
+ * | Generator
+ * 
+===================================================================================+
 */
+
+START_TEST (test_generator_1)
+{
+  struct interval_tree tree;
+  struct interval_node node, *n;
+  struct interval_generator *g;
+  interval_tree_init (&tree);
+  node.begin = 10;
+  node.end = 20;
+  interval_tree_insert (&tree, &node);
+  g = interval_generator_create (&tree);
+  interval_generator_reset (g, 0, 30, ITREE_ASCENDING);
+  n = interval_generator_next (g);
+  ck_assert (n == &node);
+  ck_assert (n->begin == 10 && n->end == 20);
+  ck_assert (interval_generator_next (g) == NULL);
+  ck_assert (interval_generator_next (g) == NULL);
+  ck_assert (interval_generator_next (g) == NULL);
+  interval_generator_destroy (g);
+
+  g = interval_generator_create (&tree);
+  interval_generator_reset (g, 30, 50, ITREE_ASCENDING);
+  ck_assert (interval_generator_next (g) == NULL);
+  ck_assert (interval_generator_next (g) == NULL);
+  ck_assert (interval_generator_next (g) == NULL);
+  interval_generator_destroy (g);
+}
+END_TEST
+
+void
+test_check_generator (struct interval_tree *tree,
+                      ptrdiff_t begin, ptrdiff_t end,
+                      int n, ...)
+{
+  va_list ap;
+  struct interval_generator *g = interval_generator_create (tree);
+  interval_generator_reset (g, begin, end, ITREE_ASCENDING);
+
+  va_start (ap, n);
+  for (int i = 0; i < n; ++i)
+    {
+      ptrdiff_t begin = va_arg (ap, ptrdiff_t);
+      struct interval_node *node = interval_generator_next (g);
+      ck_assert (node);
+      ck_assert_int_eq (node->begin, begin);
+    }
+  va_end (ap);
+  ck_assert (! interval_generator_next (g));
+  ck_assert (! interval_generator_next (g));
+  interval_generator_destroy (g);
+}
+
+#define DEF_TEST_SETUP()                        \
+
+
+START_TEST (test_generator_2)
+{
+  struct interval_tree tree;
+  struct interval_node nodes[3];
+
+  interval_tree_init (&tree);
+
+  for (int i = 0; i < 3; ++i) {
+    nodes[i].begin = 10 * (i + 1);
+    nodes[i].end = 10 * (i + 2);
+    interval_tree_insert (&tree, &nodes[i]);
+  }
+
+  test_check_generator (&tree, 0, 50, 3,
+                        10, 20, 30);
+  test_check_generator (&tree, 0, 10, 0);
+  test_check_generator (&tree, 40, 50, 0);
+  test_check_generator (&tree, 15, 35, 3,
+                        10, 20, 30);
+  test_check_generator (&tree, -100, -50, 0);
+  test_check_generator (&tree, -100, -50, 0);
+  test_check_generator (&tree, 100, 50, 0);
+  test_check_generator (&tree, 100, 150, 0);
+  test_check_generator (&tree, 0, 0, 0);
+  test_check_generator (&tree, 40, 40, 0);
+  test_check_generator (&tree, 30, 30, 0);
+  test_check_generator (&tree, 35, 35, 1,
+                        30);
+}
+END_TEST
+
+
+struct interval_node*
+test_create_tree (struct interval_tree *tree, int n,
+                  bool doshuffle, ...)
+{
+  va_list ap;
+  struct interval_node *nodes = calloc (n, sizeof (struct interval_node));
+  int *index = calloc (n, sizeof (int));
+
+  interval_tree_init (tree);
+  va_start (ap, doshuffle);
+  for (int i = 0; i < n; ++i)
+    {
+      ptrdiff_t begin = va_arg (ap, ptrdiff_t);
+      ptrdiff_t end = va_arg (ap, ptrdiff_t);
+      nodes[i].begin = begin;
+      nodes[i].end = end;
+      index[i] = i;
+    }
+  va_end (ap);
+  srand (42);
+  if (doshuffle)
+    shuffle (index, n);
+  for (int i = 0; i < n; ++i)
+    interval_tree_insert (tree, &nodes[index[i]]);
+  free (index);
+
+  return nodes;
+}
+
+START_TEST (test_generator_3)
+{
+  struct interval_tree tree;
+  struct interval_node *nodes = NULL;
+
+  nodes = test_create_tree (&tree, 3, true,
+                            10, 10,
+                            10, 10,
+                            10, 10);
+  test_check_generator (&tree, 0, 10, 0);
+  test_check_generator (&tree, 10, 10, 3, 10, 10, 10);
+  test_check_generator (&tree, 10, 20, 3, 10, 10, 10);
+  free (nodes);
+}
+END_TEST
+
+#define FOREACH(n, g)                                   \
+  for ((n) = interval_generator_next (g); (n) != NULL;  \
+       (n) = interval_generator_next (g))
+
+START_TEST (test_generator_5)
+{
+  struct interval_tree tree;
+  struct interval_node *nodes;
+  struct interval_generator *g;
+  nodes = test_create_tree (&tree, 4, false,
+                            10, 30,
+                            20, 40,
+                            30, 50,
+                            40, 60);
+  g = interval_generator_create (&tree);
+  interval_generator_reset (g, 0, 100, ITREE_PRE_ORDER);
+  for (int i = 0; i < 4; ++i)
+    {
+      struct interval_node *n = interval_generator_next (g);
+      ck_assert (n);
+      switch (i)
+        {
+        case 0: ck_assert_int_eq (20, n->begin); break;
+        case 1: ck_assert_int_eq (10, n->begin); break;
+        case 2: ck_assert_int_eq (30, n->begin); break;
+        case 3: ck_assert_int_eq (40, n->begin); break;
+        }
+    }
+  interval_generator_destroy (g);
+  free (nodes);
+
+}
+END_TEST
+
+START_TEST (test_generator_6)
+{
+  struct interval_tree tree;
+  struct interval_node *nodes;
+  struct interval_generator *g;
+  nodes = test_create_tree (&tree, 4, true,
+                            10, 30,
+                            20, 40,
+                            30, 50,
+                            40, 60);
+  g = interval_generator_create (&tree);
+  interval_generator_reset (g, 0, 100, ITREE_ASCENDING);
+  for (int i = 0; i < 4; ++i)
+    {
+      struct interval_node *n = interval_generator_next (g);
+      ck_assert (n);
+      switch (i)
+        {
+        case 0: ck_assert_int_eq (10, n->begin); break;
+        case 1: ck_assert_int_eq (20, n->begin); break;
+        case 2: ck_assert_int_eq (30, n->begin); break;
+        case 3: ck_assert_int_eq (40, n->begin); break;
+        }
+    }
+  interval_generator_destroy (g);
+  free (nodes);
+
+}
+END_TEST
+
+START_TEST (test_generator_7)
+{
+  struct interval_tree tree;
+  struct interval_node *nodes;
+  struct interval_generator *g;
+  nodes = test_create_tree (&tree, 4, true,
+                            10, 30,
+                            20, 40,
+                            30, 50,
+                            40, 60);
+  g = interval_generator_create (&tree);
+  interval_generator_reset (g, 0, 100, ITREE_DESCENDING);
+  for (int i = 0; i < 4; ++i)
+    {
+      struct interval_node *n = interval_generator_next (g);
+      ck_assert (n);
+      switch (i)
+        {
+        case 0: ck_assert_int_eq (40, n->begin); break;
+        case 1: ck_assert_int_eq (30, n->begin); break;
+        case 2: ck_assert_int_eq (20, n->begin); break;
+        case 3: ck_assert_int_eq (10, n->begin); break;
+        }
+    }
+  interval_generator_destroy (g);
+  free (nodes);
+
+}
+END_TEST
+
+START_TEST (test_generator_8)
+{
+  struct interval_tree tree;
+  struct interval_node *nodes, *n;
+  struct interval_generator *g;
+  nodes = test_create_tree (&tree, 2, false,
+                            20, 30,
+                            40, 50);
+  g = interval_generator_create (&tree);
+  interval_generator_reset (g, 1, 60, ITREE_DESCENDING);
+  n = interval_generator_next (g);
+  ck_assert_int_eq (n->begin, 40);
+  interval_generator_narrow (g, 50, 60);
+  n = interval_generator_next (g);
+  ck_assert (n == NULL);
+  free (nodes);
+}
+END_TEST
+
+
+START_TEST (test_generator_9)
+{
+  struct interval_tree tree;
+  struct interval_node *nodes, *n;
+  struct interval_generator *g;
+  nodes = test_create_tree (&tree, 2, false,
+                            25, 25,
+                            20, 30);
+  g = interval_generator_create (&tree);
+  interval_generator_reset (g, 1, 30, ITREE_DESCENDING);
+  n = interval_generator_next (g);
+  ck_assert_int_eq (n->begin, 25);
+  interval_generator_narrow (g, 25, 35);
+  n = interval_generator_next (g);
+  ck_assert_int_eq (n->begin, 20);
+  free (nodes);
+}
+END_TEST
+
+
+/* 
+===================================================================================+
+ * | Insert Gap
+ * 
+===================================================================================+
 */
+
+static struct interval_tree gap_tree;
+static struct interval_node gap_node;
+
+#define N_BEG (interval_tree_validate (&gap_tree, &gap_node)->begin)
+#define N_END (interval_tree_validate (&gap_tree, &gap_node)->end)
+
+static void
+test_setup_gap_node (ptrdiff_t begin, ptrdiff_t end,
+                     bool front_advance, bool rear_advance)
+{
+  interval_tree_init (&gap_tree);
+  gap_node.begin = begin;
+  gap_node.end = end;
+  gap_node.front_advance = front_advance;
+  gap_node.rear_advance = rear_advance;
+  interval_tree_insert (&gap_tree, &gap_node);
+}
+
+static void
+test_setup_gap_node_noadvance (ptrdiff_t begin, ptrdiff_t end)
+{
+  test_setup_gap_node (begin, end, false, false);
+}
+
+START_TEST (test_gap_insert_1)
+{
+  test_setup_gap_node (100, 200, false, false);
+  interval_tree_insert_gap (&gap_tree, 100 + 10, 20);
+  ck_assert_int_eq (N_BEG, 100);
+  ck_assert_int_eq (N_END, 200 + 20);
+}
+END_TEST
+
+START_TEST (test_gap_insert_2)
+{
+  test_setup_gap_node (100, 200, false, false);
+  interval_tree_insert_gap (&gap_tree, 300, 10);
+  ck_assert_int_eq (N_BEG, 100);
+  ck_assert_int_eq (N_END, 200);
+}
+END_TEST
+
+START_TEST (test_gap_insert_3)
+{
+  test_setup_gap_node (100, 200, false, false);
+  interval_tree_insert_gap (&gap_tree, 0, 15);
+  ck_assert_int_eq (N_BEG, 100 + 15);
+  ck_assert_int_eq (N_END, 200 + 15);
+}
+END_TEST
+
+START_TEST (test_gap_insert_4)
+{
+  test_setup_gap_node (100, 200, true, false);
+  interval_tree_insert_gap (&gap_tree, 100, 20);
+  ck_assert_int_eq (N_BEG, 100 + 20);
+  ck_assert_int_eq (N_END, 200 + 20);
+
+}
+END_TEST
+
+START_TEST (test_gap_insert_5)
+{
+  test_setup_gap_node (100, 200, false, false);
+  interval_tree_insert_gap (&gap_tree, 100, 20);
+  ck_assert_int_eq (N_BEG, 100);
+  ck_assert_int_eq (N_END, 200 + 20);
+
+}
+END_TEST
+
+START_TEST (test_gap_insert_6)
+{
+  test_setup_gap_node (100, 200, false, true);
+  interval_tree_insert_gap (&gap_tree, 200, 20);
+  ck_assert_int_eq (N_BEG, 100);
+  ck_assert_int_eq (N_END, 200 + 20);
+
+}
+END_TEST
+
+START_TEST (test_gap_insert_7)
+{
+  test_setup_gap_node (100, 200, false, false);
+  interval_tree_insert_gap (&gap_tree, 200, 20);
+  ck_assert_int_eq (N_BEG, 100);
+  ck_assert_int_eq (N_END, 200);
+
+}
+END_TEST
+
+START_TEST (test_gap_insert_8)
+{
+  test_setup_gap_node (100, 100, true, true);
+  interval_tree_insert_gap (&gap_tree, 100, 20);
+  ck_assert_int_eq (N_BEG, 100 + 20);
+  ck_assert_int_eq (N_END, 100 + 20);
+
+}
+END_TEST
+
+START_TEST (test_gap_insert_9)
+{
+  test_setup_gap_node (100, 100, false, true);
+  interval_tree_insert_gap (&gap_tree, 100, 20);
+  ck_assert_int_eq (N_BEG, 100);
+  ck_assert_int_eq (N_END, 100 + 20);
+
+}
+END_TEST
+
+START_TEST (test_gap_insert_10)
+{
+  test_setup_gap_node (100, 100, true, false);
+  interval_tree_insert_gap (&gap_tree, 100, 20);
+  ck_assert_int_eq (N_BEG, 100);
+  ck_assert_int_eq (N_END, 100);
+
+}
+END_TEST
+
+START_TEST (test_gap_insert_11)
+{
+  test_setup_gap_node (100, 100, false, false);
+  interval_tree_insert_gap (&gap_tree, 100, 20);
+  ck_assert_int_eq (N_BEG, 100);
+  ck_assert_int_eq (N_END, 100);
+
+}
+END_TEST
+
+
+/* 
+===================================================================================+
+ * | Delete Gap
+ * 
+===================================================================================+
 */
+
+START_TEST (test_gap_delete_1)
+{
+  test_setup_gap_node_noadvance (100, 200);
+  interval_tree_delete_gap (&gap_tree, 100 + 10, 20);
+  ck_assert_int_eq (N_BEG, 100);
+  ck_assert_int_eq (N_END, 200 - 20);
+
+}
+END_TEST
+
+START_TEST (test_gap_delete_2)
+{
+  test_setup_gap_node_noadvance (100, 200);
+  interval_tree_delete_gap (&gap_tree, 200 + 10, 20);
+  ck_assert_int_eq (N_BEG, 100);
+  ck_assert_int_eq (N_END, 200);
+
+}
+END_TEST
+
+START_TEST (test_gap_delete_3)
+{
+  test_setup_gap_node_noadvance (100, 200);
+  interval_tree_delete_gap (&gap_tree, 200, 20);
+  ck_assert_int_eq (N_BEG, 100);
+  ck_assert_int_eq (N_END, 200);
+
+}
+END_TEST
+
+START_TEST (test_gap_delete_4)
+{
+  test_setup_gap_node_noadvance (100, 200);
+  interval_tree_delete_gap (&gap_tree, 100 - 20, 20);
+  ck_assert_int_eq (N_BEG, 100 - 20);
+  ck_assert_int_eq (N_END, 200 - 20);
+
+}
+END_TEST
+
+START_TEST (test_gap_delete_5)
+{
+  test_setup_gap_node_noadvance (100, 200);
+  interval_tree_delete_gap (&gap_tree, 70, 20);
+  ck_assert_int_eq (N_BEG, 100 - 20);
+  ck_assert_int_eq (N_END, 200 - 20);
+
+}
+END_TEST
+
+START_TEST (test_gap_delete_6)
+{
+  test_setup_gap_node_noadvance (100, 200);
+  interval_tree_delete_gap (&gap_tree, 80, 100);
+  ck_assert_int_eq (N_BEG, 80);
+  ck_assert_int_eq (N_END, 100);
+}
+END_TEST
+
+START_TEST (test_gap_delete_7)
+{
+  test_setup_gap_node_noadvance (100, 200);
+  interval_tree_delete_gap (&gap_tree, 120, 100);
+  ck_assert_int_eq (N_BEG, 100);
+  ck_assert_int_eq (N_END, 120);
+}
+END_TEST
+
+START_TEST (test_gap_delete_8)
+{
+  test_setup_gap_node_noadvance (100, 200);
+  interval_tree_delete_gap (&gap_tree, 100 - 20, 200 + 20);
+  ck_assert_int_eq (N_BEG, 100 - 20);
+  ck_assert_int_eq (N_END, 100 - 20);
+
+}
+END_TEST
+
+
+
+Suite * basic_suite ()
+{
+  Suite *s = suite_create ("basic_suite");
+  TCase *tc = tcase_create ("basic_test");
+
+  tcase_add_test (tc, test_insert_1);
+  tcase_add_test (tc, test_insert_2);
+  tcase_add_test (tc, test_insert_3);
+  tcase_add_test (tc, test_insert_4);
+  tcase_add_test (tc, test_insert_5);
+  tcase_add_test (tc, test_insert_6);
+  tcase_add_test (tc, test_insert_7);
+  tcase_add_test (tc, test_insert_8);
+  tcase_add_test (tc, test_insert_9);
+  tcase_add_test (tc, test_insert_10);
+  tcase_add_test (tc, test_insert_11);
+  tcase_add_test (tc, test_insert_12);
+  tcase_add_test (tc, test_insert_13);
+
+  tcase_add_test (tc, test_remove_1);
+  tcase_add_test (tc, test_remove_2);
+  tcase_add_test (tc, test_remove_3);
+  tcase_add_test (tc, test_remove_4);
+  tcase_add_test (tc, test_remove_5);
+  tcase_add_test (tc, test_remove_6);
+  tcase_add_test (tc, test_remove_7);
+  tcase_add_test (tc, test_remove_8);
+  tcase_add_test (tc, test_remove_9);
+  tcase_add_test (tc, test_remove_10);
+
+  tcase_add_test (tc, test_generator_1);
+  tcase_add_test (tc, test_generator_2);
+  tcase_add_test (tc, test_generator_3);
+  tcase_add_test (tc, test_generator_5);
+  tcase_add_test (tc, test_generator_6);
+  tcase_add_test (tc, test_generator_7);
+  tcase_add_test (tc, test_generator_8);
+  tcase_add_test (tc, test_generator_9);
+
+  tcase_add_test (tc, test_gap_insert_1);
+  tcase_add_test (tc, test_gap_insert_2);
+  tcase_add_test (tc, test_gap_insert_3);
+  tcase_add_test (tc, test_gap_insert_4);
+  tcase_add_test (tc, test_gap_insert_5);
+  tcase_add_test (tc, test_gap_insert_6);
+  tcase_add_test (tc, test_gap_insert_7);
+  tcase_add_test (tc, test_gap_insert_8);
+  tcase_add_test (tc, test_gap_insert_9);
+  tcase_add_test (tc, test_gap_insert_10);
+  tcase_add_test (tc, test_gap_insert_11);
+
+  tcase_add_test (tc, test_gap_delete_1);
+  tcase_add_test (tc, test_gap_delete_2);
+  tcase_add_test (tc, test_gap_delete_3);
+  tcase_add_test (tc, test_gap_delete_4);
+  tcase_add_test (tc, test_gap_delete_5);
+  tcase_add_test (tc, test_gap_delete_6);
+  tcase_add_test (tc, test_gap_delete_7);
+  tcase_add_test (tc, test_gap_delete_8);
+
+  /* tcase_set_timeout (tc, 120); */
+  suite_add_tcase (s, tc);
+  return s;
+}
+
+int
+main (void)
+{
+  int nfailed;
+  Suite *s = basic_suite ();
+  SRunner *sr = srunner_create (s);
+
+  srunner_run_all (sr, CK_NORMAL);
+  nfailed = srunner_ntests_failed (sr);
+  srunner_free (sr);
+  return (nfailed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/test/manual/noverlay/many-errors.py 
b/test/manual/noverlay/many-errors.py
new file mode 100644
index 0000000..fa4ef5f
--- /dev/null
+++ b/test/manual/noverlay/many-errors.py
@@ -0,0 +1,2480 @@
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
+def a(x, y, y):
+    return t; pass
diff --git a/test/manual/noverlay/overlay-perf.el 
b/test/manual/noverlay/overlay-perf.el
new file mode 100644
index 0000000..e84941c
--- /dev/null
+++ b/test/manual/noverlay/overlay-perf.el
@@ -0,0 +1,764 @@
+;; -*- lexical-binding:t -*-
+(require 'cl-lib)
+(require 'subr-x)
+(require 'seq)
+(require 'hi-lock)
+
+
+;; 
+===================================================================================+
+;; | Framework
+;; 
+===================================================================================+
+
+(defmacro perf-define-constant-test (name &optional doc &rest body)
+  (declare (indent 1) (debug (symbol &optional string &rest form)))
+  `(progn
+     (put ',name 'perf-constant-test t)
+     (defun ,name nil ,doc ,@body)))
+
+(defmacro perf-define-variable-test (name args &optional doc &rest body)
+  (declare (indent 2) (debug defun))
+  (unless (and (consp args)
+               (= (length args) 1))
+    (error "Function %s should accept exactly one argument." name))
+  `(progn
+     (put ',name 'perf-variable-test t)
+     (defun ,name ,args ,doc ,@body)))
+
+(defmacro perf-define-test-suite (name &rest tests)
+  (declare (indent 1))
+  `(put ',name 'perf-test-suite
+        ,(cons 'list tests)))
+
+(defun perf-constant-test-p (test)
+  (get test 'perf-constant-test))
+
+(defun perf-variable-test-p (test)
+  (get test 'perf-variable-test))
+
+(defun perf-test-suite-p (suite)
+  (not (null (perf-test-suite-elements suite))))
+
+(defun perf-test-suite-elements (suite)
+  (get suite 'perf-test-suite))
+
+(defun perf-expand-suites (test-and-suites)
+  (apply #' append (mapcar (lambda (elt)
+                             (if (perf-test-suite-p elt)
+                                 (perf-test-suite-elements elt)
+                               (list elt)))
+                           test-and-suites)))
+(defun perf-test-p (symbol)
+  (or (perf-variable-test-p symbol)
+      (perf-constant-test-p symbol)))
+
+(defun perf-all-tests ()
+  (let (result)
+    (mapatoms (lambda (symbol)
+                (when (and (fboundp symbol)
+                           (perf-test-p symbol))
+                  (push symbol result))))
+    (sort result #'string-lessp)))
+
+(defvar perf-default-test-argument 4096)
+
+(defun perf-run-1 (&optional k n &rest tests)
+  "Run TESTS K times using N as argument for non-constant ones.
+
+Return test-total elapsed time."
+  (random "")
+  (when (and n (not (numberp n)))
+    (push k tests)
+    (push n tests)
+    (setq n nil k nil))
+  (when (and k (not (numberp k)))
+    (push k tests)
+    (setq k nil))
+  (let* ((k (or k 1))
+         (n (or n perf-default-test-argument))
+         (tests (perf-expand-suites (or tests
+                                        (perf-all-tests))))
+         (variable-tests (seq-filter #'perf-variable-test-p tests))
+         (constant-tests (seq-filter #'perf-constant-test-p tests))
+         (max-test-string-width (perf-max-symbol-length tests)))
+    (unless (seq-every-p #'perf-test-p tests)
+      (error "Some of these are not tests: %s" tests))
+    (cl-labels ((format-result (result)
+                  (cond
+                   ((numberp result) (format "%.2f" result))
+                   ((stringp result) result)
+                   ((null result) "N/A")))
+                (format-test (fn)
+                  (concat (symbol-name fn)
+                          (make-string
+                           (+ (- max-test-string-width
+                                 (length (symbol-name fn)))
+                              1)
+                           ?\s)))
+                (format-summary (results _total)
+                  (let ((min (apply #'min results))
+                        (max (apply #'max results))
+                        (avg (/ (apply #'+ results) (float (length results)))))
+                    (format "n=%d min=%.2f avg=%.2f max=%.2f" (length results) 
min avg max)))
+                (run-test (fn)
+                  (let ((total 0) results)
+                    (dotimes (_ (max 0 k))
+                      (garbage-collect)
+                      (princ (concat " " (format-test fn)))
+                      (let ((result  (condition-case-unless-debug err
+                                         (cond
+                                          ((perf-variable-test-p fn)
+                                           (random "") (car (funcall fn n)))
+                                          ((perf-constant-test-p fn)
+                                           (random "") (car (funcall fn)))
+                                          (t "skip"))
+                                       (error (error-message-string err)))))
+                        (when (numberp result)
+                          (cl-incf total result)
+                          (push result results))
+                        (princ (format-result result))
+                        (terpri)))
+                    (when (> (length results) 1)
+                      (princ (concat "#" (format-test fn)
+                                     (format-summary results total)))
+                      (terpri)))))
+      (when variable-tests
+        (terpri)
+        (dolist (fn variable-tests)
+          (run-test fn)
+          (terpri)))
+      (when constant-tests
+        (dolist (fn constant-tests)
+          (run-test fn)
+          (terpri))))))
+
+(defun perf-run (&optional k n &rest tests)
+  (interactive
+   (let* ((n (if current-prefix-arg
+                 (prefix-numeric-value current-prefix-arg)
+               perf-default-test-argument))
+          (tests (mapcar #'intern
+                         (completing-read-multiple
+                          (format "Run tests (n=%d): " n)
+                          (perf-all-tests) nil t nil 'perf-test-history))))
+     (cons 1 (cons n tests))))
+  (with-current-buffer (get-buffer-create "*perf-results*")
+    (let ((inhibit-read-only t)
+          (standard-output (current-buffer)))
+      (erase-buffer)
+      (apply #'perf-run-1 k n tests)
+      (display-buffer (current-buffer)))))
+
+
+(defun perf-batch-parse-command-line (args)
+  (let ((k 1)
+        (n perf-default-test-argument)
+        tests)
+    (while args
+      (cond ((string-match-p "\\`-[cn]\\'" (car args))
+             (unless (and (cdr args)
+                          (string-match-p "\\`[0-9]+\\'" (cadr args)))
+               (error "%s expectes a natnum argument" (car args)))
+             (if (equal (car args) "-c")
+                 (setq k (string-to-number (cadr args)))
+               (setq n (string-to-number (cadr args))))
+             (setq args (cddr args)))
+            (t (push (intern (pop args)) tests))))
+    (list k n tests)))
+
+
+(defun perf-run-batch ()
+  "Runs tests from `command-line-args-left' and kill emacs."
+  (let ((standard-output #'external-debugging-output))
+    (condition-case err
+        (cl-destructuring-bind (k n tests)
+            (perf-batch-parse-command-line command-line-args-left)
+          (apply #'perf-run-1 k n tests)
+          (save-buffers-kill-emacs))
+      (error
+       (princ (error-message-string err))
+       (save-buffers-kill-emacs)))))
+
+(defconst perf-number-of-columns 70)
+
+(defun perf-insert-lines (n)
+  "Insert N lines into the current buffer."
+  (dotimes (i n)
+    (insert (make-string 70 (if (= (% i 2) 0)
+                                ?.
+                              ?O))
+            ?\n)))
+
+(defun perf-switch-to-buffer-scroll-random (n &optional buffer)
+  (interactive)
+  (set-window-buffer nil (or buffer (current-buffer)))
+  (goto-char (point-min))
+  (redisplay t)
+  (dotimes (_ n)
+    (goto-char (random (point-max)))
+    (recenter)
+    (redisplay t)))
+
+(defun perf-insert-overlays (n &optional create-callback random-p)
+  (if random-p
+      (perf-insert-overlays-random n create-callback)
+    (perf-insert-overlays-sequential n create-callback)))
+
+(defun perf-insert-overlays-sequential (n &optional create-callback)
+  "Insert an overlay every Nth line."
+  (declare (indent 1))
+  (let ((i 0)
+        (create-callback (or create-callback #'ignore)))
+    (save-excursion
+      (goto-char (point-min))
+      (while (not (eobp))
+        (when (= 0 (% i n))
+          (let ((ov (make-overlay (point-at-bol) (point-at-eol))))
+            (funcall create-callback ov)
+            (overlay-put ov 'priority (random (buffer-size)))))
+        (cl-incf i)
+        (forward-line)))))
+
+(defun perf-insert-overlays-random (n &optional create-callback)
+  "Insert an overlay every Nth line."
+  (declare (indent 1))
+  (let ((create-callback (or create-callback #'ignore)))
+    (save-excursion
+      (while (>= (cl-decf n) 0)
+        (let* ((beg (1+ (random (point-max))))
+               (ov (make-overlay beg (+ beg (random 70)))))
+          (funcall create-callback ov)
+          (overlay-put ov 'priority (random (buffer-size))))))))
+
+(defun perf-insert-overlays-hierarchical (n &optional create-callback)
+  (let ((create-callback (or create-callback #'ignore)))
+    (save-excursion
+      (goto-char (point-min))
+      (let ((spacing (floor (/ (/ (count-lines (point-min) (point-max))
+                                  (float 3))
+                               n))))
+        (when (< spacing 1)
+          (error "Hierarchical overlay overflow !!"))
+        (dotimes (i n)
+          (funcall create-callback
+                   (make-overlay (point)
+                                 (save-excursion
+                                   (goto-char (point-max))
+                                   (forward-line (- (* spacing i)))
+                                   (point))))
+
+          (when (eobp)
+            (error "End of buffer in hierarchical overlays"))
+          (forward-line spacing))))))
+
+(defun perf-overlay-ascii-chart (&optional buffer width)
+  (interactive)
+  (save-current-buffer
+    (when buffer (set-buffer buffer))
+    (unless width (setq width 100))
+    (let* ((ovl (sort (overlays-in (point-min) (point-max))
+                      (lambda (ov1 ov2)
+                        (or (<= (overlay-start ov1)
+                                (overlay-start ov2))
+                            (and
+                             (= (overlay-start ov1)
+                                (overlay-start ov2))
+                             (< (overlay-end ov1)
+                                (overlay-end ov2)))))))
+           (ov-width (apply #'max (mapcar (lambda (ov)
+                                            (- (overlay-end ov)
+                                               (overlay-start ov)))
+                                          ovl)))
+           (ov-min (apply #'min (mapcar #'overlay-start ovl)))
+           (ov-max (apply #'max (mapcar #'overlay-end ovl)))
+           (scale (/ (float width) (+ ov-min ov-width))))
+      (with-current-buffer (get-buffer-create "*overlay-ascii-chart*")
+        (let ((inhibit-read-only t))
+          (erase-buffer)
+          (buffer-disable-undo)
+          (insert (format "%06d%s%06d\n" ov-min (make-string (- width 12) ?\s) 
ov-max))
+          (dolist (ov ovl)
+            (let ((length (round (* scale (- (overlay-end ov)
+                                             (overlay-start ov))))))
+              (insert (make-string (round (* scale (overlay-start ov))) ?\s))
+              (cl-case length
+                (0 (insert "O"))
+                (1 (insert "|"))
+                (t (insert (format "|%s|" (make-string (- length 2) ?-)))))
+              (insert "\n")))
+          (goto-char (point-min)))
+        (read-only-mode 1)
+        (pop-to-buffer (current-buffer))))))
+
+(defconst perf-overlay-faces (mapcar #'intern (seq-take hi-lock-face-defaults 
3)))
+
+(defun perf-overlay-face-callback (ov)
+  (overlay-put ov 'face (nth (random (length perf-overlay-faces))
+                             perf-overlay-faces)))
+
+(defun perf-overlay-invisible-callback (ov)
+  (overlay-put ov 'invisble (= 1 (random 2))))
+
+(defun perf-overlay-display-callback (ov)
+  (overlay-put ov 'display (make-string 70 ?*)))
+
+(defmacro perf-define-display-test (overlay-type property-type scroll-type)
+  (let ((name (intern (format "perf-display-%s/%s/%s"
+                              overlay-type property-type scroll-type)))
+        (arg (make-symbol "n")))
+
+    `(perf-define-variable-test ,name (,arg)
+       (with-temp-buffer
+         (perf-insert-lines ,arg)
+         (overlay-recenter (point-max))
+         ,@(perf-define-display-test-1 arg overlay-type property-type 
scroll-type)))))
+
+(defun perf-define-display-test-1 (arg overlay-type property-type scroll-type)
+  (list (append (cl-case overlay-type
+                  (sequential
+                   (list 'perf-insert-overlays-sequential 2))
+                  (hierarchical
+                   `(perf-insert-overlays-hierarchical (/ ,arg 10)))
+                  (random
+                   `(perf-insert-overlays-random (/ ,arg 2)))
+                  (t (error "Invalid insert type: %s" overlay-type)))
+                (list
+                 (cl-case property-type
+                   (display '#'perf-overlay-display-callback)
+                   (face '#'perf-overlay-face-callback)
+                   (invisible '#'perf-overlay-invisible-callback)
+                   (t (error "Invalid overlay type: %s" overlay-type)))))
+        (list 'benchmark-run 1
+              (cl-case scroll-type
+                (scroll '(perf-switch-to-buffer-scroll-up-and-down))
+                (random `(perf-switch-to-buffer-scroll-random (/ ,arg 50)))
+                (t (error "Invalid scroll type: %s" overlay-type))))))
+
+(defun perf-max-symbol-length (symbols)
+  "Return the longest symbol in SYMBOLS, or -1 if symbols is nil."
+  (if (null symbols)
+      -1
+    (apply #'max (mapcar
+                  (lambda (elt)
+                    (length (symbol-name elt)))
+                  symbols))))
+
+(defun perf-insert-text (n)
+  "Insert N character into the current buffer."
+  (let ((ncols 68)
+        (char ?.))
+    (dotimes (_  (/ n ncols))
+      (insert (make-string (1- ncols) char) ?\n))
+    (when (> (% n ncols) 0)
+      (insert (make-string (1- (% n ncols)) char) ?\n))))
+
+(defconst perf-insert-overlays-default-length 24)
+
+(defun perf-insert-overlays-scattered (n &optional length)
+  "Insert N overlays of max length 24 randomly."
+  (dotimes (_ n)
+    (let ((begin (random (1+ (point-max)))))
+      (make-overlay
+       begin (+ begin (random (1+ (or length 
perf-insert-overlays-default-length 0))))))))
+
+(defvar perf-marker-gc-protection nil)
+
+(defun perf-insert-marker-scattered (n)
+  "Insert N marker randomly."
+  (setq perf-marker-gc-protection nil)
+  (dotimes (_ n)
+    (push (copy-marker (random (1+ (point-max))))
+          perf-marker-gc-protection)))
+
+(defun perf-switch-to-buffer-scroll-up-and-down (&optional buffer)
+  (interactive)
+  (set-window-buffer nil (or buffer (current-buffer)))
+  (goto-char (point-min))
+  (redisplay t)
+  (while (condition-case nil
+             (progn (scroll-up) t)
+           (end-of-buffer nil))
+    (redisplay t))
+  (while (condition-case nil
+             (progn (scroll-down) t)
+           (beginning-of-buffer nil))
+    (redisplay t)))
+
+(defun perf-emacs-lisp-setup ()
+  (add-to-list 'imenu-generic-expression
+               '(nil 
"^\\s-*(perf-define\\(?:\\w\\|\\s_\\)*\\s-*\\(\\(?:\\w\\|\\s_\\)+\\)" 1)))
+
+(add-hook 'emacs-lisp-mode 'perf-emacs-lisp-setup)
+
+
+;; 
+===================================================================================+
+;; | Basic performance tests
+;; 
+===================================================================================+
+
+(perf-define-variable-test perf-make-overlay (n)
+  (with-temp-buffer
+    (overlay-recenter (point-min))
+    (benchmark-run 1
+      (dotimes (_ n)
+        (make-overlay 1 1)))))
+
+(perf-define-variable-test perf-make-overlay-continuous (n)
+  (with-temp-buffer
+    (perf-insert-text n)
+    (overlay-recenter (point-max))
+    (benchmark-run 1
+      (dotimes (i n)
+        (make-overlay i (1+ i))))))
+
+(perf-define-variable-test perf-make-overlay-scatter (n)
+  (with-temp-buffer
+    (perf-insert-text n)
+    (benchmark-run 1
+      (perf-insert-overlays-scattered n))))
+
+(perf-define-variable-test perf-delete-overlay (n)
+  (with-temp-buffer
+    (let ((ovls (cl-loop for i from 1 to n
+                        collect (make-overlay 1 1))))
+      (overlay-recenter (point-min))
+      (benchmark-run 1
+        (mapc #'delete-overlay ovls)))))
+
+(perf-define-variable-test perf-delete-overlay-continuous (n)
+  (with-temp-buffer
+    (perf-insert-text n)
+    (let ((ovls (cl-loop for i from 1 to n
+                         collect (make-overlay i (1+ i)))))
+      (overlay-recenter (point-min))
+      (benchmark-run 1
+        (mapc #'delete-overlay ovls)))))
+
+(perf-define-variable-test perf-delete-overlay-scatter (n)
+  (with-temp-buffer
+    (perf-insert-text n)
+    (let ((ovls (progn (perf-insert-overlays-scattered n)
+                       (overlays-in (point-min) (point-max)))))
+      (benchmark-run 1
+        (mapc #'delete-overlay ovls)))))
+
+(perf-define-variable-test perf-overlays-at (n)
+  (with-temp-buffer
+    (perf-insert-text n)
+    (perf-insert-overlays-scattered n)
+    (benchmark-run 1
+      (dotimes (i (point-max))
+        (overlays-at i)))))
+
+(perf-define-variable-test perf-overlays-in (n)
+  (with-temp-buffer
+    (perf-insert-text n)
+    (perf-insert-overlays-scattered n)
+    (let ((len perf-insert-overlays-default-length))
+      (benchmark-run 1
+        (dotimes (i (- (point-max) len))
+          (overlays-in i (+ i len)))))))
+
+(perf-define-variable-test perf-insert-before (n)
+  (with-temp-buffer
+    (perf-insert-text n)
+    (perf-insert-overlays-scattered n)
+    (goto-char 1)
+    (overlay-recenter (point-min))
+    (benchmark-run 1
+      (dotimes (_ (/ n 2))
+        (insert ?X)))))
+
+(perf-define-variable-test perf-insert-before-empty (n)
+  (let ((perf-insert-overlays-default-length 0))
+    (perf-insert-before n)))
+(perf-define-variable-test perf-insert-after-empty (n)
+  (let ((perf-insert-overlays-default-length 0))
+    (perf-insert-after n)))
+(perf-define-variable-test perf-insert-scatter-empty (n)
+  (let ((perf-insert-overlays-default-length 0))
+    (perf-insert-scatter n)))
+(perf-define-variable-test perf-delete-before-empty (n)
+  (let ((perf-insert-overlays-default-length 0))
+    (perf-delete-before n)))
+(perf-define-variable-test perf-delete-after-empty (n)
+  (let ((perf-insert-overlays-default-length 0))
+    (perf-delete-after n)))
+(perf-define-variable-test perf-delete-scatter-empty (n)
+  (let ((perf-insert-overlays-default-length 0))
+    (perf-delete-scatter n)))
+
+(defmacro perf-define-marker-test (type where)
+  (let ((name (intern (format "perf-%s-%s-marker" type where))))
+    `(perf-define-variable-test ,name (n)
+       (with-temp-buffer
+         (perf-insert-text n)
+         (perf-insert-marker-scattered n)
+         (goto-char ,(cl-case where
+                       (after (list 'point-max))
+                       (t (list 'point-min))))
+         (benchmark-run 1
+           (dotimes (_ (/ n 2))
+             ,@(when (eq where 'scatter)
+                 (list '(goto-char (max 1 (random (point-max))))))
+             ,(cl-case type
+                (insert (list 'insert ?X))
+                (delete (list 'delete-char (if (eq where 'after) -1 1))))))))))
+
+(perf-define-test-suite perf-marker-suite
+  (perf-define-marker-test insert before)
+  (perf-define-marker-test insert after)
+  (perf-define-marker-test insert scatter)
+  (perf-define-marker-test delete before)
+  (perf-define-marker-test delete after)
+  (perf-define-marker-test delete scatter))
+
+(perf-define-variable-test perf-insert-after (n)
+  (with-temp-buffer
+    (perf-insert-text n)
+    (perf-insert-overlays-scattered n)
+    (goto-char (point-max))
+    (overlay-recenter (point-max))
+    (benchmark-run 1
+      (dotimes (_ (/ n 2))
+        (insert ?X)))))
+
+(perf-define-variable-test perf-insert-scatter (n)
+  (with-temp-buffer
+    (perf-insert-text n)
+    (perf-insert-overlays-scattered n)
+    (goto-char (point-max))
+    (benchmark-run 1
+      (dotimes (_ (/ n 2))
+        (goto-char (1+ (random (point-max))))
+        (insert ?X)))))
+
+(perf-define-variable-test perf-delete-before (n)
+  (with-temp-buffer
+    (perf-insert-text n)
+    (perf-insert-overlays-scattered n)
+    (goto-char 1)
+    (overlay-recenter (point-min))
+    (benchmark-run 1
+      (dotimes (_ (/ n 2))
+        (delete-char 1)))))
+
+(perf-define-variable-test perf-delete-after (n)
+  (with-temp-buffer
+    (perf-insert-text n)
+    (perf-insert-overlays-scattered n)
+    (goto-char (point-max))
+    (overlay-recenter (point-max))
+    (benchmark-run 1
+      (dotimes (_ (/ n 2))
+        (delete-char -1)))))
+
+(perf-define-variable-test perf-delete-scatter (n)
+  (with-temp-buffer
+    (perf-insert-text n)
+    (perf-insert-overlays-scattered n)
+    (goto-char (point-max))
+    (benchmark-run 1
+      (dotimes (_ (/ n 2))
+        (goto-char (max 1 (random (point-max))))
+        (delete-char 1)))))
+
+(perf-define-test-suite perf-insert-delete-suite
+  'perf-insert-before
+  'perf-insert-after
+  'perf-insert-scatter
+  'perf-delete-before
+  'perf-delete-after
+  'perf-delete-scatter
+  )
+
+
+;; 
+===================================================================================+
+;; | Redisplay (new)
+;; 
+===================================================================================+
+
+;; 5000
+;; 25000
+;; 75000
+
+;; Number of Overlays =  N / 2
+;;
+;; (except for the hierarchical case, where it is divided by 10.)
+
+  ;; . scrolling through a buffer with lots of overlays that affect faces
+  ;;   of characters in the buffer text
+  ;; . scrolling through a buffer with lots of overlays that define
+  ;;   'display' properties which are strings
+  ;; . scrolling through a buffer with lots of overlays that define
+  ;;   'invisible' properties
+
+(perf-define-test-suite perf-display-suite
+  (perf-define-display-test sequential display scroll)
+  (perf-define-display-test sequential display random)
+  (perf-define-display-test sequential face scroll)
+  (perf-define-display-test sequential face random)
+  (perf-define-display-test sequential invisible scroll)
+  (perf-define-display-test sequential invisible random)
+  (perf-define-display-test random display scroll)
+  (perf-define-display-test random display random)
+  (perf-define-display-test random face scroll)
+  (perf-define-display-test random face random)
+  (perf-define-display-test random invisible scroll)
+  (perf-define-display-test random invisible random))
+
+;; |------------|
+;;   |--------|
+;;     |----|
+(perf-define-display-test hierarchical face scroll)
+
+
+
+
+;; 
+===================================================================================+
+;; | Real World
+;; 
+===================================================================================+
+
+(require 'python)
+
+(defconst perf-many-errors-file
+  (expand-file-name "many-errors.py"
+                    (and load-file-name (file-name-directory load-file-name))))
+
+(perf-define-constant-test perf-realworld-flycheck
+  (interactive)
+  (package-initialize)
+  (when (and (require 'flycheck nil t)
+             (file-exists-p perf-many-errors-file)
+             (or (executable-find "pylint")
+                 (executable-find "flake8")))
+    (setq flycheck-python-pylint-executable
+          (executable-find "pylint"))
+    (setq flycheck-python-flake8-executable
+          (executable-find "flake8"))
+    (setq python-indent-guess-indent-offset-verbose nil)
+    (setq flycheck-check-syntax-automatically nil)
+    (setq flycheck-checker-error-threshold nil)
+    (setq flycheck-display-errors-function nil)
+    (with-current-buffer (find-file-noselect perf-many-errors-file)
+      (let* ((done)
+             (flycheck-after-syntax-check-hook
+              (list (lambda () (setq done t)))))
+        (flycheck-mode 1)
+        (flycheck-buffer)
+        (benchmark-run 1
+          (while (not done)
+            (accept-process-output))
+          (perf-switch-to-buffer-scroll-up-and-down)
+          (flycheck-mode -1))))))
+
+;; https://lists.gnu.org/archive/html/emacs-devel/2009-04/msg00242.html
+(defun make-lines-invisible (regexp &optional arg)
+  "Make all lines matching a regexp invisible and intangible.
+With a prefix arg, make it visible again.  It is not necessary
+that REGEXP matches the whole line; if a hit is found, the
+affected line gets automatically selected.
+
+This command affects the whole buffer."
+  (interactive "MRegexp: \nP")
+  (let (ov
+        ovs
+        count)
+    (cond
+     ((equal arg '(4))
+      (setq ovs (overlays-in (point-min) (point-max)))
+      (mapc (lambda (o)
+              (if (overlay-get o 'make-lines-invisible)
+                  (delete-overlay o)))
+            ovs))
+     (t
+      (save-excursion
+        (goto-char (point-min))
+        (setq count 0)
+        (while (re-search-forward regexp nil t)
+          (setq count (1+ count))
+          (if (= (% count 100) 0)
+              (message "%d" count))
+          (setq ov (make-overlay (line-beginning-position)
+                                 (1+ (line-end-position))))
+          (overlay-put ov 'make-lines-invisible t)
+          (overlay-put ov 'invisible t)
+          (overlay-put ov 'intangible t)
+          (goto-char (line-end-position))))))))
+
+(perf-define-constant-test perf-realworld-make-lines-invisible
+  (with-temp-buffer
+    (insert-file-contents "/usr/share/dict/words")
+    (set-window-buffer nil (current-buffer))
+    (redisplay t)
+    (overlay-recenter (point-max))
+    (benchmark-run 1
+      (make-lines-invisible "a"))))
+
+(perf-define-constant-test perf-realworld-line-numbering
+  (interactive)
+  (with-temp-buffer
+    (insert-file-contents "/usr/share/dict/words")
+    (overlay-recenter (point-max))
+    (goto-char (point-min))
+    (let* ((nlines (count-lines (point-min) (point-max)))
+           (line 1)
+           (width 0))
+      (dotimes (i nlines) ;;-with-progress-reporter "Creating overlays"
+        (let ((ov (make-overlay (point) (point)))
+              (str (propertize (format "%04d" line) 'face 'shadow)))
+          (overlay-put ov 'before-string
+                       (propertize " " 'display `((margin left-margin) ,str)))
+          (setq width (max width (length str)))
+          (cl-incf line)
+          (forward-line)))
+      (benchmark-run 1
+        (let ((left-margin-width width))
+          (perf-switch-to-buffer-scroll-up-and-down))))))
+
+(perf-define-test-suite perf-realworld-suite
+  'perf-realworld-flycheck
+  'perf-realworld-make-lines-invisible
+  'perf-realworld-line-numbering)
+
+
+;; 
+===================================================================================+
+;; | next-overlay-change
+;; 
+===================================================================================+
+
+(perf-define-variable-test perf-noc-hierarchical/forward/linear (n)
+  "Search linear for the next change on every line."
+  (with-temp-buffer
+    (perf-insert-lines (* 3 n))
+    (perf-insert-overlays-hierarchical n)
+    (goto-char (point-min))
+    (benchmark-run 1
+      (while (not (eobp))
+        (next-overlay-change (point))
+        (forward-line)))))
+
+(perf-define-variable-test perf-noc-sequential/forward/linear (n)
+  "Search linear for the next change on every line."
+  (with-temp-buffer
+    (perf-insert-lines (* 3 n))
+    (perf-insert-overlays-sequential n)
+    (goto-char (point-min))
+    (benchmark-run 1
+      (while (not (eobp))
+        (next-overlay-change (point))
+        (forward-line)))))
+
+(perf-define-variable-test perf-noc-hierarchical/forward/backnforth (n)
+  "Search back and forth for the next change from `point-min' to `point-max'."
+  (with-temp-buffer
+    (perf-insert-lines (* 3 n))
+    (overlay-recenter (point-max))
+    (perf-insert-overlays-hierarchical n)
+    (goto-char (point-min))
+    (benchmark-run 1
+      (while (not (eobp))
+        (next-overlay-change (point))
+        (next-overlay-change (+ (point) 2))
+        (forward-char)))))
+
+(perf-define-test-suite perf-noc-suite
+  'perf-noc-hierarchical/forward/linear
+  'perf-noc-hierarchical/forward/backnforth
+  'perf-noc-hierarchical/forward/backnforth)
diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el
index 834acaf..71f8705 100644
--- a/test/src/buffer-tests.el
+++ b/test/src/buffer-tests.el
@@ -20,6 +20,7 @@
 ;;; Code:
 
 (require 'ert)
+(require 'seq)
 
 (ert-deftest overlay-modification-hooks-message-other-buf ()
   "Test for bug#21824.
@@ -50,4 +51,7522 @@ with parameters from the *Messages* buffer modification."
                             (progn (get-buffer-create "nil")
                                    (generate-new-buffer-name "nil")))))
 
+
+;; 
+===================================================================================+
+;; | Overlay test setup
+;; 
+===================================================================================+
+
+(eval-when-compile
+  (defun make-overlay-test-name (fn x y)
+    (intern (format "test-%s-%s-%s" fn x y))))
+
+(defun unmake-ov-test-name (symbol)
+  (let ((name (if (stringp symbol) symbol (symbol-name symbol))))
+    (when (string-match "\\`test-\\(.*\\)-\\(.*\\)-\\(.*\\)\\'" name)
+      (list (match-string 1 name) (match-string 2 name) (match-string 3 
name)))))
+
+(defmacro deftest-make-overlay-1 (id args)
+  (declare (indent 1))
+  `(ert-deftest ,(make-overlay-test-name 'make-overlay 1 id) ()
+     (with-temp-buffer
+       (should ,(cons 'make-overlay args)))))
+
+(defmacro deftest-make-overlay-2 (id args condition)
+  (declare (indent 1))
+  `(ert-deftest ,(make-overlay-test-name 'make-overlay 2 id) ()
+     (with-temp-buffer
+       (should-error
+        ,(cons 'make-overlay args)
+        :type ',condition
+        :exclude-subtypes t))))
+
+(defmacro deftest-overlay-start/end-1 (id start-end-args start-end-should)
+  (declare (indent 1))
+  (cl-destructuring-bind (start end sstart send)
+      (append start-end-args start-end-should)
+    `(ert-deftest ,(make-overlay-test-name 'overlay-start/end 1 id) ()
+       (with-temp-buffer
+         (insert (make-string 9 ?\n))
+         (let ((ov (make-overlay ,start ,end)))
+           (should (equal ,sstart (overlay-start ov)))
+           (should (equal ,send (overlay-end ov))))))))
+
+(defmacro deftest-overlay-buffer-1 (id arg-expr should-expr)
+  (declare (indent 1))
+  `(ert-deftest ,(make-overlay-test-name 'overlay-buffer 1 id) ()
+     (with-temp-buffer
+       (should (equal (overlay-buffer (make-overlay 1 1 ,arg-expr))
+                   ,should-expr)))))
+
+(defmacro deftest-overlayp-1 (id arg-expr should-expr)
+  (declare (indent 1))
+  `(ert-deftest ,(make-overlay-test-name 'overlay-buffer 1 id) ()
+     (with-temp-buffer
+       (should (equal ,should-expr (overlayp ,arg-expr))))))
+
+(defmacro deftest-next-overlay-change-1 (id pos result &rest ov-tuple)
+  `(ert-deftest ,(make-overlay-test-name 'next-overlay-change 1 id) ()
+     (let ((tuple (copy-sequence ',ov-tuple)))
+       (with-temp-buffer
+         (insert (make-string (max 100 (if tuple
+                                           (apply #'max
+                                                  (mapcar
+                                                   (lambda (m) (apply #'max 
m)) tuple))
+                                         0))
+                              ?\n))
+         (dolist (tup tuple)
+           (make-overlay (car tup) (cadr tup)))
+         (should (equal (next-overlay-change ,pos)
+                        ,result))))))
+
+(defmacro deftest-previous-overlay-change-1 (id pos result &rest ov-tuple)
+  `(ert-deftest ,(make-overlay-test-name 'previous-overlay-change 1 id) ()
+     (let ((tuple ',ov-tuple))
+       (with-temp-buffer
+         (insert (make-string (max 100 (if tuple
+                                           (apply #'max
+                                                  (mapcar
+                                                   (lambda (m) (apply #'max 
m)) tuple))
+                                         0))
+                              ?\n))
+         (dolist (tup tuple)
+           (make-overlay (car tup) (cadr tup)))
+         (should (equal (previous-overlay-change ,pos)
+                        ,result))))))
+
+(defmacro deftest-overlays-at-1 (id pos result &rest ov-triple)
+  `(ert-deftest ,(make-overlay-test-name 'overlays-at 1 id) ()
+     (let ((pos* ,pos))
+       (with-temp-buffer
+         (insert (make-string 100 ?\s))
+         (should-not (memq nil ',result))
+         (dolist (v ',ov-triple)
+           (cl-destructuring-bind (tag start end)
+               v
+             (overlay-put (make-overlay start end) 'tag tag)))
+         (let ((ovl (overlays-at pos*)))
+           (should (equal (length ovl) (length ',result)))
+           (dolist (ov ovl)
+             (should (memq (overlay-get ov 'tag) ',result))))))))
+
+(defmacro deftest-overlays-in-1 (id beg end result &rest ov-triple)
+  `(ert-deftest ,(make-overlay-test-name 'overlays-in 1 id) ()
+     (let ((beg* ,beg)
+           (end* ,end))
+       (with-temp-buffer
+         (insert (make-string 100 ?\s))
+         (should-not (memq nil ',result))
+         (dolist (v ',ov-triple)
+           (cl-destructuring-bind (tag start end)
+               v
+             (overlay-put (make-overlay start end) 'tag tag)))
+         (let ((ovl (overlays-in beg* end*)))
+           (should (equal (length ovl) (length ',result)))
+           (dolist (ov ovl)
+             (should (memq (overlay-get ov 'tag) ',result))))))))
+
+(defmacro test-with-overlay-in-buffer (symbol-beg-end-fa-ra &rest body)
+  (declare (indent 1))
+  (cl-destructuring-bind (symbol beg end &optional fa ra)
+      symbol-beg-end-fa-ra
+    `(with-temp-buffer
+       (insert (make-string (max 1000 (1- ,end)) ?\s))
+       (goto-char 1)
+       (let ((,symbol (make-overlay ,beg ,end nil ,fa ,ra)))
+         ,@body))))
+
+(defmacro deftest-overlays-equal-1 (id result ov1-args ov2-args)
+  `(ert-deftest ,(make-overlay-test-name 'overlays-equal 1 id) ()
+     (cl-labels ((create-overlay (args)
+                   (cl-destructuring-bind (start end &optional fa ra &rest 
properties)
+                       args
+                     (let ((ov (make-overlay start end nil fa ra)))
+                       (while properties
+                         (overlay-put ov (pop properties) (pop properties)))
+                       ov))))
+       (with-temp-buffer
+         (insert (make-string 1024 ?\s))
+         (should (,(if result 'identity 'not)
+                  (equal (create-overlay ',ov1-args)
+                         (create-overlay ',ov2-args))))))))
+
+
+(defun find-ert-overlay-test (name)
+  (let ((test (unmake-ov-test-name name)))
+    (or (and test
+             (cl-destructuring-bind (fn x y)
+                 test
+               (let ((regexp (format "deftest-%s-%s +%s" fn x y)))
+                 (re-search-forward regexp nil t))))
+        (let ((find-function-regexp-alist
+               (cl-remove 'find-ert-overlay-test find-function-regexp-alist 
:key #'cdr)))
+          (find-function-do-it name 'ert-deftest 
'switch-to-buffer-other-window)))))
+
+(add-to-list 'find-function-regexp-alist
+             '(ert-deftest . find-ert-overlay-test))
+
+
+;; 
+===================================================================================+
+;; | make-overlay
+;; 
+===================================================================================+
+
+;; Test if making an overlay succeeds.
+(deftest-make-overlay-1 A (1 1))
+(deftest-make-overlay-1 B (7 26))
+(deftest-make-overlay-1 C (29 7))
+(deftest-make-overlay-1 D (most-positive-fixnum 1))
+(deftest-make-overlay-1 E (most-negative-fixnum 1))
+(deftest-make-overlay-1 F (1 most-positive-fixnum))
+(deftest-make-overlay-1 G (1 most-negative-fixnum))
+(deftest-make-overlay-1 H (1 1 nil t))
+(deftest-make-overlay-1 I (1 1 nil nil))
+(deftest-make-overlay-1 J (1 1 nil nil nil))
+(deftest-make-overlay-1 K (1 1 nil nil t))
+(deftest-make-overlay-1 L (1 1 nil t t))
+(deftest-make-overlay-1 M (1 1 nil "yes" "yes"))
+
+;; Test if trying to make an overlay signals conditions.
+(deftest-make-overlay-2 A ()            wrong-number-of-arguments)
+(deftest-make-overlay-2 B (1)           wrong-number-of-arguments)
+(deftest-make-overlay-2 C (1 2 3 4 5 6) wrong-number-of-arguments)
+(deftest-make-overlay-2 D ("1")         wrong-number-of-arguments)
+(deftest-make-overlay-2 E ("1" "2")     wrong-type-argument)
+(deftest-make-overlay-2 F (1 2 "b")     wrong-type-argument)
+(deftest-make-overlay-2 G (1 2 3.14)    wrong-type-argument)
+(deftest-make-overlay-2 H (3.14 3)      wrong-type-argument)
+(deftest-make-overlay-2 I (1 [1])       wrong-type-argument)
+(deftest-make-overlay-2 J (1 1 (with-temp-buffer
+                                 (current-buffer)))
+                        error)
+
+
+;; 
+===================================================================================+
+;; | overlay-start/end
+;; 
+===================================================================================+
+
+;; Test if the overlays return proper positions.  point-max of the
+;; buffer will equal 10.        ARG RESULT
+(deftest-overlay-start/end-1 A (1 1) (1 1))
+(deftest-overlay-start/end-1 B (2 7) (2 7))
+(deftest-overlay-start/end-1 C (7 2) (2 7))
+(deftest-overlay-start/end-1 D (1 10) (1 10))
+(deftest-overlay-start/end-1 E (1 11) (1 10))
+(deftest-overlay-start/end-1 F (1 most-positive-fixnum) (1 10))
+(deftest-overlay-start/end-1 G (most-positive-fixnum 1) (1 10))
+(deftest-overlay-start/end-1 H (most-positive-fixnum most-positive-fixnum) (10 
10))
+(deftest-overlay-start/end-1 I (100 11) (10 10))
+(deftest-overlay-start/end-1 J (11 100) (10 10))
+(deftest-overlay-start/end-1 K (0 1) (1 1))
+(deftest-overlay-start/end-1 L (1 0) (1 1))
+(deftest-overlay-start/end-1 M (0 0) (1 1))
+
+(ert-deftest test-overlay-start/end-2 ()
+  (should-not (overlay-start (with-temp-buffer (make-overlay 1 1))))
+  (should-not (overlay-end (with-temp-buffer (make-overlay 1 1)))))
+
+
+;; 
+===================================================================================+
+;; | overlay-buffer
+;; 
+===================================================================================+
+
+;; Test if overlay-buffer returns appropriate values.
+(deftest-overlay-buffer-1 A (current-buffer) (current-buffer))
+(deftest-overlay-buffer-1 B nil (current-buffer))
+(ert-deftest test-overlay-buffer-1-C ()
+  (should-error (make-overlay
+                 1 1 (with-temp-buffer (current-buffer)))))
+
+
+;; 
+===================================================================================+
+;; | overlayp
+;; 
+===================================================================================+
+
+;; Check the overlay predicate.
+(deftest-overlayp-1 A (make-overlay 1 1) t)
+(deftest-overlayp-1 B (with-temp-buffer (make-overlay 1 1)) t)
+(deftest-overlayp-1 C nil                            nil)
+(deftest-overlayp-1 D 'symbol                        nil)
+(deftest-overlayp-1 E "string"                       nil)
+(deftest-overlayp-1 F 42                             nil)
+(deftest-overlayp-1 G [1 2]                          nil)
+(deftest-overlayp-1 H (symbol-function 'car)         nil)
+(deftest-overlayp-1 I float-pi                       nil)
+(deftest-overlayp-1 J (cons 1 2)                     nil)
+(deftest-overlayp-1 K (make-hash-table)              nil)
+(deftest-overlayp-1 L (symbol-function 'ert-deftest) nil)
+(deftest-overlayp-1 M (current-buffer)               nil)
+(deftest-overlayp-1 N (selected-window)              nil)
+(deftest-overlayp-1 O (selected-frame)               nil)
+
+
+;; 
+===================================================================================+
+;; | overlay equality
+;; 
+===================================================================================+
+
+(deftest-overlays-equal-1 A t (1 1) (1 1))
+(deftest-overlays-equal-1 B t (5 10) (5 10))
+(deftest-overlays-equal-1 C nil (5 11) (5 10))
+(deftest-overlays-equal-1 D t (10 20 t) (10 20))
+(deftest-overlays-equal-1 E t (10 20 nil t) (10 20))
+(deftest-overlays-equal-1 F t (10 20 t t) (10 20 nil t))
+(deftest-overlays-equal-1 G t (10 20 t t) (10 20 t nil))
+(deftest-overlays-equal-1 H t (10 20 nil nil foo 42) (10 20 nil nil foo 42))
+(deftest-overlays-equal-1 I nil (10 20 nil nil foo 42) (10 20 nil nil foo 43))
+
+
+;; 
+===================================================================================+
+;; | overlay-lists
+;; 
+===================================================================================+
+
+;; Check whether overlay-lists returns something sensible.
+(ert-deftest test-overlay-lists-1 ()
+  (with-temp-buffer
+    (should (equal (cons nil nil) (overlay-lists)))
+    (dotimes (i 10) (make-overlay 1 i))
+    (should (listp (car (overlay-lists))))
+    (should (listp (cdr (overlay-lists))))
+    (let ((list (append (car (overlay-lists))
+                        (cdr (overlay-lists)))))
+      (should (= 10 (length list)))
+      (should (seq-every-p #'overlayp list)))))
+
+
+;; 
+===================================================================================+
+;; | overlay-put/get/properties
+;; 
+===================================================================================+
+
+;; Test if overlay-put properties can be retrieved by overlay-get and
+;; overlay-properties.
+(ert-deftest test-overlay-props-1 ()
+  (with-temp-buffer
+    (let* ((keys '(:k1 :k2 :k3))
+           (values '(1 "v2" v3))
+           (ov (make-overlay 1 1))
+           (n (length keys)))
+      (should (equal (length keys) (length values)))
+      (should (null (overlay-properties ov)))
+      ;; Insert keys and values.
+      (dotimes (i n)
+        (should (equal (overlay-put ov (nth i keys) (nth i values))
+                       (nth i values))))
+      ;; Compare with what overlay-get says.
+      (dotimes (i n)
+        (should (equal (overlay-get ov (nth i keys))
+                       (nth i values))))
+      ;; Test if overlay-properties is a superset.
+      (dotimes (i n)
+        (should (equal (plist-get (overlay-properties ov)
+                                  (nth i keys))
+                       (nth i values))))
+      ;; Check if overlay-properties is a subset.
+      (should (= (length (overlay-properties ov)) (* n 2))))))
+
+
+;; 
+===================================================================================+
+;; | next-overlay-change
+;; 
+===================================================================================+
+
+;; Test if next-overlay-change returns RESULT if called with POS in a
+;; buffer with overlays corresponding to OVS and point-max >= 100.
+;;                               (POS RESULT &rest OVS)
+;; 0 overlays
+(deftest-next-overlay-change-1 A (point-min) (point-max))
+(deftest-next-overlay-change-1 B (point-max) (point-max))
+;; 1 non-empty overlay
+(deftest-next-overlay-change-1 C 1 10 (10 20))
+(deftest-next-overlay-change-1 D 10 20 (10 20))
+(deftest-next-overlay-change-1 E 15 20 (10 20))
+(deftest-next-overlay-change-1 F 20 (point-max) (10 20))
+(deftest-next-overlay-change-1 G 30 (point-max) (10 20))
+;; 1 empty overlay
+(deftest-next-overlay-change-1 H 1 10 (10 10))
+(deftest-next-overlay-change-1 I 10 (point-max) (10 10))
+(deftest-next-overlay-change-1 J 20 (point-max) (10 10))
+;; 2 non-empty, non-intersecting
+(deftest-next-overlay-change-1 D 10 20 (20 30) (40 50))
+(deftest-next-overlay-change-1 E 35 40 (20 30) (40 50))
+(deftest-next-overlay-change-1 F 60 (point-max) (20 30) (40 50))
+(deftest-next-overlay-change-1 G 30 40 (20 30) (40 50))
+(deftest-next-overlay-change-1 H 50 (point-max) (20 30) (40 50))
+;; 2 non-empty, intersecting
+(deftest-next-overlay-change-1 I 10 20 (20 30) (25 35))
+(deftest-next-overlay-change-1 J 20 25 (20 30) (25 35))
+(deftest-next-overlay-change-1 K 23 25 (20 30) (25 35))
+(deftest-next-overlay-change-1 L 25 30 (20 30) (25 35))
+(deftest-next-overlay-change-1 M 28 30 (20 30) (25 35))
+(deftest-next-overlay-change-1 N 30 35 (20 30) (25 35))
+(deftest-next-overlay-change-1 O 35 (point-max) (20 30) (25 35))
+(deftest-next-overlay-change-1 P 50 (point-max) (20 30) (25 35))
+;; 2 non-empty, continuous
+(deftest-next-overlay-change-1 Q 10 20 (20 30) (30 40))
+(deftest-next-overlay-change-1 R 20 30 (20 30) (30 40))
+(deftest-next-overlay-change-1 S 25 30 (20 30) (30 40))
+(deftest-next-overlay-change-1 T 30 40 (20 30) (30 40))
+(deftest-next-overlay-change-1 U 35 40 (20 30) (30 40))
+(deftest-next-overlay-change-1 V 40 (point-max) (20 30) (30 40))
+(deftest-next-overlay-change-1 W 50 (point-max) (20 30) (30 40))
+;; 1 empty, 1 non-empty, non-in
+(deftest-next-overlay-change-1 a 10 20 (20 20) (30 40))
+(deftest-next-overlay-change-1 b 20 30 (20 30) (30 40))
+(deftest-next-overlay-change-1 c 25 30 (20 30) (30 40))
+(deftest-next-overlay-change-1 d 30 40 (20 30) (30 40))
+(deftest-next-overlay-change-1 e 35 40 (20 30) (30 40))
+(deftest-next-overlay-change-1 f 40 (point-max) (20 30) (30 40))
+(deftest-next-overlay-change-1 g 50 (point-max) (20 30) (30 40))
+;; 1 empty, 1 non-empty, intersecting at begin
+(deftest-next-overlay-change-1 h 10 20 (20 20) (20 30))
+(deftest-next-overlay-change-1 i 20 30 (20 20) (20 30))
+(deftest-next-overlay-change-1 j 25 30 (20 20) (20 30))
+(deftest-next-overlay-change-1 k 30 (point-max) (20 20) (20 30))
+(deftest-next-overlay-change-1 l 40 (point-max) (20 20) (20 30))
+;; 1 empty, 1 non-empty, intersecting at end
+(deftest-next-overlay-change-1 h 10 20 (30 30) (20 30))
+(deftest-next-overlay-change-1 i 20 30 (30 30) (20 30))
+(deftest-next-overlay-change-1 j 25 30 (30 30) (20 30))
+(deftest-next-overlay-change-1 k 30 (point-max) (20 20) (20 30))
+(deftest-next-overlay-change-1 l 40 (point-max) (20 20) (20 30))
+;; 1 empty, 1 non-empty, intersecting in the middle
+(deftest-next-overlay-change-1 m 10 20 (25 25) (20 30))
+(deftest-next-overlay-change-1 n 20 25 (25 25) (20 30))
+(deftest-next-overlay-change-1 o 25 30 (25 25) (20 30))
+(deftest-next-overlay-change-1 p 30 (point-max) (25 25) (20 30))
+(deftest-next-overlay-change-1 q 40 (point-max) (25 25) (20 30))
+;; 2 empty, intersecting
+(deftest-next-overlay-change-1 r 10 20 (20 20) (20 20))
+(deftest-next-overlay-change-1 s 20 (point-max) (20 20) (20 20))
+(deftest-next-overlay-change-1 t 30 (point-max) (20 20) (20 20))
+;; 2 empty, non-intersecting
+(deftest-next-overlay-change-1 u 10 20 (20 20) (30 30))
+(deftest-next-overlay-change-1 v 20 30 (20 20) (30 30))
+(deftest-next-overlay-change-1 w 25 30 (20 20) (30 30))
+(deftest-next-overlay-change-1 x 30 (point-max) (20 20) (30 30))
+(deftest-next-overlay-change-1 y 50 (point-max) (20 20) (30 30))
+;; 10 random
+(deftest-next-overlay-change-1 aa 1 5
+  (58 66) (41 10) (9 67) (28 88) (27 43)
+  (24 27) (48 36) (5 90) (61 9))
+(deftest-next-overlay-change-1 ab (point-max) (point-max)
+  (58 66) (41 10) (9 67) (28 88) (27 43)
+  (24 27) (48 36) (5 90) (61 9))
+(deftest-next-overlay-change-1 ac 67 88
+  (58 66) (41 10) (9 67) (28 88) (27 43)
+  (24 27) (48 36) (5 90) (61 9))
+
+
+;; 
+===================================================================================+
+;; | previous-overlay-change.
+;; 
+===================================================================================+
+
+;; Same for previous-overlay-change.
+;; 1 non-empty overlay
+(deftest-previous-overlay-change-1 A (point-max) 1)
+(deftest-previous-overlay-change-1 B 1 1)
+(deftest-previous-overlay-change-1 C 1 1 (10 20))
+(deftest-previous-overlay-change-1 D 10 1 (10 20))
+(deftest-previous-overlay-change-1 E 15 10 (10 20))
+(deftest-previous-overlay-change-1 F 20 10 (10 20))
+(deftest-previous-overlay-change-1 G 30 20 (10 20))
+;; 1 empty overlay
+(deftest-previous-overlay-change-1 H 1 1 (10 10))
+(deftest-previous-overlay-change-1 I 10 1 (10 10))
+(deftest-previous-overlay-change-1 J 20 10 (10 10))
+;; 2 non-empty, non-intersecting
+(deftest-previous-overlay-change-1 D 10 1 (20 30) (40 50))
+(deftest-previous-overlay-change-1 E 35 30 (20 30) (40 50))
+(deftest-previous-overlay-change-1 F 60 50 (20 30) (40 50))
+(deftest-previous-overlay-change-1 G 30 20 (20 30) (40 50))
+(deftest-previous-overlay-change-1 H 50 40 (20 30) (40 50))
+;; 2 non-empty, intersecting
+(deftest-previous-overlay-change-1 I 10 1 (20 30) (25 35))
+(deftest-previous-overlay-change-1 J 20 1 (20 30) (25 35))
+(deftest-previous-overlay-change-1 K 23 20 (20 30) (25 35))
+(deftest-previous-overlay-change-1 L 25 20 (20 30) (25 35))
+(deftest-previous-overlay-change-1 M 28 25 (20 30) (25 35))
+(deftest-previous-overlay-change-1 N 30 25 (20 30) (25 35))
+(deftest-previous-overlay-change-1 O 35 30 (20 30) (25 35))
+(deftest-previous-overlay-change-1 P 50 35 (20 30) (25 35))
+;; 2 non-empty, continuous
+(deftest-previous-overlay-change-1 Q 10 1 (20 30) (30 40))
+(deftest-previous-overlay-change-1 R 20 1 (20 30) (30 40))
+(deftest-previous-overlay-change-1 S 25 20 (20 30) (30 40))
+(deftest-previous-overlay-change-1 T 30 20 (20 30) (30 40))
+(deftest-previous-overlay-change-1 U 35 30 (20 30) (30 40))
+(deftest-previous-overlay-change-1 V 40 30 (20 30) (30 40))
+(deftest-previous-overlay-change-1 W 50 40 (20 30) (30 40))
+;; 1 empty, 1 non-empty, non-intersecting
+(deftest-previous-overlay-change-1 a 10 1 (20 20) (30 40))
+(deftest-previous-overlay-change-1 b 20 1 (20 30) (30 40))
+(deftest-previous-overlay-change-1 c 25 20 (20 30) (30 40))
+(deftest-previous-overlay-change-1 d 30 20 (20 30) (30 40))
+(deftest-previous-overlay-change-1 e 35 30 (20 30) (30 40))
+(deftest-previous-overlay-change-1 f 40 30 (20 30) (30 40))
+(deftest-previous-overlay-change-1 g 50 40 (20 30) (30 40))
+;; 1 empty, 1 non-empty, intersecting at begin
+(deftest-previous-overlay-change-1 h 10 1 (20 20) (20 30))
+(deftest-previous-overlay-change-1 i 20 1 (20 20) (20 30))
+(deftest-previous-overlay-change-1 j 25 20 (20 20) (20 30))
+(deftest-previous-overlay-change-1 k 30 20 (20 20) (20 30))
+(deftest-previous-overlay-change-1 l 40 30 (20 20) (20 30))
+;; 1 empty, 1 non-empty, intersecting at end
+(deftest-previous-overlay-change-1 m 10 1 (30 30) (20 30))
+(deftest-previous-overlay-change-1 n 20 1 (30 30) (20 30))
+(deftest-previous-overlay-change-1 o 25 20 (30 30) (20 30))
+(deftest-previous-overlay-change-1 p 30 20 (20 20) (20 30))
+(deftest-previous-overlay-change-1 q 40 30 (20 20) (20 30))
+;; 1 empty, 1 non-empty, intersectig in the middle
+(deftest-previous-overlay-change-1 r 10 1 (25 25) (20 30))
+(deftest-previous-overlay-change-1 s 20 1 (25 25) (20 30))
+(deftest-previous-overlay-change-1 t 25 20 (25 25) (20 30))
+(deftest-previous-overlay-change-1 u 30 25 (25 25) (20 30))
+(deftest-previous-overlay-change-1 v 40 30 (25 25) (20 30))
+;; 2 empty, intersecting
+(deftest-previous-overlay-change-1 w 10 1 (20 20) (20 20))
+(deftest-previous-overlay-change-1 x 20 1 (20 20) (20 20))
+(deftest-previous-overlay-change-1 y 30 20 (20 20) (20 20))
+;; 2 empty, non-intersecting
+(deftest-previous-overlay-change-1 z 10 1 (20 20) (30 30))
+(deftest-previous-overlay-change-1 aa 20 1 (20 20) (30 30))
+(deftest-previous-overlay-change-1 ab 25 20 (20 20) (30 30))
+(deftest-previous-overlay-change-1 ac 30 20 (20 20) (30 30))
+(deftest-previous-overlay-change-1 ad 50 30 (20 20) (30 30))
+;; 10 random
+(deftest-previous-overlay-change-1 ae 100 90
+  (58 66) (41 10) (9 67) (28 88) (27 43)
+  (24 27) (48 36) (5 90) (61 9))
+(deftest-previous-overlay-change-1 af (point-min) (point-min)
+  (58 66) (41 10) (9 67) (28 88) (27 43)
+  (24 27) (48 36) (5 90) (61 9))
+(deftest-previous-overlay-change-1 ag 29 28
+  (58 66) (41 10) (9 67) (28 88) (27 43)
+  (24 27) (48 36) (5 90) (61 9))
+
+
+;; 
+===================================================================================+
+;; | overlays-at
+;; 
+===================================================================================+
+
+
+;; Test whether overlay-at returns RESULT at POS after overlays OVL were
+;; created in a buffer.         POS RES OVL
+(deftest-overlays-at-1 A 1 ())
+;; 1 overlay
+(deftest-overlays-at-1 B 10 (a) (a 10 20))
+(deftest-overlays-at-1 C 15 (a) (a 10 20))
+(deftest-overlays-at-1 D 19 (a) (a 10 20))
+(deftest-overlays-at-1 E 20 ()  (a 10 20))
+(deftest-overlays-at-1 F 1 () (a 10 20))
+
+;; 2 non-empty overlays non-intersecting
+(deftest-overlays-at-1 G 1 () (a 10 20) (b 30 40))
+(deftest-overlays-at-1 H 10 (a) (a 10 20) (b 30 40))
+(deftest-overlays-at-1 I 15 (a) (a 10 20) (b 30 40))
+(deftest-overlays-at-1 K 20 () (a 10 20) (b 30 40))
+(deftest-overlays-at-1 L 25 () (a 10 20) (b 30 40))
+(deftest-overlays-at-1 M 30 (b) (a 10 20) (b 30 40))
+(deftest-overlays-at-1 N 35 (b) (a 10 20) (b 30 40))
+(deftest-overlays-at-1 O 40 () (a 10 20) (b 30 40))
+(deftest-overlays-at-1 P 50 () (a 10 20) (b 30 40))
+
+;; 2 non-empty overlays intersecting
+(deftest-overlays-at-1 G 1 () (a 10 30) (b 20 40))
+(deftest-overlays-at-1 H 10 (a) (a 10 30) (b 20 40))
+(deftest-overlays-at-1 I 15 (a) (a 10 30) (b 20 40))
+(deftest-overlays-at-1 K 20 (a b) (a 10 30) (b 20 40))
+(deftest-overlays-at-1 L 25 (a b) (a 10 30) (b 20 40))
+(deftest-overlays-at-1 M 30 (b) (a 10 30) (b 20 40))
+(deftest-overlays-at-1 N 35 (b) (a 10 30) (b 20 40))
+(deftest-overlays-at-1 O 40 () (a 10 30) (b 20 40))
+(deftest-overlays-at-1 P 50 () (a 10 30) (b 20 40))
+
+;; 2 non-empty overlays continuous
+(deftest-overlays-at-1 G 1 () (a 10 20) (b 20 30))
+(deftest-overlays-at-1 H 10 (a) (a 10 20) (b 20 30))
+(deftest-overlays-at-1 I 15 (a) (a 10 20) (b 20 30))
+(deftest-overlays-at-1 K 20 (b) (a 10 20) (b 20 30))
+(deftest-overlays-at-1 L 25 (b) (a 10 20) (b 20 30))
+(deftest-overlays-at-1 M 30 () (a 10 20) (b 20 30))
+
+;; overlays-at never returns empty overlays.
+(deftest-overlays-at-1 N 1 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
+(deftest-overlays-at-1 O 20 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
+(deftest-overlays-at-1 P 30 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
+(deftest-overlays-at-1 Q 40 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
+(deftest-overlays-at-1 R 50 (a) (a 1 60) (c 1 1) (b 30 30) (d 50 50))
+(deftest-overlays-at-1 S 60 () (a 1 60) (c 1 1) (b 30 30) (d 50 50))
+
+;; behaviour at point-min and point-max
+(ert-deftest test-overlays-at-2 ()
+  (cl-macrolet ((should-length (n list)
+                  `(should (= ,n (length ,list)))))
+    (with-temp-buffer
+      (insert (make-string 100 ?\s))
+      (make-overlay 1 (point-max))
+      (make-overlay 10 10)
+      (make-overlay 20 20)
+      (make-overlay (point-max) (point-max))
+      (should-length 1 (overlays-at 1))
+      (should-length 1 (overlays-at 10))
+      (should-length 1 (overlays-at 20))
+      (should-length 0 (overlays-at (point-max)))
+      (narrow-to-region 10 20)
+      (should-length 1 (overlays-at (point-min)))
+      (should-length 1 (overlays-at 15))
+      (should-length 1 (overlays-at (point-max))))))
+
+
+;; 
+===================================================================================+
+;; | overlay-in
+;; 
+===================================================================================+
+
+
+;; Test whether overlays-in returns RES in BEG,END after overlays OVL were
+;; created in a buffer.
+
+(deftest-overlays-in-1 A 1 (point-max) ());;POS RES OVL
+;; 1 overlay
+(deftest-overlays-in-1 B 1 10 () (a 10 20))
+(deftest-overlays-in-1 C 5 10 () (a 10 20))
+(deftest-overlays-in-1 D 5 15 (a) (a 10 20))
+(deftest-overlays-in-1 E 10 15 (a)  (a 10 20))
+(deftest-overlays-in-1 F 10 20 (a) (a 10 20))
+(deftest-overlays-in-1 G 15 20 (a) (a 10 20))
+(deftest-overlays-in-1 H 15 25 (a) (a 10 20))
+(deftest-overlays-in-1 I 20 25 () (a 10 20))
+(deftest-overlays-in-1 J 30 50 () (a 10 20))
+
+;; 2 non-empty overlays non-intersecting
+(deftest-overlays-in-1 K 1 5 () (a 10 20) (b 30 40))
+(deftest-overlays-in-1 L 5 10 () (a 10 20) (b 30 40))
+(deftest-overlays-in-1 M 5 15 (a) (a 10 20) (b 30 40))
+(deftest-overlays-in-1 N 10 15 (a) (a 10 20) (b 30 40))
+(deftest-overlays-in-1 O 15 20 (a) (a 10 20) (b 30 40))
+(deftest-overlays-in-1 P 15 25 (a) (a 10 20) (b 30 40))
+(deftest-overlays-in-1 Q 20 25 () (a 10 20) (b 30 40))
+(deftest-overlays-in-1 R 20 30 () (a 10 20) (b 30 40))
+(deftest-overlays-in-1 S 25 30 () (a 10 20) (b 30 40))
+(deftest-overlays-in-1 T 25 35 (b) (a 10 20) (b 30 40))
+(deftest-overlays-in-1 U 30 35 (b) (a 10 20) (b 30 40))
+(deftest-overlays-in-1 V 40 50  () (a 10 20) (b 30 40))
+(deftest-overlays-in-1 W 50 60  () (a 10 20) (b 30 40))
+(deftest-overlays-in-1 X 1 50  (a b) (a 10 20) (b 30 40))
+(deftest-overlays-in-1 Y 10 40  (a b) (a 10 20) (b 30 40))
+(deftest-overlays-in-1 Z 10 41  (a b) (a 10 20) (b 30 40))
+
+;; 2 non-empty overlays intersecting
+(deftest-overlays-in-1 a 1 5 () (a 10 30) (b 20 40))
+(deftest-overlays-in-1 b 5 10 () (a 10 30) (b 20 40))
+(deftest-overlays-in-1 c 5 15 (a) (a 10 30) (b 20 40))
+(deftest-overlays-in-1 d 10 15 (a) (a 10 30) (b 20 40))
+(deftest-overlays-in-1 e 10 20 (a) (a 10 30) (b 20 40))
+(deftest-overlays-in-1 f 15 20 (a) (a 10 30) (b 20 40))
+(deftest-overlays-in-1 g 20 30 (a b) (a 10 30) (b 20 40))
+(deftest-overlays-in-1 h 20 40 (a b) (a 10 30) (b 20 40))
+(deftest-overlays-in-1 i 25 30 (a b) (a 10 30) (b 20 40))
+(deftest-overlays-in-1 j 30 30 (b) (a 10 30) (b 20 40))
+(deftest-overlays-in-1 k 30 35 (b) (a 10 30) (b 20 40))
+(deftest-overlays-in-1 l 35 40 (b) (a 10 30) (b 20 40))
+(deftest-overlays-in-1 m 40 45 () (a 10 30) (b 20 40))
+(deftest-overlays-in-1 n 41 45 () (a 10 30) (b 20 40))
+(deftest-overlays-in-1 o 50 60 () (a 10 30) (b 20 40))
+
+;; 2 non-empty overlays continuous
+(deftest-overlays-in-1 p 1 5 () (a 10 20) (b 20 30))
+(deftest-overlays-in-1 q 5 10 () (a 10 20) (b 20 30))
+(deftest-overlays-in-1 r 15 20 (a) (a 10 20) (b 20 30))
+(deftest-overlays-in-1 s 15 25 (a b) (a 10 20) (b 20 30))
+(deftest-overlays-in-1 t 20 25 (b) (a 10 20) (b 20 30))
+(deftest-overlays-in-1 u 25 30 (b) (a 10 20) (b 20 30))
+(deftest-overlays-in-1 v 29 35 (b) (a 10 20) (b 20 30))
+(deftest-overlays-in-1 w 30 35 () (a 10 20) (b 20 30))
+(deftest-overlays-in-1 x 35 50 () (a 10 20) (b 20 30))
+(deftest-overlays-in-1 y 1 50 (a b) (a 10 20) (b 20 30))
+(deftest-overlays-in-1 z 15 50 (a b) (a 10 20) (b 20 30))
+(deftest-overlays-in-1 aa 1 25 (a b) (a 10 20) (b 20 30))
+
+;; 1 empty overlay
+(deftest-overlays-in-1 ab 1 10 () (a 10 10))
+(deftest-overlays-in-1 ac 10 10 (a) (a 10 10))
+(deftest-overlays-in-1 ad 9 10 () (a 10 10))
+(deftest-overlays-in-1 ae 9 11 (a) (a 10 10))
+(deftest-overlays-in-1 af 10 11 (a) (a 10 10))
+
+
+;; behaviour at point-max
+(ert-deftest test-overlays-in-2 ()
+  (cl-macrolet ((should-length (n list)
+                  `(should (= ,n (length ,list)))))
+    (with-temp-buffer
+      (insert (make-string 100 ?\s))
+      (make-overlay (point-max) (point-max))
+      (make-overlay 50 50)
+      (should-length 1 (overlays-in 50 50))
+      (should-length 2 (overlays-in 1 (point-max)))
+      (should-length 1 (overlays-in (point-max) (point-max)))
+      (narrow-to-region 1 50)
+      (should-length 0 (overlays-in 1 (point-max)))
+      (should-length 1 (overlays-in (point-max) (point-max))))))
+
+
+;; 
+===================================================================================+
+;; | overlay-recenter
+;; 
+===================================================================================+
+
+;; This function is a noop in the overlay tree branch.
+(ert-deftest test-overlay-recenter ()
+  (with-temp-buffer
+    (should-not (overlay-recenter 1))
+    (insert (make-string 100 ?\s))
+    (dotimes (i 10)
+      (make-overlay i (1+ i))
+      (should-not (overlay-recenter i)))))
+
+
+;; 
+===================================================================================+
+;; | move-overlay
+;; 
+===================================================================================+
+
+;; buffer nil with live overlay
+(ert-deftest test-move-overlay-1 ()
+  (test-with-overlay-in-buffer (ov 1 100)
+    (move-overlay ov 50 60)
+    (should (= 50 (overlay-start ov)))
+    (should (= 60 (overlay-end ov)))
+    (should (eq (current-buffer) (overlay-buffer ov)))))
+
+;; buffer nil, dead overlay
+(ert-deftest test-move-overlay-2 ()
+  (with-temp-buffer
+    (let ((ov (test-with-overlay-in-buffer (ov 1 100) ov)))
+      (insert (make-string 100 ?\s))
+      (move-overlay ov 50 60)
+      (should (= 50 (overlay-start ov)))
+      (should (= 60 (overlay-end ov)))
+      (should (eq (current-buffer) (overlay-buffer ov))))))
+
+;; buffer non-nil, live overlay
+(ert-deftest test-move-overlay-3 ()
+  (test-with-overlay-in-buffer (ov 10 100)
+    (with-temp-buffer
+      (move-overlay ov 1 1 (current-buffer))
+      (should (= 1 (overlay-start ov)))
+      (should (= 1 (overlay-end ov)))
+      (should (eq (current-buffer) (overlay-buffer ov))))
+    (should-not (overlay-start ov))
+    (should-not (overlay-end ov))
+    (should-not (overlay-buffer ov))))
+
+;; buffer non-nil, dead overlay
+(ert-deftest test-move-overlay-4 ()
+  (let ((ov (test-with-overlay-in-buffer (ov 1 1) ov)))
+    (with-temp-buffer
+      (move-overlay ov 1 1 (current-buffer))
+      (should (= 1 (overlay-start ov)))
+      (should (= 1 (overlay-end ov)))
+      (should (eq (current-buffer) (overlay-buffer ov))))
+    (should-not (overlay-start ov))
+    (should-not (overlay-end ov))
+    (should-not (overlay-buffer ov))))
+
+;; This used to fail.
+(ert-deftest test-move-overlay-5 ()
+  (skip-unless (fboundp 'overlay-tree))
+  (with-temp-buffer
+    (insert (make-string 1 ?.))
+    (let ((other (make-overlay 1 1)))
+      (make-overlay 1 1)
+      (insert "()")
+      (move-overlay other (point-max) (1+ (point-max)) (current-buffer))
+      (delete-overlay other))
+    (should (= (plist-get (car (with-no-warnings (overlay-tree))) :limit)
+               1))))
+
+
+;; 
+===================================================================================+
+;; | delete-(all-)overlay
+;; 
+===================================================================================+
+
+;; delete live overlay
+(ert-deftest test-delete-overlay-1 ()
+  (test-with-overlay-in-buffer (ov 10 100)
+    (should (buffer-live-p (overlay-buffer ov)))
+    (delete-overlay ov)
+    (should-not (overlay-start ov))
+    (should-not (overlay-end ov))
+    (should-not (overlay-buffer ov))))
+
+;; delete dead overlay
+(ert-deftest test-delete-overlay-2 ()
+  (let ((ov (test-with-overlay-in-buffer (ov 10 100) ov)))
+    (should-not (overlay-start ov))
+    (should-not (overlay-end ov))
+    (should-not (overlay-buffer ov))
+    (should-not (delete-overlay ov))
+    (should-not (overlay-start ov))
+    (should-not (overlay-end ov))
+    (should-not (overlay-buffer ov))))
+
+(ert-deftest test-delete-all-overlay-1 ()
+  (with-temp-buffer
+    (should-not (delete-all-overlays))
+    (should-not (delete-all-overlays (current-buffer)))
+    (insert (make-string 100 ?\s))
+    (dotimes (i 10) (make-overlay i (1+ i)))
+    (should-not (delete-all-overlays (current-buffer)))
+    (should-not (delete-all-overlays))))
+
+
+;; 
+===================================================================================+
+;; | get-char-property(-and-overlay)
+;; 
+===================================================================================+
+
+;; FIXME: TBD
+
+
+;; 
+===================================================================================+
+;; | Moving by insertions
+;; 
+===================================================================================+
+
+(defmacro deftest-moving-insert-1 (id beg-end insert sbeg-send fa ra)
+  (cl-destructuring-bind (beg end ipos ilen sbeg send fa ra)
+      (append beg-end insert sbeg-send (list fa ra) nil)
+    `(ert-deftest ,(make-overlay-test-name 'moving-insert 1 id) ()
+       (test-with-overlay-in-buffer (ov ,beg ,end ,fa ,ra)
+         (should (= ,beg (overlay-start ov)))
+         (should (= ,end (overlay-end ov)))
+         (goto-char ,ipos)
+         (insert (make-string ,ilen ?x))
+         (should (= ,sbeg (overlay-start ov)))
+         (should (= ,send (overlay-end ov)))))))
+
+;; non-empty, no fa, no ra
+;; --------------------  OV      INS    RESULT
+(deftest-moving-insert-1 A (10 20) (15 3) (10 23) nil nil)
+(deftest-moving-insert-1 B (10 20) (20 4) (10 20) nil nil)
+(deftest-moving-insert-1 C (10 20) (5 5) (15 25) nil nil)
+(deftest-moving-insert-1 D (10 20) (10 3) (10 23) nil nil)
+(deftest-moving-insert-1 E (10 20) (20 4) (10 20) nil nil)
+
+;; non-empty no fa, ra
+(deftest-moving-insert-1 F (10 20) (15 3) (10 23) nil t)
+(deftest-moving-insert-1 G (10 20) (20 4) (10 24) nil t)
+(deftest-moving-insert-1 H (10 20) (5 5) (15 25) nil t)
+(deftest-moving-insert-1 I (10 20) (10 3) (10 23) nil t)
+(deftest-moving-insert-1 J (10 20) (20 4) (10 24) nil t)
+
+;; non-empty, fa, no r
+(deftest-moving-insert-1 K (10 20) (15 3) (10 23) t nil)
+(deftest-moving-insert-1 L (10 20) (20 4) (10 20) t nil)
+(deftest-moving-insert-1 M (10 20) (5 5) (15 25) t nil)
+(deftest-moving-insert-1 N (10 20) (10 3) (13 23) t nil)
+(deftest-moving-insert-1 O (10 20) (20 4) (10 20) t nil)
+
+;; This used to fail.
+(ert-deftest test-moving-insert-2-a ()
+  (with-temp-buffer
+    (insert (make-string 1 ?.))
+    (let ((ov (make-overlay 1 1 nil t nil)))
+      (insert "()")
+      (should (= 1 (overlay-end ov))))))
+
+;; non-empty, fa, ra
+(deftest-moving-insert-1 P (10 20) (15 3) (10 23) t t)
+(deftest-moving-insert-1 Q (10 20) (20 4) (10 24) t t)
+(deftest-moving-insert-1 R (10 20) (5 5) (15 25) t t)
+(deftest-moving-insert-1 S (10 20) (10 3) (13 23) t t)
+(deftest-moving-insert-1 T (10 20) (20 4) (10 24) t t)
+
+;; empty, no fa, no ra
+(deftest-moving-insert-1 U (15 15) (20 4) (15 15) nil nil)
+(deftest-moving-insert-1 V (15 15) (5 5) (20 20) nil nil)
+(deftest-moving-insert-1 W (15 15) (15 3) (15 15) nil nil)
+
+;; empty no fa, ra
+(deftest-moving-insert-1 X (15 15) (20 4) (15 15) nil t)
+(deftest-moving-insert-1 Y (15 15) (5 5) (20 20) nil t)
+(deftest-moving-insert-1 Z (15 15) (15 3) (15 18) nil t)
+
+;; empty, fa, no ra
+(deftest-moving-insert-1 a (15 15) (20 4) (15 15) t nil)
+(deftest-moving-insert-1 b (15 15) (5 5) (20 20) t nil)
+(deftest-moving-insert-1 c (15 15) (15 3) (15 15) t nil)
+
+;; empty, fa, ra
+(deftest-moving-insert-1 d (15 15) (20 4) (15 15) t t)
+(deftest-moving-insert-1 e (15 15) (5 5) (20 20) t t)
+(deftest-moving-insert-1 f (15 15) (15 3) (18 18) t t)
+
+;; Try to trigger a pathological case where the tree could become
+;; unordered due to an insert operation.
+
+(ert-deftest test-moving-insert-2 ()
+  (with-temp-buffer
+    (insert (make-string 1000 ?x))
+    (let ((root (make-overlay 50 75 nil    nil             'rear-advance))
+          (left (make-overlay 25 50 nil    'front-advance  'rear-advance))
+          (right (make-overlay 75 100 nil  nil             nil)))
+      ;;     [50] <--- start
+      ;;    /    \
+      ;; (25)    (75)
+      (delete-region 25 75)
+      ;;     [25]
+      ;;    /    \
+      ;; (25)    (25)
+      (should (= 25 (overlay-start root)))
+      (should (= 25 (overlay-end root)))
+      (should (= 25 (overlay-start left)))
+      (should (= 25 (overlay-end left)))
+      (should (= 25 (overlay-start right)))
+      (should (= 50 (overlay-end right)))
+      ;; Inserting at start should make left advance while right and
+      ;; root stay, thus we would have left > right .
+      (goto-char 25)
+      (insert (make-string 25 ?x))
+      ;;     [25]
+      ;;    /    \
+      ;; (50)    (25)
+      (should (= 25 (overlay-start root)))
+      (should (= 50 (overlay-end root)))
+      (should (= 50 (overlay-start left)))
+      (should (= 50 (overlay-end left)))
+      (should (= 25 (overlay-start right)))
+      (should (= 75 (overlay-end right)))
+      ;; Try to detect the error, by removing left.  The should fail
+      ;; an eassert, since it won't be found by a reular tree
+      ;; traversal - in theory.
+      (delete-overlay left)
+      (should (= 2 (length (overlays-in 1 (point-max))))))))
+
+
+
+;; 
+===================================================================================+
+;; | Moving by deletions
+;; 
+===================================================================================+
+
+(defmacro deftest-moving-delete-1 (id beg-end delete sbeg-send fa ra)
+  (cl-destructuring-bind (beg end dpos dlen sbeg send fa ra)
+      (append beg-end delete sbeg-send (list fa ra) nil)
+    `(ert-deftest ,(make-overlay-test-name 'moving-delete 1 id) ()
+       (test-with-overlay-in-buffer (ov ,beg ,end ,fa ,ra)
+         (should (= ,beg (overlay-start ov)))
+         (should (= ,end (overlay-end ov)))
+         (delete-region ,dpos (+ ,dpos ,dlen))
+         (should (= ,sbeg (overlay-start ov)))
+         (should (= ,send (overlay-end ov)))))))
+
+;; non-empty, no fa, no ra
+;; --------------------  OV      DEL    RESULT
+(deftest-moving-delete-1 A (10 20) (15 3) (10 17) nil nil)
+(deftest-moving-delete-1 B (10 20) (20 4) (10 20) nil nil)
+(deftest-moving-delete-1 C (10 20) (5 5) (5 15) nil nil)
+(deftest-moving-delete-1 D (10 20) (10 3) (10 17) nil nil)
+(deftest-moving-delete-1 E (10 20) (20 4) (10 20) nil nil)
+
+;; non-empty no fa, ra
+(deftest-moving-delete-1 F (10 20) (15 3) (10 17) nil t)
+(deftest-moving-delete-1 G (10 20) (20 4) (10 20) nil t)
+(deftest-moving-delete-1 H (10 20) (5 5) (5 15) nil t)
+(deftest-moving-delete-1 I (10 20) (10 3) (10 17) nil t)
+(deftest-moving-delete-1 J (10 20) (20 4) (10 20) nil t)
+
+;; non-empty, fa, no ra
+(deftest-moving-delete-1 K (10 20) (15 3) (10 17) t nil)
+(deftest-moving-delete-1 L (10 20) (20 4) (10 20) t nil)
+(deftest-moving-delete-1 M (10 20) (5 5) (5 15) t nil)
+(deftest-moving-delete-1 N (10 20) (10 3) (10 17) t nil)
+(deftest-moving-delete-1 O (10 20) (20 4) (10 20) t nil)
+
+;; non-empty, fa, ra
+(deftest-moving-delete-1 P (10 20) (15 3) (10 17) t t)
+(deftest-moving-delete-1 Q (10 20) (20 4) (10 20) t t)
+(deftest-moving-delete-1 R (10 20) (5 5) (5 15) t t)
+(deftest-moving-delete-1 S (10 20) (10 3) (10 17) t t)
+(deftest-moving-delete-1 T (10 20) (20 4) (10 20) t t)
+
+;; empty, no fa, no ra
+(deftest-moving-delete-1 U (15 15) (20 4) (15 15) nil nil)
+(deftest-moving-delete-1 V (15 15) (5 5) (10 10) nil nil)
+(deftest-moving-delete-1 W (15 15) (15 3) (15 15) nil nil)
+
+;; empty no fa, ra
+(deftest-moving-delete-1 X (15 15) (20 4) (15 15) nil t)
+(deftest-moving-delete-1 Y (15 15) (5 5) (10 10) nil t)
+(deftest-moving-delete-1 Z (15 15) (15 3) (15 15) nil t)
+
+;; empty, fa, no ra
+(deftest-moving-delete-1 a (15 15) (20 4) (15 15) t nil)
+(deftest-moving-delete-1 b (15 15) (5 5) (10 10) t nil)
+(deftest-moving-delete-1 c (15 15) (15 3) (15 15) t nil)
+
+;; empty, fa, ra
+(deftest-moving-delete-1 d (15 15) (20 4) (15 15) t t)
+(deftest-moving-delete-1 e (15 15) (5 5) (10 10) t t)
+(deftest-moving-delete-1 f (15 15) (15 3) (15 15) t t)
+
+
+;; 
+===================================================================================+
+;; | make-indirect-buffer
+;; 
+===================================================================================+
+
+;; Check if overlays are cloned/seperate from indirect buffer.
+(ert-deftest test-make-indirect-buffer-1 ()
+  (with-temp-buffer
+    (dotimes (_ 10) (make-overlay 1 1))
+    (let (indirect clone)
+      (unwind-protect
+          (progn
+            (setq indirect (make-indirect-buffer
+                            (current-buffer) "indirect"))
+            (with-current-buffer indirect
+              (should-not (overlays-in (point-min) (point-max)))
+              (dotimes (_ 20) (make-overlay 1 1))
+              (should (= 20 (length (overlays-in (point-min) (point-max)))))
+              (delete-all-overlays)
+              (should-not (overlays-in (point-min) (point-max))))
+            (should (= 10 (length (overlays-in (point-min) (point-max)))))
+            (setq clone (make-indirect-buffer
+                         (current-buffer) "clone" 'clone))
+            (with-current-buffer clone
+              (should (= 10 (length (overlays-in (point-min) (point-max)))))
+              (dotimes (_ 30) (make-overlay 1 1))
+              (should (= 40 (length (overlays-in (point-min) (point-max))))))
+            ;; back in temp buffer
+            (should (= 10 (length (overlays-in (point-min) (point-max)))))
+            (with-current-buffer clone
+              (mapc #'delete-overlay
+                    (seq-take (overlays-in (point-min) (point-max)) 10))
+              (should (= 30 (length (overlays-in (point-min) (point-max))))))
+            (should (= 10 (length (overlays-in (point-min) (point-max)))))
+            (delete-all-overlays)
+            (with-current-buffer clone
+              (should (= 30 (length (overlays-in (point-min) (point-max)))))))
+        (when (buffer-live-p clone)
+          (kill-buffer clone))
+        (when (buffer-live-p indirect)
+          (kill-buffer indirect))))))
+
+
+
+;; 
+===================================================================================+
+;; | buffer-swap-text
+;; 
+===================================================================================+
+
+(defmacro test-with-temp-buffers (vars &rest body)
+  (declare (indent 1) (debug (sexp &rest form)))
+  (if (null vars)
+      `(progn ,@body)
+    `(with-temp-buffer
+       (let ((,(car vars) (current-buffer)))
+         (test-with-temp-buffers ,(cdr vars) ,@body)))))
+
+;; basic
+(ert-deftest test-buffer-swap-text-1 ()
+  (test-with-temp-buffers (buffer other)
+    (with-current-buffer buffer
+      (let ((ov (make-overlay 1 1)))
+        (buffer-swap-text other)
+        (should-not (overlays-in 1 1))
+        (with-current-buffer other
+          (should (overlays-in 1 1))
+          (should (eq ov (car (overlays-in 1 1)))))))))
+
+;; properties
+(ert-deftest test-buffer-swap-text-1 ()
+  (test-with-temp-buffers (buffer other)
+    (with-current-buffer other
+      (overlay-put (make-overlay 1 1) 'buffer 'other))
+    (with-current-buffer buffer
+      (overlay-put (make-overlay 1 1) 'buffer 'buffer)
+      (buffer-swap-text other)
+      (should (= 1 (length (overlays-in 1 1))))
+      (should (eq (overlay-get (car (overlays-in 1 1)) 'buffer) 'other)))
+    (with-current-buffer other
+      (should (= 1 (length (overlays-in 1 1))))
+      (should (eq (overlay-get (car (overlays-in 1 1)) 'buffer) 'buffer)))))
+
+
+;; 
+===================================================================================+
+;; | priorities
+;; 
+===================================================================================+
+
+(ert-deftest test-overlay-priorities-1 ()
+  (with-temp-buffer
+    (insert " ")
+    (dotimes (i 10)
+      (let ((ov (make-overlay 1 2)))
+        (overlay-put ov 'priority i)
+        (overlay-put ov 'value i)))
+    (should (eq 9 (get-char-property 1 'value)))))
+
+(ert-deftest test-overlay-priorities-2 ()
+  (with-temp-buffer
+    (insert " ")
+    (dotimes (j 10)
+      (let* ((i (- 9 j))
+             (ov (make-overlay 1 2)))
+        (overlay-put ov 'priority i)
+        (overlay-put ov 'value i)))
+    (should (eq 9 (get-char-property 1 'value)))))
+
+
+;; 
+===================================================================================+
+;; | Other
+;; 
+===================================================================================+
+
+(defun test-overlay-regions ()
+  (sort (mapcar (lambda (ov)
+                  (cons (overlay-start ov)
+                        (overlay-end ov)))
+                (overlays-in (point-min)
+                             (point-max)))
+        (lambda (o1 o2)
+          (or (< (car o1) (car o2))
+              (and (= (car o1) (car o2))
+                   (< (cdr o1) (cdr o2)))))))
+
+;; This test used to fail.
+(ert-deftest overlay-complex-delete-with-offset ()
+  (with-temp-buffer
+    (let (todelete)
+      (insert (make-string 1000 ?\s))
+      (make-overlay 1 2 nil t nil)
+      (make-overlay 2 3 nil t nil)
+      (make-overlay 3 4 nil t nil)
+      (make-overlay 4 5 nil t nil)
+      (setq todelete (make-overlay 280 287 nil t nil))
+      (make-overlay 265 275 nil t nil)
+      (make-overlay 329 386 nil t nil)
+      (make-overlay 386 390 nil t nil)
+      (goto-char 50)
+      (delete-char 50)
+      (goto-char 1)
+      (delete-char 2)
+      (delete-overlay todelete)
+      (should (equal (test-overlay-regions)
+                     '((1 . 1) (1 . 1) (1 . 2) (2 . 3) (213 . 223) (277 . 334) 
(334 . 338)))))))
+
+;; This test used to fail.
+(ert-deftest overlay-complex-insert-1 ()
+  (with-temp-buffer
+    (insert "          ")
+    (make-overlay 8 11 nil nil t)
+    (make-overlay 2 7 nil nil nil)
+    (make-overlay 2 4 nil t nil)
+    (goto-char 1)
+    (insert "     ")
+    (should (equal (test-overlay-regions)
+                   '((7 . 9)
+                     (7 . 12)
+                     (13 . 16))))))
+
+;; This test used to fail.
+(ert-deftest overlay-complex-insert-2 ()
+  (with-temp-buffer
+    (insert (make-string 100 ?\s))
+    (make-overlay 77 7 nil nil t)
+    (make-overlay 21 53 nil t t)
+    (make-overlay 84 14 nil nil nil)
+    (make-overlay 38 69 nil t nil)
+    (make-overlay 93 15 nil nil t)
+    (make-overlay 73 48 nil t t)
+    (make-overlay 96 51 nil t t)
+    (make-overlay 6 43 nil t t)
+    (make-overlay 15 100 nil t t)
+    (make-overlay 22 17 nil nil nil)
+    (make-overlay 72 45 nil t nil)
+    (make-overlay 2 74 nil nil t)
+    (make-overlay 15 29 nil t t)
+    (make-overlay 17 34 nil t t)
+    (make-overlay 101 66 nil t nil)
+    (make-overlay 94 24 nil nil nil)
+    (goto-char 78)
+    (insert "           ")
+    (narrow-to-region 47 19)
+    (goto-char 46)
+    (widen)
+    (narrow-to-region 13 3)
+    (goto-char 9)
+    (delete-char 0)
+    (goto-char 11)
+    (insert "           ")
+    (goto-char 3)
+    (insert "          ")
+    (goto-char 8)
+    (insert "       ")
+    (goto-char 26)
+    (insert "  ")
+    (goto-char 14)
+    (widen)
+    (narrow-to-region 71 35)
+    (should
+     (equal (test-overlay-regions)
+            '((2 . 104)
+              (23 . 73)
+              (24 . 107)
+              (44 . 125)
+              (45 . 59)
+              (45 . 134)
+              (45 . 141)
+              (47 . 52)
+              (47 . 64)
+              (51 . 83)
+              (54 . 135)
+              (68 . 99))))))
+
+
+;; 
+===================================================================================+
+;; | Autogenerated insert/delete/narrow tests
+;; 
+===================================================================================+
+
+
+;; (defun test-overlay-generate-test (name)
+;;   (interactive)
+;;   (with-temp-buffer
+;;     (let ((forms nil)
+;;           (buffer-size 64)
+;;           (noverlays 16)
+;;           (nforms 32)
+;;           (dist '(0.5 0.4 0.1)))
+;;       (cl-labels ((brand ()
+;;                     (+ (point-min)
+;;                        (random (1+ (- (point-max) (point-min)))))))
+;;         (cl-macrolet ((push-eval (form)
+;;                         `(cl-destructuring-bind (&rest args)
+;;                              (list ,@(cdr form))
+;;                            (push (cons ',(car form) args) forms)
+;;                            (apply #',(car form) args))))
+;;           (push-eval (insert (make-string buffer-size ?.)))
+;;           (dotimes (_ noverlays)
+;;             (push-eval (make-overlay (brand) (brand)
+;;                                      nil
+;;                                      (= 0 (random 2))
+;;                                      (= 0 (random 2)))))
+;;           (dotimes (_ nforms)
+;;             (push-eval (goto-char (brand)))
+;;             (pcase (/ (random 100) 100.0)
+;;               ((and x (guard (< x (nth 0 dist))))
+;;                (push-eval (insert (make-string (random 16) ?.))))
+;;               ((and x (guard (< x (+ (nth 0 dist) (nth 1 dist)))))
+;;                (push-eval (delete-char (random (1+ (- (point-max) 
(point)))))))
+;;               (_
+;;                (push-eval (widen))
+;;                (push-eval (narrow-to-region (brand) (brand))))))
+;;           `(ert-deftest ,name ()
+;;              (with-temp-buffer
+;;                ,@(nreverse forms)
+;;                (should (equal (test-overlay-regions)
+;;                               ',(test-overlay-regions))))))))))
+
+;; (defun test-overlay-generate-tests (n)
+;;   (let ((namefmt "overlay-autogenerated-test-%d")
+;;         (standard-output (current-buffer))
+;;         (print-length nil)
+;;         (print-level nil)
+;;         (print-quoted t))
+;;     (dotimes (i n)
+;;       (pp (test-overlay-generate-test (intern (format namefmt i))))
+;;       (terpri))))
+
+;; (progn (random "4711") (test-overlay-generate-tests 64))
+
+(ert-deftest overlay-autogenerated-test-0 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 63 7 nil t t)
+    (make-overlay 47 9 nil nil nil)
+    (make-overlay 50 43 nil nil nil)
+    (make-overlay 20 53 nil nil t)
+    (make-overlay 62 4 nil nil t)
+    (make-overlay 40 27 nil t t)
+    (make-overlay 58 44 nil t t)
+    (make-overlay 46 38 nil nil nil)
+    (make-overlay 51 28 nil t nil)
+    (make-overlay 12 53 nil t t)
+    (make-overlay 52 60 nil nil nil)
+    (make-overlay 13 47 nil nil nil)
+    (make-overlay 16 31 nil nil nil)
+    (make-overlay 9 48 nil t t)
+    (make-overlay 43 29 nil nil t)
+    (make-overlay 48 13 nil t nil)
+    (goto-char 44)
+    (delete-char 15)
+    (goto-char 19)
+    (widen)
+    (narrow-to-region 20 8)
+    (goto-char 9)
+    (delete-char 3)
+    (goto-char 16)
+    (insert "..............")
+    (goto-char 12)
+    (delete-char 15)
+    (goto-char 12)
+    (delete-char 4)
+    (goto-char 12)
+    (delete-char 0)
+    (goto-char 12)
+    (insert "......")
+    (goto-char 13)
+    (delete-char 5)
+    (goto-char 8)
+    (insert "...")
+    (goto-char 10)
+    (insert ".............")
+    (goto-char 14)
+    (insert ".......")
+    (goto-char 25)
+    (delete-char 4)
+    (goto-char 26)
+    (insert "...............")
+    (goto-char 27)
+    (insert "...")
+    (goto-char 29)
+    (delete-char 7)
+    (goto-char 24)
+    (insert "...")
+    (goto-char 30)
+    (insert "..........")
+    (goto-char 29)
+    (widen)
+    (narrow-to-region 34 41)
+    (goto-char 40)
+    (delete-char 0)
+    (goto-char 35)
+    (delete-char 4)
+    (goto-char 36)
+    (widen)
+    (narrow-to-region 80 66)
+    (goto-char 74)
+    (delete-char 5)
+    (goto-char 69)
+    (delete-char 5)
+    (goto-char 70)
+    (widen)
+    (narrow-to-region 50 71)
+    (goto-char 66)
+    (insert "...............")
+    (goto-char 54)
+    (insert "...............")
+    (goto-char 84)
+    (insert "....")
+    (goto-char 72)
+    (insert "...........")
+    (goto-char 84)
+    (insert "..........")
+    (goto-char 102)
+    (insert "")
+    (goto-char 80)
+    (delete-char 25)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((4 . 99)
+        (7 . 100)
+        (48 . 99)
+        (48 . 99)
+        (48 . 99)
+        (49 . 99)
+        (49 . 99)
+        (51 . 80)
+        (51 . 99)
+        (80 . 99)
+        (80 . 99)
+        (80 . 99)
+        (99 . 99)
+        (99 . 99)
+        (99 . 99)
+        (99 . 99))))))
+
+(ert-deftest overlay-autogenerated-test-1 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 17 27 nil nil nil)
+    (make-overlay 13 28 nil nil t)
+    (make-overlay 8 56 nil nil nil)
+    (make-overlay 34 64 nil nil nil)
+    (make-overlay 51 4 nil t t)
+    (make-overlay 1 19 nil nil nil)
+    (make-overlay 53 59 nil nil t)
+    (make-overlay 25 13 nil nil nil)
+    (make-overlay 19 28 nil t nil)
+    (make-overlay 33 23 nil t nil)
+    (make-overlay 10 46 nil t t)
+    (make-overlay 18 39 nil nil nil)
+    (make-overlay 1 49 nil t nil)
+    (make-overlay 57 21 nil t t)
+    (make-overlay 10 58 nil t t)
+    (make-overlay 39 49 nil nil t)
+    (goto-char 37)
+    (delete-char 9)
+    (goto-char 3)
+    (insert "......")
+    (goto-char 38)
+    (delete-char 14)
+    (goto-char 18)
+    (insert "..........")
+    (goto-char 53)
+    (insert "....")
+    (goto-char 49)
+    (delete-char 10)
+    (goto-char 11)
+    (delete-char 12)
+    (goto-char 17)
+    (delete-char 22)
+    (goto-char 8)
+    (insert ".")
+    (goto-char 16)
+    (insert "........")
+    (goto-char 16)
+    (delete-char 5)
+    (goto-char 11)
+    (delete-char 0)
+    (goto-char 22)
+    (insert ".......")
+    (goto-char 18)
+    (delete-char 11)
+    (goto-char 16)
+    (delete-char 0)
+    (goto-char 9)
+    (insert "...........")
+    (goto-char 7)
+    (insert "...............")
+    (goto-char 2)
+    (insert ".......")
+    (goto-char 21)
+    (delete-char 11)
+    (goto-char 13)
+    (insert "..............")
+    (goto-char 17)
+    (delete-char 3)
+    (goto-char 21)
+    (insert "......")
+    (goto-char 15)
+    (delete-char 32)
+    (goto-char 10)
+    (insert "........")
+    (goto-char 25)
+    (widen)
+    (narrow-to-region 15 20)
+    (goto-char 17)
+    (insert ".............")
+    (goto-char 22)
+    (insert "............")
+    (goto-char 21)
+    (delete-char 8)
+    (goto-char 36)
+    (delete-char 1)
+    (goto-char 32)
+    (delete-char 2)
+    (goto-char 21)
+    (insert ".....")
+    (goto-char 31)
+    (insert "......")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 58)
+        (1 . 58))))))
+
+(ert-deftest overlay-autogenerated-test-2 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 15 59 nil t t)
+    (make-overlay 56 16 nil nil nil)
+    (make-overlay 65 51 nil t nil)
+    (make-overlay 14 24 nil t nil)
+    (make-overlay 28 9 nil t nil)
+    (make-overlay 58 50 nil t t)
+    (make-overlay 13 32 nil t t)
+    (make-overlay 12 21 nil t nil)
+    (make-overlay 60 23 nil t nil)
+    (make-overlay 39 38 nil nil t)
+    (make-overlay 15 64 nil t nil)
+    (make-overlay 17 21 nil nil t)
+    (make-overlay 46 23 nil t t)
+    (make-overlay 19 40 nil t nil)
+    (make-overlay 13 48 nil nil t)
+    (make-overlay 35 11 nil t nil)
+    (goto-char 41)
+    (delete-char 19)
+    (goto-char 45)
+    (insert "......")
+    (goto-char 3)
+    (delete-char 32)
+    (goto-char 19)
+    (insert "")
+    (goto-char 16)
+    (insert "...............")
+    (goto-char 2)
+    (insert "")
+    (goto-char 30)
+    (delete-char 0)
+    (goto-char 18)
+    (delete-char 17)
+    (goto-char 2)
+    (insert "...............")
+    (goto-char 12)
+    (insert "...")
+    (goto-char 2)
+    (insert ".............")
+    (goto-char 16)
+    (insert ".......")
+    (goto-char 15)
+    (insert ".......")
+    (goto-char 43)
+    (insert "......")
+    (goto-char 22)
+    (insert ".........")
+    (goto-char 25)
+    (delete-char 1)
+    (goto-char 38)
+    (insert "...............")
+    (goto-char 76)
+    (delete-char 3)
+    (goto-char 12)
+    (delete-char 5)
+    (goto-char 70)
+    (delete-char 9)
+    (goto-char 36)
+    (delete-char 4)
+    (goto-char 18)
+    (insert "...............")
+    (goto-char 52)
+    (delete-char 14)
+    (goto-char 23)
+    (insert "..........")
+    (goto-char 64)
+    (insert "...........")
+    (goto-char 68)
+    (delete-char 21)
+    (goto-char 71)
+    (insert "........")
+    (goto-char 28)
+    (delete-char 43)
+    (goto-char 25)
+    (insert "....")
+    (goto-char 2)
+    (insert "...............")
+    (goto-char 40)
+    (insert "....")
+    (goto-char 56)
+    (delete-char 2)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((51 . 51)
+        (51 . 51)
+        (51 . 51)
+        (51 . 51)
+        (51 . 51)
+        (51 . 51)
+        (51 . 51)
+        (51 . 51)
+        (51 . 51)
+        (51 . 51)
+        (51 . 51)
+        (51 . 51)
+        (51 . 51)
+        (51 . 51)
+        (51 . 51)
+        (51 . 58))))))
+
+(ert-deftest overlay-autogenerated-test-3 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 53 38 nil t nil)
+    (make-overlay 17 40 nil t t)
+    (make-overlay 64 26 nil t t)
+    (make-overlay 48 24 nil t nil)
+    (make-overlay 21 18 nil nil nil)
+    (make-overlay 2 20 nil nil t)
+    (make-overlay 43 26 nil t t)
+    (make-overlay 56 28 nil t nil)
+    (make-overlay 19 51 nil nil nil)
+    (make-overlay 39 61 nil t nil)
+    (make-overlay 59 12 nil t nil)
+    (make-overlay 65 7 nil t nil)
+    (make-overlay 41 7 nil t nil)
+    (make-overlay 62 50 nil t nil)
+    (make-overlay 7 10 nil t t)
+    (make-overlay 45 28 nil t nil)
+    (goto-char 13)
+    (insert "...")
+    (goto-char 37)
+    (widen)
+    (narrow-to-region 2 10)
+    (goto-char 8)
+    (delete-char 1)
+    (goto-char 3)
+    (delete-char 6)
+    (goto-char 2)
+    (insert "...........")
+    (goto-char 5)
+    (widen)
+    (narrow-to-region 55 70)
+    (goto-char 55)
+    (insert "......")
+    (goto-char 64)
+    (delete-char 12)
+    (goto-char 61)
+    (insert ".....")
+    (goto-char 64)
+    (insert "..............")
+    (goto-char 72)
+    (delete-char 6)
+    (goto-char 63)
+    (delete-char 12)
+    (goto-char 63)
+    (delete-char 2)
+    (goto-char 57)
+    (insert "..............")
+    (goto-char 68)
+    (insert "........")
+    (goto-char 77)
+    (delete-char 6)
+    (goto-char 77)
+    (insert ".............")
+    (goto-char 67)
+    (delete-char 0)
+    (goto-char 84)
+    (insert "........")
+    (goto-char 74)
+    (delete-char 12)
+    (goto-char 78)
+    (insert "...")
+    (goto-char 80)
+    (insert "............")
+    (goto-char 69)
+    (insert "......")
+    (goto-char 89)
+    (insert ".")
+    (goto-char 56)
+    (insert "....")
+    (goto-char 100)
+    (insert ".............")
+    (goto-char 114)
+    (delete-char 0)
+    (goto-char 61)
+    (widen)
+    (narrow-to-region 94 50)
+    (goto-char 55)
+    (insert "............")
+    (goto-char 53)
+    (insert ".............")
+    (goto-char 116)
+    (delete-char 3)
+    (goto-char 81)
+    (insert "...............")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((14 . 166)
+        (16 . 164)
+        (26 . 164)
+        (31 . 68)
+        (33 . 165)
+        (35 . 52)
+        (35 . 164)
+        (45 . 164)
+        (46 . 164))))))
+
+(ert-deftest overlay-autogenerated-test-4 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 25 15 nil nil t)
+    (make-overlay 8 13 nil nil nil)
+    (make-overlay 45 49 nil t t)
+    (make-overlay 22 13 nil t t)
+    (make-overlay 34 17 nil nil t)
+    (make-overlay 42 15 nil nil t)
+    (make-overlay 43 28 nil t t)
+    (make-overlay 3 28 nil t nil)
+    (make-overlay 32 61 nil nil t)
+    (make-overlay 30 64 nil t t)
+    (make-overlay 21 39 nil nil t)
+    (make-overlay 32 62 nil t nil)
+    (make-overlay 25 29 nil t nil)
+    (make-overlay 34 43 nil t nil)
+    (make-overlay 9 11 nil t nil)
+    (make-overlay 21 65 nil nil t)
+    (goto-char 21)
+    (delete-char 4)
+    (goto-char 25)
+    (insert "..")
+    (goto-char 53)
+    (insert "..")
+    (goto-char 2)
+    (insert "...............")
+    (goto-char 42)
+    (delete-char 36)
+    (goto-char 23)
+    (delete-char 12)
+    (goto-char 22)
+    (widen)
+    (narrow-to-region 30 32)
+    (goto-char 30)
+    (delete-char 0)
+    (goto-char 31)
+    (delete-char 1)
+    (goto-char 31)
+    (widen)
+    (narrow-to-region 28 27)
+    (goto-char 27)
+    (delete-char 1)
+    (goto-char 27)
+    (delete-char 0)
+    (goto-char 27)
+    (delete-char 0)
+    (goto-char 27)
+    (insert ".")
+    (goto-char 28)
+    (insert "......")
+    (goto-char 34)
+    (delete-char 0)
+    (goto-char 27)
+    (delete-char 5)
+    (goto-char 27)
+    (delete-char 1)
+    (goto-char 27)
+    (insert ".............")
+    (goto-char 30)
+    (insert "..............")
+    (goto-char 37)
+    (delete-char 15)
+    (goto-char 32)
+    (delete-char 2)
+    (goto-char 36)
+    (delete-char 1)
+    (goto-char 34)
+    (delete-char 0)
+    (goto-char 34)
+    (delete-char 1)
+    (goto-char 32)
+    (widen)
+    (narrow-to-region 24 19)
+    (goto-char 21)
+    (delete-char 1)
+    (goto-char 21)
+    (widen)
+    (narrow-to-region 11 38)
+    (goto-char 27)
+    (widen)
+    (narrow-to-region 20 22)
+    (goto-char 20)
+    (delete-char 1)
+    (goto-char 20)
+    (widen)
+    (narrow-to-region 36 4)
+    (goto-char 26)
+    (delete-char 9)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((18 . 25)
+        (21 . 21)
+        (21 . 21)
+        (21 . 22)
+        (21 . 22)
+        (21 . 27)
+        (21 . 27)
+        (22 . 25)
+        (22 . 27)
+        (22 . 28)
+        (26 . 27))))))
+
+(ert-deftest overlay-autogenerated-test-5 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 64 1 nil nil nil)
+    (make-overlay 38 43 nil nil nil)
+    (make-overlay 42 19 nil t nil)
+    (make-overlay 22 12 nil nil nil)
+    (make-overlay 12 30 nil t t)
+    (make-overlay 38 46 nil nil nil)
+    (make-overlay 18 23 nil nil nil)
+    (make-overlay 58 65 nil nil t)
+    (make-overlay 52 41 nil nil nil)
+    (make-overlay 12 26 nil nil nil)
+    (make-overlay 39 4 nil nil nil)
+    (make-overlay 20 1 nil nil t)
+    (make-overlay 36 60 nil nil nil)
+    (make-overlay 24 18 nil t nil)
+    (make-overlay 9 50 nil nil nil)
+    (make-overlay 19 17 nil t nil)
+    (goto-char 40)
+    (insert "")
+    (goto-char 64)
+    (insert ".............")
+    (goto-char 32)
+    (delete-char 40)
+    (goto-char 25)
+    (insert "...")
+    (goto-char 31)
+    (delete-char 1)
+    (goto-char 8)
+    (delete-char 14)
+    (goto-char 20)
+    (delete-char 5)
+    (goto-char 20)
+    (insert "...........")
+    (goto-char 20)
+    (insert ".........")
+    (goto-char 17)
+    (widen)
+    (narrow-to-region 11 21)
+    (goto-char 14)
+    (widen)
+    (narrow-to-region 9 24)
+    (goto-char 24)
+    (insert ".............")
+    (goto-char 30)
+    (widen)
+    (narrow-to-region 47 45)
+    (goto-char 47)
+    (insert ".")
+    (goto-char 46)
+    (widen)
+    (narrow-to-region 30 42)
+    (goto-char 32)
+    (delete-char 0)
+    (goto-char 34)
+    (insert ".......")
+    (goto-char 42)
+    (delete-char 4)
+    (goto-char 39)
+    (delete-char 6)
+    (goto-char 31)
+    (delete-char 6)
+    (goto-char 31)
+    (insert "............")
+    (goto-char 30)
+    (insert "......")
+    (goto-char 50)
+    (delete-char 0)
+    (goto-char 30)
+    (insert "....")
+    (goto-char 53)
+    (insert "............")
+    (goto-char 41)
+    (delete-char 12)
+    (goto-char 52)
+    (insert ".......")
+    (goto-char 56)
+    (insert "...........")
+    (goto-char 68)
+    (insert ".......")
+    (goto-char 52)
+    (insert "......")
+    (goto-char 71)
+    (delete-char 10)
+    (goto-char 47)
+    (insert "")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((20 . 89))))))
+
+(ert-deftest overlay-autogenerated-test-6 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 28 59 nil nil nil)
+    (make-overlay 36 21 nil t t)
+    (make-overlay 60 19 nil t nil)
+    (make-overlay 26 30 nil t nil)
+    (make-overlay 47 27 nil nil t)
+    (make-overlay 8 25 nil t t)
+    (make-overlay 57 43 nil t t)
+    (make-overlay 28 61 nil nil t)
+    (make-overlay 42 31 nil nil t)
+    (make-overlay 15 44 nil t nil)
+    (make-overlay 56 38 nil nil nil)
+    (make-overlay 39 44 nil nil t)
+    (make-overlay 50 6 nil t nil)
+    (make-overlay 6 19 nil t nil)
+    (make-overlay 50 44 nil t t)
+    (make-overlay 34 60 nil nil t)
+    (goto-char 27)
+    (insert "...............")
+    (goto-char 23)
+    (insert "..............")
+    (goto-char 50)
+    (widen)
+    (narrow-to-region 53 67)
+    (goto-char 60)
+    (delete-char 0)
+    (goto-char 54)
+    (insert "......")
+    (goto-char 64)
+    (delete-char 1)
+    (goto-char 66)
+    (delete-char 3)
+    (goto-char 58)
+    (insert ".............")
+    (goto-char 58)
+    (insert ".........")
+    (goto-char 76)
+    (insert "...........")
+    (goto-char 57)
+    (insert "....")
+    (goto-char 106)
+    (widen)
+    (narrow-to-region 5 45)
+    (goto-char 31)
+    (delete-char 8)
+    (goto-char 36)
+    (insert "...")
+    (goto-char 6)
+    (insert "........")
+    (goto-char 33)
+    (insert ".............")
+    (goto-char 38)
+    (delete-char 3)
+    (goto-char 28)
+    (delete-char 6)
+    (goto-char 42)
+    (widen)
+    (narrow-to-region 17 25)
+    (goto-char 19)
+    (insert "..............")
+    (goto-char 37)
+    (delete-char 1)
+    (goto-char 22)
+    (delete-char 9)
+    (goto-char 28)
+    (insert "..............")
+    (goto-char 37)
+    (delete-char 3)
+    (goto-char 18)
+    (insert "...............")
+    (goto-char 30)
+    (widen)
+    (narrow-to-region 68 25)
+    (goto-char 38)
+    (delete-char 22)
+    (goto-char 43)
+    (widen)
+    (narrow-to-region 47 96)
+    (goto-char 86)
+    (insert ".")
+    (goto-char 63)
+    (insert "......")
+    (goto-char 78)
+    (widen)
+    (narrow-to-region 61 27)
+    (goto-char 43)
+    (delete-char 8)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((14 . 38)
+        (14 . 132)
+        (16 . 43)
+        (38 . 118)
+        (38 . 126)
+        (38 . 142)
+        (44 . 115)
+        (45 . 129))))))
+
+(ert-deftest overlay-autogenerated-test-7 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 13 50 nil t nil)
+    (make-overlay 28 44 nil nil t)
+    (make-overlay 56 27 nil t nil)
+    (make-overlay 8 34 nil nil nil)
+    (make-overlay 22 8 nil nil t)
+    (make-overlay 8 28 nil t nil)
+    (make-overlay 65 31 nil nil t)
+    (make-overlay 44 8 nil nil nil)
+    (make-overlay 52 64 nil nil t)
+    (make-overlay 52 27 nil t t)
+    (make-overlay 47 32 nil nil nil)
+    (make-overlay 18 62 nil nil nil)
+    (make-overlay 18 24 nil t t)
+    (make-overlay 33 46 nil nil t)
+    (make-overlay 20 8 nil t nil)
+    (make-overlay 51 51 nil t nil)
+    (goto-char 2)
+    (delete-char 46)
+    (goto-char 12)
+    (delete-char 5)
+    (goto-char 2)
+    (delete-char 12)
+    (goto-char 2)
+    (insert "..")
+    (goto-char 2)
+    (widen)
+    (narrow-to-region 2 4)
+    (goto-char 4)
+    (insert "......")
+    (goto-char 4)
+    (widen)
+    (narrow-to-region 4 6)
+    (goto-char 5)
+    (insert "")
+    (goto-char 6)
+    (insert "...............")
+    (goto-char 9)
+    (insert "...")
+    (goto-char 7)
+    (delete-char 13)
+    (goto-char 8)
+    (delete-char 1)
+    (goto-char 9)
+    (insert "...............")
+    (goto-char 24)
+    (delete-char 1)
+    (goto-char 15)
+    (insert "...............")
+    (goto-char 16)
+    (insert "............")
+    (goto-char 17)
+    (delete-char 8)
+    (goto-char 36)
+    (widen)
+    (narrow-to-region 47 38)
+    (goto-char 43)
+    (delete-char 0)
+    (goto-char 46)
+    (delete-char 0)
+    (goto-char 40)
+    (delete-char 4)
+    (goto-char 39)
+    (insert ".......")
+    (goto-char 50)
+    (delete-char 0)
+    (goto-char 47)
+    (insert "...........")
+    (goto-char 45)
+    (insert ".....")
+    (goto-char 38)
+    (delete-char 3)
+    (goto-char 59)
+    (delete-char 1)
+    (goto-char 42)
+    (insert "...............")
+    (goto-char 65)
+    (insert "...........")
+    (goto-char 73)
+    (delete-char 13)
+    (goto-char 72)
+    (insert "....")
+    (goto-char 47)
+    (insert "..")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((2 . 81)
+        (2 . 81)
+        (2 . 81)
+        (2 . 81)
+        (2 . 81)
+        (81 . 81)
+        (81 . 81))))))
+
+(ert-deftest overlay-autogenerated-test-8 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 20 6 nil t nil)
+    (make-overlay 48 13 nil t nil)
+    (make-overlay 58 65 nil nil t)
+    (make-overlay 63 65 nil nil nil)
+    (make-overlay 42 40 nil t t)
+    (make-overlay 40 6 nil nil t)
+    (make-overlay 37 46 nil t nil)
+    (make-overlay 4 14 nil nil nil)
+    (make-overlay 58 44 nil t t)
+    (make-overlay 14 16 nil nil t)
+    (make-overlay 31 61 nil t nil)
+    (make-overlay 34 3 nil nil nil)
+    (make-overlay 11 16 nil t nil)
+    (make-overlay 19 42 nil nil t)
+    (make-overlay 30 9 nil nil t)
+    (make-overlay 63 52 nil t t)
+    (goto-char 57)
+    (delete-char 2)
+    (goto-char 8)
+    (insert "........")
+    (goto-char 30)
+    (insert "...........")
+    (goto-char 35)
+    (insert "...........")
+    (goto-char 66)
+    (insert "...............")
+    (goto-char 53)
+    (delete-char 15)
+    (goto-char 75)
+    (delete-char 10)
+    (goto-char 62)
+    (delete-char 21)
+    (goto-char 52)
+    (delete-char 10)
+    (goto-char 10)
+    (insert "............")
+    (goto-char 42)
+    (insert "...........")
+    (goto-char 68)
+    (insert ".............")
+    (goto-char 12)
+    (insert "........")
+    (goto-char 1)
+    (insert "...............")
+    (goto-char 89)
+    (insert "")
+    (goto-char 94)
+    (insert ".............")
+    (goto-char 57)
+    (insert "...........")
+    (goto-char 130)
+    (insert "...")
+    (goto-char 69)
+    (insert "..")
+    (goto-char 101)
+    (insert "......")
+    (goto-char 128)
+    (delete-char 13)
+    (goto-char 19)
+    (delete-char 100)
+    (goto-char 22)
+    (insert "..")
+    (goto-char 13)
+    (widen)
+    (narrow-to-region 30 16)
+    (goto-char 19)
+    (insert "..........")
+    (goto-char 22)
+    (delete-char 3)
+    (goto-char 19)
+    (insert ".........")
+    (goto-char 17)
+    (insert "..")
+    (goto-char 16)
+    (insert "............")
+    (goto-char 47)
+    (insert ".")
+    (goto-char 50)
+    (insert "..........")
+    (goto-char 70)
+    (delete-char 1)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((32 . 75)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 60)
+        (33 . 75)
+        (33 . 75)
+        (33 . 75)
+        (60 . 75))))))
+
+(ert-deftest overlay-autogenerated-test-9 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 58 13 nil nil nil)
+    (make-overlay 29 4 nil nil t)
+    (make-overlay 3 53 nil nil nil)
+    (make-overlay 31 9 nil t t)
+    (make-overlay 48 30 nil nil nil)
+    (make-overlay 43 50 nil nil nil)
+    (make-overlay 7 27 nil nil t)
+    (make-overlay 30 59 nil nil nil)
+    (make-overlay 42 25 nil nil t)
+    (make-overlay 15 13 nil t t)
+    (make-overlay 39 11 nil t t)
+    (make-overlay 21 62 nil t t)
+    (make-overlay 35 2 nil t nil)
+    (make-overlay 60 53 nil nil t)
+    (make-overlay 64 8 nil nil t)
+    (make-overlay 58 59 nil t t)
+    (goto-char 28)
+    (insert ".............")
+    (goto-char 28)
+    (insert "...............")
+    (goto-char 71)
+    (insert ".......")
+    (goto-char 65)
+    (insert "......")
+    (goto-char 3)
+    (delete-char 12)
+    (goto-char 79)
+    (delete-char 11)
+    (goto-char 65)
+    (widen)
+    (narrow-to-region 12 53)
+    (goto-char 38)
+    (insert ".......")
+    (goto-char 20)
+    (insert ".........")
+    (goto-char 27)
+    (insert "...........")
+    (goto-char 75)
+    (insert "........")
+    (goto-char 85)
+    (insert "............")
+    (goto-char 52)
+    (insert "..........")
+    (goto-char 16)
+    (delete-char 8)
+    (goto-char 15)
+    (insert "...............")
+    (goto-char 112)
+    (insert "")
+    (goto-char 61)
+    (insert "..")
+    (goto-char 29)
+    (delete-char 34)
+    (goto-char 52)
+    (delete-char 32)
+    (goto-char 43)
+    (insert "........")
+    (goto-char 45)
+    (insert "..")
+    (goto-char 35)
+    (insert "...........")
+    (goto-char 29)
+    (insert ".......")
+    (goto-char 75)
+    (widen)
+    (narrow-to-region 69 55)
+    (goto-char 67)
+    (delete-char 2)
+    (goto-char 66)
+    (delete-char 0)
+    (goto-char 62)
+    (delete-char 1)
+    (goto-char 61)
+    (delete-char 3)
+    (goto-char 63)
+    (insert ".")
+    (goto-char 56)
+    (insert ".....")
+    (goto-char 67)
+    (insert ".............")
+    (goto-char 76)
+    (delete-char 3)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((2 . 90)
+        (3 . 90)
+        (3 . 90)
+        (3 . 99)
+        (3 . 117)
+        (3 . 117)
+        (3 . 120)
+        (9 . 118)
+        (13 . 102))))))
+
+(ert-deftest overlay-autogenerated-test-10 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 16 60 nil nil nil)
+    (make-overlay 36 53 nil nil nil)
+    (make-overlay 44 39 nil t t)
+    (make-overlay 61 47 nil t t)
+    (make-overlay 58 39 nil nil t)
+    (make-overlay 23 54 nil nil t)
+    (make-overlay 65 59 nil t t)
+    (make-overlay 13 57 nil nil t)
+    (make-overlay 22 64 nil nil t)
+    (make-overlay 16 19 nil nil nil)
+    (make-overlay 16 1 nil nil t)
+    (make-overlay 28 21 nil t t)
+    (make-overlay 10 62 nil nil nil)
+    (make-overlay 12 18 nil nil t)
+    (make-overlay 15 5 nil nil t)
+    (make-overlay 36 31 nil nil t)
+    (goto-char 42)
+    (insert "...")
+    (goto-char 25)
+    (delete-char 28)
+    (goto-char 30)
+    (delete-char 10)
+    (goto-char 8)
+    (delete-char 9)
+    (goto-char 5)
+    (insert "........")
+    (goto-char 6)
+    (delete-char 2)
+    (goto-char 4)
+    (insert "")
+    (goto-char 21)
+    (insert ".............")
+    (goto-char 6)
+    (delete-char 33)
+    (goto-char 1)
+    (delete-char 1)
+    (goto-char 6)
+    (insert "..........")
+    (goto-char 8)
+    (insert "...........")
+    (goto-char 21)
+    (insert "........")
+    (goto-char 16)
+    (delete-char 18)
+    (goto-char 5)
+    (insert "...")
+    (goto-char 5)
+    (delete-char 8)
+    (goto-char 11)
+    (insert ".")
+    (goto-char 1)
+    (insert ".......")
+    (goto-char 9)
+    (delete-char 9)
+    (goto-char 5)
+    (insert "")
+    (goto-char 8)
+    (delete-char 0)
+    (goto-char 11)
+    (insert "..............")
+    (goto-char 12)
+    (insert "")
+    (goto-char 11)
+    (delete-char 8)
+    (goto-char 7)
+    (delete-char 3)
+    (goto-char 5)
+    (delete-char 3)
+    (goto-char 1)
+    (delete-char 8)
+    (goto-char 1)
+    (insert "....")
+    (goto-char 1)
+    (insert "..")
+    (goto-char 7)
+    (insert "...")
+    (goto-char 8)
+    (widen)
+    (narrow-to-region 9 11)
+    (goto-char 11)
+    (delete-char 0)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 10)
+        (1 . 10)
+        (1 . 10)
+        (1 . 10)
+        (1 . 10)
+        (1 . 12)
+        (1 . 12)
+        (1 . 12)
+        (10 . 10)
+        (10 . 10)
+        (10 . 12))))))
+
+(ert-deftest overlay-autogenerated-test-11 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 33 18 nil nil nil)
+    (make-overlay 56 38 nil t nil)
+    (make-overlay 2 45 nil nil t)
+    (make-overlay 19 55 nil nil t)
+    (make-overlay 28 42 nil t t)
+    (make-overlay 50 29 nil t nil)
+    (make-overlay 40 63 nil nil nil)
+    (make-overlay 13 2 nil nil t)
+    (make-overlay 26 7 nil t t)
+    (make-overlay 22 25 nil nil nil)
+    (make-overlay 14 14 nil t nil)
+    (make-overlay 15 39 nil t t)
+    (make-overlay 51 22 nil t t)
+    (make-overlay 58 5 nil t nil)
+    (make-overlay 16 10 nil nil nil)
+    (make-overlay 32 33 nil t nil)
+    (goto-char 40)
+    (delete-char 20)
+    (goto-char 45)
+    (delete-char 0)
+    (goto-char 6)
+    (insert "..")
+    (goto-char 45)
+    (insert "...")
+    (goto-char 26)
+    (insert "...............")
+    (goto-char 27)
+    (insert "...........")
+    (goto-char 38)
+    (insert "......")
+    (goto-char 62)
+    (insert "...............")
+    (goto-char 18)
+    (insert "...........")
+    (goto-char 99)
+    (widen)
+    (narrow-to-region 37 17)
+    (goto-char 29)
+    (delete-char 2)
+    (goto-char 28)
+    (delete-char 2)
+    (goto-char 17)
+    (insert ".....")
+    (goto-char 21)
+    (widen)
+    (narrow-to-region 34 96)
+    (goto-char 44)
+    (delete-char 22)
+    (goto-char 39)
+    (insert "..")
+    (goto-char 53)
+    (insert "...............")
+    (goto-char 58)
+    (insert ".............")
+    (goto-char 93)
+    (insert ".........")
+    (goto-char 78)
+    (widen)
+    (narrow-to-region 27 104)
+    (goto-char 93)
+    (delete-char 11)
+    (goto-char 59)
+    (insert "....")
+    (goto-char 59)
+    (insert "..............")
+    (goto-char 74)
+    (delete-char 5)
+    (goto-char 70)
+    (insert ".")
+    (goto-char 37)
+    (insert "...........")
+    (goto-char 34)
+    (delete-char 46)
+    (goto-char 49)
+    (insert "......")
+    (goto-char 55)
+    (insert "...")
+    (goto-char 42)
+    (insert "...")
+    (goto-char 70)
+    (delete-char 8)
+    (goto-char 48)
+    (delete-char 28)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((2 . 62)
+        (5 . 62)
+        (9 . 34)
+        (22 . 61)
+        (33 . 55)
+        (33 . 62)
+        (34 . 34)
+        (34 . 62))))))
+
+(ert-deftest overlay-autogenerated-test-12 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 18 50 nil nil nil)
+    (make-overlay 63 3 nil nil t)
+    (make-overlay 44 20 nil t t)
+    (make-overlay 58 38 nil nil t)
+    (make-overlay 3 17 nil t nil)
+    (make-overlay 31 62 nil t nil)
+    (make-overlay 12 17 nil t nil)
+    (make-overlay 17 52 nil nil nil)
+    (make-overlay 9 35 nil nil nil)
+    (make-overlay 17 38 nil nil nil)
+    (make-overlay 53 54 nil nil t)
+    (make-overlay 65 34 nil t nil)
+    (make-overlay 12 33 nil t nil)
+    (make-overlay 54 58 nil nil nil)
+    (make-overlay 42 26 nil t nil)
+    (make-overlay 2 4 nil t nil)
+    (goto-char 4)
+    (delete-char 26)
+    (goto-char 39)
+    (insert ".")
+    (goto-char 2)
+    (delete-char 14)
+    (goto-char 16)
+    (widen)
+    (narrow-to-region 19 1)
+    (goto-char 7)
+    (delete-char 9)
+    (goto-char 6)
+    (insert ".........")
+    (goto-char 6)
+    (insert "..........")
+    (goto-char 16)
+    (insert ".............")
+    (goto-char 36)
+    (delete-char 1)
+    (goto-char 4)
+    (insert "..........")
+    (goto-char 49)
+    (delete-char 2)
+    (goto-char 16)
+    (insert "............")
+    (goto-char 52)
+    (widen)
+    (narrow-to-region 36 38)
+    (goto-char 37)
+    (delete-char 1)
+    (goto-char 37)
+    (insert ".............")
+    (goto-char 46)
+    (insert ".")
+    (goto-char 40)
+    (delete-char 5)
+    (goto-char 45)
+    (delete-char 0)
+    (goto-char 46)
+    (delete-char 0)
+    (goto-char 40)
+    (insert "..........")
+    (goto-char 39)
+    (delete-char 4)
+    (goto-char 39)
+    (delete-char 3)
+    (goto-char 40)
+    (widen)
+    (narrow-to-region 8 9)
+    (goto-char 8)
+    (delete-char 1)
+    (goto-char 8)
+    (delete-char 0)
+    (goto-char 8)
+    (widen)
+    (narrow-to-region 45 15)
+    (goto-char 40)
+    (insert "...............")
+    (goto-char 29)
+    (delete-char 7)
+    (goto-char 30)
+    (delete-char 6)
+    (goto-char 21)
+    (delete-char 9)
+    (goto-char 22)
+    (insert "...............")
+    (goto-char 51)
+    (insert "..............")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((2 . 92)
+        (2 . 92)
+        (2 . 93)
+        (2 . 96)
+        (2 . 97)
+        (2 . 99))))))
+
+(ert-deftest overlay-autogenerated-test-13 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 18 30 nil t t)
+    (make-overlay 54 37 nil nil t)
+    (make-overlay 16 61 nil nil t)
+    (make-overlay 58 7 nil nil t)
+    (make-overlay 27 39 nil nil t)
+    (make-overlay 39 31 nil nil t)
+    (make-overlay 11 47 nil nil nil)
+    (make-overlay 47 40 nil t t)
+    (make-overlay 27 18 nil nil nil)
+    (make-overlay 33 26 nil nil t)
+    (make-overlay 55 4 nil t t)
+    (make-overlay 62 50 nil t t)
+    (make-overlay 47 65 nil t t)
+    (make-overlay 17 23 nil nil t)
+    (make-overlay 30 31 nil t nil)
+    (make-overlay 10 37 nil t nil)
+    (goto-char 8)
+    (delete-char 6)
+    (goto-char 56)
+    (delete-char 0)
+    (goto-char 28)
+    (insert ".........")
+    (goto-char 19)
+    (insert "..............")
+    (goto-char 4)
+    (delete-char 28)
+    (goto-char 49)
+    (delete-char 4)
+    (goto-char 2)
+    (insert "............")
+    (goto-char 10)
+    (delete-char 37)
+    (goto-char 19)
+    (delete-char 2)
+    (goto-char 20)
+    (delete-char 0)
+    (goto-char 16)
+    (insert "..")
+    (goto-char 8)
+    (widen)
+    (narrow-to-region 12 3)
+    (goto-char 10)
+    (delete-char 2)
+    (goto-char 9)
+    (insert "..")
+    (goto-char 12)
+    (insert "...............")
+    (goto-char 25)
+    (insert ".....")
+    (goto-char 10)
+    (widen)
+    (narrow-to-region 42 18)
+    (goto-char 20)
+    (insert ".......")
+    (goto-char 18)
+    (insert ".........")
+    (goto-char 55)
+    (delete-char 3)
+    (goto-char 48)
+    (insert ".......")
+    (goto-char 52)
+    (delete-char 6)
+    (goto-char 45)
+    (delete-char 11)
+    (goto-char 27)
+    (delete-char 13)
+    (goto-char 22)
+    (insert "...........")
+    (goto-char 19)
+    (delete-char 15)
+    (goto-char 20)
+    (delete-char 0)
+    (goto-char 23)
+    (widen)
+    (narrow-to-region 12 25)
+    (goto-char 16)
+    (insert "..........")
+    (goto-char 25)
+    (widen)
+    (narrow-to-region 2 38)
+    (goto-char 34)
+    (delete-char 0)
+    (goto-char 31)
+    (insert "...............")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((12 . 12)
+        (12 . 12)
+        (12 . 12)
+        (12 . 12)
+        (12 . 53)
+        (12 . 53)
+        (12 . 53)
+        (12 . 53)
+        (12 . 53)
+        (12 . 53)
+        (12 . 55))))))
+
+(ert-deftest overlay-autogenerated-test-14 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 29 37 nil t nil)
+    (make-overlay 15 44 nil nil nil)
+    (make-overlay 31 34 nil nil t)
+    (make-overlay 35 33 nil t t)
+    (make-overlay 4 27 nil t t)
+    (make-overlay 37 5 nil nil t)
+    (make-overlay 58 19 nil nil t)
+    (make-overlay 57 47 nil nil t)
+    (make-overlay 49 5 nil t t)
+    (make-overlay 21 59 nil t t)
+    (make-overlay 42 33 nil t nil)
+    (make-overlay 22 16 nil t t)
+    (make-overlay 9 51 nil t nil)
+    (make-overlay 20 24 nil nil t)
+    (make-overlay 21 7 nil t t)
+    (make-overlay 58 52 nil t t)
+    (goto-char 39)
+    (widen)
+    (narrow-to-region 55 54)
+    (goto-char 54)
+    (insert ".............")
+    (goto-char 55)
+    (insert "............")
+    (goto-char 66)
+    (delete-char 10)
+    (goto-char 62)
+    (insert "...............")
+    (goto-char 82)
+    (delete-char 2)
+    (goto-char 82)
+    (delete-char 0)
+    (goto-char 76)
+    (insert "..............")
+    (goto-char 60)
+    (insert ".............")
+    (goto-char 71)
+    (insert "...............")
+    (goto-char 122)
+    (delete-char 0)
+    (goto-char 93)
+    (delete-char 3)
+    (goto-char 108)
+    (delete-char 1)
+    (goto-char 121)
+    (insert "........")
+    (goto-char 92)
+    (insert "")
+    (goto-char 103)
+    (insert "..........")
+    (goto-char 85)
+    (delete-char 13)
+    (goto-char 116)
+    (delete-char 7)
+    (goto-char 103)
+    (widen)
+    (narrow-to-region 60 27)
+    (goto-char 28)
+    (delete-char 16)
+    (goto-char 35)
+    (insert ".......")
+    (goto-char 47)
+    (insert "........")
+    (goto-char 38)
+    (delete-char 1)
+    (goto-char 43)
+    (insert "..........")
+    (goto-char 59)
+    (insert "........")
+    (goto-char 57)
+    (insert "........")
+    (goto-char 36)
+    (insert "...........")
+    (goto-char 82)
+    (delete-char 11)
+    (goto-char 67)
+    (insert "..........")
+    (goto-char 46)
+    (delete-char 1)
+    (goto-char 47)
+    (insert "......")
+    (goto-char 69)
+    (delete-char 7)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((5 . 28)
+        (5 . 33)
+        (9 . 35)
+        (15 . 28)
+        (19 . 154)
+        (21 . 155)
+        (28 . 28)
+        (28 . 28)
+        (28 . 28)
+        (28 . 28)
+        (31 . 153)
+        (58 . 154))))))
+
+(ert-deftest overlay-autogenerated-test-15 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 3 19 nil t t)
+    (make-overlay 11 18 nil t nil)
+    (make-overlay 28 51 nil nil t)
+    (make-overlay 29 15 nil t t)
+    (make-overlay 46 57 nil t t)
+    (make-overlay 26 24 nil nil nil)
+    (make-overlay 29 43 nil nil nil)
+    (make-overlay 54 29 nil nil nil)
+    (make-overlay 34 52 nil t nil)
+    (make-overlay 10 32 nil nil nil)
+    (make-overlay 28 34 nil nil t)
+    (make-overlay 11 43 nil nil nil)
+    (make-overlay 18 50 nil t t)
+    (make-overlay 28 39 nil nil nil)
+    (make-overlay 62 62 nil t t)
+    (make-overlay 30 62 nil t nil)
+    (goto-char 30)
+    (widen)
+    (narrow-to-region 6 22)
+    (goto-char 9)
+    (insert "..")
+    (goto-char 12)
+    (insert ".............")
+    (goto-char 29)
+    (insert "..............")
+    (goto-char 47)
+    (insert "........")
+    (goto-char 46)
+    (insert ".............")
+    (goto-char 55)
+    (insert "..........")
+    (goto-char 62)
+    (insert "...............")
+    (goto-char 47)
+    (delete-char 49)
+    (goto-char 11)
+    (insert "...........")
+    (goto-char 40)
+    (delete-char 1)
+    (goto-char 27)
+    (insert "..............")
+    (goto-char 51)
+    (insert "......")
+    (goto-char 60)
+    (delete-char 10)
+    (goto-char 37)
+    (insert ".........")
+    (goto-char 69)
+    (insert ".")
+    (goto-char 36)
+    (insert "............")
+    (goto-char 75)
+    (insert ".............")
+    (goto-char 21)
+    (widen)
+    (narrow-to-region 44 21)
+    (goto-char 37)
+    (insert ".............")
+    (goto-char 55)
+    (widen)
+    (narrow-to-region 84 28)
+    (goto-char 58)
+    (widen)
+    (narrow-to-region 96 49)
+    (goto-char 62)
+    (delete-char 0)
+    (goto-char 72)
+    (delete-char 24)
+    (goto-char 61)
+    (widen)
+    (narrow-to-region 105 83)
+    (goto-char 96)
+    (widen)
+    (narrow-to-region 109 46)
+    (goto-char 95)
+    (delete-char 4)
+    (goto-char 81)
+    (insert ".")
+    (goto-char 51)
+    (delete-char 8)
+    (goto-char 52)
+    (insert ".")
+    (goto-char 60)
+    (delete-char 10)
+    (goto-char 50)
+    (insert "......")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((3 . 81)
+        (23 . 88)
+        (66 . 99)
+        (69 . 81)
+        (78 . 85)
+        (81 . 106)
+        (84 . 85)
+        (85 . 90)
+        (85 . 95)
+        (85 . 99)
+        (85 . 107)
+        (85 . 110)
+        (86 . 118)
+        (90 . 108))))))
+
+(ert-deftest overlay-autogenerated-test-16 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 3 55 nil t nil)
+    (make-overlay 45 47 nil nil nil)
+    (make-overlay 23 57 nil t t)
+    (make-overlay 64 55 nil nil nil)
+    (make-overlay 37 26 nil t t)
+    (make-overlay 29 38 nil nil t)
+    (make-overlay 33 3 nil t t)
+    (make-overlay 49 16 nil t nil)
+    (make-overlay 35 56 nil t t)
+    (make-overlay 9 39 nil nil nil)
+    (make-overlay 2 61 nil nil nil)
+    (make-overlay 59 26 nil nil t)
+    (make-overlay 5 50 nil t t)
+    (make-overlay 19 19 nil nil t)
+    (make-overlay 64 21 nil t nil)
+    (make-overlay 21 8 nil nil t)
+    (goto-char 17)
+    (insert ".....")
+    (goto-char 29)
+    (insert "............")
+    (goto-char 42)
+    (delete-char 38)
+    (goto-char 24)
+    (insert "")
+    (goto-char 9)
+    (delete-char 2)
+    (goto-char 20)
+    (insert "..")
+    (goto-char 27)
+    (delete-char 8)
+    (goto-char 25)
+    (delete-char 6)
+    (goto-char 8)
+    (delete-char 21)
+    (goto-char 9)
+    (insert "..............")
+    (goto-char 3)
+    (insert "....")
+    (goto-char 8)
+    (delete-char 18)
+    (goto-char 6)
+    (widen)
+    (narrow-to-region 5 8)
+    (goto-char 5)
+    (delete-char 3)
+    (goto-char 5)
+    (insert "...")
+    (goto-char 8)
+    (insert "..........")
+    (goto-char 5)
+    (insert "")
+    (goto-char 7)
+    (delete-char 8)
+    (goto-char 8)
+    (widen)
+    (narrow-to-region 2 2)
+    (goto-char 2)
+    (delete-char 0)
+    (goto-char 2)
+    (delete-char 0)
+    (goto-char 2)
+    (delete-char 0)
+    (goto-char 2)
+    (delete-char 0)
+    (goto-char 2)
+    (widen)
+    (narrow-to-region 10 3)
+    (goto-char 8)
+    (delete-char 2)
+    (goto-char 7)
+    (insert ".......")
+    (goto-char 8)
+    (delete-char 3)
+    (goto-char 12)
+    (insert "..")
+    (goto-char 9)
+    (delete-char 2)
+    (goto-char 7)
+    (insert "......")
+    (goto-char 15)
+    (insert "..........")
+    (goto-char 4)
+    (insert "........")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((2 . 13)
+        (13 . 13)
+        (13 . 13)
+        (13 . 13)
+        (13 . 13)
+        (13 . 13)
+        (13 . 13)
+        (13 . 36)
+        (13 . 36)
+        (13 . 36)
+        (13 . 36))))))
+
+(ert-deftest overlay-autogenerated-test-17 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 15 37 nil t nil)
+    (make-overlay 40 3 nil t t)
+    (make-overlay 61 19 nil t t)
+    (make-overlay 46 9 nil nil t)
+    (make-overlay 64 39 nil nil t)
+    (make-overlay 50 58 nil nil t)
+    (make-overlay 21 30 nil t nil)
+    (make-overlay 44 54 nil t nil)
+    (make-overlay 32 2 nil t nil)
+    (make-overlay 14 9 nil t t)
+    (make-overlay 41 40 nil t nil)
+    (make-overlay 17 26 nil t nil)
+    (make-overlay 57 50 nil t t)
+    (make-overlay 16 65 nil nil t)
+    (make-overlay 13 61 nil t t)
+    (make-overlay 39 64 nil nil t)
+    (goto-char 37)
+    (widen)
+    (narrow-to-region 12 1)
+    (goto-char 12)
+    (insert "......")
+    (goto-char 8)
+    (delete-char 4)
+    (goto-char 11)
+    (delete-char 3)
+    (goto-char 6)
+    (insert ".....")
+    (goto-char 6)
+    (widen)
+    (narrow-to-region 53 48)
+    (goto-char 48)
+    (delete-char 5)
+    (goto-char 48)
+    (widen)
+    (narrow-to-region 59 58)
+    (goto-char 59)
+    (delete-char 0)
+    (goto-char 58)
+    (insert "...")
+    (goto-char 60)
+    (insert "...............")
+    (goto-char 58)
+    (insert ".............")
+    (goto-char 67)
+    (insert ".....")
+    (goto-char 73)
+    (insert "")
+    (goto-char 68)
+    (insert ".....")
+    (goto-char 64)
+    (insert "....")
+    (goto-char 62)
+    (insert "..")
+    (goto-char 91)
+    (insert "..........")
+    (goto-char 80)
+    (insert "............")
+    (goto-char 100)
+    (delete-char 21)
+    (goto-char 74)
+    (insert "...")
+    (goto-char 60)
+    (delete-char 30)
+    (goto-char 64)
+    (widen)
+    (narrow-to-region 71 23)
+    (goto-char 53)
+    (delete-char 11)
+    (goto-char 23)
+    (delete-char 21)
+    (goto-char 39)
+    (delete-char 0)
+    (goto-char 35)
+    (insert "")
+    (goto-char 35)
+    (insert ".........")
+    (goto-char 30)
+    (insert "...........")
+    (goto-char 35)
+    (insert "..")
+    (goto-char 37)
+    (delete-char 1)
+    (goto-char 28)
+    (delete-char 3)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((13 . 27)
+        (17 . 67)
+        (20 . 71)
+        (23 . 23)
+        (23 . 24)
+        (23 . 67)
+        (23 . 70)
+        (23 . 70)
+        (27 . 41)
+        (28 . 41)
+        (28 . 41))))))
+
+(ert-deftest overlay-autogenerated-test-18 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 43 52 nil nil t)
+    (make-overlay 27 29 nil nil t)
+    (make-overlay 24 18 nil nil nil)
+    (make-overlay 39 52 nil nil nil)
+    (make-overlay 33 62 nil t t)
+    (make-overlay 16 7 nil t nil)
+    (make-overlay 47 39 nil nil t)
+    (make-overlay 59 41 nil nil nil)
+    (make-overlay 22 55 nil nil t)
+    (make-overlay 60 16 nil t t)
+    (make-overlay 55 20 nil nil t)
+    (make-overlay 25 12 nil nil t)
+    (make-overlay 26 2 nil nil t)
+    (make-overlay 17 35 nil nil t)
+    (make-overlay 46 41 nil t nil)
+    (make-overlay 57 53 nil t t)
+    (goto-char 52)
+    (insert "")
+    (goto-char 4)
+    (delete-char 21)
+    (goto-char 17)
+    (insert "")
+    (goto-char 35)
+    (insert "...............")
+    (goto-char 8)
+    (insert "...............")
+    (goto-char 9)
+    (insert "........")
+    (goto-char 73)
+    (delete-char 9)
+    (goto-char 62)
+    (insert "...............")
+    (goto-char 27)
+    (widen)
+    (narrow-to-region 34 84)
+    (goto-char 81)
+    (insert "...........")
+    (goto-char 48)
+    (insert "...")
+    (goto-char 74)
+    (insert ".......")
+    (goto-char 41)
+    (widen)
+    (narrow-to-region 37 105)
+    (goto-char 75)
+    (insert "...............")
+    (goto-char 47)
+    (insert "..........")
+    (goto-char 99)
+    (delete-char 13)
+    (goto-char 105)
+    (delete-char 4)
+    (goto-char 94)
+    (delete-char 5)
+    (goto-char 96)
+    (insert "..............")
+    (goto-char 74)
+    (insert "")
+    (goto-char 121)
+    (insert "...")
+    (goto-char 102)
+    (insert "...")
+    (goto-char 64)
+    (insert "......")
+    (goto-char 67)
+    (insert "...")
+    (goto-char 95)
+    (delete-char 19)
+    (goto-char 37)
+    (insert "..........")
+    (goto-char 50)
+    (widen)
+    (narrow-to-region 67 96)
+    (goto-char 88)
+    (insert "..........")
+    (goto-char 91)
+    (insert ".............")
+    (goto-char 70)
+    (delete-char 8)
+    (goto-char 111)
+    (widen)
+    (narrow-to-region 72 103)
+    (goto-char 101)
+    (insert "...............")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((4 . 119)
+        (4 . 119)
+        (4 . 162)
+        (35 . 162)
+        (51 . 78)
+        (53 . 162)
+        (55 . 78)
+        (79 . 162))))))
+
+(ert-deftest overlay-autogenerated-test-19 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 19 31 nil t t)
+    (make-overlay 40 5 nil nil nil)
+    (make-overlay 13 41 nil t t)
+    (make-overlay 41 43 nil nil t)
+    (make-overlay 7 60 nil t nil)
+    (make-overlay 40 23 nil t nil)
+    (make-overlay 32 15 nil t t)
+    (make-overlay 12 45 nil nil nil)
+    (make-overlay 18 1 nil nil nil)
+    (make-overlay 58 32 nil t t)
+    (make-overlay 30 3 nil t t)
+    (make-overlay 43 61 nil t nil)
+    (make-overlay 54 57 nil nil t)
+    (make-overlay 34 14 nil t t)
+    (make-overlay 26 49 nil nil t)
+    (make-overlay 54 49 nil nil t)
+    (goto-char 28)
+    (insert "........")
+    (goto-char 32)
+    (insert "...........")
+    (goto-char 78)
+    (delete-char 6)
+    (goto-char 37)
+    (delete-char 0)
+    (goto-char 49)
+    (insert ".........")
+    (goto-char 40)
+    (widen)
+    (narrow-to-region 8 30)
+    (goto-char 20)
+    (delete-char 4)
+    (goto-char 23)
+    (delete-char 1)
+    (goto-char 10)
+    (insert ".")
+    (goto-char 22)
+    (delete-char 2)
+    (goto-char 22)
+    (insert "......")
+    (goto-char 17)
+    (insert "..........")
+    (goto-char 34)
+    (delete-char 0)
+    (goto-char 21)
+    (insert "............")
+    (goto-char 45)
+    (delete-char 7)
+    (goto-char 39)
+    (insert "...............")
+    (goto-char 29)
+    (insert "........")
+    (goto-char 9)
+    (delete-char 3)
+    (goto-char 63)
+    (delete-char 1)
+    (goto-char 33)
+    (insert "........")
+    (goto-char 16)
+    (delete-char 36)
+    (goto-char 20)
+    (delete-char 2)
+    (goto-char 28)
+    (delete-char 0)
+    (goto-char 24)
+    (insert "...........")
+    (goto-char 43)
+    (insert "..........")
+    (goto-char 30)
+    (delete-char 1)
+    (goto-char 40)
+    (delete-char 13)
+    (goto-char 22)
+    (delete-char 19)
+    (goto-char 10)
+    (delete-char 8)
+    (goto-char 14)
+    (delete-char 0)
+    (goto-char 12)
+    (delete-char 2)
+    (goto-char 11)
+    (delete-char 0)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 12)
+        (3 . 40)
+        (5 . 50)
+        (7 . 69)
+        (10 . 42)
+        (10 . 44)
+        (10 . 51)
+        (10 . 55))))))
+
+(ert-deftest overlay-autogenerated-test-20 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 44 42 nil t t)
+    (make-overlay 47 1 nil nil nil)
+    (make-overlay 24 48 nil nil nil)
+    (make-overlay 62 50 nil nil t)
+    (make-overlay 54 38 nil nil nil)
+    (make-overlay 3 9 nil nil nil)
+    (make-overlay 61 28 nil t nil)
+    (make-overlay 33 33 nil nil t)
+    (make-overlay 37 37 nil t nil)
+    (make-overlay 20 13 nil nil t)
+    (make-overlay 54 36 nil t nil)
+    (make-overlay 18 58 nil nil t)
+    (make-overlay 55 3 nil nil t)
+    (make-overlay 23 21 nil t t)
+    (make-overlay 47 55 nil t t)
+    (make-overlay 50 12 nil nil nil)
+    (goto-char 11)
+    (delete-char 46)
+    (goto-char 7)
+    (delete-char 3)
+    (goto-char 14)
+    (delete-char 1)
+    (goto-char 14)
+    (insert "......")
+    (goto-char 14)
+    (delete-char 4)
+    (goto-char 12)
+    (widen)
+    (narrow-to-region 11 12)
+    (goto-char 11)
+    (insert "...")
+    (goto-char 13)
+    (delete-char 1)
+    (goto-char 14)
+    (insert ".")
+    (goto-char 13)
+    (delete-char 2)
+    (goto-char 11)
+    (delete-char 2)
+    (goto-char 11)
+    (insert "")
+    (goto-char 11)
+    (delete-char 0)
+    (goto-char 11)
+    (delete-char 0)
+    (goto-char 11)
+    (delete-char 0)
+    (goto-char 11)
+    (insert ".")
+    (goto-char 11)
+    (insert ".")
+    (goto-char 12)
+    (insert "......")
+    (goto-char 14)
+    (delete-char 2)
+    (goto-char 11)
+    (delete-char 2)
+    (goto-char 14)
+    (insert "............")
+    (goto-char 19)
+    (insert "..............")
+    (goto-char 29)
+    (insert ".....")
+    (goto-char 42)
+    (delete-char 1)
+    (goto-char 22)
+    (insert ".....")
+    (goto-char 19)
+    (insert "..............")
+    (goto-char 42)
+    (insert ".....")
+    (goto-char 63)
+    (widen)
+    (narrow-to-region 26 42)
+    (goto-char 36)
+    (insert "..........")
+    (goto-char 40)
+    (delete-char 11)
+    (goto-char 26)
+    (delete-char 13)
+    (goto-char 28)
+    (delete-char 0)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((8 . 56))))))
+
+(ert-deftest overlay-autogenerated-test-21 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 65 15 nil nil nil)
+    (make-overlay 52 31 nil nil nil)
+    (make-overlay 12 51 nil t t)
+    (make-overlay 42 20 nil nil t)
+    (make-overlay 51 48 nil nil nil)
+    (make-overlay 59 28 nil t t)
+    (make-overlay 51 53 nil t nil)
+    (make-overlay 50 59 nil nil t)
+    (make-overlay 24 40 nil t nil)
+    (make-overlay 51 61 nil nil nil)
+    (make-overlay 12 58 nil nil t)
+    (make-overlay 64 17 nil t t)
+    (make-overlay 26 38 nil t t)
+    (make-overlay 23 36 nil nil nil)
+    (make-overlay 57 50 nil nil nil)
+    (make-overlay 42 15 nil nil t)
+    (goto-char 14)
+    (insert "............")
+    (goto-char 37)
+    (insert ".")
+    (goto-char 73)
+    (insert "..........")
+    (goto-char 17)
+    (delete-char 31)
+    (goto-char 21)
+    (delete-char 35)
+    (goto-char 9)
+    (delete-char 0)
+    (goto-char 7)
+    (delete-char 2)
+    (goto-char 1)
+    (insert "")
+    (goto-char 5)
+    (insert ".......")
+    (goto-char 8)
+    (insert "....")
+    (goto-char 27)
+    (delete-char 0)
+    (goto-char 10)
+    (insert ".............")
+    (goto-char 24)
+    (delete-char 16)
+    (goto-char 14)
+    (insert ".............")
+    (goto-char 25)
+    (delete-char 11)
+    (goto-char 3)
+    (insert "........")
+    (goto-char 38)
+    (insert "............")
+    (goto-char 41)
+    (insert "..............")
+    (goto-char 56)
+    (delete-char 3)
+    (goto-char 15)
+    (widen)
+    (narrow-to-region 16 53)
+    (goto-char 19)
+    (widen)
+    (narrow-to-region 18 33)
+    (goto-char 32)
+    (insert "......")
+    (goto-char 38)
+    (delete-char 1)
+    (goto-char 19)
+    (widen)
+    (narrow-to-region 11 11)
+    (goto-char 11)
+    (insert ".........")
+    (goto-char 11)
+    (insert ".........")
+    (goto-char 20)
+    (widen)
+    (narrow-to-region 22 69)
+    (goto-char 49)
+    (insert ".........")
+    (goto-char 54)
+    (delete-char 22)
+    (goto-char 44)
+    (insert "........")
+    (goto-char 40)
+    (delete-char 7)
+    (goto-char 29)
+    (delete-char 22)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33)
+        (33 . 33))))))
+
+(ert-deftest overlay-autogenerated-test-22 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 12 14 nil nil t)
+    (make-overlay 54 7 nil nil t)
+    (make-overlay 8 3 nil nil nil)
+    (make-overlay 42 32 nil nil nil)
+    (make-overlay 10 27 nil t t)
+    (make-overlay 50 28 nil t t)
+    (make-overlay 39 35 nil nil nil)
+    (make-overlay 12 4 nil t t)
+    (make-overlay 29 54 nil nil nil)
+    (make-overlay 14 52 nil t t)
+    (make-overlay 9 15 nil t nil)
+    (make-overlay 44 11 nil nil nil)
+    (make-overlay 46 29 nil t t)
+    (make-overlay 40 58 nil t t)
+    (make-overlay 40 61 nil t nil)
+    (make-overlay 13 59 nil nil t)
+    (goto-char 32)
+    (insert ".............")
+    (goto-char 25)
+    (delete-char 10)
+    (goto-char 3)
+    (insert ".............")
+    (goto-char 33)
+    (delete-char 32)
+    (goto-char 39)
+    (widen)
+    (narrow-to-region 41 46)
+    (goto-char 43)
+    (delete-char 2)
+    (goto-char 42)
+    (delete-char 2)
+    (goto-char 42)
+    (insert "...")
+    (goto-char 43)
+    (delete-char 1)
+    (goto-char 42)
+    (widen)
+    (narrow-to-region 8 46)
+    (goto-char 25)
+    (delete-char 7)
+    (goto-char 12)
+    (delete-char 10)
+    (goto-char 23)
+    (insert "...............")
+    (goto-char 41)
+    (delete-char 3)
+    (goto-char 17)
+    (insert ".........")
+    (goto-char 37)
+    (insert "...............")
+    (goto-char 53)
+    (delete-char 7)
+    (goto-char 53)
+    (delete-char 0)
+    (goto-char 42)
+    (widen)
+    (narrow-to-region 20 54)
+    (goto-char 20)
+    (delete-char 28)
+    (goto-char 23)
+    (insert "..........")
+    (goto-char 30)
+    (insert "......")
+    (goto-char 26)
+    (delete-char 1)
+    (goto-char 27)
+    (widen)
+    (narrow-to-region 40 37)
+    (goto-char 37)
+    (insert ".....")
+    (goto-char 41)
+    (widen)
+    (narrow-to-region 13 37)
+    (goto-char 29)
+    (insert "...........")
+    (goto-char 33)
+    (delete-char 7)
+    (goto-char 33)
+    (delete-char 8)
+    (goto-char 20)
+    (insert "")
+    (goto-char 23)
+    (delete-char 7)
+    (goto-char 14)
+    (widen)
+    (narrow-to-region 33 33)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((15 . 39)
+        (16 . 38)
+        (16 . 39))))))
+
+(ert-deftest overlay-autogenerated-test-23 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 51 32 nil t t)
+    (make-overlay 13 61 nil t nil)
+    (make-overlay 47 19 nil nil t)
+    (make-overlay 11 30 nil nil nil)
+    (make-overlay 50 26 nil t t)
+    (make-overlay 64 13 nil t t)
+    (make-overlay 29 8 nil t t)
+    (make-overlay 25 42 nil t t)
+    (make-overlay 33 28 nil t t)
+    (make-overlay 54 7 nil nil nil)
+    (make-overlay 30 59 nil nil nil)
+    (make-overlay 65 50 nil t t)
+    (make-overlay 64 15 nil t nil)
+    (make-overlay 16 35 nil nil nil)
+    (make-overlay 40 36 nil nil t)
+    (make-overlay 31 35 nil t nil)
+    (goto-char 61)
+    (insert "......")
+    (goto-char 55)
+    (delete-char 2)
+    (goto-char 20)
+    (insert "..............")
+    (goto-char 56)
+    (insert "............")
+    (goto-char 48)
+    (delete-char 6)
+    (goto-char 9)
+    (delete-char 54)
+    (goto-char 20)
+    (delete-char 2)
+    (goto-char 16)
+    (delete-char 12)
+    (goto-char 18)
+    (insert ".............")
+    (goto-char 24)
+    (delete-char 7)
+    (goto-char 5)
+    (delete-char 2)
+    (goto-char 1)
+    (insert ".......")
+    (goto-char 1)
+    (insert ".......")
+    (goto-char 33)
+    (insert "")
+    (goto-char 4)
+    (insert "..")
+    (goto-char 5)
+    (widen)
+    (narrow-to-region 17 4)
+    (goto-char 13)
+    (insert ".")
+    (goto-char 8)
+    (insert "............")
+    (goto-char 9)
+    (delete-char 3)
+    (goto-char 4)
+    (widen)
+    (narrow-to-region 32 32)
+    (goto-char 32)
+    (delete-char 0)
+    (goto-char 32)
+    (delete-char 0)
+    (goto-char 32)
+    (delete-char 0)
+    (goto-char 32)
+    (insert "...............")
+    (goto-char 43)
+    (delete-char 4)
+    (goto-char 32)
+    (delete-char 1)
+    (goto-char 40)
+    (widen)
+    (narrow-to-region 33 19)
+    (goto-char 27)
+    (insert "........")
+    (goto-char 38)
+    (delete-char 2)
+    (goto-char 26)
+    (insert "")
+    (goto-char 33)
+    (delete-char 1)
+    (goto-char 27)
+    (insert ".")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((38 . 56))))))
+
+(ert-deftest overlay-autogenerated-test-24 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 63 8 nil t t)
+    (make-overlay 10 13 nil nil t)
+    (make-overlay 40 38 nil nil nil)
+    (make-overlay 21 34 nil t t)
+    (make-overlay 55 29 nil nil nil)
+    (make-overlay 36 65 nil t t)
+    (make-overlay 29 12 nil t nil)
+    (make-overlay 41 3 nil nil t)
+    (make-overlay 20 9 nil t t)
+    (make-overlay 52 42 nil t t)
+    (make-overlay 21 56 nil nil t)
+    (make-overlay 25 65 nil nil nil)
+    (make-overlay 38 4 nil t t)
+    (make-overlay 48 23 nil t t)
+    (make-overlay 52 9 nil nil t)
+    (make-overlay 48 19 nil nil nil)
+    (goto-char 43)
+    (delete-char 8)
+    (goto-char 30)
+    (delete-char 16)
+    (goto-char 7)
+    (insert "...")
+    (goto-char 14)
+    (delete-char 5)
+    (goto-char 36)
+    (delete-char 0)
+    (goto-char 9)
+    (insert "...............")
+    (goto-char 13)
+    (delete-char 17)
+    (goto-char 16)
+    (delete-char 2)
+    (goto-char 9)
+    (insert "")
+    (goto-char 11)
+    (delete-char 5)
+    (goto-char 18)
+    (insert "........")
+    (goto-char 15)
+    (insert "....")
+    (goto-char 16)
+    (delete-char 14)
+    (goto-char 20)
+    (insert ".")
+    (goto-char 25)
+    (delete-char 1)
+    (goto-char 14)
+    (delete-char 14)
+    (goto-char 3)
+    (delete-char 7)
+    (goto-char 3)
+    (delete-char 4)
+    (goto-char 1)
+    (insert "...........")
+    (goto-char 9)
+    (insert ".......")
+    (goto-char 5)
+    (delete-char 7)
+    (goto-char 12)
+    (insert ".........")
+    (goto-char 2)
+    (delete-char 4)
+    (goto-char 3)
+    (widen)
+    (narrow-to-region 14 6)
+    (goto-char 9)
+    (insert "..........")
+    (goto-char 13)
+    (delete-char 8)
+    (goto-char 7)
+    (delete-char 7)
+    (goto-char 7)
+    (insert "..")
+    (goto-char 9)
+    (insert ".............")
+    (goto-char 9)
+    (insert "..........")
+    (goto-char 21)
+    (insert "...............")
+    (goto-char 42)
+    (insert ".........")
+    (should
+     (equal
+      (test-overlay-regions)
+      'nil))))
+
+(ert-deftest overlay-autogenerated-test-25 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 24 8 nil nil t)
+    (make-overlay 41 16 nil t nil)
+    (make-overlay 3 16 nil nil nil)
+    (make-overlay 26 42 nil nil nil)
+    (make-overlay 32 45 nil nil t)
+    (make-overlay 34 19 nil nil nil)
+    (make-overlay 37 54 nil nil t)
+    (make-overlay 44 34 nil t nil)
+    (make-overlay 49 40 nil t t)
+    (make-overlay 29 34 nil t nil)
+    (make-overlay 54 16 nil t t)
+    (make-overlay 29 4 nil t nil)
+    (make-overlay 44 57 nil nil nil)
+    (make-overlay 5 32 nil nil nil)
+    (make-overlay 12 33 nil nil t)
+    (make-overlay 38 29 nil t nil)
+    (goto-char 12)
+    (delete-char 53)
+    (goto-char 1)
+    (delete-char 6)
+    (goto-char 5)
+    (widen)
+    (narrow-to-region 6 1)
+    (goto-char 6)
+    (insert "......")
+    (goto-char 10)
+    (insert "...............")
+    (goto-char 17)
+    (delete-char 5)
+    (goto-char 7)
+    (insert ".....")
+    (goto-char 8)
+    (insert "...............")
+    (goto-char 4)
+    (insert ".....")
+    (goto-char 44)
+    (widen)
+    (narrow-to-region 18 11)
+    (goto-char 15)
+    (delete-char 1)
+    (goto-char 17)
+    (delete-char 0)
+    (goto-char 13)
+    (delete-char 3)
+    (goto-char 14)
+    (insert "..")
+    (goto-char 16)
+    (insert "..")
+    (goto-char 15)
+    (delete-char 3)
+    (goto-char 13)
+    (delete-char 0)
+    (goto-char 14)
+    (insert "..........")
+    (goto-char 19)
+    (insert ".")
+    (goto-char 23)
+    (delete-char 1)
+    (goto-char 12)
+    (widen)
+    (narrow-to-region 23 40)
+    (goto-char 35)
+    (insert "....")
+    (goto-char 33)
+    (insert "..........")
+    (goto-char 37)
+    (delete-char 16)
+    (goto-char 37)
+    (delete-char 0)
+    (goto-char 23)
+    (widen)
+    (narrow-to-region 30 8)
+    (goto-char 29)
+    (delete-char 0)
+    (goto-char 15)
+    (delete-char 15)
+    (goto-char 9)
+    (insert "...........")
+    (goto-char 9)
+    (delete-char 1)
+    (goto-char 22)
+    (delete-char 3)
+    (goto-char 10)
+    (insert ".........")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 30)
+        (1 . 30)
+        (1 . 30)
+        (2 . 53)
+        (30 . 30)
+        (30 . 30)
+        (30 . 30)
+        (30 . 30)
+        (30 . 30)
+        (30 . 30)
+        (30 . 30)
+        (30 . 53)
+        (30 . 53)
+        (30 . 53))))))
+
+(ert-deftest overlay-autogenerated-test-26 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 60 59 nil t nil)
+    (make-overlay 18 11 nil nil t)
+    (make-overlay 4 44 nil nil nil)
+    (make-overlay 7 22 nil nil nil)
+    (make-overlay 54 50 nil t nil)
+    (make-overlay 59 28 nil nil nil)
+    (make-overlay 49 23 nil nil t)
+    (make-overlay 21 5 nil t nil)
+    (make-overlay 17 39 nil t nil)
+    (make-overlay 16 14 nil nil nil)
+    (make-overlay 50 26 nil nil nil)
+    (make-overlay 37 14 nil nil nil)
+    (make-overlay 6 59 nil nil t)
+    (make-overlay 30 17 nil nil t)
+    (make-overlay 17 34 nil nil t)
+    (make-overlay 7 22 nil t nil)
+    (goto-char 35)
+    (delete-char 25)
+    (goto-char 30)
+    (delete-char 7)
+    (goto-char 25)
+    (widen)
+    (narrow-to-region 3 19)
+    (goto-char 6)
+    (insert ".........")
+    (goto-char 21)
+    (insert "...............")
+    (goto-char 12)
+    (insert ".............")
+    (goto-char 34)
+    (widen)
+    (narrow-to-region 64 37)
+    (goto-char 62)
+    (insert ".............")
+    (goto-char 50)
+    (widen)
+    (narrow-to-region 72 38)
+    (goto-char 66)
+    (insert "")
+    (goto-char 54)
+    (insert "...")
+    (goto-char 70)
+    (delete-char 4)
+    (goto-char 49)
+    (delete-char 13)
+    (goto-char 38)
+    (insert "....")
+    (goto-char 46)
+    (insert ".")
+    (goto-char 43)
+    (widen)
+    (narrow-to-region 74 53)
+    (goto-char 60)
+    (delete-char 10)
+    (goto-char 53)
+    (insert "..............")
+    (goto-char 72)
+    (insert "............")
+    (goto-char 87)
+    (delete-char 2)
+    (goto-char 73)
+    (insert "............")
+    (goto-char 81)
+    (insert "........")
+    (goto-char 106)
+    (insert "...")
+    (goto-char 95)
+    (widen)
+    (narrow-to-region 77 39)
+    (goto-char 43)
+    (insert "..........")
+    (goto-char 40)
+    (insert "...............")
+    (goto-char 101)
+    (insert "")
+    (goto-char 53)
+    (insert "....")
+    (goto-char 79)
+    (delete-char 21)
+    (goto-char 85)
+    (insert "........")
+    (goto-char 52)
+    (delete-char 41)
+    (goto-char 43)
+    (insert ".....")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((4 . 90)
+        (5 . 57)
+        (6 . 90)
+        (29 . 57)
+        (29 . 57)
+        (33 . 57))))))
+
+(ert-deftest overlay-autogenerated-test-27 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 20 12 nil t nil)
+    (make-overlay 3 10 nil t t)
+    (make-overlay 11 53 nil t nil)
+    (make-overlay 59 3 nil t nil)
+    (make-overlay 28 19 nil t t)
+    (make-overlay 16 30 nil t t)
+    (make-overlay 39 19 nil t t)
+    (make-overlay 33 50 nil t nil)
+    (make-overlay 36 54 nil nil nil)
+    (make-overlay 42 59 nil nil nil)
+    (make-overlay 30 48 nil t nil)
+    (make-overlay 20 13 nil nil t)
+    (make-overlay 63 48 nil t nil)
+    (make-overlay 48 12 nil t t)
+    (make-overlay 64 50 nil nil nil)
+    (make-overlay 7 7 nil nil nil)
+    (goto-char 20)
+    (widen)
+    (narrow-to-region 21 54)
+    (goto-char 40)
+    (insert "..........")
+    (goto-char 21)
+    (delete-char 2)
+    (goto-char 35)
+    (widen)
+    (narrow-to-region 70 11)
+    (goto-char 45)
+    (insert "...............")
+    (goto-char 74)
+    (insert ".")
+    (goto-char 28)
+    (widen)
+    (narrow-to-region 77 67)
+    (goto-char 72)
+    (insert "..........")
+    (goto-char 85)
+    (delete-char 1)
+    (goto-char 82)
+    (widen)
+    (narrow-to-region 83 86)
+    (goto-char 83)
+    (delete-char 0)
+    (goto-char 86)
+    (delete-char 0)
+    (goto-char 86)
+    (insert "...........")
+    (goto-char 97)
+    (insert ".......")
+    (goto-char 103)
+    (widen)
+    (narrow-to-region 44 68)
+    (goto-char 49)
+    (insert "..")
+    (goto-char 65)
+    (insert ".............")
+    (goto-char 59)
+    (delete-char 0)
+    (goto-char 57)
+    (insert "........")
+    (goto-char 55)
+    (delete-char 30)
+    (goto-char 45)
+    (insert "...............")
+    (goto-char 44)
+    (insert "")
+    (goto-char 62)
+    (insert "............")
+    (goto-char 63)
+    (widen)
+    (narrow-to-region 12 5)
+    (goto-char 8)
+    (delete-char 4)
+    (goto-char 6)
+    (delete-char 0)
+    (goto-char 7)
+    (insert "..........")
+    (goto-char 15)
+    (delete-char 0)
+    (goto-char 16)
+    (insert "............")
+    (goto-char 20)
+    (insert ".........")
+    (goto-char 13)
+    (insert "..")
+    (goto-char 32)
+    (insert "..............")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((3 . 55)
+        (3 . 173)
+        (7 . 7))))))
+
+(ert-deftest overlay-autogenerated-test-28 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 59 48 nil t nil)
+    (make-overlay 59 4 nil nil t)
+    (make-overlay 45 35 nil t nil)
+    (make-overlay 13 18 nil t t)
+    (make-overlay 10 7 nil t t)
+    (make-overlay 9 8 nil nil nil)
+    (make-overlay 33 47 nil nil t)
+    (make-overlay 1 57 nil t nil)
+    (make-overlay 16 59 nil nil t)
+    (make-overlay 43 58 nil nil t)
+    (make-overlay 6 11 nil nil nil)
+    (make-overlay 59 7 nil t nil)
+    (make-overlay 3 57 nil t t)
+    (make-overlay 61 35 nil nil nil)
+    (make-overlay 57 8 nil nil nil)
+    (make-overlay 5 32 nil t nil)
+    (goto-char 18)
+    (insert "............")
+    (goto-char 43)
+    (delete-char 2)
+    (goto-char 38)
+    (delete-char 26)
+    (goto-char 42)
+    (insert ".....")
+    (goto-char 52)
+    (insert "..........")
+    (goto-char 45)
+    (delete-char 11)
+    (goto-char 33)
+    (insert "....")
+    (goto-char 23)
+    (delete-char 14)
+    (goto-char 33)
+    (widen)
+    (narrow-to-region 30 33)
+    (goto-char 30)
+    (delete-char 0)
+    (goto-char 30)
+    (insert "...........")
+    (goto-char 30)
+    (delete-char 7)
+    (goto-char 30)
+    (insert ".")
+    (goto-char 32)
+    (delete-char 4)
+    (goto-char 34)
+    (delete-char 0)
+    (goto-char 34)
+    (delete-char 0)
+    (goto-char 32)
+    (insert "...............")
+    (goto-char 46)
+    (insert ".........")
+    (goto-char 45)
+    (delete-char 3)
+    (goto-char 49)
+    (delete-char 2)
+    (goto-char 42)
+    (delete-char 2)
+    (goto-char 32)
+    (insert "..........")
+    (goto-char 47)
+    (insert "....")
+    (goto-char 59)
+    (insert ".......")
+    (goto-char 35)
+    (insert ".")
+    (goto-char 45)
+    (insert "..............")
+    (goto-char 37)
+    (insert "..")
+    (goto-char 80)
+    (insert ".....")
+    (goto-char 30)
+    (insert ".............")
+    (goto-char 102)
+    (insert "............")
+    (goto-char 113)
+    (insert "")
+    (goto-char 66)
+    (widen)
+    (narrow-to-region 47 38)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 45)
+        (3 . 117)
+        (4 . 121)
+        (7 . 121)
+        (8 . 45)
+        (16 . 121)
+        (28 . 121)
+        (28 . 121)
+        (28 . 121))))))
+
+(ert-deftest overlay-autogenerated-test-29 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 5 63 nil nil t)
+    (make-overlay 20 28 nil t t)
+    (make-overlay 58 53 nil t nil)
+    (make-overlay 4 57 nil t t)
+    (make-overlay 4 16 nil nil nil)
+    (make-overlay 33 26 nil t nil)
+    (make-overlay 9 32 nil t t)
+    (make-overlay 11 8 nil nil nil)
+    (make-overlay 59 35 nil nil t)
+    (make-overlay 15 25 nil t t)
+    (make-overlay 36 16 nil nil nil)
+    (make-overlay 8 37 nil nil nil)
+    (make-overlay 65 63 nil nil t)
+    (make-overlay 3 20 nil nil t)
+    (make-overlay 44 55 nil t t)
+    (make-overlay 45 25 nil t nil)
+    (goto-char 39)
+    (insert "...")
+    (goto-char 22)
+    (insert "........")
+    (goto-char 60)
+    (insert ".........")
+    (goto-char 17)
+    (insert "............")
+    (goto-char 13)
+    (widen)
+    (narrow-to-region 79 16)
+    (goto-char 19)
+    (delete-char 11)
+    (goto-char 25)
+    (insert "........")
+    (goto-char 61)
+    (insert "....")
+    (goto-char 45)
+    (widen)
+    (narrow-to-region 73 66)
+    (goto-char 71)
+    (insert "............")
+    (goto-char 81)
+    (delete-char 2)
+    (goto-char 73)
+    (insert "..........")
+    (goto-char 74)
+    (insert "............")
+    (goto-char 82)
+    (delete-char 7)
+    (goto-char 78)
+    (delete-char 18)
+    (goto-char 75)
+    (insert ".........")
+    (goto-char 66)
+    (insert ".........")
+    (goto-char 86)
+    (delete-char 12)
+    (goto-char 77)
+    (widen)
+    (narrow-to-region 23 55)
+    (goto-char 43)
+    (insert ".")
+    (goto-char 50)
+    (insert "..")
+    (goto-char 25)
+    (delete-char 18)
+    (goto-char 33)
+    (delete-char 7)
+    (goto-char 26)
+    (insert "........")
+    (goto-char 29)
+    (insert "...........")
+    (goto-char 33)
+    (insert "...")
+    (goto-char 40)
+    (insert "..........")
+    (goto-char 26)
+    (insert "")
+    (goto-char 35)
+    (insert ".")
+    (goto-char 59)
+    (insert ".")
+    (goto-char 51)
+    (insert "..")
+    (goto-char 59)
+    (insert ".............")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((4 . 130)
+        (5 . 136)
+        (8 . 82)
+        (9 . 82)
+        (15 . 25)
+        (16 . 82)
+        (21 . 77)
+        (25 . 105)
+        (75 . 82))))))
+
+(ert-deftest overlay-autogenerated-test-30 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 27 65 nil t t)
+    (make-overlay 39 51 nil t t)
+    (make-overlay 53 2 nil nil nil)
+    (make-overlay 3 17 nil nil t)
+    (make-overlay 35 4 nil nil t)
+    (make-overlay 65 53 nil t nil)
+    (make-overlay 8 21 nil t t)
+    (make-overlay 18 62 nil t t)
+    (make-overlay 42 59 nil nil t)
+    (make-overlay 12 37 nil t t)
+    (make-overlay 64 31 nil t nil)
+    (make-overlay 39 54 nil nil t)
+    (make-overlay 41 24 nil t nil)
+    (make-overlay 10 21 nil nil t)
+    (make-overlay 49 15 nil t nil)
+    (make-overlay 49 63 nil nil t)
+    (goto-char 43)
+    (insert "..........")
+    (goto-char 44)
+    (delete-char 29)
+    (goto-char 32)
+    (insert "..")
+    (goto-char 13)
+    (insert ".")
+    (goto-char 42)
+    (insert ".........")
+    (goto-char 39)
+    (insert "..........")
+    (goto-char 15)
+    (insert "............")
+    (goto-char 58)
+    (delete-char 9)
+    (goto-char 63)
+    (insert ".........")
+    (goto-char 49)
+    (insert ".")
+    (goto-char 28)
+    (delete-char 51)
+    (goto-char 12)
+    (delete-char 6)
+    (goto-char 20)
+    (delete-char 2)
+    (goto-char 7)
+    (widen)
+    (narrow-to-region 2 9)
+    (goto-char 5)
+    (insert "...............")
+    (goto-char 18)
+    (delete-char 1)
+    (goto-char 4)
+    (insert ".............")
+    (goto-char 13)
+    (delete-char 22)
+    (goto-char 12)
+    (insert "")
+    (goto-char 3)
+    (insert ".............")
+    (goto-char 22)
+    (insert "...............")
+    (goto-char 9)
+    (insert "....")
+    (goto-char 8)
+    (insert "...........")
+    (goto-char 6)
+    (delete-char 34)
+    (goto-char 21)
+    (insert "....")
+    (goto-char 14)
+    (insert ".....")
+    (goto-char 20)
+    (insert ".......")
+    (goto-char 34)
+    (widen)
+    (narrow-to-region 3 2)
+    (goto-char 3)
+    (delete-char 0)
+    (goto-char 2)
+    (insert "..............")
+    (goto-char 15)
+    (delete-char 2)
+    (goto-char 11)
+    (insert "......")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((2 . 68))))))
+
+(ert-deftest overlay-autogenerated-test-31 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 54 64 nil nil nil)
+    (make-overlay 49 12 nil nil t)
+    (make-overlay 40 12 nil t nil)
+    (make-overlay 17 38 nil nil nil)
+    (make-overlay 21 36 nil t t)
+    (make-overlay 8 38 nil t nil)
+    (make-overlay 50 22 nil t nil)
+    (make-overlay 65 15 nil nil t)
+    (make-overlay 57 60 nil t t)
+    (make-overlay 35 11 nil nil t)
+    (make-overlay 49 44 nil nil t)
+    (make-overlay 45 31 nil nil t)
+    (make-overlay 51 24 nil t t)
+    (make-overlay 20 14 nil nil nil)
+    (make-overlay 6 18 nil t t)
+    (make-overlay 25 3 nil nil nil)
+    (goto-char 18)
+    (delete-char 10)
+    (goto-char 36)
+    (delete-char 13)
+    (goto-char 8)
+    (delete-char 4)
+    (goto-char 2)
+    (delete-char 8)
+    (goto-char 12)
+    (delete-char 10)
+    (goto-char 15)
+    (delete-char 4)
+    (goto-char 16)
+    (insert ".........")
+    (goto-char 17)
+    (insert "...............")
+    (goto-char 33)
+    (delete-char 0)
+    (goto-char 38)
+    (delete-char 0)
+    (goto-char 11)
+    (insert "...........")
+    (goto-char 8)
+    (delete-char 14)
+    (goto-char 32)
+    (insert "........")
+    (goto-char 40)
+    (widen)
+    (narrow-to-region 14 6)
+    (goto-char 10)
+    (delete-char 1)
+    (goto-char 7)
+    (widen)
+    (narrow-to-region 18 39)
+    (goto-char 36)
+    (delete-char 1)
+    (goto-char 34)
+    (widen)
+    (narrow-to-region 39 14)
+    (goto-char 22)
+    (widen)
+    (narrow-to-region 25 21)
+    (goto-char 23)
+    (delete-char 2)
+    (goto-char 23)
+    (delete-char 0)
+    (goto-char 23)
+    (insert ".........")
+    (goto-char 32)
+    (delete-char 0)
+    (goto-char 31)
+    (insert ".........")
+    (goto-char 32)
+    (insert "...")
+    (goto-char 30)
+    (widen)
+    (narrow-to-region 10 56)
+    (goto-char 10)
+    (insert ".........")
+    (goto-char 38)
+    (insert ".........")
+    (goto-char 19)
+    (insert "..")
+    (goto-char 11)
+    (insert "..............")
+    (goto-char 66)
+    (insert "...............")
+    (goto-char 13)
+    (insert "......")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((2 . 41)
+        (3 . 117)
+        (6 . 41)
+        (8 . 41)
+        (9 . 41)
+        (10 . 42)
+        (41 . 42))))))
+
+(ert-deftest overlay-autogenerated-test-32 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 35 60 nil nil t)
+    (make-overlay 45 46 nil nil nil)
+    (make-overlay 47 11 nil nil t)
+    (make-overlay 12 51 nil t nil)
+    (make-overlay 61 17 nil t nil)
+    (make-overlay 7 24 nil t nil)
+    (make-overlay 36 37 nil nil t)
+    (make-overlay 5 39 nil t t)
+    (make-overlay 5 40 nil nil t)
+    (make-overlay 38 40 nil t t)
+    (make-overlay 47 45 nil t nil)
+    (make-overlay 61 48 nil nil nil)
+    (make-overlay 23 39 nil t t)
+    (make-overlay 11 52 nil nil nil)
+    (make-overlay 37 35 nil nil nil)
+    (make-overlay 19 20 nil t nil)
+    (goto-char 43)
+    (insert "........")
+    (goto-char 7)
+    (insert "")
+    (goto-char 28)
+    (delete-char 41)
+    (goto-char 3)
+    (delete-char 17)
+    (goto-char 2)
+    (insert ".")
+    (goto-char 7)
+    (insert ".........")
+    (goto-char 21)
+    (delete-char 4)
+    (goto-char 13)
+    (delete-char 1)
+    (goto-char 2)
+    (insert "...............")
+    (goto-char 7)
+    (insert "")
+    (goto-char 14)
+    (insert ".....")
+    (goto-char 16)
+    (insert ".")
+    (goto-char 10)
+    (insert "..............")
+    (goto-char 16)
+    (delete-char 18)
+    (goto-char 1)
+    (delete-char 36)
+    (goto-char 1)
+    (delete-char 0)
+    (goto-char 1)
+    (delete-char 0)
+    (goto-char 1)
+    (insert ".............")
+    (goto-char 9)
+    (insert ".")
+    (goto-char 14)
+    (insert ".....")
+    (goto-char 9)
+    (delete-char 0)
+    (goto-char 15)
+    (delete-char 0)
+    (goto-char 6)
+    (delete-char 4)
+    (goto-char 11)
+    (delete-char 5)
+    (goto-char 5)
+    (insert "....")
+    (goto-char 5)
+    (insert ".....")
+    (goto-char 12)
+    (insert "")
+    (goto-char 13)
+    (insert ".......")
+    (goto-char 14)
+    (insert "......")
+    (goto-char 9)
+    (delete-char 3)
+    (goto-char 17)
+    (delete-char 0)
+    (goto-char 7)
+    (delete-char 12)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 18)
+        (1 . 18)
+        (1 . 18)
+        (1 . 18)
+        (18 . 18)
+        (18 . 18)
+        (18 . 18))))))
+
+(ert-deftest overlay-autogenerated-test-33 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 65 33 nil t nil)
+    (make-overlay 45 54 nil t t)
+    (make-overlay 17 38 nil t nil)
+    (make-overlay 58 46 nil nil t)
+    (make-overlay 21 36 nil t t)
+    (make-overlay 31 63 nil nil t)
+    (make-overlay 37 64 nil t t)
+    (make-overlay 42 19 nil nil nil)
+    (make-overlay 51 60 nil t nil)
+    (make-overlay 47 15 nil t t)
+    (make-overlay 57 47 nil nil nil)
+    (make-overlay 40 45 nil nil nil)
+    (make-overlay 44 47 nil t nil)
+    (make-overlay 42 35 nil t nil)
+    (make-overlay 1 65 nil nil t)
+    (make-overlay 29 63 nil t nil)
+    (goto-char 33)
+    (insert "...........")
+    (goto-char 56)
+    (insert ".........")
+    (goto-char 67)
+    (insert "....")
+    (goto-char 28)
+    (delete-char 35)
+    (goto-char 9)
+    (insert "......")
+    (goto-char 43)
+    (delete-char 17)
+    (goto-char 29)
+    (insert ".......")
+    (goto-char 20)
+    (insert "....")
+    (goto-char 53)
+    (insert ".......")
+    (goto-char 14)
+    (widen)
+    (narrow-to-region 38 57)
+    (goto-char 51)
+    (insert "")
+    (goto-char 57)
+    (insert ".......")
+    (goto-char 64)
+    (insert ".....")
+    (goto-char 59)
+    (delete-char 3)
+    (goto-char 45)
+    (delete-char 12)
+    (goto-char 43)
+    (insert "......")
+    (goto-char 48)
+    (insert "......")
+    (goto-char 52)
+    (insert "........")
+    (goto-char 57)
+    (delete-char 16)
+    (goto-char 43)
+    (delete-char 9)
+    (goto-char 40)
+    (insert "")
+    (goto-char 39)
+    (insert "..........")
+    (goto-char 50)
+    (widen)
+    (narrow-to-region 31 27)
+    (goto-char 27)
+    (insert "..........")
+    (goto-char 33)
+    (delete-char 0)
+    (goto-char 37)
+    (insert "..")
+    (goto-char 38)
+    (delete-char 4)
+    (goto-char 38)
+    (insert "..........")
+    (goto-char 45)
+    (insert ".....")
+    (goto-char 53)
+    (insert "...")
+    (goto-char 51)
+    (insert ".")
+    (goto-char 28)
+    (insert "...")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 93)
+        (25 . 92)
+        (41 . 88)
+        (60 . 88))))))
+
+(ert-deftest overlay-autogenerated-test-34 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 2 63 nil nil t)
+    (make-overlay 54 30 nil t nil)
+    (make-overlay 21 57 nil t nil)
+    (make-overlay 61 19 nil nil nil)
+    (make-overlay 55 8 nil nil t)
+    (make-overlay 14 51 nil nil nil)
+    (make-overlay 33 13 nil t t)
+    (make-overlay 36 25 nil t t)
+    (make-overlay 22 21 nil nil t)
+    (make-overlay 21 48 nil nil t)
+    (make-overlay 36 7 nil nil t)
+    (make-overlay 2 40 nil nil nil)
+    (make-overlay 21 27 nil nil t)
+    (make-overlay 26 2 nil nil nil)
+    (make-overlay 60 43 nil nil nil)
+    (make-overlay 12 50 nil t t)
+    (goto-char 44)
+    (delete-char 6)
+    (goto-char 5)
+    (insert "..")
+    (goto-char 17)
+    (insert "........")
+    (goto-char 48)
+    (insert "..")
+    (goto-char 27)
+    (delete-char 29)
+    (goto-char 10)
+    (delete-char 2)
+    (goto-char 35)
+    (insert ".............")
+    (goto-char 20)
+    (delete-char 0)
+    (goto-char 6)
+    (insert ".")
+    (goto-char 9)
+    (delete-char 6)
+    (goto-char 38)
+    (insert ".........")
+    (goto-char 5)
+    (insert ".........")
+    (goto-char 10)
+    (delete-char 20)
+    (goto-char 6)
+    (delete-char 6)
+    (goto-char 14)
+    (insert ".............")
+    (goto-char 31)
+    (delete-char 10)
+    (goto-char 20)
+    (widen)
+    (narrow-to-region 27 39)
+    (goto-char 34)
+    (delete-char 5)
+    (goto-char 32)
+    (delete-char 1)
+    (goto-char 27)
+    (insert "..")
+    (goto-char 28)
+    (insert "........")
+    (goto-char 39)
+    (insert "........")
+    (goto-char 38)
+    (delete-char 7)
+    (goto-char 44)
+    (delete-char 0)
+    (goto-char 30)
+    (insert "...............")
+    (goto-char 43)
+    (insert "............")
+    (goto-char 56)
+    (delete-char 1)
+    (goto-char 65)
+    (delete-char 3)
+    (goto-char 36)
+    (insert ".........")
+    (goto-char 74)
+    (insert ".....")
+    (goto-char 67)
+    (delete-char 5)
+    (goto-char 38)
+    (insert "..")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((2 . 80)
+        (6 . 78))))))
+
+(ert-deftest overlay-autogenerated-test-35 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 38 16 nil nil nil)
+    (make-overlay 19 22 nil t nil)
+    (make-overlay 16 43 nil nil t)
+    (make-overlay 27 5 nil nil nil)
+    (make-overlay 43 34 nil t nil)
+    (make-overlay 47 4 nil nil t)
+    (make-overlay 1 47 nil nil t)
+    (make-overlay 27 35 nil t nil)
+    (make-overlay 41 41 nil nil t)
+    (make-overlay 21 19 nil nil nil)
+    (make-overlay 16 38 nil nil t)
+    (make-overlay 33 39 nil t nil)
+    (make-overlay 34 51 nil nil t)
+    (make-overlay 45 36 nil t nil)
+    (make-overlay 42 18 nil t t)
+    (make-overlay 12 30 nil nil nil)
+    (goto-char 18)
+    (insert "")
+    (goto-char 58)
+    (delete-char 3)
+    (goto-char 58)
+    (delete-char 0)
+    (goto-char 1)
+    (insert ".......")
+    (goto-char 48)
+    (delete-char 17)
+    (goto-char 39)
+    (delete-char 6)
+    (goto-char 33)
+    (widen)
+    (narrow-to-region 45 46)
+    (goto-char 46)
+    (insert "")
+    (goto-char 46)
+    (delete-char 0)
+    (goto-char 46)
+    (insert ".....")
+    (goto-char 51)
+    (widen)
+    (narrow-to-region 17 26)
+    (goto-char 25)
+    (widen)
+    (narrow-to-region 50 41)
+    (goto-char 45)
+    (insert "..............")
+    (goto-char 59)
+    (insert "...........")
+    (goto-char 47)
+    (delete-char 9)
+    (goto-char 59)
+    (insert "")
+    (goto-char 46)
+    (insert "")
+    (goto-char 54)
+    (delete-char 5)
+    (goto-char 57)
+    (widen)
+    (narrow-to-region 57 31)
+    (goto-char 42)
+    (delete-char 2)
+    (goto-char 52)
+    (insert "....")
+    (goto-char 44)
+    (insert "..")
+    (goto-char 44)
+    (insert "...............")
+    (goto-char 72)
+    (delete-char 1)
+    (goto-char 66)
+    (delete-char 6)
+    (goto-char 64)
+    (delete-char 5)
+    (goto-char 49)
+    (delete-char 12)
+    (goto-char 32)
+    (insert "......")
+    (goto-char 44)
+    (delete-char 2)
+    (goto-char 39)
+    (delete-char 12)
+    (goto-char 42)
+    (insert "......")
+    (goto-char 36)
+    (widen)
+    (narrow-to-region 14 47)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 39)
+        (11 . 39)
+        (12 . 39)
+        (19 . 39)
+        (23 . 39)
+        (23 . 39)
+        (23 . 39)
+        (25 . 39)
+        (26 . 28)
+        (26 . 29)
+        (39 . 39)
+        (39 . 39)
+        (39 . 39)
+        (39 . 39)
+        (39 . 39)
+        (39 . 39))))))
+
+(ert-deftest overlay-autogenerated-test-36 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 1 38 nil t t)
+    (make-overlay 58 34 nil t nil)
+    (make-overlay 6 33 nil nil t)
+    (make-overlay 63 54 nil nil t)
+    (make-overlay 54 54 nil t t)
+    (make-overlay 21 61 nil nil nil)
+    (make-overlay 64 55 nil nil t)
+    (make-overlay 28 65 nil nil t)
+    (make-overlay 32 51 nil t nil)
+    (make-overlay 36 38 nil nil nil)
+    (make-overlay 35 21 nil nil nil)
+    (make-overlay 65 48 nil nil nil)
+    (make-overlay 32 27 nil nil t)
+    (make-overlay 27 55 nil t t)
+    (make-overlay 30 22 nil t nil)
+    (make-overlay 14 58 nil t nil)
+    (goto-char 40)
+    (delete-char 7)
+    (goto-char 42)
+    (insert "......")
+    (goto-char 11)
+    (widen)
+    (narrow-to-region 64 9)
+    (goto-char 21)
+    (delete-char 23)
+    (goto-char 24)
+    (insert "...")
+    (goto-char 13)
+    (insert "..........")
+    (goto-char 12)
+    (delete-char 5)
+    (goto-char 10)
+    (delete-char 0)
+    (goto-char 21)
+    (widen)
+    (narrow-to-region 9 5)
+    (goto-char 6)
+    (delete-char 0)
+    (goto-char 9)
+    (delete-char 0)
+    (goto-char 9)
+    (delete-char 0)
+    (goto-char 7)
+    (insert "............")
+    (goto-char 9)
+    (insert "...")
+    (goto-char 18)
+    (insert ".")
+    (goto-char 23)
+    (delete-char 1)
+    (goto-char 9)
+    (insert "....")
+    (goto-char 6)
+    (insert ".....")
+    (goto-char 23)
+    (widen)
+    (narrow-to-region 28 1)
+    (goto-char 6)
+    (insert "...........")
+    (goto-char 30)
+    (delete-char 8)
+    (goto-char 2)
+    (insert ".")
+    (goto-char 18)
+    (insert "......")
+    (goto-char 5)
+    (delete-char 9)
+    (goto-char 5)
+    (delete-char 20)
+    (goto-char 4)
+    (delete-char 3)
+    (goto-char 3)
+    (delete-char 2)
+    (goto-char 3)
+    (delete-char 0)
+    (goto-char 1)
+    (insert "......")
+    (goto-char 8)
+    (widen)
+    (narrow-to-region 39 2)
+    (goto-char 13)
+    (delete-char 12)
+    (goto-char 24)
+    (delete-char 0)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((7 . 20)
+        (9 . 20)
+        (13 . 36)
+        (20 . 20)
+        (20 . 20)
+        (20 . 20)
+        (20 . 20)
+        (20 . 29)
+        (20 . 33)
+        (20 . 36)
+        (20 . 39)
+        (20 . 43)
+        (20 . 43))))))
+
+(ert-deftest overlay-autogenerated-test-37 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 26 30 nil nil nil)
+    (make-overlay 55 50 nil nil t)
+    (make-overlay 43 54 nil nil t)
+    (make-overlay 53 48 nil nil nil)
+    (make-overlay 37 51 nil nil t)
+    (make-overlay 15 30 nil nil nil)
+    (make-overlay 2 24 nil t t)
+    (make-overlay 56 61 nil t nil)
+    (make-overlay 65 46 nil t nil)
+    (make-overlay 28 47 nil t nil)
+    (make-overlay 21 24 nil t t)
+    (make-overlay 17 13 nil t t)
+    (make-overlay 7 44 nil t nil)
+    (make-overlay 28 63 nil nil nil)
+    (make-overlay 22 16 nil t t)
+    (make-overlay 26 44 nil t t)
+    (goto-char 57)
+    (delete-char 6)
+    (goto-char 42)
+    (insert ".....")
+    (goto-char 63)
+    (insert ".............")
+    (goto-char 17)
+    (insert "")
+    (goto-char 57)
+    (insert "...........")
+    (goto-char 3)
+    (delete-char 47)
+    (goto-char 15)
+    (insert ".............")
+    (goto-char 28)
+    (insert "")
+    (goto-char 17)
+    (delete-char 31)
+    (goto-char 7)
+    (delete-char 16)
+    (goto-char 2)
+    (insert "...........")
+    (goto-char 2)
+    (insert "..")
+    (goto-char 18)
+    (widen)
+    (narrow-to-region 20 8)
+    (goto-char 13)
+    (widen)
+    (narrow-to-region 12 10)
+    (goto-char 10)
+    (delete-char 1)
+    (goto-char 11)
+    (delete-char 0)
+    (goto-char 10)
+    (insert "...")
+    (goto-char 11)
+    (delete-char 0)
+    (goto-char 13)
+    (insert "..")
+    (goto-char 16)
+    (delete-char 0)
+    (goto-char 10)
+    (delete-char 2)
+    (goto-char 11)
+    (insert ".....")
+    (goto-char 16)
+    (widen)
+    (narrow-to-region 6 13)
+    (goto-char 10)
+    (insert "..")
+    (goto-char 6)
+    (delete-char 6)
+    (goto-char 8)
+    (insert "...............")
+    (goto-char 21)
+    (delete-char 0)
+    (goto-char 21)
+    (widen)
+    (narrow-to-region 36 11)
+    (goto-char 12)
+    (insert "...............")
+    (goto-char 19)
+    (insert ".......")
+    (goto-char 56)
+    (delete-char 2)
+    (goto-char 42)
+    (delete-char 11)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((44 . 45))))))
+
+(ert-deftest overlay-autogenerated-test-38 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 29 13 nil t t)
+    (make-overlay 19 28 nil nil t)
+    (make-overlay 47 33 nil nil nil)
+    (make-overlay 8 44 nil t nil)
+    (make-overlay 48 4 nil t nil)
+    (make-overlay 8 20 nil t t)
+    (make-overlay 38 31 nil nil t)
+    (make-overlay 17 65 nil nil t)
+    (make-overlay 49 31 nil nil nil)
+    (make-overlay 39 19 nil nil t)
+    (make-overlay 40 49 nil t t)
+    (make-overlay 24 16 nil t t)
+    (make-overlay 4 41 nil t nil)
+    (make-overlay 61 42 nil t nil)
+    (make-overlay 46 11 nil nil nil)
+    (make-overlay 1 43 nil nil t)
+    (goto-char 62)
+    (delete-char 2)
+    (goto-char 25)
+    (widen)
+    (narrow-to-region 30 38)
+    (goto-char 37)
+    (delete-char 1)
+    (goto-char 37)
+    (insert "...........")
+    (goto-char 41)
+    (delete-char 3)
+    (goto-char 39)
+    (delete-char 5)
+    (goto-char 39)
+    (widen)
+    (narrow-to-region 31 9)
+    (goto-char 11)
+    (insert "..............")
+    (goto-char 9)
+    (widen)
+    (narrow-to-region 62 30)
+    (goto-char 32)
+    (widen)
+    (narrow-to-region 17 48)
+    (goto-char 39)
+    (delete-char 7)
+    (goto-char 24)
+    (delete-char 8)
+    (goto-char 19)
+    (insert "")
+    (goto-char 25)
+    (delete-char 5)
+    (goto-char 28)
+    (delete-char 0)
+    (goto-char 22)
+    (widen)
+    (narrow-to-region 52 35)
+    (goto-char 49)
+    (delete-char 0)
+    (goto-char 49)
+    (delete-char 3)
+    (goto-char 48)
+    (insert "...........")
+    (goto-char 37)
+    (delete-char 23)
+    (goto-char 36)
+    (delete-char 0)
+    (goto-char 35)
+    (insert "....")
+    (goto-char 35)
+    (insert "..")
+    (goto-char 39)
+    (delete-char 4)
+    (goto-char 39)
+    (delete-char 0)
+    (goto-char 36)
+    (delete-char 3)
+    (goto-char 36)
+    (delete-char 0)
+    (goto-char 36)
+    (delete-char 0)
+    (goto-char 36)
+    (delete-char 0)
+    (goto-char 36)
+    (insert ".....")
+    (goto-char 38)
+    (delete-char 1)
+    (goto-char 35)
+    (delete-char 3)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 37)
+        (24 . 44)
+        (25 . 37))))))
+
+(ert-deftest overlay-autogenerated-test-39 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 15 49 nil t t)
+    (make-overlay 27 20 nil t nil)
+    (make-overlay 55 50 nil t nil)
+    (make-overlay 17 5 nil t t)
+    (make-overlay 26 56 nil nil t)
+    (make-overlay 42 11 nil t t)
+    (make-overlay 24 35 nil nil t)
+    (make-overlay 47 45 nil t t)
+    (make-overlay 37 12 nil nil t)
+    (make-overlay 17 25 nil t nil)
+    (make-overlay 32 53 nil nil nil)
+    (make-overlay 20 34 nil nil t)
+    (make-overlay 56 58 nil nil t)
+    (make-overlay 42 31 nil nil t)
+    (make-overlay 22 55 nil t t)
+    (make-overlay 55 11 nil t nil)
+    (goto-char 16)
+    (insert ".............")
+    (goto-char 30)
+    (insert ".")
+    (goto-char 12)
+    (delete-char 56)
+    (goto-char 9)
+    (insert ".............")
+    (goto-char 6)
+    (insert "....")
+    (goto-char 19)
+    (delete-char 19)
+    (goto-char 19)
+    (insert "...............")
+    (goto-char 13)
+    (delete-char 21)
+    (goto-char 7)
+    (delete-char 0)
+    (goto-char 14)
+    (widen)
+    (narrow-to-region 5 6)
+    (goto-char 5)
+    (delete-char 0)
+    (goto-char 6)
+    (insert "......")
+    (goto-char 10)
+    (delete-char 0)
+    (goto-char 7)
+    (widen)
+    (narrow-to-region 2 6)
+    (goto-char 2)
+    (insert "..........")
+    (goto-char 2)
+    (delete-char 9)
+    (goto-char 7)
+    (insert "...")
+    (goto-char 9)
+    (insert "...")
+    (goto-char 10)
+    (insert "......")
+    (goto-char 4)
+    (delete-char 14)
+    (goto-char 4)
+    (insert ".")
+    (goto-char 5)
+    (insert "..............")
+    (goto-char 13)
+    (insert "......")
+    (goto-char 10)
+    (insert "......")
+    (goto-char 20)
+    (insert "............")
+    (goto-char 16)
+    (widen)
+    (narrow-to-region 3 32)
+    (goto-char 18)
+    (insert "..")
+    (goto-char 6)
+    (insert "......")
+    (goto-char 38)
+    (delete-char 0)
+    (goto-char 31)
+    (insert "............")
+    (goto-char 28)
+    (insert "")
+    (goto-char 9)
+    (delete-char 23)
+    (should
+     (equal
+      (test-overlay-regions)
+      'nil))))
+
+(ert-deftest overlay-autogenerated-test-40 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 52 3 nil t nil)
+    (make-overlay 35 41 nil t t)
+    (make-overlay 4 2 nil t nil)
+    (make-overlay 51 48 nil nil t)
+    (make-overlay 44 57 nil t t)
+    (make-overlay 13 32 nil nil nil)
+    (make-overlay 46 29 nil t nil)
+    (make-overlay 28 13 nil t nil)
+    (make-overlay 10 65 nil t t)
+    (make-overlay 41 48 nil nil t)
+    (make-overlay 36 44 nil nil t)
+    (make-overlay 29 61 nil t nil)
+    (make-overlay 25 24 nil nil t)
+    (make-overlay 22 45 nil nil t)
+    (make-overlay 37 55 nil nil t)
+    (make-overlay 36 39 nil nil nil)
+    (goto-char 16)
+    (delete-char 48)
+    (goto-char 17)
+    (delete-char 0)
+    (goto-char 7)
+    (insert "..............")
+    (goto-char 30)
+    (insert "........")
+    (goto-char 11)
+    (insert "..........")
+    (goto-char 5)
+    (delete-char 14)
+    (goto-char 19)
+    (insert ".")
+    (goto-char 27)
+    (insert "..")
+    (goto-char 35)
+    (delete-char 1)
+    (goto-char 29)
+    (delete-char 0)
+    (goto-char 33)
+    (delete-char 2)
+    (goto-char 33)
+    (insert "..")
+    (goto-char 28)
+    (insert ".........")
+    (goto-char 30)
+    (delete-char 4)
+    (goto-char 40)
+    (delete-char 1)
+    (goto-char 15)
+    (widen)
+    (narrow-to-region 40 8)
+    (goto-char 10)
+    (delete-char 13)
+    (goto-char 11)
+    (delete-char 5)
+    (goto-char 15)
+    (insert "........")
+    (goto-char 26)
+    (delete-char 4)
+    (goto-char 11)
+    (delete-char 1)
+    (goto-char 14)
+    (insert "............")
+    (goto-char 33)
+    (insert ".")
+    (goto-char 10)
+    (insert "...")
+    (goto-char 30)
+    (widen)
+    (narrow-to-region 28 9)
+    (goto-char 27)
+    (delete-char 0)
+    (goto-char 27)
+    (delete-char 1)
+    (goto-char 26)
+    (insert "..")
+    (goto-char 27)
+    (insert "..")
+    (goto-char 20)
+    (delete-char 5)
+    (goto-char 12)
+    (widen)
+    (narrow-to-region 40 30)
+    (goto-char 37)
+    (delete-char 3)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((13 . 37)
+        (14 . 37)
+        (14 . 37)
+        (14 . 37)
+        (14 . 37)
+        (14 . 37)
+        (14 . 37)
+        (37 . 37)
+        (37 . 37))))))
+
+(ert-deftest overlay-autogenerated-test-41 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 28 48 nil nil t)
+    (make-overlay 30 11 nil nil t)
+    (make-overlay 7 12 nil t nil)
+    (make-overlay 65 35 nil t nil)
+    (make-overlay 22 61 nil t nil)
+    (make-overlay 37 42 nil nil nil)
+    (make-overlay 33 38 nil nil t)
+    (make-overlay 48 45 nil t t)
+    (make-overlay 45 62 nil t nil)
+    (make-overlay 63 7 nil nil t)
+    (make-overlay 23 42 nil t nil)
+    (make-overlay 21 4 nil t nil)
+    (make-overlay 64 41 nil t nil)
+    (make-overlay 20 33 nil t t)
+    (make-overlay 41 26 nil t nil)
+    (make-overlay 43 31 nil t t)
+    (goto-char 55)
+    (delete-char 3)
+    (goto-char 12)
+    (insert "..")
+    (goto-char 62)
+    (insert "")
+    (goto-char 24)
+    (delete-char 2)
+    (goto-char 41)
+    (insert "............")
+    (goto-char 2)
+    (insert ".")
+    (goto-char 55)
+    (insert "........")
+    (goto-char 67)
+    (delete-char 6)
+    (goto-char 58)
+    (delete-char 10)
+    (goto-char 29)
+    (insert "")
+    (goto-char 6)
+    (widen)
+    (narrow-to-region 44 45)
+    (goto-char 44)
+    (delete-char 1)
+    (goto-char 44)
+    (widen)
+    (narrow-to-region 24 37)
+    (goto-char 30)
+    (delete-char 7)
+    (goto-char 27)
+    (insert "......")
+    (goto-char 35)
+    (delete-char 0)
+    (goto-char 32)
+    (insert "...............")
+    (goto-char 37)
+    (delete-char 9)
+    (goto-char 40)
+    (insert "..........")
+    (goto-char 35)
+    (insert "......")
+    (goto-char 25)
+    (delete-char 7)
+    (goto-char 40)
+    (delete-char 4)
+    (goto-char 25)
+    (delete-char 14)
+    (goto-char 28)
+    (insert "")
+    (goto-char 28)
+    (widen)
+    (narrow-to-region 17 43)
+    (goto-char 20)
+    (insert "..........")
+    (goto-char 22)
+    (delete-char 2)
+    (goto-char 48)
+    (insert "............")
+    (goto-char 47)
+    (insert ".........")
+    (goto-char 69)
+    (widen)
+    (narrow-to-region 52 25)
+    (goto-char 26)
+    (insert "......")
+    (goto-char 53)
+    (insert "..")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((5 . 38)
+        (8 . 97)
+        (12 . 47)
+        (37 . 47)
+        (39 . 52)
+        (39 . 87)
+        (39 . 95)
+        (46 . 90)
+        (47 . 49)
+        (47 . 90)
+        (47 . 99)
+        (48 . 87))))))
+
+(ert-deftest overlay-autogenerated-test-42 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 20 23 nil nil nil)
+    (make-overlay 45 51 nil t nil)
+    (make-overlay 34 58 nil t nil)
+    (make-overlay 27 11 nil nil nil)
+    (make-overlay 14 8 nil t t)
+    (make-overlay 64 43 nil t nil)
+    (make-overlay 61 56 nil nil t)
+    (make-overlay 28 14 nil t nil)
+    (make-overlay 21 46 nil t t)
+    (make-overlay 30 34 nil t t)
+    (make-overlay 47 40 nil nil nil)
+    (make-overlay 5 44 nil t t)
+    (make-overlay 11 45 nil nil nil)
+    (make-overlay 65 8 nil nil t)
+    (make-overlay 47 54 nil t t)
+    (make-overlay 37 57 nil t nil)
+    (goto-char 11)
+    (insert "....")
+    (goto-char 65)
+    (delete-char 0)
+    (goto-char 56)
+    (delete-char 4)
+    (goto-char 11)
+    (delete-char 2)
+    (goto-char 23)
+    (insert ".............")
+    (goto-char 2)
+    (insert "............")
+    (goto-char 84)
+    (delete-char 1)
+    (goto-char 10)
+    (insert "..............")
+    (goto-char 19)
+    (insert "............")
+    (goto-char 69)
+    (delete-char 6)
+    (goto-char 15)
+    (insert "........")
+    (goto-char 104)
+    (insert "")
+    (goto-char 94)
+    (delete-char 11)
+    (goto-char 66)
+    (insert ".....")
+    (goto-char 67)
+    (insert "")
+    (goto-char 53)
+    (delete-char 22)
+    (goto-char 42)
+    (insert ".")
+    (goto-char 38)
+    (delete-char 13)
+    (goto-char 27)
+    (insert "......")
+    (goto-char 16)
+    (insert "............")
+    (goto-char 71)
+    (widen)
+    (narrow-to-region 59 15)
+    (goto-char 46)
+    (insert "..")
+    (goto-char 20)
+    (widen)
+    (narrow-to-region 95 93)
+    (goto-char 94)
+    (insert ".............")
+    (goto-char 103)
+    (widen)
+    (narrow-to-region 97 7)
+    (goto-char 93)
+    (insert "....")
+    (goto-char 85)
+    (insert "...........")
+    (goto-char 69)
+    (delete-char 24)
+    (goto-char 87)
+    (insert ".............")
+    (goto-char 7)
+    (delete-char 28)
+    (goto-char 65)
+    (delete-char 8)
+    (goto-char 48)
+    (insert "......")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((31 . 44)
+        (33 . 33)
+        (33 . 41)
+        (33 . 41)
+        (33 . 41)
+        (33 . 41)
+        (33 . 82)
+        (40 . 44)
+        (41 . 41)
+        (41 . 41)
+        (41 . 47)
+        (41 . 48)
+        (44 . 45)
+        (44 . 46)
+        (44 . 63)
+        (46 . 57))))))
+
+(ert-deftest overlay-autogenerated-test-43 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 8 53 nil t nil)
+    (make-overlay 11 50 nil t nil)
+    (make-overlay 1 30 nil nil nil)
+    (make-overlay 54 15 nil t t)
+    (make-overlay 22 30 nil nil nil)
+    (make-overlay 1 33 nil nil nil)
+    (make-overlay 18 15 nil t nil)
+    (make-overlay 43 39 nil nil t)
+    (make-overlay 43 17 nil t nil)
+    (make-overlay 2 29 nil t nil)
+    (make-overlay 57 42 nil t nil)
+    (make-overlay 40 1 nil nil nil)
+    (make-overlay 8 64 nil nil nil)
+    (make-overlay 64 15 nil nil nil)
+    (make-overlay 9 11 nil nil t)
+    (make-overlay 40 21 nil t nil)
+    (goto-char 5)
+    (delete-char 37)
+    (goto-char 25)
+    (delete-char 2)
+    (goto-char 17)
+    (insert "...........")
+    (goto-char 19)
+    (widen)
+    (narrow-to-region 20 20)
+    (goto-char 20)
+    (delete-char 0)
+    (goto-char 20)
+    (insert "..........")
+    (goto-char 24)
+    (delete-char 5)
+    (goto-char 24)
+    (insert "...")
+    (goto-char 28)
+    (widen)
+    (narrow-to-region 20 36)
+    (goto-char 26)
+    (delete-char 2)
+    (goto-char 31)
+    (insert ".............")
+    (goto-char 22)
+    (insert ".....")
+    (goto-char 38)
+    (delete-char 0)
+    (goto-char 31)
+    (delete-char 4)
+    (goto-char 27)
+    (insert "...")
+    (goto-char 23)
+    (widen)
+    (narrow-to-region 37 20)
+    (goto-char 22)
+    (insert ".............")
+    (goto-char 33)
+    (insert "......")
+    (goto-char 43)
+    (insert "............")
+    (goto-char 59)
+    (insert ".......")
+    (goto-char 25)
+    (delete-char 26)
+    (goto-char 49)
+    (insert ".........")
+    (goto-char 50)
+    (insert ".......")
+    (goto-char 39)
+    (widen)
+    (narrow-to-region 54 86)
+    (goto-char 64)
+    (insert "...............")
+    (goto-char 83)
+    (insert "............")
+    (goto-char 70)
+    (insert "........")
+    (goto-char 58)
+    (insert "..............")
+    (goto-char 83)
+    (insert "............")
+    (goto-char 83)
+    (insert "..........")
+    (goto-char 69)
+    (delete-char 75)
+    (goto-char 75)
+    (delete-char 3)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((5 . 75)
+        (5 . 75)
+        (5 . 80)
+        (5 . 80))))))
+
+(ert-deftest overlay-autogenerated-test-44 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 8 48 nil nil t)
+    (make-overlay 52 38 nil nil nil)
+    (make-overlay 3 63 nil nil nil)
+    (make-overlay 44 15 nil nil t)
+    (make-overlay 27 44 nil nil t)
+    (make-overlay 43 9 nil nil t)
+    (make-overlay 11 27 nil t nil)
+    (make-overlay 36 41 nil nil t)
+    (make-overlay 23 25 nil t t)
+    (make-overlay 19 60 nil t t)
+    (make-overlay 11 55 nil t nil)
+    (make-overlay 59 2 nil t nil)
+    (make-overlay 32 64 nil t nil)
+    (make-overlay 15 8 nil nil nil)
+    (make-overlay 61 15 nil nil nil)
+    (make-overlay 64 30 nil t t)
+    (goto-char 42)
+    (delete-char 20)
+    (goto-char 44)
+    (delete-char 1)
+    (goto-char 43)
+    (insert "...........")
+    (goto-char 43)
+    (delete-char 1)
+    (goto-char 28)
+    (delete-char 8)
+    (goto-char 37)
+    (delete-char 9)
+    (goto-char 4)
+    (delete-char 30)
+    (goto-char 6)
+    (delete-char 0)
+    (goto-char 7)
+    (delete-char 0)
+    (goto-char 2)
+    (delete-char 2)
+    (goto-char 5)
+    (delete-char 0)
+    (goto-char 5)
+    (delete-char 0)
+    (goto-char 2)
+    (insert ".....")
+    (goto-char 10)
+    (insert "...........")
+    (goto-char 21)
+    (insert "...")
+    (goto-char 10)
+    (delete-char 13)
+    (goto-char 9)
+    (insert "..........")
+    (goto-char 16)
+    (delete-char 1)
+    (goto-char 16)
+    (delete-char 4)
+    (goto-char 16)
+    (delete-char 0)
+    (goto-char 14)
+    (delete-char 1)
+    (goto-char 3)
+    (widen)
+    (narrow-to-region 2 9)
+    (goto-char 2)
+    (insert "")
+    (goto-char 2)
+    (insert ".............")
+    (goto-char 17)
+    (insert "....")
+    (goto-char 12)
+    (insert "........")
+    (goto-char 8)
+    (widen)
+    (narrow-to-region 32 23)
+    (goto-char 29)
+    (insert ".....")
+    (goto-char 35)
+    (delete-char 2)
+    (goto-char 27)
+    (delete-char 7)
+    (goto-char 23)
+    (widen)
+    (narrow-to-region 4 14)
+    (goto-char 8)
+    (insert "...............")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((2 . 43)
+        (2 . 43)
+        (2 . 43)
+        (2 . 43)
+        (2 . 43)
+        (2 . 44))))))
+
+(ert-deftest overlay-autogenerated-test-45 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 15 48 nil nil nil)
+    (make-overlay 1 47 nil t nil)
+    (make-overlay 43 4 nil t t)
+    (make-overlay 9 45 nil t t)
+    (make-overlay 1 25 nil t t)
+    (make-overlay 5 46 nil t t)
+    (make-overlay 7 14 nil t nil)
+    (make-overlay 1 53 nil nil t)
+    (make-overlay 13 41 nil t nil)
+    (make-overlay 5 31 nil t t)
+    (make-overlay 26 10 nil nil nil)
+    (make-overlay 56 37 nil nil nil)
+    (make-overlay 23 15 nil t nil)
+    (make-overlay 62 30 nil t t)
+    (make-overlay 2 35 nil t t)
+    (make-overlay 46 41 nil nil nil)
+    (goto-char 65)
+    (delete-char 0)
+    (goto-char 55)
+    (insert "...........")
+    (goto-char 22)
+    (insert "")
+    (goto-char 73)
+    (delete-char 3)
+    (goto-char 43)
+    (widen)
+    (narrow-to-region 54 63)
+    (goto-char 56)
+    (insert "......")
+    (goto-char 61)
+    (delete-char 3)
+    (goto-char 65)
+    (insert "......")
+    (goto-char 66)
+    (insert ".....")
+    (goto-char 62)
+    (insert ".")
+    (goto-char 74)
+    (insert ".........")
+    (goto-char 76)
+    (delete-char 4)
+    (goto-char 56)
+    (widen)
+    (narrow-to-region 2 46)
+    (goto-char 43)
+    (insert "...........")
+    (goto-char 20)
+    (delete-char 4)
+    (goto-char 38)
+    (delete-char 7)
+    (goto-char 25)
+    (delete-char 21)
+    (goto-char 12)
+    (insert ".........")
+    (goto-char 19)
+    (widen)
+    (narrow-to-region 72 61)
+    (goto-char 63)
+    (insert "")
+    (goto-char 65)
+    (delete-char 4)
+    (goto-char 61)
+    (delete-char 5)
+    (goto-char 63)
+    (delete-char 0)
+    (goto-char 63)
+    (delete-char 0)
+    (goto-char 62)
+    (delete-char 0)
+    (goto-char 61)
+    (insert "............")
+    (goto-char 72)
+    (insert "..............")
+    (goto-char 62)
+    (delete-char 7)
+    (goto-char 71)
+    (delete-char 5)
+    (goto-char 75)
+    (widen)
+    (narrow-to-region 29 8)
+    (goto-char 17)
+    (delete-char 2)
+    (goto-char 27)
+    (insert "........")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 36)
+        (1 . 41)
+        (1 . 47)
+        (2 . 40)
+        (4 . 40)
+        (5 . 40)
+        (5 . 40)
+        (7 . 21)
+        (9 . 40)
+        (10 . 37)
+        (20 . 40)
+        (22 . 27)
+        (22 . 42))))))
+
+(ert-deftest overlay-autogenerated-test-46 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 2 43 nil nil t)
+    (make-overlay 44 40 nil nil t)
+    (make-overlay 49 14 nil nil t)
+    (make-overlay 6 55 nil nil nil)
+    (make-overlay 13 52 nil t t)
+    (make-overlay 40 54 nil t nil)
+    (make-overlay 51 41 nil nil t)
+    (make-overlay 7 28 nil nil t)
+    (make-overlay 10 47 nil nil t)
+    (make-overlay 63 21 nil t nil)
+    (make-overlay 4 55 nil nil nil)
+    (make-overlay 52 58 nil t nil)
+    (make-overlay 62 11 nil t t)
+    (make-overlay 22 49 nil t nil)
+    (make-overlay 23 65 nil nil nil)
+    (make-overlay 50 33 nil nil t)
+    (goto-char 22)
+    (insert "..............")
+    (goto-char 12)
+    (insert "....")
+    (goto-char 25)
+    (delete-char 16)
+    (goto-char 14)
+    (delete-char 53)
+    (goto-char 2)
+    (insert "............")
+    (goto-char 20)
+    (delete-char 5)
+    (goto-char 11)
+    (delete-char 7)
+    (goto-char 9)
+    (widen)
+    (narrow-to-region 11 7)
+    (goto-char 8)
+    (insert "...............")
+    (goto-char 12)
+    (delete-char 4)
+    (goto-char 21)
+    (insert "...")
+    (goto-char 20)
+    (delete-char 5)
+    (goto-char 7)
+    (delete-char 3)
+    (goto-char 16)
+    (delete-char 0)
+    (goto-char 12)
+    (delete-char 1)
+    (goto-char 15)
+    (delete-char 0)
+    (goto-char 7)
+    (insert "..............")
+    (goto-char 17)
+    (insert "...........")
+    (goto-char 15)
+    (insert "............")
+    (goto-char 20)
+    (delete-char 5)
+    (goto-char 7)
+    (insert "....")
+    (goto-char 37)
+    (delete-char 7)
+    (goto-char 8)
+    (insert "..........")
+    (goto-char 47)
+    (insert ".............")
+    (goto-char 65)
+    (insert ".......")
+    (goto-char 39)
+    (delete-char 26)
+    (goto-char 14)
+    (delete-char 2)
+    (goto-char 27)
+    (insert ".............")
+    (goto-char 17)
+    (widen)
+    (narrow-to-region 54 32)
+    (goto-char 40)
+    (widen)
+    (narrow-to-region 10 3)
+    (goto-char 7)
+    (insert "........")
+    (goto-char 13)
+    (insert "..............")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((2 . 85))))))
+
+(ert-deftest overlay-autogenerated-test-47 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 58 62 nil t nil)
+    (make-overlay 14 38 nil nil nil)
+    (make-overlay 63 44 nil t t)
+    (make-overlay 41 41 nil nil t)
+    (make-overlay 19 39 nil nil nil)
+    (make-overlay 10 49 nil t t)
+    (make-overlay 56 38 nil t t)
+    (make-overlay 23 38 nil nil t)
+    (make-overlay 1 64 nil nil t)
+    (make-overlay 21 3 nil t nil)
+    (make-overlay 1 1 nil nil t)
+    (make-overlay 27 61 nil nil nil)
+    (make-overlay 29 59 nil nil nil)
+    (make-overlay 37 30 nil t nil)
+    (make-overlay 47 21 nil nil t)
+    (make-overlay 34 26 nil t nil)
+    (goto-char 6)
+    (delete-char 44)
+    (goto-char 8)
+    (delete-char 0)
+    (goto-char 8)
+    (insert "....")
+    (goto-char 17)
+    (delete-char 2)
+    (goto-char 12)
+    (insert "...")
+    (goto-char 20)
+    (insert "")
+    (goto-char 2)
+    (delete-char 20)
+    (goto-char 1)
+    (insert ".........")
+    (goto-char 7)
+    (insert ".............")
+    (goto-char 27)
+    (delete-char 0)
+    (goto-char 15)
+    (insert "..........")
+    (goto-char 36)
+    (insert "..............")
+    (goto-char 26)
+    (insert "..............")
+    (goto-char 63)
+    (insert "...........")
+    (goto-char 9)
+    (insert "............")
+    (goto-char 71)
+    (delete-char 17)
+    (goto-char 36)
+    (insert "....")
+    (goto-char 45)
+    (delete-char 31)
+    (goto-char 28)
+    (delete-char 8)
+    (goto-char 10)
+    (delete-char 16)
+    (goto-char 14)
+    (delete-char 4)
+    (goto-char 16)
+    (delete-char 0)
+    (goto-char 15)
+    (insert "")
+    (goto-char 14)
+    (delete-char 1)
+    (goto-char 10)
+    (delete-char 2)
+    (goto-char 6)
+    (delete-char 0)
+    (goto-char 1)
+    (insert ".........")
+    (goto-char 23)
+    (insert "......")
+    (goto-char 25)
+    (insert "..........")
+    (goto-char 25)
+    (widen)
+    (narrow-to-region 10 30)
+    (goto-char 21)
+    (delete-char 1)
+    (goto-char 17)
+    (insert "..........")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 48)
+        (1 . 48)
+        (32 . 32)
+        (32 . 32)
+        (32 . 32)
+        (32 . 32)
+        (32 . 32)
+        (32 . 32)
+        (32 . 32)
+        (32 . 32)
+        (32 . 48)
+        (32 . 48)
+        (32 . 48))))))
+
+(ert-deftest overlay-autogenerated-test-48 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 1 11 nil nil nil)
+    (make-overlay 35 29 nil t t)
+    (make-overlay 24 46 nil nil t)
+    (make-overlay 15 43 nil nil t)
+    (make-overlay 51 49 nil t t)
+    (make-overlay 25 43 nil t nil)
+    (make-overlay 23 59 nil nil nil)
+    (make-overlay 10 4 nil t nil)
+    (make-overlay 40 45 nil nil nil)
+    (make-overlay 42 43 nil nil t)
+    (make-overlay 20 38 nil t nil)
+    (make-overlay 17 49 nil nil nil)
+    (make-overlay 9 25 nil nil t)
+    (make-overlay 13 19 nil nil nil)
+    (make-overlay 44 31 nil t nil)
+    (make-overlay 12 65 nil nil t)
+    (goto-char 59)
+    (widen)
+    (narrow-to-region 28 14)
+    (goto-char 26)
+    (insert "...")
+    (goto-char 30)
+    (delete-char 1)
+    (goto-char 23)
+    (insert "...")
+    (goto-char 27)
+    (widen)
+    (narrow-to-region 45 67)
+    (goto-char 50)
+    (insert "...............")
+    (goto-char 59)
+    (insert "..............")
+    (goto-char 55)
+    (insert ".............")
+    (goto-char 106)
+    (delete-char 0)
+    (goto-char 97)
+    (delete-char 10)
+    (goto-char 67)
+    (delete-char 16)
+    (goto-char 76)
+    (insert "..............")
+    (goto-char 71)
+    (insert ".............")
+    (goto-char 110)
+    (delete-char 0)
+    (goto-char 56)
+    (delete-char 38)
+    (goto-char 61)
+    (delete-char 10)
+    (goto-char 56)
+    (delete-char 5)
+    (goto-char 49)
+    (insert ".......")
+    (goto-char 62)
+    (insert "...")
+    (goto-char 54)
+    (insert "..........")
+    (goto-char 47)
+    (delete-char 10)
+    (goto-char 47)
+    (delete-char 20)
+    (goto-char 46)
+    (insert ".............")
+    (goto-char 56)
+    (insert "...........")
+    (goto-char 70)
+    (delete-char 1)
+    (goto-char 62)
+    (widen)
+    (narrow-to-region 50 64)
+    (goto-char 60)
+    (insert "..")
+    (goto-char 55)
+    (delete-char 6)
+    (goto-char 60)
+    (insert ".............")
+    (goto-char 61)
+    (delete-char 9)
+    (goto-char 64)
+    (delete-char 0)
+    (goto-char 53)
+    (widen)
+    (narrow-to-region 15 62)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((9 . 28)
+        (12 . 73)
+        (13 . 19)
+        (15 . 70)
+        (17 . 70)
+        (20 . 43)
+        (23 . 70)
+        (27 . 70)
+        (28 . 70)
+        (34 . 40)
+        (36 . 70)
+        (45 . 70))))))
+
+(ert-deftest overlay-autogenerated-test-49 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 24 10 nil nil t)
+    (make-overlay 53 23 nil t nil)
+    (make-overlay 53 9 nil nil t)
+    (make-overlay 65 64 nil t t)
+    (make-overlay 48 2 nil nil t)
+    (make-overlay 12 58 nil nil t)
+    (make-overlay 64 64 nil nil nil)
+    (make-overlay 26 13 nil t t)
+    (make-overlay 46 26 nil nil t)
+    (make-overlay 28 59 nil t t)
+    (make-overlay 33 52 nil nil nil)
+    (make-overlay 39 8 nil t t)
+    (make-overlay 9 59 nil t t)
+    (make-overlay 50 45 nil nil t)
+    (make-overlay 41 53 nil nil t)
+    (make-overlay 51 51 nil t nil)
+    (goto-char 61)
+    (insert "..............")
+    (goto-char 19)
+    (widen)
+    (narrow-to-region 10 65)
+    (goto-char 65)
+    (delete-char 0)
+    (goto-char 11)
+    (insert "...............")
+    (goto-char 77)
+    (delete-char 0)
+    (goto-char 51)
+    (insert "...")
+    (goto-char 75)
+    (insert ".....")
+    (goto-char 77)
+    (delete-char 11)
+    (goto-char 45)
+    (delete-char 0)
+    (goto-char 24)
+    (widen)
+    (narrow-to-region 33 52)
+    (goto-char 46)
+    (insert "..............")
+    (goto-char 46)
+    (insert "..........")
+    (goto-char 39)
+    (widen)
+    (narrow-to-region 46 77)
+    (goto-char 77)
+    (insert "..............")
+    (goto-char 54)
+    (insert ".......")
+    (goto-char 87)
+    (insert ".")
+    (goto-char 70)
+    (delete-char 16)
+    (goto-char 79)
+    (delete-char 0)
+    (goto-char 73)
+    (widen)
+    (narrow-to-region 74 100)
+    (goto-char 91)
+    (insert ".............")
+    (goto-char 80)
+    (delete-char 11)
+    (goto-char 82)
+    (insert "......")
+    (goto-char 108)
+    (delete-char 0)
+    (goto-char 104)
+    (insert ".....")
+    (goto-char 100)
+    (delete-char 1)
+    (goto-char 90)
+    (insert ".............")
+    (goto-char 99)
+    (insert ".............")
+    (goto-char 124)
+    (insert "..............")
+    (goto-char 114)
+    (insert "....")
+    (goto-char 134)
+    (delete-char 0)
+    (goto-char 89)
+    (delete-char 65)
+    (goto-char 75)
+    (delete-char 16)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((2 . 75)
+        (8 . 75)
+        (9 . 76)
+        (9 . 82)
+        (27 . 82)
+        (38 . 76)
+        (41 . 75)
+        (43 . 82)
+        (70 . 75))))))
+
+(ert-deftest overlay-autogenerated-test-50 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 29 53 nil t t)
+    (make-overlay 65 64 nil nil nil)
+    (make-overlay 3 31 nil nil t)
+    (make-overlay 45 59 nil t nil)
+    (make-overlay 60 37 nil t t)
+    (make-overlay 7 5 nil t t)
+    (make-overlay 37 24 nil nil nil)
+    (make-overlay 45 20 nil nil nil)
+    (make-overlay 33 42 nil nil t)
+    (make-overlay 47 57 nil t nil)
+    (make-overlay 14 49 nil t t)
+    (make-overlay 14 30 nil t nil)
+    (make-overlay 21 40 nil t t)
+    (make-overlay 5 45 nil t t)
+    (make-overlay 59 40 nil t t)
+    (make-overlay 37 52 nil nil nil)
+    (goto-char 48)
+    (insert "")
+    (goto-char 7)
+    (insert ".........")
+    (goto-char 31)
+    (insert "...........")
+    (goto-char 41)
+    (delete-char 7)
+    (goto-char 21)
+    (delete-char 11)
+    (goto-char 41)
+    (widen)
+    (narrow-to-region 51 53)
+    (goto-char 52)
+    (insert ".....")
+    (goto-char 55)
+    (widen)
+    (narrow-to-region 18 24)
+    (goto-char 23)
+    (widen)
+    (narrow-to-region 39 38)
+    (goto-char 38)
+    (insert ".............")
+    (goto-char 41)
+    (insert "......")
+    (goto-char 38)
+    (insert "..............")
+    (goto-char 52)
+    (insert "...............")
+    (goto-char 78)
+    (delete-char 5)
+    (goto-char 50)
+    (insert "..........")
+    (goto-char 50)
+    (delete-char 3)
+    (goto-char 85)
+    (widen)
+    (narrow-to-region 86 1)
+    (goto-char 5)
+    (insert "....")
+    (goto-char 69)
+    (insert "...........")
+    (goto-char 94)
+    (insert "......")
+    (goto-char 98)
+    (delete-char 7)
+    (goto-char 46)
+    (insert "...............")
+    (goto-char 79)
+    (insert "............")
+    (goto-char 89)
+    (insert "")
+    (goto-char 14)
+    (delete-char 63)
+    (goto-char 20)
+    (insert ".........")
+    (goto-char 34)
+    (insert "...")
+    (goto-char 53)
+    (delete-char 14)
+    (goto-char 6)
+    (widen)
+    (narrow-to-region 6 52)
+    (goto-char 42)
+    (insert "...........")
+    (goto-char 40)
+    (insert ".......")
+    (goto-char 46)
+    (widen)
+    (narrow-to-region 1 68)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((3 . 14)
+        (9 . 14)
+        (9 . 91)
+        (14 . 14)
+        (14 . 83)
+        (14 . 86)
+        (14 . 88)
+        (14 . 91)
+        (14 . 95)
+        (14 . 104))))))
+
+(ert-deftest overlay-autogenerated-test-51 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 14 5 nil t nil)
+    (make-overlay 62 34 nil nil t)
+    (make-overlay 7 62 nil nil t)
+    (make-overlay 23 12 nil t t)
+    (make-overlay 16 4 nil nil nil)
+    (make-overlay 24 15 nil nil nil)
+    (make-overlay 6 6 nil t t)
+    (make-overlay 25 64 nil t t)
+    (make-overlay 23 6 nil t t)
+    (make-overlay 55 64 nil nil nil)
+    (make-overlay 8 62 nil nil t)
+    (make-overlay 65 65 nil nil nil)
+    (make-overlay 57 51 nil t t)
+    (make-overlay 35 8 nil t nil)
+    (make-overlay 55 13 nil nil t)
+    (make-overlay 60 62 nil nil t)
+    (goto-char 12)
+    (insert "..")
+    (goto-char 66)
+    (insert "............")
+    (goto-char 32)
+    (insert "..")
+    (goto-char 27)
+    (insert ".........")
+    (goto-char 8)
+    (insert ".............")
+    (goto-char 79)
+    (insert ".")
+    (goto-char 47)
+    (insert "....")
+    (goto-char 49)
+    (insert "...")
+    (goto-char 81)
+    (insert "....")
+    (goto-char 112)
+    (delete-char 0)
+    (goto-char 97)
+    (insert ".....")
+    (goto-char 109)
+    (delete-char 5)
+    (goto-char 20)
+    (insert ".....")
+    (goto-char 59)
+    (delete-char 33)
+    (goto-char 87)
+    (insert ".............")
+    (goto-char 98)
+    (insert "....")
+    (goto-char 22)
+    (delete-char 36)
+    (goto-char 45)
+    (insert "..............")
+    (goto-char 42)
+    (delete-char 29)
+    (goto-char 51)
+    (widen)
+    (narrow-to-region 39 41)
+    (goto-char 39)
+    (delete-char 2)
+    (goto-char 39)
+    (insert ".............")
+    (goto-char 51)
+    (insert "......")
+    (goto-char 52)
+    (insert "...............")
+    (goto-char 56)
+    (widen)
+    (narrow-to-region 59 20)
+    (goto-char 56)
+    (insert "............")
+    (goto-char 57)
+    (insert ".")
+    (goto-char 37)
+    (delete-char 12)
+    (goto-char 39)
+    (delete-char 11)
+    (goto-char 38)
+    (delete-char 8)
+    (goto-char 36)
+    (widen)
+    (narrow-to-region 65 26)
+    (goto-char 40)
+    (widen)
+    (narrow-to-region 27 55)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((7 . 55)
+        (8 . 55)
+        (22 . 29)
+        (23 . 55)
+        (23 . 56)
+        (24 . 31)
+        (29 . 56)
+        (37 . 55))))))
+
+(ert-deftest overlay-autogenerated-test-52 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 58 32 nil nil nil)
+    (make-overlay 44 54 nil nil t)
+    (make-overlay 27 50 nil nil nil)
+    (make-overlay 55 35 nil nil t)
+    (make-overlay 40 46 nil nil t)
+    (make-overlay 56 63 nil t nil)
+    (make-overlay 29 48 nil nil nil)
+    (make-overlay 45 24 nil t nil)
+    (make-overlay 60 25 nil t nil)
+    (make-overlay 55 41 nil t nil)
+    (make-overlay 55 1 nil nil t)
+    (make-overlay 30 45 nil t t)
+    (make-overlay 26 19 nil nil t)
+    (make-overlay 61 5 nil nil nil)
+    (make-overlay 33 5 nil nil nil)
+    (make-overlay 42 18 nil t nil)
+    (goto-char 55)
+    (insert ".")
+    (goto-char 49)
+    (delete-char 12)
+    (goto-char 41)
+    (insert "..........")
+    (goto-char 27)
+    (insert ".....")
+    (goto-char 58)
+    (insert "...........")
+    (goto-char 24)
+    (delete-char 23)
+    (goto-char 47)
+    (delete-char 9)
+    (goto-char 4)
+    (insert "...")
+    (goto-char 10)
+    (delete-char 32)
+    (goto-char 4)
+    (insert "..............")
+    (goto-char 29)
+    (insert "....")
+    (goto-char 28)
+    (delete-char 2)
+    (goto-char 34)
+    (insert "...........")
+    (goto-char 9)
+    (insert "......")
+    (goto-char 5)
+    (insert "")
+    (goto-char 45)
+    (delete-char 1)
+    (goto-char 18)
+    (insert ".........")
+    (goto-char 36)
+    (delete-char 5)
+    (goto-char 15)
+    (delete-char 27)
+    (goto-char 15)
+    (delete-char 10)
+    (goto-char 16)
+    (delete-char 2)
+    (goto-char 16)
+    (widen)
+    (narrow-to-region 10 2)
+    (goto-char 9)
+    (delete-char 1)
+    (goto-char 3)
+    (delete-char 2)
+    (goto-char 2)
+    (widen)
+    (narrow-to-region 9 10)
+    (goto-char 9)
+    (insert "...........")
+    (goto-char 19)
+    (delete-char 0)
+    (goto-char 14)
+    (delete-char 3)
+    (goto-char 11)
+    (delete-char 2)
+    (goto-char 9)
+    (delete-char 6)
+    (goto-char 9)
+    (delete-char 0)
+    (goto-char 10)
+    (insert "....")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 17))))))
+
+(ert-deftest overlay-autogenerated-test-53 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 10 30 nil nil nil)
+    (make-overlay 11 57 nil t nil)
+    (make-overlay 59 56 nil nil t)
+    (make-overlay 20 37 nil nil t)
+    (make-overlay 41 29 nil nil nil)
+    (make-overlay 31 10 nil nil t)
+    (make-overlay 6 36 nil nil nil)
+    (make-overlay 12 54 nil nil nil)
+    (make-overlay 25 26 nil t t)
+    (make-overlay 21 19 nil nil t)
+    (make-overlay 1 21 nil nil t)
+    (make-overlay 48 51 nil nil nil)
+    (make-overlay 54 55 nil t nil)
+    (make-overlay 64 48 nil t t)
+    (make-overlay 56 25 nil nil t)
+    (make-overlay 12 60 nil t nil)
+    (goto-char 41)
+    (delete-char 1)
+    (goto-char 63)
+    (insert "")
+    (goto-char 14)
+    (delete-char 5)
+    (goto-char 11)
+    (insert "..............")
+    (goto-char 41)
+    (widen)
+    (narrow-to-region 12 1)
+    (goto-char 1)
+    (delete-char 3)
+    (goto-char 9)
+    (delete-char 0)
+    (goto-char 5)
+    (insert "..............")
+    (goto-char 1)
+    (insert "..........")
+    (goto-char 29)
+    (insert "...............")
+    (goto-char 4)
+    (insert "..")
+    (goto-char 31)
+    (delete-char 15)
+    (goto-char 31)
+    (insert "")
+    (goto-char 27)
+    (insert "......")
+    (goto-char 6)
+    (insert "...")
+    (goto-char 23)
+    (widen)
+    (narrow-to-region 23 47)
+    (goto-char 37)
+    (delete-char 2)
+    (goto-char 35)
+    (delete-char 5)
+    (goto-char 38)
+    (delete-char 2)
+    (goto-char 30)
+    (insert ".......")
+    (goto-char 45)
+    (widen)
+    (narrow-to-region 13 2)
+    (goto-char 9)
+    (delete-char 1)
+    (goto-char 3)
+    (insert ".....")
+    (goto-char 2)
+    (insert "...............")
+    (goto-char 16)
+    (delete-char 5)
+    (goto-char 20)
+    (insert ".....")
+    (goto-char 26)
+    (delete-char 0)
+    (goto-char 26)
+    (widen)
+    (narrow-to-region 76 98)
+    (goto-char 88)
+    (insert ".........")
+    (goto-char 92)
+    (insert ".")
+    (goto-char 108)
+    (delete-char 0)
+    (goto-char 103)
+    (delete-char 3)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 79)
+        (37 . 103)
+        (61 . 88)
+        (61 . 99)
+        (74 . 121)
+        (75 . 118)
+        (75 . 124)
+        (77 . 79)
+        (78 . 103)
+        (83 . 84)
+        (83 . 120)
+        (87 . 106))))))
+
+(ert-deftest overlay-autogenerated-test-54 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 58 36 nil t t)
+    (make-overlay 55 49 nil nil t)
+    (make-overlay 12 25 nil nil t)
+    (make-overlay 16 37 nil t t)
+    (make-overlay 42 25 nil t t)
+    (make-overlay 8 41 nil t t)
+    (make-overlay 13 27 nil nil t)
+    (make-overlay 52 22 nil t nil)
+    (make-overlay 36 17 nil t nil)
+    (make-overlay 1 52 nil t nil)
+    (make-overlay 55 5 nil nil t)
+    (make-overlay 50 50 nil t nil)
+    (make-overlay 32 15 nil t nil)
+    (make-overlay 39 26 nil t nil)
+    (make-overlay 26 4 nil nil nil)
+    (make-overlay 38 47 nil t t)
+    (goto-char 23)
+    (insert ".")
+    (goto-char 57)
+    (delete-char 6)
+    (goto-char 54)
+    (insert "..............")
+    (goto-char 46)
+    (insert "...............")
+    (goto-char 29)
+    (insert ".......")
+    (goto-char 58)
+    (delete-char 21)
+    (goto-char 45)
+    (delete-char 4)
+    (goto-char 50)
+    (delete-char 4)
+    (goto-char 20)
+    (insert ".........")
+    (goto-char 16)
+    (insert "......")
+    (goto-char 17)
+    (insert ".....")
+    (goto-char 63)
+    (insert "........")
+    (goto-char 83)
+    (insert "....")
+    (goto-char 73)
+    (delete-char 8)
+    (goto-char 69)
+    (insert "...........")
+    (goto-char 48)
+    (widen)
+    (narrow-to-region 19 31)
+    (goto-char 22)
+    (delete-char 3)
+    (goto-char 23)
+    (delete-char 5)
+    (goto-char 20)
+    (insert "............")
+    (goto-char 23)
+    (delete-char 11)
+    (goto-char 19)
+    (insert "..........")
+    (goto-char 23)
+    (insert "........")
+    (goto-char 38)
+    (delete-char 1)
+    (goto-char 33)
+    (delete-char 5)
+    (goto-char 27)
+    (insert "..........")
+    (goto-char 35)
+    (delete-char 8)
+    (goto-char 35)
+    (insert ".")
+    (goto-char 20)
+    (insert "......")
+    (goto-char 22)
+    (delete-char 22)
+    (goto-char 23)
+    (delete-char 0)
+    (goto-char 22)
+    (widen)
+    (narrow-to-region 1 41)
+    (goto-char 13)
+    (insert ".......")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 83)
+        (4 . 46)
+        (5 . 97)
+        (8 . 83)
+        (12 . 45)
+        (13 . 47)
+        (22 . 59)
+        (30 . 82)
+        (30 . 83)
+        (41 . 83)
+        (45 . 83)
+        (46 . 83))))))
+
+(ert-deftest overlay-autogenerated-test-55 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 58 20 nil nil nil)
+    (make-overlay 60 33 nil t nil)
+    (make-overlay 6 27 nil nil nil)
+    (make-overlay 53 31 nil nil t)
+    (make-overlay 30 55 nil t t)
+    (make-overlay 4 64 nil t t)
+    (make-overlay 51 31 nil nil t)
+    (make-overlay 4 65 nil t t)
+    (make-overlay 57 62 nil t t)
+    (make-overlay 28 7 nil nil t)
+    (make-overlay 61 48 nil t nil)
+    (make-overlay 23 54 nil nil t)
+    (make-overlay 47 49 nil nil nil)
+    (make-overlay 12 52 nil t nil)
+    (make-overlay 39 57 nil t t)
+    (make-overlay 28 61 nil nil t)
+    (goto-char 8)
+    (insert "..............")
+    (goto-char 63)
+    (delete-char 3)
+    (goto-char 67)
+    (delete-char 6)
+    (goto-char 3)
+    (widen)
+    (narrow-to-region 10 67)
+    (goto-char 43)
+    (insert ".............")
+    (goto-char 20)
+    (insert "...............")
+    (goto-char 18)
+    (insert "..")
+    (goto-char 37)
+    (delete-char 47)
+    (goto-char 34)
+    (insert "..............")
+    (goto-char 31)
+    (delete-char 2)
+    (goto-char 16)
+    (widen)
+    (narrow-to-region 29 36)
+    (goto-char 31)
+    (delete-char 2)
+    (goto-char 31)
+    (insert ".......")
+    (goto-char 40)
+    (delete-char 0)
+    (goto-char 32)
+    (widen)
+    (narrow-to-region 40 19)
+    (goto-char 40)
+    (insert "..")
+    (goto-char 37)
+    (delete-char 0)
+    (goto-char 40)
+    (delete-char 1)
+    (goto-char 34)
+    (delete-char 4)
+    (goto-char 33)
+    (insert "..............")
+    (goto-char 19)
+    (widen)
+    (narrow-to-region 78 70)
+    (goto-char 77)
+    (insert ".........")
+    (goto-char 80)
+    (delete-char 1)
+    (goto-char 73)
+    (delete-char 3)
+    (goto-char 70)
+    (insert ".........")
+    (goto-char 75)
+    (delete-char 10)
+    (goto-char 74)
+    (delete-char 3)
+    (goto-char 73)
+    (insert "...............")
+    (goto-char 90)
+    (insert "......")
+    (goto-char 94)
+    (insert "..............")
+    (goto-char 101)
+    (insert "........")
+    (goto-char 111)
+    (insert "........")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((4 . 132)
+        (4 . 133)
+        (65 . 89)
+        (65 . 89)
+        (65 . 89)
+        (65 . 89)
+        (65 . 129)
+        (65 . 130)
+        (65 . 130)
+        (65 . 130)
+        (65 . 130)
+        (89 . 89)
+        (89 . 130))))))
+
+(ert-deftest overlay-autogenerated-test-56 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 7 14 nil nil t)
+    (make-overlay 10 10 nil nil t)
+    (make-overlay 21 23 nil nil t)
+    (make-overlay 4 44 nil t nil)
+    (make-overlay 42 16 nil t t)
+    (make-overlay 1 57 nil t nil)
+    (make-overlay 15 27 nil nil nil)
+    (make-overlay 31 1 nil t nil)
+    (make-overlay 56 45 nil t t)
+    (make-overlay 46 19 nil t nil)
+    (make-overlay 15 6 nil nil nil)
+    (make-overlay 31 26 nil nil t)
+    (make-overlay 39 41 nil t t)
+    (make-overlay 52 48 nil nil t)
+    (make-overlay 44 2 nil t nil)
+    (make-overlay 60 7 nil nil t)
+    (goto-char 49)
+    (delete-char 11)
+    (goto-char 43)
+    (delete-char 9)
+    (goto-char 42)
+    (delete-char 2)
+    (goto-char 12)
+    (insert "...........")
+    (goto-char 36)
+    (insert ".........")
+    (goto-char 1)
+    (insert "......")
+    (goto-char 67)
+    (delete-char 0)
+    (goto-char 47)
+    (insert ".............")
+    (goto-char 57)
+    (insert "........")
+    (goto-char 22)
+    (widen)
+    (narrow-to-region 75 33)
+    (goto-char 41)
+    (delete-char 28)
+    (goto-char 43)
+    (delete-char 0)
+    (goto-char 33)
+    (delete-char 5)
+    (goto-char 38)
+    (insert "..")
+    (goto-char 42)
+    (delete-char 0)
+    (goto-char 38)
+    (delete-char 0)
+    (goto-char 38)
+    (insert "............")
+    (goto-char 51)
+    (insert ".......")
+    (goto-char 48)
+    (insert "..")
+    (goto-char 55)
+    (insert ".")
+    (goto-char 33)
+    (delete-char 8)
+    (goto-char 42)
+    (insert "..")
+    (goto-char 45)
+    (insert "..")
+    (goto-char 59)
+    (insert ".............")
+    (goto-char 53)
+    (insert ".......")
+    (goto-char 81)
+    (delete-char 0)
+    (goto-char 44)
+    (delete-char 36)
+    (goto-char 38)
+    (delete-char 8)
+    (goto-char 33)
+    (insert ".............")
+    (goto-char 41)
+    (insert "..............")
+    (goto-char 65)
+    (insert "...............")
+    (goto-char 61)
+    (insert "...")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((7 . 86)
+        (7 . 97)
+        (8 . 97)
+        (10 . 97)
+        (13 . 97)
+        (32 . 68)
+        (33 . 60)
+        (60 . 97)
+        (60 . 97)
+        (68 . 86))))))
+
+(ert-deftest overlay-autogenerated-test-57 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 52 31 nil t nil)
+    (make-overlay 39 17 nil t nil)
+    (make-overlay 19 20 nil t t)
+    (make-overlay 18 3 nil nil t)
+    (make-overlay 19 47 nil nil t)
+    (make-overlay 38 54 nil nil nil)
+    (make-overlay 30 51 nil nil t)
+    (make-overlay 29 60 nil t t)
+    (make-overlay 57 38 nil nil nil)
+    (make-overlay 13 41 nil t nil)
+    (make-overlay 9 44 nil t nil)
+    (make-overlay 30 55 nil t nil)
+    (make-overlay 33 10 nil nil nil)
+    (make-overlay 14 35 nil nil t)
+    (make-overlay 53 50 nil t nil)
+    (make-overlay 25 28 nil nil t)
+    (goto-char 40)
+    (insert "..")
+    (goto-char 64)
+    (insert "........")
+    (goto-char 47)
+    (insert "............")
+    (goto-char 65)
+    (delete-char 0)
+    (goto-char 86)
+    (delete-char 1)
+    (goto-char 59)
+    (delete-char 11)
+    (goto-char 64)
+    (delete-char 8)
+    (goto-char 53)
+    (delete-char 0)
+    (goto-char 28)
+    (delete-char 8)
+    (goto-char 6)
+    (delete-char 33)
+    (goto-char 14)
+    (delete-char 2)
+    (goto-char 2)
+    (delete-char 10)
+    (goto-char 3)
+    (insert "..")
+    (goto-char 5)
+    (insert ".........")
+    (goto-char 1)
+    (insert "........")
+    (goto-char 10)
+    (delete-char 4)
+    (goto-char 26)
+    (insert "........")
+    (goto-char 23)
+    (insert "....")
+    (goto-char 1)
+    (widen)
+    (narrow-to-region 15 23)
+    (goto-char 19)
+    (insert "...")
+    (goto-char 24)
+    (delete-char 0)
+    (goto-char 19)
+    (insert ".......")
+    (goto-char 18)
+    (insert "..")
+    (goto-char 33)
+    (insert "...")
+    (goto-char 32)
+    (insert "...............")
+    (goto-char 29)
+    (delete-char 10)
+    (goto-char 29)
+    (insert "..........")
+    (goto-char 50)
+    (insert "")
+    (goto-char 16)
+    (insert ".........")
+    (goto-char 52)
+    (widen)
+    (narrow-to-region 59 15)
+    (goto-char 35)
+    (delete-char 4)
+    (goto-char 18)
+    (insert "....")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((10 . 57)
+        (10 . 57)
+        (10 . 57)
+        (10 . 60)
+        (10 . 60)
+        (10 . 61)
+        (10 . 68)
+        (57 . 57))))))
+
+(ert-deftest overlay-autogenerated-test-58 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 8 16 nil t nil)
+    (make-overlay 57 27 nil nil nil)
+    (make-overlay 15 62 nil nil nil)
+    (make-overlay 32 33 nil nil t)
+    (make-overlay 47 27 nil nil t)
+    (make-overlay 41 4 nil nil t)
+    (make-overlay 57 61 nil t nil)
+    (make-overlay 18 43 nil nil t)
+    (make-overlay 64 51 nil t t)
+    (make-overlay 44 26 nil nil nil)
+    (make-overlay 9 13 nil nil t)
+    (make-overlay 41 65 nil nil t)
+    (make-overlay 23 13 nil t t)
+    (make-overlay 26 59 nil t t)
+    (make-overlay 65 65 nil t t)
+    (make-overlay 15 7 nil nil nil)
+    (goto-char 41)
+    (insert "........")
+    (goto-char 35)
+    (delete-char 14)
+    (goto-char 32)
+    (widen)
+    (narrow-to-region 23 46)
+    (goto-char 41)
+    (delete-char 5)
+    (goto-char 29)
+    (delete-char 10)
+    (goto-char 31)
+    (insert ".")
+    (goto-char 29)
+    (insert "........")
+    (goto-char 27)
+    (delete-char 7)
+    (goto-char 29)
+    (insert "")
+    (goto-char 24)
+    (insert "............")
+    (goto-char 43)
+    (delete-char 1)
+    (goto-char 31)
+    (delete-char 9)
+    (goto-char 34)
+    (widen)
+    (narrow-to-region 20 14)
+    (goto-char 20)
+    (delete-char 0)
+    (goto-char 17)
+    (insert "...........")
+    (goto-char 31)
+    (delete-char 0)
+    (goto-char 16)
+    (insert "...........")
+    (goto-char 17)
+    (delete-char 8)
+    (goto-char 23)
+    (delete-char 5)
+    (goto-char 20)
+    (insert "..........")
+    (goto-char 33)
+    (widen)
+    (narrow-to-region 16 29)
+    (goto-char 24)
+    (insert "...............")
+    (goto-char 44)
+    (delete-char 0)
+    (goto-char 30)
+    (insert "....")
+    (goto-char 27)
+    (widen)
+    (narrow-to-region 4 22)
+    (goto-char 10)
+    (insert "..............")
+    (goto-char 36)
+    (insert "..")
+    (goto-char 10)
+    (delete-char 21)
+    (goto-char 14)
+    (delete-char 1)
+    (goto-char 14)
+    (insert "...........")
+    (goto-char 12)
+    (insert "........")
+    (goto-char 32)
+    (insert "........")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((4 . 92)
+        (7 . 10)
+        (8 . 10)
+        (9 . 10)
+        (10 . 82)
+        (10 . 104))))))
+
+(ert-deftest overlay-autogenerated-test-59 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 46 30 nil t t)
+    (make-overlay 3 26 nil nil nil)
+    (make-overlay 36 28 nil t t)
+    (make-overlay 49 49 nil t t)
+    (make-overlay 27 61 nil t nil)
+    (make-overlay 14 16 nil nil nil)
+    (make-overlay 50 61 nil t nil)
+    (make-overlay 59 63 nil nil nil)
+    (make-overlay 36 34 nil t nil)
+    (make-overlay 35 29 nil nil nil)
+    (make-overlay 5 65 nil nil nil)
+    (make-overlay 20 61 nil nil t)
+    (make-overlay 10 42 nil nil nil)
+    (make-overlay 47 49 nil nil t)
+    (make-overlay 12 4 nil nil nil)
+    (make-overlay 32 24 nil t t)
+    (goto-char 11)
+    (insert ".")
+    (goto-char 32)
+    (delete-char 2)
+    (goto-char 61)
+    (insert ".........")
+    (goto-char 36)
+    (insert "........")
+    (goto-char 55)
+    (widen)
+    (narrow-to-region 8 55)
+    (goto-char 21)
+    (insert "....")
+    (goto-char 32)
+    (delete-char 15)
+    (goto-char 30)
+    (delete-char 5)
+    (goto-char 31)
+    (insert "......")
+    (goto-char 18)
+    (insert "..")
+    (goto-char 14)
+    (insert ".............")
+    (goto-char 34)
+    (insert "............")
+    (goto-char 51)
+    (widen)
+    (narrow-to-region 58 31)
+    (goto-char 50)
+    (delete-char 5)
+    (goto-char 53)
+    (insert ".........")
+    (goto-char 56)
+    (insert "...............")
+    (goto-char 45)
+    (delete-char 1)
+    (goto-char 67)
+    (insert "............")
+    (goto-char 84)
+    (insert "")
+    (goto-char 39)
+    (delete-char 27)
+    (goto-char 39)
+    (delete-char 21)
+    (goto-char 32)
+    (insert "............")
+    (goto-char 36)
+    (widen)
+    (narrow-to-region 7 37)
+    (goto-char 11)
+    (insert ".......")
+    (goto-char 21)
+    (delete-char 13)
+    (goto-char 15)
+    (insert "....")
+    (goto-char 9)
+    (insert ".............")
+    (goto-char 13)
+    (delete-char 21)
+    (goto-char 21)
+    (delete-char 6)
+    (goto-char 16)
+    (insert ".......")
+    (goto-char 22)
+    (insert "")
+    (goto-char 27)
+    (delete-char 0)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((3 . 42)
+        (4 . 16)
+        (5 . 83)
+        (13 . 51)
+        (25 . 27))))))
+
+(ert-deftest overlay-autogenerated-test-60 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 38 32 nil t nil)
+    (make-overlay 32 42 nil t nil)
+    (make-overlay 29 11 nil nil t)
+    (make-overlay 52 22 nil t t)
+    (make-overlay 39 59 nil t nil)
+    (make-overlay 41 30 nil t t)
+    (make-overlay 29 61 nil nil t)
+    (make-overlay 11 45 nil nil nil)
+    (make-overlay 46 17 nil nil t)
+    (make-overlay 35 51 nil t t)
+    (make-overlay 22 13 nil nil t)
+    (make-overlay 52 34 nil nil t)
+    (make-overlay 59 4 nil nil t)
+    (make-overlay 8 22 nil nil nil)
+    (make-overlay 4 49 nil nil nil)
+    (make-overlay 52 45 nil t t)
+    (goto-char 48)
+    (delete-char 16)
+    (goto-char 37)
+    (delete-char 8)
+    (goto-char 14)
+    (insert "...............")
+    (goto-char 40)
+    (delete-char 16)
+    (goto-char 19)
+    (insert ".........")
+    (goto-char 16)
+    (insert "......")
+    (goto-char 10)
+    (insert "........")
+    (goto-char 11)
+    (insert "...............")
+    (goto-char 22)
+    (insert ".")
+    (goto-char 62)
+    (delete-char 16)
+    (goto-char 14)
+    (delete-char 11)
+    (goto-char 47)
+    (insert "....")
+    (goto-char 33)
+    (insert ".............")
+    (goto-char 49)
+    (delete-char 13)
+    (goto-char 28)
+    (insert "..")
+    (goto-char 35)
+    (delete-char 13)
+    (goto-char 44)
+    (insert "....")
+    (goto-char 34)
+    (delete-char 14)
+    (goto-char 23)
+    (insert ".....")
+    (goto-char 25)
+    (delete-char 4)
+    (goto-char 33)
+    (insert ".....")
+    (goto-char 27)
+    (delete-char 3)
+    (goto-char 16)
+    (widen)
+    (narrow-to-region 36 37)
+    (goto-char 36)
+    (delete-char 1)
+    (goto-char 36)
+    (insert ".......")
+    (goto-char 37)
+    (widen)
+    (narrow-to-region 35 31)
+    (goto-char 34)
+    (delete-char 0)
+    (goto-char 31)
+    (delete-char 2)
+    (goto-char 31)
+    (widen)
+    (narrow-to-region 24 3)
+    (goto-char 22)
+    (delete-char 2)
+    (goto-char 22)
+    (insert ".............")
+    (goto-char 4)
+    (insert ".")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((4 . 54)
+        (4 . 54)
+        (9 . 46))))))
+
+(ert-deftest overlay-autogenerated-test-61 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 45 56 nil t nil)
+    (make-overlay 60 45 nil nil nil)
+    (make-overlay 26 8 nil t t)
+    (make-overlay 63 39 nil nil nil)
+    (make-overlay 18 11 nil t nil)
+    (make-overlay 22 64 nil nil t)
+    (make-overlay 8 41 nil nil t)
+    (make-overlay 6 51 nil t t)
+    (make-overlay 38 26 nil t t)
+    (make-overlay 7 46 nil t nil)
+    (make-overlay 2 42 nil nil t)
+    (make-overlay 44 64 nil nil nil)
+    (make-overlay 7 62 nil t nil)
+    (make-overlay 8 40 nil nil t)
+    (make-overlay 62 36 nil t t)
+    (make-overlay 61 27 nil nil nil)
+    (goto-char 21)
+    (delete-char 0)
+    (goto-char 8)
+    (insert "")
+    (goto-char 55)
+    (insert "......")
+    (goto-char 38)
+    (delete-char 25)
+    (goto-char 37)
+    (delete-char 4)
+    (goto-char 12)
+    (delete-char 4)
+    (goto-char 3)
+    (delete-char 26)
+    (goto-char 10)
+    (insert ".......")
+    (goto-char 18)
+    (delete-char 0)
+    (goto-char 16)
+    (insert ".............")
+    (goto-char 18)
+    (delete-char 3)
+    (goto-char 7)
+    (insert "...")
+    (goto-char 20)
+    (insert "........")
+    (goto-char 38)
+    (delete-char 0)
+    (goto-char 1)
+    (delete-char 36)
+    (goto-char 3)
+    (delete-char 1)
+    (goto-char 2)
+    (insert "......")
+    (goto-char 4)
+    (insert ".......")
+    (goto-char 2)
+    (insert "...........")
+    (goto-char 27)
+    (insert ".....")
+    (goto-char 15)
+    (insert "...............")
+    (goto-char 2)
+    (insert "......")
+    (goto-char 17)
+    (delete-char 8)
+    (goto-char 15)
+    (delete-char 7)
+    (goto-char 33)
+    (delete-char 5)
+    (goto-char 13)
+    (insert "...........")
+    (goto-char 34)
+    (insert "...............")
+    (goto-char 33)
+    (insert "")
+    (goto-char 51)
+    (insert "....")
+    (goto-char 14)
+    (delete-char 36)
+    (goto-char 16)
+    (delete-char 1)
+    (goto-char 14)
+    (delete-char 8)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 1)
+        (1 . 18)
+        (1 . 18))))))
+
+(ert-deftest overlay-autogenerated-test-62 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 25 36 nil t nil)
+    (make-overlay 38 6 nil t nil)
+    (make-overlay 40 63 nil nil t)
+    (make-overlay 34 23 nil nil nil)
+    (make-overlay 48 46 nil nil nil)
+    (make-overlay 43 57 nil t t)
+    (make-overlay 6 53 nil t t)
+    (make-overlay 37 27 nil t t)
+    (make-overlay 8 39 nil t nil)
+    (make-overlay 62 6 nil nil nil)
+    (make-overlay 51 6 nil t t)
+    (make-overlay 58 11 nil nil t)
+    (make-overlay 19 25 nil t nil)
+    (make-overlay 13 8 nil nil nil)
+    (make-overlay 19 8 nil nil t)
+    (make-overlay 39 5 nil t t)
+    (goto-char 51)
+    (delete-char 5)
+    (goto-char 16)
+    (delete-char 9)
+    (goto-char 18)
+    (insert "")
+    (goto-char 47)
+    (delete-char 4)
+    (goto-char 24)
+    (insert ".........")
+    (goto-char 24)
+    (insert ".....")
+    (goto-char 18)
+    (insert "...........")
+    (goto-char 5)
+    (delete-char 6)
+    (goto-char 30)
+    (insert "...........")
+    (goto-char 8)
+    (insert ".............")
+    (goto-char 78)
+    (insert "............")
+    (goto-char 67)
+    (insert "")
+    (goto-char 58)
+    (insert "")
+    (goto-char 5)
+    (insert ".")
+    (goto-char 79)
+    (widen)
+    (narrow-to-region 51 55)
+    (goto-char 51)
+    (insert "....")
+    (goto-char 58)
+    (widen)
+    (narrow-to-region 36 37)
+    (goto-char 37)
+    (insert "....")
+    (goto-char 40)
+    (insert ".......")
+    (goto-char 47)
+    (delete-char 1)
+    (goto-char 43)
+    (delete-char 4)
+    (goto-char 37)
+    (insert "........")
+    (goto-char 49)
+    (insert "............")
+    (goto-char 42)
+    (widen)
+    (narrow-to-region 75 111)
+    (goto-char 104)
+    (widen)
+    (narrow-to-region 21 95)
+    (goto-char 22)
+    (widen)
+    (narrow-to-region 64 79)
+    (goto-char 64)
+    (delete-char 0)
+    (goto-char 68)
+    (insert "........")
+    (goto-char 82)
+    (insert "")
+    (goto-char 81)
+    (insert "........")
+    (goto-char 92)
+    (delete-char 2)
+    (goto-char 87)
+    (insert ".")
+    (should
+     (equal
+      (test-overlay-regions)
+      '((5 . 145)
+        (5 . 148)
+        (6 . 118)
+        (6 . 119)
+        (6 . 119)
+        (6 . 143)
+        (6 . 143)
+        (24 . 114)
+        (24 . 116)
+        (63 . 117))))))
+
+(ert-deftest overlay-autogenerated-test-63 nil
+  (with-temp-buffer
+    (insert "................................................................")
+    (make-overlay 9 49 nil t nil)
+    (make-overlay 9 16 nil nil nil)
+    (make-overlay 64 2 nil t t)
+    (make-overlay 17 31 nil nil t)
+    (make-overlay 24 51 nil nil nil)
+    (make-overlay 27 56 nil t t)
+    (make-overlay 21 4 nil nil nil)
+    (make-overlay 24 29 nil t t)
+    (make-overlay 4 63 nil nil t)
+    (make-overlay 34 49 nil t nil)
+    (make-overlay 19 47 nil nil t)
+    (make-overlay 8 50 nil t nil)
+    (make-overlay 49 61 nil t nil)
+    (make-overlay 52 10 nil t t)
+    (make-overlay 64 30 nil t nil)
+    (make-overlay 5 13 nil t nil)
+    (goto-char 27)
+    (insert "........")
+    (goto-char 42)
+    (insert "......")
+    (goto-char 48)
+    (insert "....")
+    (goto-char 55)
+    (widen)
+    (narrow-to-region 10 5)
+    (goto-char 8)
+    (insert ".............")
+    (goto-char 19)
+    (insert "......")
+    (goto-char 19)
+    (delete-char 3)
+    (goto-char 8)
+    (delete-char 3)
+    (goto-char 9)
+    (insert ".......")
+    (goto-char 29)
+    (insert "...............")
+    (goto-char 38)
+    (insert ".......")
+    (goto-char 34)
+    (insert "......")
+    (goto-char 28)
+    (delete-char 20)
+    (goto-char 22)
+    (insert "............")
+    (goto-char 21)
+    (delete-char 23)
+    (goto-char 25)
+    (delete-char 2)
+    (goto-char 19)
+    (delete-char 2)
+    (goto-char 12)
+    (delete-char 6)
+    (goto-char 12)
+    (delete-char 0)
+    (goto-char 13)
+    (delete-char 0)
+    (goto-char 12)
+    (insert "........")
+    (goto-char 23)
+    (delete-char 2)
+    (goto-char 5)
+    (insert "...............")
+    (goto-char 28)
+    (delete-char 0)
+    (goto-char 16)
+    (insert "..........")
+    (goto-char 8)
+    (delete-char 17)
+    (goto-char 27)
+    (delete-char 0)
+    (goto-char 12)
+    (insert ".")
+    (goto-char 14)
+    (delete-char 12)
+    (goto-char 11)
+    (insert "..............")
+    (goto-char 34)
+    (insert "")
+    (goto-char 25)
+    (delete-char 8)
+    (should
+     (equal
+      (test-overlay-regions)
+      '((2 . 98)
+        (4 . 37)
+        (4 . 97)
+        (25 . 29)
+        (25 . 32)
+        (25 . 84))))))
+
 ;;; buffer-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]