Commits

James Taylor committed 276575a

Another cleanup pass on intersecter interfaces. Simplified interval node, added wrapper class IntervalTree that includes and expands on the old intersecter (that name is still definied for backward compat). Upstream/downstream methods moved out to the wrapper, the nodes only know about left/right queries based on a single position, variants are all in the wrapper.

Comments (0)

Files changed (3)

lib/bx/intervals/intersection.c

-/* Generated by Cython 0.10.3 on Thu Feb 26 12:44:08 2009 */
+/* Generated by Cython 0.10.3 on Sun Mar  1 17:29:36 2009 */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
 
 typedef char *__pyx_t_2bx_9intervals_12intersection_char_star;
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":301
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":281
  *     ##     return [left, right]
  * 
- *     cpdef left(self, f, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
+ *     cpdef left(self, position, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
  *         """
- *         find n features with a start > than f.end
+ *         find n features with a start > than `position`
  */
 
 struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_left {
   int max_dist;
 };
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":316
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":296
  *         return r[:n]
  * 
- *     cpdef right(self, f, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
- *         """find n features with a end < than f.start
- *         f: a Interval object (or anything with a `start` attribute)
+ *     cpdef right(self, position, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
+ *         """
+ *         find n features with a end < than position
  */
 
 struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_right {
   int max_dist;
 };
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":447
- *             self.intervals = self.intervals.insert( interval.start, interval.end, interval )
- * 
- *     cpdef add( self, start, end, value=None ):             # <<<<<<<<<<<<<<
- *         self.add_interval( Interval( start, end, value ) )
- * 
- */
-
-struct __pyx_opt_args_2bx_9intervals_12intersection_11Intersecter_add {
-  int __pyx_n;
-  PyObject *value;
-};
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":60
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":60
  * cdef float nlog = -1.0 / log(0.5)
  * 
  * cdef class IntervalNode:             # <<<<<<<<<<<<<<
   struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *croot;
 };
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":404
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":357
  *         return cmp( self.start, other.start ) or cmp( self.end, other.end )
  * 
- * cdef class Intersecter:             # <<<<<<<<<<<<<<
- *     cdef IntervalNode intervals
+ * cdef class IntervalTree:             # <<<<<<<<<<<<<<
  *     """
- */
-
-struct __pyx_obj_2bx_9intervals_12intersection_Intersecter {
+ *     Data structure for performing window intersect queries on a set of
+ */
+
+struct __pyx_obj_2bx_9intervals_12intersection_IntervalTree {
   PyObject_HEAD
-  struct __pyx_vtabstruct_2bx_9intervals_12intersection_Intersecter *__pyx_vtab;
-  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *intervals;
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *root;
 };
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":370
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":323
  * ## ---- Wrappers that retain the old interface -------------------------------
  * 
  * cdef class Interval:             # <<<<<<<<<<<<<<
   PyObject_HEAD
   int start;
   int end;
-  int strand;
   PyObject *value;
+  PyObject *strand;
 };
 
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":404
- *         return cmp( self.start, other.start ) or cmp( self.end, other.end )
- * 
- * cdef class Intersecter:             # <<<<<<<<<<<<<<
- *     cdef IntervalNode intervals
- *     """
- */
-
-struct __pyx_vtabstruct_2bx_9intervals_12intersection_Intersecter {
-  PyObject *(*add_interval)(struct __pyx_obj_2bx_9intervals_12intersection_Intersecter *, PyObject *, int __pyx_skip_dispatch);
-  PyObject *(*add)(struct __pyx_obj_2bx_9intervals_12intersection_Intersecter *, PyObject *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_2bx_9intervals_12intersection_11Intersecter_add *__pyx_optional_args);
-  PyObject *(*find)(struct __pyx_obj_2bx_9intervals_12intersection_Intersecter *, PyObject *, PyObject *, int __pyx_skip_dispatch);
-};
-static struct __pyx_vtabstruct_2bx_9intervals_12intersection_Intersecter *__pyx_vtabptr_2bx_9intervals_12intersection_Intersecter;
-
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":60
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":60
  * cdef float nlog = -1.0 / log(0.5)
  * 
  * cdef class IntervalNode:             # <<<<<<<<<<<<<<
  */
 
 struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode {
-  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *(*_insert)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, int, int, PyObject *);
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *(*insert)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, int, int, PyObject *, int __pyx_skip_dispatch);
   struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *(*rotate_right)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *);
   struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *(*rotate_left)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *);
   void (*set_ends)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *);
 
 static PyTypeObject *__pyx_ptype_2bx_9intervals_12intersection_IntervalNode = 0;
 static PyTypeObject *__pyx_ptype_2bx_9intervals_12intersection_Interval = 0;
-static PyTypeObject *__pyx_ptype_2bx_9intervals_12intersection_Intersecter = 0;
+static PyTypeObject *__pyx_ptype_2bx_9intervals_12intersection_IntervalTree = 0;
 static float __pyx_v_2bx_9intervals_12intersection_nlog;
 static struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_2bx_9intervals_12intersection_EmptyNode = 0;
-static PyObject *__pyx_k_1;
+static PyObject *__pyx_k_3;
 static int __pyx_f_2bx_9intervals_12intersection_imax2(int, int); /*proto*/
 static int __pyx_f_2bx_9intervals_12intersection_imax3(int, int, int); /*proto*/
 static int __pyx_f_2bx_9intervals_12intersection_imin3(int, int, int); /*proto*/
 /* Implementation of bx.intervals.intersection */
 static PyObject *__pyx_int_0;
 static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2500;
 static PyObject *__pyx_int_neg_1;
 static char __pyx_k___repr__[] = "__repr__";
 static PyObject *__pyx_kp___repr__;
 static PyObject *__pyx_kp_left;
 static char __pyx_k_right[] = "right";
 static PyObject *__pyx_kp_right;
-static char __pyx_k_upstream[] = "upstream";
-static PyObject *__pyx_kp_upstream;
-static char __pyx_k_downstream[] = "downstream";
-static PyObject *__pyx_kp_downstream;
 static char __pyx_k_traverse[] = "traverse";
 static PyObject *__pyx_kp_traverse;
 static char __pyx_k___init__[] = "__init__";
 static PyObject *__pyx_kp___init__;
 static char __pyx_k___cmp__[] = "__cmp__";
 static PyObject *__pyx_kp___cmp__;
+static char __pyx_k_before[] = "before";
+static PyObject *__pyx_kp_before;
+static char __pyx_k_after[] = "after";
+static PyObject *__pyx_kp_after;
+static char __pyx_k_insert_interval[] = "insert_interval";
+static PyObject *__pyx_kp_insert_interval;
+static char __pyx_k_before_interval[] = "before_interval";
+static PyObject *__pyx_kp_before_interval;
+static char __pyx_k_after_interval[] = "after_interval";
+static PyObject *__pyx_kp_after_interval;
+static char __pyx_k_1[] = "upstream_of_interval";
+static PyObject *__pyx_kp_1;
+static char __pyx_k_2[] = "downstream_of_interval";
+static PyObject *__pyx_kp_2;
+static char __pyx_k_add[] = "add";
+static PyObject *__pyx_kp_add;
 static char __pyx_k_add_interval[] = "add_interval";
 static PyObject *__pyx_kp_add_interval;
-static char __pyx_k_add[] = "add";
-static PyObject *__pyx_kp_add;
 static char __pyx_k_start[] = "start";
 static PyObject *__pyx_kp_start;
 static char __pyx_k_end[] = "end";
 static PyObject *__pyx_kp_interval;
 static char __pyx_k_sort[] = "sort";
 static PyObject *__pyx_kp_sort;
-static char __pyx_k_f[] = "f";
-static PyObject *__pyx_kp_f;
+static char __pyx_k_position[] = "position";
+static PyObject *__pyx_kp_position;
 static char __pyx_k_n[] = "n";
 static PyObject *__pyx_kp_n;
 static char __pyx_k_max_dist[] = "max_dist";
 static PyObject *__pyx_kp_strand;
 static char __pyx_k_other[] = "other";
 static PyObject *__pyx_kp_other;
+static char __pyx_k_num_intervals[] = "num_intervals";
+static PyObject *__pyx_kp_num_intervals;
 static char __pyx_k_operator[] = "operator";
 static PyObject *__pyx_kp_operator;
+static char __pyx_k_Intersecter[] = "Intersecter";
+static PyObject *__pyx_kp_Intersecter;
 static char __pyx_k_key[] = "key";
 static PyObject *__pyx_kp_key;
 static char __pyx_k_attrgetter[] = "attrgetter";
 static PyObject *__pyx_kp_attrgetter;
-static char __pyx_k_3[] = "end";
-static PyObject *__pyx_kp_3;
+static char __pyx_k_5[] = "end";
+static PyObject *__pyx_kp_5;
 static char __pyx_k_reverse[] = "reverse";
 static PyObject *__pyx_kp_reverse;
-static char __pyx_k_4[] = "start";
-static PyObject *__pyx_kp_4;
+static char __pyx_k_6[] = "start";
+static PyObject *__pyx_kp_6;
 static char __pyx_k_cmp[] = "cmp";
 static PyObject *__pyx_kp_cmp;
 static PyObject *__pyx_builtin_cmp;
-static PyObject *__pyx_kp_2;
-static char __pyx_k_2[] = "IntervalNode(%i, %i)";
-static PyObject *__pyx_kp_5;
-static char __pyx_k_5[] = "-";
-static PyObject *__pyx_kp_6;
-static char __pyx_k_6[] = "-";
+static PyObject *__pyx_kp_4;
+static char __pyx_k_4[] = "IntervalNode(%i, %i)";
 static PyObject *__pyx_kp_7;
 static char __pyx_k_7[] = "start must be less than end";
 static PyObject *__pyx_kp_8;
 static char __pyx_k_8[] = "Interval(%d, %d";
 static char __pyx_k_9[] = ", value=";
 static char __pyx_k_10[] = ")";
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":32
+static PyObject *__pyx_kp_11;
+static char __pyx_k_11[] = "-";
+static PyObject *__pyx_kp_12;
+static char __pyx_k_12[] = "-";
+
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":32
  * ctypedef char * char_star
  * 
  * cdef inline int imax2(int a, int b):             # <<<<<<<<<<<<<<
   int __pyx_r;
   int __pyx_1;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":33
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":33
  * 
  * cdef inline int imax2(int a, int b):
  *     if b > a: return b             # <<<<<<<<<<<<<<
   }
   __pyx_L3:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":34
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":34
  * cdef inline int imax2(int a, int b):
  *     if b > a: return b
  *     return a             # <<<<<<<<<<<<<<
   return __pyx_r;
 }
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":36
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":36
  *     return a
  * 
  * cdef inline int imax3(int a, int b, int c):             # <<<<<<<<<<<<<<
   int __pyx_r;
   int __pyx_1;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":37
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":37
  * 
  * cdef inline int imax3(int a, int b, int c):
  *     if b > a:             # <<<<<<<<<<<<<<
   __pyx_1 = (__pyx_v_b > __pyx_v_a);
   if (__pyx_1) {
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":38
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":38
  * cdef inline int imax3(int a, int b, int c):
  *     if b > a:
  *         if c > b:             # <<<<<<<<<<<<<<
     __pyx_1 = (__pyx_v_c > __pyx_v_b);
     if (__pyx_1) {
 
-      /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":39
+      /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":39
  *     if b > a:
  *         if c > b:
  *             return c             # <<<<<<<<<<<<<<
     }
     __pyx_L4:;
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":40
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":40
  *         if c > b:
  *             return c
  *         return b             # <<<<<<<<<<<<<<
   }
   __pyx_L3:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":41
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":41
  *             return c
  *         return b
  *     if a > c:             # <<<<<<<<<<<<<<
   __pyx_1 = (__pyx_v_a > __pyx_v_c);
   if (__pyx_1) {
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":42
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":42
  *         return b
  *     if a > c:
  *         return a             # <<<<<<<<<<<<<<
   }
   __pyx_L5:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":43
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":43
  *     if a > c:
  *         return a
  *     return c             # <<<<<<<<<<<<<<
   return __pyx_r;
 }
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":45
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":45
  *     return c
  * 
  * cdef inline int imin3(int a, int b, int c):             # <<<<<<<<<<<<<<
   int __pyx_r;
   int __pyx_1;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":46
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":46
  * 
  * cdef inline int imin3(int a, int b, int c):
  *     if b < a:             # <<<<<<<<<<<<<<
   __pyx_1 = (__pyx_v_b < __pyx_v_a);
   if (__pyx_1) {
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":47
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":47
  * cdef inline int imin3(int a, int b, int c):
  *     if b < a:
  *         if c < b:             # <<<<<<<<<<<<<<
     __pyx_1 = (__pyx_v_c < __pyx_v_b);
     if (__pyx_1) {
 
-      /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":48
+      /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":48
  *     if b < a:
  *         if c < b:
  *             return c             # <<<<<<<<<<<<<<
     }
     __pyx_L4:;
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":49
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":49
  *         if c < b:
  *             return c
  *         return b             # <<<<<<<<<<<<<<
   }
   __pyx_L3:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":50
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":50
  *             return c
  *         return b
  *     if a < c:             # <<<<<<<<<<<<<<
   __pyx_1 = (__pyx_v_a < __pyx_v_c);
   if (__pyx_1) {
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":51
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":51
  *         return b
  *     if a < c:
  *         return a             # <<<<<<<<<<<<<<
   }
   __pyx_L5:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":52
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":52
  *     if a < c:
  *         return a
  *     return c             # <<<<<<<<<<<<<<
   return __pyx_r;
 }
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":54
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":54
  *     return c
  * 
  * cdef inline int imin2(int a, int b):             # <<<<<<<<<<<<<<
   int __pyx_r;
   int __pyx_1;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":55
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":55
  * 
  * cdef inline int imin2(int a, int b):
  *     if b < a: return b             # <<<<<<<<<<<<<<
   }
   __pyx_L3:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":56
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":56
  * cdef inline int imin2(int a, int b):
  *     if b < a: return b
  *     return a             # <<<<<<<<<<<<<<
   return __pyx_r;
 }
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":132
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":115
  * 
  *     property left_node:
  *         def __get__(self):             # <<<<<<<<<<<<<<
   PyObject *__pyx_1 = 0;
   int __pyx_2;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":133
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":116
  *     property left_node:
  *         def __get__(self):
  *             return self.cleft if self.cleft is not EmptyNode else None             # <<<<<<<<<<<<<<
   return __pyx_r;
 }
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":135
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":118
  *             return self.cleft if self.cleft is not EmptyNode else None
  *     property right_node:
  *         def __get__(self):             # <<<<<<<<<<<<<<
   PyObject *__pyx_1 = 0;
   int __pyx_2;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":136
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":119
  *     property right_node:
  *         def __get__(self):
  *             return self.cright if self.cright is not EmptyNode else None             # <<<<<<<<<<<<<<
   return __pyx_r;
 }
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":138
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":121
  *             return self.cright if self.cright is not EmptyNode else None
  *     property root_node:
  *         def __get__(self):             # <<<<<<<<<<<<<<
   PyObject *__pyx_1 = 0;
   int __pyx_2;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":139
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":122
  *     property root_node:
  *         def __get__(self):
  *             return self.croot if self.croot is not EmptyNode else None             # <<<<<<<<<<<<<<
   return __pyx_r;
 }
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":141
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":124
  *             return self.croot if self.croot is not EmptyNode else None
  * 
  *     def __repr__(self):             # <<<<<<<<<<<<<<
   PyObject *__pyx_3 = 0;
   PyObject *__pyx_t_1 = NULL;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":142
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":125
  * 
  *     def __repr__(self):
  *         return "IntervalNode(%i, %i)" % (self.start, self.end)             # <<<<<<<<<<<<<<
  * 
  *     def __cinit__(IntervalNode self, int start, int end, object interval):
  */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->start); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_2 = PyInt_FromLong(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->end); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_3 = PyTuple_New(2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->start); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_2 = PyInt_FromLong(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->end); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_3 = PyTuple_New(2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   PyTuple_SET_ITEM(__pyx_3, 0, __pyx_1);
   PyTuple_SET_ITEM(__pyx_3, 1, __pyx_2);
   __pyx_1 = 0;
   __pyx_2 = 0;
-  __pyx_t_1 = PyNumber_Remainder(__pyx_kp_2, ((PyObject *)__pyx_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyNumber_Remainder(__pyx_kp_4, ((PyObject *)__pyx_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   return __pyx_r;
 }
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":144
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":127
  *         return "IntervalNode(%i, %i)" % (self.start, self.end)
  * 
  *     def __cinit__(IntervalNode self, int start, int end, object interval):             # <<<<<<<<<<<<<<
       values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_end);
       if (likely(values[1])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
       case  2:
       values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_interval);
       if (likely(values[2])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     }
     if (unlikely(kw_args > 0)) {
-      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     }
-    __pyx_v_start = __pyx_PyInt_int(values[0]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-    __pyx_v_end = __pyx_PyInt_int(values[1]); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __pyx_PyInt_int(values[0]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __pyx_PyInt_int(values[1]); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     __pyx_v_interval = values[2];
   } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
     goto __pyx_L5_argtuple_error;
   } else {
-    __pyx_v_start = __pyx_PyInt_int(PyTuple_GET_ITEM(__pyx_args, 0)); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-    __pyx_v_end = __pyx_PyInt_int(PyTuple_GET_ITEM(__pyx_args, 1)); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __pyx_PyInt_int(PyTuple_GET_ITEM(__pyx_args, 0)); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __pyx_PyInt_int(PyTuple_GET_ITEM(__pyx_args, 1)); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     __pyx_v_interval = PyTuple_GET_ITEM(__pyx_args, 2);
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.__cinit__");
   return -1;
   __pyx_L4_argument_unpacking_done:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":149
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":132
  *         # tree size.  Also, python's uniform is perfect since the
  *         # upper limit is not inclusive, which gives us undefined here.
  *         self.priority   = ceil(nlog * log(-1.0/(1.0 * rand()/RAND_MAX - 1)))             # <<<<<<<<<<<<<<
  */
   ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->priority = ceil((__pyx_v_2bx_9intervals_12intersection_nlog * log(((-1.0) / (((1.0 * rand()) / RAND_MAX) - 1)))));
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":150
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":133
  *         # upper limit is not inclusive, which gives us undefined here.
  *         self.priority   = ceil(nlog * log(-1.0/(1.0 * rand()/RAND_MAX - 1)))
  *         self.start      = start             # <<<<<<<<<<<<<<
  */
   ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->start = __pyx_v_start;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":151
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":134
  *         self.priority   = ceil(nlog * log(-1.0/(1.0 * rand()/RAND_MAX - 1)))
  *         self.start      = start
  *         self.end       = end             # <<<<<<<<<<<<<<
  */
   ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->end = __pyx_v_end;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":152
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":135
  *         self.start      = start
  *         self.end       = end
  *         self.interval   = interval             # <<<<<<<<<<<<<<
   Py_DECREF(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->interval);
   ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->interval = __pyx_v_interval;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":153
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":136
  *         self.end       = end
  *         self.interval   = interval
  *         self.maxend    = end             # <<<<<<<<<<<<<<
  */
   ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->maxend = __pyx_v_end;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":154
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":137
  *         self.interval   = interval
  *         self.maxend    = end
  *         self.minstart   = start             # <<<<<<<<<<<<<<
  */
   ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->minstart = __pyx_v_start;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":155
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":138
  *         self.maxend    = end
  *         self.minstart   = start
  *         self.minend    = end             # <<<<<<<<<<<<<<
  */
   ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->minend = __pyx_v_end;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":156
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":139
  *         self.minstart   = start
  *         self.minend    = end
  *         self.cleft       = EmptyNode             # <<<<<<<<<<<<<<
   Py_DECREF(((PyObject *)((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->cleft));
   ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->cleft = __pyx_v_2bx_9intervals_12intersection_EmptyNode;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":157
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":140
  *         self.minend    = end
  *         self.cleft       = EmptyNode
  *         self.cright      = EmptyNode             # <<<<<<<<<<<<<<
   Py_DECREF(((PyObject *)((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->cright));
   ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->cright = __pyx_v_2bx_9intervals_12intersection_EmptyNode;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":158
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":141
  *         self.cleft       = EmptyNode
  *         self.cright      = EmptyNode
  *         self.croot       = EmptyNode             # <<<<<<<<<<<<<<
  * 
- *     def insert( self, interval ):
+ *     cpdef IntervalNode insert(IntervalNode self, int start, int end, object interval):
  */
   Py_INCREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_EmptyNode));
   Py_DECREF(((PyObject *)((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->croot));
   return __pyx_r;
 }
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":160
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":143
  *         self.croot       = EmptyNode
  * 
- *     def insert( self, interval ):             # <<<<<<<<<<<<<<
- *         return self._insert( interval.start, interval.end, interval)
- * 
- */
-
-static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_insert(PyObject *__pyx_v_self, PyObject *__pyx_v_interval); /*proto*/
-static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_insert(PyObject *__pyx_v_self, PyObject *__pyx_v_interval) {
-  PyObject *__pyx_r;
-  PyObject *__pyx_1 = 0;
-  int __pyx_2;
-  int __pyx_3;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":161
- * 
- *     def insert( self, interval ):
- *         return self._insert( interval.start, interval.end, interval)             # <<<<<<<<<<<<<<
- * 
- *     cdef IntervalNode _insert(IntervalNode self, int start, int end, object interval):
- */
-  __pyx_1 = PyObject_GetAttr(__pyx_v_interval, __pyx_kp_start); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_2 = __pyx_PyInt_int(__pyx_1); if (unlikely((__pyx_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = PyObject_GetAttr(__pyx_v_interval, __pyx_kp_end); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_3 = __pyx_PyInt_int(__pyx_1); if (unlikely((__pyx_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_1 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->__pyx_vtab)->_insert(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self), __pyx_2, __pyx_3, __pyx_v_interval)); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_r = __pyx_1;
-  __pyx_1 = 0;
-  goto __pyx_L0;
-
-  __pyx_r = Py_None; Py_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  Py_XDECREF(__pyx_1);
-  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.insert");
-  __pyx_r = NULL;
-  __pyx_L0:;
-  return __pyx_r;
-}
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":163
- *         return self._insert( interval.start, interval.end, interval)
- * 
- *     cdef IntervalNode _insert(IntervalNode self, int start, int end, object interval):             # <<<<<<<<<<<<<<
+ *     cpdef IntervalNode insert(IntervalNode self, int start, int end, object interval):             # <<<<<<<<<<<<<<
  *         cdef IntervalNode croot = self
  *         # If starts are the same, decide which to add interval to based on
  */
 
-static  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_f_2bx_9intervals_12intersection_12IntervalNode__insert(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_interval) {
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_f_2bx_9intervals_12intersection_12IntervalNode_insert(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self, int __pyx_v_start, int __pyx_v_end, PyObject *__pyx_v_interval, int __pyx_skip_dispatch) {
   struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_croot = 0;
   int __pyx_v_decision_endpoint;
   struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_r;
-  int __pyx_1;
+  PyObject *__pyx_1 = 0;
   PyObject *__pyx_2 = 0;
   PyObject *__pyx_3 = 0;
   PyObject *__pyx_4 = 0;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":164
- * 
- *     cdef IntervalNode _insert(IntervalNode self, int start, int end, object interval):
- *         cdef IntervalNode croot = self             # <<<<<<<<<<<<<<
- *         # If starts are the same, decide which to add interval to based on
- *         # end, thus maintaining sortedness relative to start/end
- */
-  Py_INCREF(((PyObject *)__pyx_v_self));
-  __pyx_v_croot = __pyx_v_self;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":167
- *         # If starts are the same, decide which to add interval to based on
- *         # end, thus maintaining sortedness relative to start/end
- *         cdef int decision_endpoint = start             # <<<<<<<<<<<<<<
- *         if start == self.start:
- *             decision_endpoint = end
- */
-  __pyx_v_decision_endpoint = __pyx_v_start;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":168
- *         # end, thus maintaining sortedness relative to start/end
- *         cdef int decision_endpoint = start
- *         if start == self.start:             # <<<<<<<<<<<<<<
- *             decision_endpoint = end
- * 
- */
-  __pyx_1 = (__pyx_v_start == __pyx_v_self->start);
-  if (__pyx_1) {
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":169
- *         cdef int decision_endpoint = start
- *         if start == self.start:
- *             decision_endpoint = end             # <<<<<<<<<<<<<<
- * 
- *         if decision_endpoint > self.start:
- */
-    __pyx_v_decision_endpoint = __pyx_v_end;
-    goto __pyx_L3;
-  }
-  __pyx_L3:;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":171
- *             decision_endpoint = end
- * 
- *         if decision_endpoint > self.start:             # <<<<<<<<<<<<<<
- *             # insert to cright tree
- *             if self.cright is not EmptyNode:
- */
-  __pyx_1 = (__pyx_v_decision_endpoint > __pyx_v_self->start);
-  if (__pyx_1) {
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":173
- *         if decision_endpoint > self.start:
- *             # insert to cright tree
- *             if self.cright is not EmptyNode:             # <<<<<<<<<<<<<<
- *                 self.cright = self.cright._insert( start, end, interval )
- *             else:
- */
-    __pyx_1 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
-    if (__pyx_1) {
-
-      /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":174
- *             # insert to cright tree
- *             if self.cright is not EmptyNode:
- *                 self.cright = self.cright._insert( start, end, interval )             # <<<<<<<<<<<<<<
- *             else:
- *                 self.cright = IntervalNode( start, end, interval )
- */
-      __pyx_2 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cright->__pyx_vtab)->_insert(__pyx_v_self->cright, __pyx_v_start, __pyx_v_end, __pyx_v_interval)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      Py_DECREF(((PyObject *)__pyx_v_self->cright));
-      __pyx_v_self->cright = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_2);
-      __pyx_2 = 0;
-      goto __pyx_L5;
-    }
-    /*else*/ {
-
-      /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":176
- *                 self.cright = self.cright._insert( start, end, interval )
- *             else:
- *                 self.cright = IntervalNode( start, end, interval )             # <<<<<<<<<<<<<<
- *             # rebalance tree
- *             if self.priority < self.cright.priority:
- */
-      __pyx_2 = PyInt_FromLong(__pyx_v_start); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_3 = PyInt_FromLong(__pyx_v_end); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_4 = PyTuple_New(3); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  int __pyx_5;
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overriden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_kp_insert); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!(strcmp(Py_TYPE(__pyx_1)->tp_name, "builtin_function_or_method") == 0) || (PyCFunction_GET_FUNCTION(__pyx_1) != (void *)&__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_insert)) {
+      __pyx_2 = PyInt_FromLong(__pyx_v_start); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_3 = PyInt_FromLong(__pyx_v_end); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_4 = PyTuple_New(3); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       PyTuple_SET_ITEM(__pyx_4, 0, __pyx_2);
       PyTuple_SET_ITEM(__pyx_4, 1, __pyx_3);
       Py_INCREF(__pyx_v_interval);
       PyTuple_SET_ITEM(__pyx_4, 2, __pyx_v_interval);
       __pyx_2 = 0;
       __pyx_3 = 0;
-      __pyx_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_9intervals_12intersection_IntervalNode)), ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_2 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      Py_DECREF(__pyx_1); __pyx_1 = 0;
       Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
-      if (!(__Pyx_TypeTest(__pyx_2, __pyx_ptype_2bx_9intervals_12intersection_IntervalNode))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      if (!(__Pyx_TypeTest(__pyx_2, __pyx_ptype_2bx_9intervals_12intersection_IntervalNode))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_r = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_2);
+      __pyx_2 = 0;
+      goto __pyx_L0;
+    }
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+  }
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":144
+ * 
+ *     cpdef IntervalNode insert(IntervalNode self, int start, int end, object interval):
+ *         cdef IntervalNode croot = self             # <<<<<<<<<<<<<<
+ *         # If starts are the same, decide which to add interval to based on
+ *         # end, thus maintaining sortedness relative to start/end
+ */
+  Py_INCREF(((PyObject *)__pyx_v_self));
+  __pyx_v_croot = __pyx_v_self;
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":147
+ *         # If starts are the same, decide which to add interval to based on
+ *         # end, thus maintaining sortedness relative to start/end
+ *         cdef int decision_endpoint = start             # <<<<<<<<<<<<<<
+ *         if start == self.start:
+ *             decision_endpoint = end
+ */
+  __pyx_v_decision_endpoint = __pyx_v_start;
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":148
+ *         # end, thus maintaining sortedness relative to start/end
+ *         cdef int decision_endpoint = start
+ *         if start == self.start:             # <<<<<<<<<<<<<<
+ *             decision_endpoint = end
+ * 
+ */
+  __pyx_5 = (__pyx_v_start == __pyx_v_self->start);
+  if (__pyx_5) {
+
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":149
+ *         cdef int decision_endpoint = start
+ *         if start == self.start:
+ *             decision_endpoint = end             # <<<<<<<<<<<<<<
+ * 
+ *         if decision_endpoint > self.start:
+ */
+    __pyx_v_decision_endpoint = __pyx_v_end;
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":151
+ *             decision_endpoint = end
+ * 
+ *         if decision_endpoint > self.start:             # <<<<<<<<<<<<<<
+ *             # insert to cright tree
+ *             if self.cright is not EmptyNode:
+ */
+  __pyx_5 = (__pyx_v_decision_endpoint > __pyx_v_self->start);
+  if (__pyx_5) {
+
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":153
+ *         if decision_endpoint > self.start:
+ *             # insert to cright tree
+ *             if self.cright is not EmptyNode:             # <<<<<<<<<<<<<<
+ *                 self.cright = self.cright.insert( start, end, interval )
+ *             else:
+ */
+    __pyx_5 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+    if (__pyx_5) {
+
+      /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":154
+ *             # insert to cright tree
+ *             if self.cright is not EmptyNode:
+ *                 self.cright = self.cright.insert( start, end, interval )             # <<<<<<<<<<<<<<
+ *             else:
+ *                 self.cright = IntervalNode( start, end, interval )
+ */
+      __pyx_3 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cright->__pyx_vtab)->insert(__pyx_v_self->cright, __pyx_v_start, __pyx_v_end, __pyx_v_interval, 0)); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       Py_DECREF(((PyObject *)__pyx_v_self->cright));
-      __pyx_v_self->cright = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_2);
-      __pyx_2 = 0;
+      __pyx_v_self->cright = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_3);
+      __pyx_3 = 0;
+      goto __pyx_L5;
+    }
+    /*else*/ {
+
+      /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":156
+ *                 self.cright = self.cright.insert( start, end, interval )
+ *             else:
+ *                 self.cright = IntervalNode( start, end, interval )             # <<<<<<<<<<<<<<
+ *             # rebalance tree
+ *             if self.priority < self.cright.priority:
+ */
+      __pyx_1 = PyInt_FromLong(__pyx_v_start); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_4 = PyInt_FromLong(__pyx_v_end); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_2 = PyTuple_New(3); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      PyTuple_SET_ITEM(__pyx_2, 0, __pyx_1);
+      PyTuple_SET_ITEM(__pyx_2, 1, __pyx_4);
+      Py_INCREF(__pyx_v_interval);
+      PyTuple_SET_ITEM(__pyx_2, 2, __pyx_v_interval);
+      __pyx_1 = 0;
+      __pyx_4 = 0;
+      __pyx_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_9intervals_12intersection_IntervalNode)), ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
+      if (!(__Pyx_TypeTest(__pyx_3, __pyx_ptype_2bx_9intervals_12intersection_IntervalNode))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      Py_DECREF(((PyObject *)__pyx_v_self->cright));
+      __pyx_v_self->cright = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_3);
+      __pyx_3 = 0;
     }
     __pyx_L5:;
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":178
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":158
  *                 self.cright = IntervalNode( start, end, interval )
  *             # rebalance tree
  *             if self.priority < self.cright.priority:             # <<<<<<<<<<<<<<
  *                 croot = self.rotate_left()
  *         else:
  */
-    __pyx_1 = (__pyx_v_self->priority < __pyx_v_self->cright->priority);
-    if (__pyx_1) {
-
-      /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":179
+    __pyx_5 = (__pyx_v_self->priority < __pyx_v_self->cright->priority);
+    if (__pyx_5) {
+
+      /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":159
  *             # rebalance tree
  *             if self.priority < self.cright.priority:
  *                 croot = self.rotate_left()             # <<<<<<<<<<<<<<
  *         else:
  *             # insert to cleft tree
  */
-      __pyx_3 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->rotate_left(__pyx_v_self)); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_1 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->rotate_left(__pyx_v_self)); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       Py_DECREF(((PyObject *)__pyx_v_croot));
-      __pyx_v_croot = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_3);
-      __pyx_3 = 0;
+      __pyx_v_croot = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_1);
+      __pyx_1 = 0;
       goto __pyx_L6;
     }
     __pyx_L6:;
   }
   /*else*/ {
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":182
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":162
  *         else:
  *             # insert to cleft tree
  *             if self.cleft is not EmptyNode:             # <<<<<<<<<<<<<<
- *                 self.cleft = self.cleft._insert( start, end, interval)
+ *                 self.cleft = self.cleft.insert( start, end, interval)
  *             else:
  */
-    __pyx_1 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
-    if (__pyx_1) {
-
-      /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":183
+    __pyx_5 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+    if (__pyx_5) {
+
+      /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":163
  *             # insert to cleft tree
  *             if self.cleft is not EmptyNode:
- *                 self.cleft = self.cleft._insert( start, end, interval)             # <<<<<<<<<<<<<<
+ *                 self.cleft = self.cleft.insert( start, end, interval)             # <<<<<<<<<<<<<<
  *             else:
  *                 self.cleft = IntervalNode( start, end, interval)
  */
-      __pyx_4 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cleft->__pyx_vtab)->_insert(__pyx_v_self->cleft, __pyx_v_start, __pyx_v_end, __pyx_v_interval)); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_4 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cleft->__pyx_vtab)->insert(__pyx_v_self->cleft, __pyx_v_start, __pyx_v_end, __pyx_v_interval, 0)); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       Py_DECREF(((PyObject *)__pyx_v_self->cleft));
       __pyx_v_self->cleft = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_4);
       __pyx_4 = 0;
     }
     /*else*/ {
 
-      /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":185
- *                 self.cleft = self.cleft._insert( start, end, interval)
+      /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":165
+ *                 self.cleft = self.cleft.insert( start, end, interval)
  *             else:
  *                 self.cleft = IntervalNode( start, end, interval)             # <<<<<<<<<<<<<<
  *             # rebalance tree
  *             if self.priority < self.cleft.priority:
  */
-      __pyx_2 = PyInt_FromLong(__pyx_v_start); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_3 = PyInt_FromLong(__pyx_v_end); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_4 = PyTuple_New(3); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      PyTuple_SET_ITEM(__pyx_4, 0, __pyx_2);
-      PyTuple_SET_ITEM(__pyx_4, 1, __pyx_3);
+      __pyx_2 = PyInt_FromLong(__pyx_v_start); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_3 = PyInt_FromLong(__pyx_v_end); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_1 = PyTuple_New(3); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
+      PyTuple_SET_ITEM(__pyx_1, 1, __pyx_3);
       Py_INCREF(__pyx_v_interval);
-      PyTuple_SET_ITEM(__pyx_4, 2, __pyx_v_interval);
+      PyTuple_SET_ITEM(__pyx_1, 2, __pyx_v_interval);
       __pyx_2 = 0;
       __pyx_3 = 0;
-      __pyx_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_9intervals_12intersection_IntervalNode)), ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
-      if (!(__Pyx_TypeTest(__pyx_2, __pyx_ptype_2bx_9intervals_12intersection_IntervalNode))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_2bx_9intervals_12intersection_IntervalNode)), ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
+      if (!(__Pyx_TypeTest(__pyx_4, __pyx_ptype_2bx_9intervals_12intersection_IntervalNode))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       Py_DECREF(((PyObject *)__pyx_v_self->cleft));
-      __pyx_v_self->cleft = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_2);
-      __pyx_2 = 0;
+      __pyx_v_self->cleft = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_4);
+      __pyx_4 = 0;
     }
     __pyx_L7:;
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":187
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":167
  *                 self.cleft = IntervalNode( start, end, interval)
  *             # rebalance tree
  *             if self.priority < self.cleft.priority:             # <<<<<<<<<<<<<<
  *                 croot = self.rotate_right()
  * 
  */
-    __pyx_1 = (__pyx_v_self->priority < __pyx_v_self->cleft->priority);
-    if (__pyx_1) {
-
-      /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":188
+    __pyx_5 = (__pyx_v_self->priority < __pyx_v_self->cleft->priority);
+    if (__pyx_5) {
+
+      /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":168
  *             # rebalance tree
  *             if self.priority < self.cleft.priority:
  *                 croot = self.rotate_right()             # <<<<<<<<<<<<<<
  * 
  *         croot.set_ends()
  */
-      __pyx_3 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->rotate_right(__pyx_v_self)); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_2 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->rotate_right(__pyx_v_self)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       Py_DECREF(((PyObject *)__pyx_v_croot));
-      __pyx_v_croot = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_3);
-      __pyx_3 = 0;
+      __pyx_v_croot = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_2);
+      __pyx_2 = 0;
       goto __pyx_L8;
     }
     __pyx_L8:;
   }
   __pyx_L4:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":190
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":170
  *                 croot = self.rotate_right()
  * 
  *         croot.set_ends()             # <<<<<<<<<<<<<<
  */
   ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_croot->__pyx_vtab)->set_ends(__pyx_v_croot);
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":191
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":171
  * 
  *         croot.set_ends()
  *         self.cleft.croot  = croot             # <<<<<<<<<<<<<<
   Py_DECREF(((PyObject *)__pyx_v_self->cleft->croot));
   __pyx_v_self->cleft->croot = __pyx_v_croot;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":192
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":172
  *         croot.set_ends()
  *         self.cleft.croot  = croot
  *         self.cright.croot = croot             # <<<<<<<<<<<<<<
   Py_DECREF(((PyObject *)__pyx_v_self->cright->croot));
   __pyx_v_self->cright->croot = __pyx_v_croot;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":193
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":173
  *         self.cleft.croot  = croot
  *         self.cright.croot = croot
  *         return croot             # <<<<<<<<<<<<<<
   __pyx_r = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1_error:;
+  Py_XDECREF(__pyx_1);
   Py_XDECREF(__pyx_2);
   Py_XDECREF(__pyx_3);
   Py_XDECREF(__pyx_4);
-  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode._insert");
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.insert");
   __pyx_r = 0;
   __pyx_L0:;
   Py_XDECREF(__pyx_v_croot);
   return __pyx_r;
 }
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":195
- *         return croot
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":143
+ *         self.croot       = EmptyNode
  * 
- *     cdef IntervalNode rotate_right(IntervalNode self):             # <<<<<<<<<<<<<<
- *         cdef IntervalNode croot = self.cleft
- *         self.cleft  = self.cleft.cright
- */
-
-static  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_f_2bx_9intervals_12intersection_12IntervalNode_rotate_right(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
-  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_croot = 0;
-  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_r;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":196
- * 
- *     cdef IntervalNode rotate_right(IntervalNode self):
- *         cdef IntervalNode croot = self.cleft             # <<<<<<<<<<<<<<
- *         self.cleft  = self.cleft.cright
- *         croot.cright = self
- */
-  Py_INCREF(((PyObject *)__pyx_v_self->cleft));
-  __pyx_v_croot = __pyx_v_self->cleft;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":197
- *     cdef IntervalNode rotate_right(IntervalNode self):
- *         cdef IntervalNode croot = self.cleft
- *         self.cleft  = self.cleft.cright             # <<<<<<<<<<<<<<
- *         croot.cright = self
- *         self.set_ends()
- */
-  Py_INCREF(((PyObject *)__pyx_v_self->cleft->cright));
-  Py_DECREF(((PyObject *)__pyx_v_self->cleft));
-  __pyx_v_self->cleft = __pyx_v_self->cleft->cright;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":198
- *         cdef IntervalNode croot = self.cleft
- *         self.cleft  = self.cleft.cright
- *         croot.cright = self             # <<<<<<<<<<<<<<
- *         self.set_ends()
- *         return croot
- */
-  Py_INCREF(((PyObject *)__pyx_v_self));
-  Py_DECREF(((PyObject *)__pyx_v_croot->cright));
-  __pyx_v_croot->cright = __pyx_v_self;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":199
- *         self.cleft  = self.cleft.cright
- *         croot.cright = self
- *         self.set_ends()             # <<<<<<<<<<<<<<
- *         return croot
- * 
- */
-  ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->set_ends(__pyx_v_self);
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":200
- *         croot.cright = self
- *         self.set_ends()
- *         return croot             # <<<<<<<<<<<<<<
- * 
- *     cdef IntervalNode rotate_left(IntervalNode self):
- */
-  Py_INCREF(((PyObject *)__pyx_v_croot));
-  __pyx_r = __pyx_v_croot;
-  goto __pyx_L0;
-
-  __pyx_r = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
-  __pyx_L0:;
-  Py_XDECREF(__pyx_v_croot);
-  return __pyx_r;
-}
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":202
- *         return croot
- * 
- *     cdef IntervalNode rotate_left(IntervalNode self):             # <<<<<<<<<<<<<<
- *         cdef IntervalNode croot = self.cright
- *         self.cright = self.cright.cleft
- */
-
-static  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_f_2bx_9intervals_12intersection_12IntervalNode_rotate_left(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
-  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_croot = 0;
-  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_r;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":203
- * 
- *     cdef IntervalNode rotate_left(IntervalNode self):
- *         cdef IntervalNode croot = self.cright             # <<<<<<<<<<<<<<
- *         self.cright = self.cright.cleft
- *         croot.cleft  = self
- */
-  Py_INCREF(((PyObject *)__pyx_v_self->cright));
-  __pyx_v_croot = __pyx_v_self->cright;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":204
- *     cdef IntervalNode rotate_left(IntervalNode self):
- *         cdef IntervalNode croot = self.cright
- *         self.cright = self.cright.cleft             # <<<<<<<<<<<<<<
- *         croot.cleft  = self
- *         self.set_ends()
- */
-  Py_INCREF(((PyObject *)__pyx_v_self->cright->cleft));
-  Py_DECREF(((PyObject *)__pyx_v_self->cright));
-  __pyx_v_self->cright = __pyx_v_self->cright->cleft;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":205
- *         cdef IntervalNode croot = self.cright
- *         self.cright = self.cright.cleft
- *         croot.cleft  = self             # <<<<<<<<<<<<<<
- *         self.set_ends()
- *         return croot
- */
-  Py_INCREF(((PyObject *)__pyx_v_self));
-  Py_DECREF(((PyObject *)__pyx_v_croot->cleft));
-  __pyx_v_croot->cleft = __pyx_v_self;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":206
- *         self.cright = self.cright.cleft
- *         croot.cleft  = self
- *         self.set_ends()             # <<<<<<<<<<<<<<
- *         return croot
- * 
- */
-  ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->set_ends(__pyx_v_self);
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":207
- *         croot.cleft  = self
- *         self.set_ends()
- *         return croot             # <<<<<<<<<<<<<<
- * 
- *     cdef inline void set_ends(IntervalNode self):
- */
-  Py_INCREF(((PyObject *)__pyx_v_croot));
-  __pyx_r = __pyx_v_croot;
-  goto __pyx_L0;
-
-  __pyx_r = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
-  __pyx_L0:;
-  Py_XDECREF(__pyx_v_croot);
-  return __pyx_r;
-}
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":209
- *         return croot
- * 
- *     cdef inline void set_ends(IntervalNode self):             # <<<<<<<<<<<<<<
- *         if self.cright is not EmptyNode and self.cleft is not EmptyNode:
- *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)
- */
-
-static INLINE void __pyx_f_2bx_9intervals_12intersection_12IntervalNode_set_ends(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
-  int __pyx_1;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":210
- * 
- *     cdef inline void set_ends(IntervalNode self):
- *         if self.cright is not EmptyNode and self.cleft is not EmptyNode:             # <<<<<<<<<<<<<<
- *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)
- *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)
- */
-  __pyx_1 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
-  if (__pyx_1) {
-    __pyx_1 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
-  }
-  if (__pyx_1) {
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":211
- *     cdef inline void set_ends(IntervalNode self):
- *         if self.cright is not EmptyNode and self.cleft is not EmptyNode:
- *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)             # <<<<<<<<<<<<<<
- *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)
- *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)
- */
-    __pyx_v_self->maxend = __pyx_f_2bx_9intervals_12intersection_imax3(__pyx_v_self->end, __pyx_v_self->cright->maxend, __pyx_v_self->cleft->maxend);
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":212
- *         if self.cright is not EmptyNode and self.cleft is not EmptyNode:
- *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)
- *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)             # <<<<<<<<<<<<<<
- *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)
- *         elif self.cright is not EmptyNode:
- */
-    __pyx_v_self->minend = __pyx_f_2bx_9intervals_12intersection_imin3(__pyx_v_self->end, __pyx_v_self->cright->minend, __pyx_v_self->cleft->minend);
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":213
- *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)
- *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)
- *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)             # <<<<<<<<<<<<<<
- *         elif self.cright is not EmptyNode:
- *             self.maxend = imax2(self.end, self.cright.maxend)
- */
-    __pyx_v_self->minstart = __pyx_f_2bx_9intervals_12intersection_imin3(__pyx_v_self->start, __pyx_v_self->cright->minstart, __pyx_v_self->cleft->minstart);
-    goto __pyx_L3;
-  }
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":214
- *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)
- *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)
- *         elif self.cright is not EmptyNode:             # <<<<<<<<<<<<<<
- *             self.maxend = imax2(self.end, self.cright.maxend)
- *             self.minend = imin2(self.end, self.cright.minend)
- */
-  __pyx_1 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
-  if (__pyx_1) {
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":215
- *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)
- *         elif self.cright is not EmptyNode:
- *             self.maxend = imax2(self.end, self.cright.maxend)             # <<<<<<<<<<<<<<
- *             self.minend = imin2(self.end, self.cright.minend)
- *             self.minstart = imin2(self.start, self.cright.minstart)
- */
-    __pyx_v_self->maxend = __pyx_f_2bx_9intervals_12intersection_imax2(__pyx_v_self->end, __pyx_v_self->cright->maxend);
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":216
- *         elif self.cright is not EmptyNode:
- *             self.maxend = imax2(self.end, self.cright.maxend)
- *             self.minend = imin2(self.end, self.cright.minend)             # <<<<<<<<<<<<<<
- *             self.minstart = imin2(self.start, self.cright.minstart)
- *         elif self.cleft is not EmptyNode:
- */
-    __pyx_v_self->minend = __pyx_f_2bx_9intervals_12intersection_imin2(__pyx_v_self->end, __pyx_v_self->cright->minend);
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":217
- *             self.maxend = imax2(self.end, self.cright.maxend)
- *             self.minend = imin2(self.end, self.cright.minend)
- *             self.minstart = imin2(self.start, self.cright.minstart)             # <<<<<<<<<<<<<<
- *         elif self.cleft is not EmptyNode:
- *             self.maxend = imax2(self.end, self.cleft.maxend)
- */
-    __pyx_v_self->minstart = __pyx_f_2bx_9intervals_12intersection_imin2(__pyx_v_self->start, __pyx_v_self->cright->minstart);
-    goto __pyx_L3;
-  }
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":218
- *             self.minend = imin2(self.end, self.cright.minend)
- *             self.minstart = imin2(self.start, self.cright.minstart)
- *         elif self.cleft is not EmptyNode:             # <<<<<<<<<<<<<<
- *             self.maxend = imax2(self.end, self.cleft.maxend)
- *             self.minend = imin2(self.end, self.cleft.minend)
- */
-  __pyx_1 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
-  if (__pyx_1) {
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":219
- *             self.minstart = imin2(self.start, self.cright.minstart)
- *         elif self.cleft is not EmptyNode:
- *             self.maxend = imax2(self.end, self.cleft.maxend)             # <<<<<<<<<<<<<<
- *             self.minend = imin2(self.end, self.cleft.minend)
- *             self.minstart = imin2(self.start, self.cleft.minstart)
- */
-    __pyx_v_self->maxend = __pyx_f_2bx_9intervals_12intersection_imax2(__pyx_v_self->end, __pyx_v_self->cleft->maxend);
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":220
- *         elif self.cleft is not EmptyNode:
- *             self.maxend = imax2(self.end, self.cleft.maxend)
- *             self.minend = imin2(self.end, self.cleft.minend)             # <<<<<<<<<<<<<<
- *             self.minstart = imin2(self.start, self.cleft.minstart)
- * 
- */
-    __pyx_v_self->minend = __pyx_f_2bx_9intervals_12intersection_imin2(__pyx_v_self->end, __pyx_v_self->cleft->minend);
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":221
- *             self.maxend = imax2(self.end, self.cleft.maxend)
- *             self.minend = imin2(self.end, self.cleft.minend)
- *             self.minstart = imin2(self.start, self.cleft.minstart)             # <<<<<<<<<<<<<<
- * 
- * 
- */
-    __pyx_v_self->minstart = __pyx_f_2bx_9intervals_12intersection_imin2(__pyx_v_self->start, __pyx_v_self->cleft->minstart);
-    goto __pyx_L3;
-  }
-  __pyx_L3:;
-
-}
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":224
- * 
- * 
- *     def intersect( self, int start, int end, sort=True ):             # <<<<<<<<<<<<<<
- *         """
- *         given a start and a end, return a list of features
- */
-
-static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_intersect(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_2bx_9intervals_12intersection_12IntervalNode_intersect[] = "\n        given a start and a end, return a list of features\n        falling within that range\n        ";
-static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_intersect(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ *     cpdef IntervalNode insert(IntervalNode self, int start, int end, object interval):             # <<<<<<<<<<<<<<
+ *         cdef IntervalNode croot = self
+ *         # If starts are the same, decide which to add interval to based on
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   int __pyx_v_start;
   int __pyx_v_end;
-  PyObject *__pyx_v_sort = 0;
-  PyObject *__pyx_v_results = 0;
+  PyObject *__pyx_v_interval = 0;
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_start,&__pyx_kp_end,&__pyx_kp_sort,0};
-  __pyx_v_sort = __pyx_k_1;
+  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_start,&__pyx_kp_end,&__pyx_kp_interval,0};
   if (unlikely(__pyx_kwds)) {
     PyObject* values[3] = {0,0,0};
     Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
       values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_end);
       if (likely(values[1])) kw_args--;
       else {
-        __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("insert", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+      case  2:
+      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_interval);
+      if (likely(values[2])) kw_args--;
+      else {
+        __Pyx_RaiseArgtupleInvalid("insert", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     }
     if (unlikely(kw_args > 0)) {
-      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "intersect") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "insert") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     }
-    __pyx_v_start = __pyx_PyInt_int(values[0]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-    __pyx_v_end = __pyx_PyInt_int(values[1]); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_start = __pyx_PyInt_int(values[0]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __pyx_PyInt_int(values[1]); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_interval = values[2];
+  } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+    goto __pyx_L5_argtuple_error;
+  } else {
+    __pyx_v_start = __pyx_PyInt_int(PyTuple_GET_ITEM(__pyx_args, 0)); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __pyx_PyInt_int(PyTuple_GET_ITEM(__pyx_args, 1)); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_interval = PyTuple_GET_ITEM(__pyx_args, 2);
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("insert", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.insert");
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_1 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->__pyx_vtab)->insert(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self), __pyx_v_start, __pyx_v_end, __pyx_v_interval, 1)); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.insert");
+  __pyx_r = NULL;
+  __pyx_L0:;
+  return __pyx_r;
+}
+
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":175
+ *         return croot
+ * 
+ *     cdef IntervalNode rotate_right(IntervalNode self):             # <<<<<<<<<<<<<<
+ *         cdef IntervalNode croot = self.cleft
+ *         self.cleft  = self.cleft.cright
+ */
+
+static  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_f_2bx_9intervals_12intersection_12IntervalNode_rotate_right(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_croot = 0;
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_r;
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":176
+ * 
+ *     cdef IntervalNode rotate_right(IntervalNode self):
+ *         cdef IntervalNode croot = self.cleft             # <<<<<<<<<<<<<<
+ *         self.cleft  = self.cleft.cright
+ *         croot.cright = self
+ */
+  Py_INCREF(((PyObject *)__pyx_v_self->cleft));
+  __pyx_v_croot = __pyx_v_self->cleft;
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":177
+ *     cdef IntervalNode rotate_right(IntervalNode self):
+ *         cdef IntervalNode croot = self.cleft
+ *         self.cleft  = self.cleft.cright             # <<<<<<<<<<<<<<
+ *         croot.cright = self
+ *         self.set_ends()
+ */
+  Py_INCREF(((PyObject *)__pyx_v_self->cleft->cright));
+  Py_DECREF(((PyObject *)__pyx_v_self->cleft));
+  __pyx_v_self->cleft = __pyx_v_self->cleft->cright;
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":178
+ *         cdef IntervalNode croot = self.cleft
+ *         self.cleft  = self.cleft.cright
+ *         croot.cright = self             # <<<<<<<<<<<<<<
+ *         self.set_ends()
+ *         return croot
+ */
+  Py_INCREF(((PyObject *)__pyx_v_self));
+  Py_DECREF(((PyObject *)__pyx_v_croot->cright));
+  __pyx_v_croot->cright = __pyx_v_self;
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":179
+ *         self.cleft  = self.cleft.cright
+ *         croot.cright = self
+ *         self.set_ends()             # <<<<<<<<<<<<<<
+ *         return croot
+ * 
+ */
+  ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->set_ends(__pyx_v_self);
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":180
+ *         croot.cright = self
+ *         self.set_ends()
+ *         return croot             # <<<<<<<<<<<<<<
+ * 
+ *     cdef IntervalNode rotate_left(IntervalNode self):
+ */
+  Py_INCREF(((PyObject *)__pyx_v_croot));
+  __pyx_r = __pyx_v_croot;
+  goto __pyx_L0;
+
+  __pyx_r = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
+  __pyx_L0:;
+  Py_XDECREF(__pyx_v_croot);
+  return __pyx_r;
+}
+
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":182
+ *         return croot
+ * 
+ *     cdef IntervalNode rotate_left(IntervalNode self):             # <<<<<<<<<<<<<<
+ *         cdef IntervalNode croot = self.cright
+ *         self.cright = self.cright.cleft
+ */
+
+static  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_f_2bx_9intervals_12intersection_12IntervalNode_rotate_left(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_croot = 0;
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_r;
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":183
+ * 
+ *     cdef IntervalNode rotate_left(IntervalNode self):
+ *         cdef IntervalNode croot = self.cright             # <<<<<<<<<<<<<<
+ *         self.cright = self.cright.cleft
+ *         croot.cleft  = self
+ */
+  Py_INCREF(((PyObject *)__pyx_v_self->cright));
+  __pyx_v_croot = __pyx_v_self->cright;
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":184
+ *     cdef IntervalNode rotate_left(IntervalNode self):
+ *         cdef IntervalNode croot = self.cright
+ *         self.cright = self.cright.cleft             # <<<<<<<<<<<<<<
+ *         croot.cleft  = self
+ *         self.set_ends()
+ */
+  Py_INCREF(((PyObject *)__pyx_v_self->cright->cleft));
+  Py_DECREF(((PyObject *)__pyx_v_self->cright));
+  __pyx_v_self->cright = __pyx_v_self->cright->cleft;
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":185
+ *         cdef IntervalNode croot = self.cright
+ *         self.cright = self.cright.cleft
+ *         croot.cleft  = self             # <<<<<<<<<<<<<<
+ *         self.set_ends()
+ *         return croot
+ */
+  Py_INCREF(((PyObject *)__pyx_v_self));
+  Py_DECREF(((PyObject *)__pyx_v_croot->cleft));
+  __pyx_v_croot->cleft = __pyx_v_self;
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":186
+ *         self.cright = self.cright.cleft
+ *         croot.cleft  = self
+ *         self.set_ends()             # <<<<<<<<<<<<<<
+ *         return croot
+ * 
+ */
+  ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->set_ends(__pyx_v_self);
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":187
+ *         croot.cleft  = self
+ *         self.set_ends()
+ *         return croot             # <<<<<<<<<<<<<<
+ * 
+ *     cdef inline void set_ends(IntervalNode self):
+ */
+  Py_INCREF(((PyObject *)__pyx_v_croot));
+  __pyx_r = __pyx_v_croot;
+  goto __pyx_L0;
+
+  __pyx_r = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)Py_None); Py_INCREF(Py_None);
+  __pyx_L0:;
+  Py_XDECREF(__pyx_v_croot);
+  return __pyx_r;
+}
+
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":189
+ *         return croot
+ * 
+ *     cdef inline void set_ends(IntervalNode self):             # <<<<<<<<<<<<<<
+ *         if self.cright is not EmptyNode and self.cleft is not EmptyNode:
+ *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)
+ */
+
+static INLINE void __pyx_f_2bx_9intervals_12intersection_12IntervalNode_set_ends(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *__pyx_v_self) {
+  int __pyx_1;
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":190
+ * 
+ *     cdef inline void set_ends(IntervalNode self):
+ *         if self.cright is not EmptyNode and self.cleft is not EmptyNode:             # <<<<<<<<<<<<<<
+ *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)
+ *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)
+ */
+  __pyx_1 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_1) {
+    __pyx_1 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  }
+  if (__pyx_1) {
+
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":191
+ *     cdef inline void set_ends(IntervalNode self):
+ *         if self.cright is not EmptyNode and self.cleft is not EmptyNode:
+ *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)             # <<<<<<<<<<<<<<
+ *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)
+ *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)
+ */
+    __pyx_v_self->maxend = __pyx_f_2bx_9intervals_12intersection_imax3(__pyx_v_self->end, __pyx_v_self->cright->maxend, __pyx_v_self->cleft->maxend);
+
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":192
+ *         if self.cright is not EmptyNode and self.cleft is not EmptyNode:
+ *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)
+ *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)             # <<<<<<<<<<<<<<
+ *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)
+ *         elif self.cright is not EmptyNode:
+ */
+    __pyx_v_self->minend = __pyx_f_2bx_9intervals_12intersection_imin3(__pyx_v_self->end, __pyx_v_self->cright->minend, __pyx_v_self->cleft->minend);
+
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":193
+ *             self.maxend = imax3(self.end, self.cright.maxend, self.cleft.maxend)
+ *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)
+ *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)             # <<<<<<<<<<<<<<
+ *         elif self.cright is not EmptyNode:
+ *             self.maxend = imax2(self.end, self.cright.maxend)
+ */
+    __pyx_v_self->minstart = __pyx_f_2bx_9intervals_12intersection_imin3(__pyx_v_self->start, __pyx_v_self->cright->minstart, __pyx_v_self->cleft->minstart);
+    goto __pyx_L3;
+  }
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":194
+ *             self.minend = imin3(self.end, self.cright.minend, self.cleft.minend)
+ *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)
+ *         elif self.cright is not EmptyNode:             # <<<<<<<<<<<<<<
+ *             self.maxend = imax2(self.end, self.cright.maxend)
+ *             self.minend = imin2(self.end, self.cright.minend)
+ */
+  __pyx_1 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_1) {
+
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":195
+ *             self.minstart = imin3(self.start, self.cright.minstart, self.cleft.minstart)
+ *         elif self.cright is not EmptyNode:
+ *             self.maxend = imax2(self.end, self.cright.maxend)             # <<<<<<<<<<<<<<
+ *             self.minend = imin2(self.end, self.cright.minend)
+ *             self.minstart = imin2(self.start, self.cright.minstart)
+ */
+    __pyx_v_self->maxend = __pyx_f_2bx_9intervals_12intersection_imax2(__pyx_v_self->end, __pyx_v_self->cright->maxend);
+
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":196
+ *         elif self.cright is not EmptyNode:
+ *             self.maxend = imax2(self.end, self.cright.maxend)
+ *             self.minend = imin2(self.end, self.cright.minend)             # <<<<<<<<<<<<<<
+ *             self.minstart = imin2(self.start, self.cright.minstart)
+ *         elif self.cleft is not EmptyNode:
+ */
+    __pyx_v_self->minend = __pyx_f_2bx_9intervals_12intersection_imin2(__pyx_v_self->end, __pyx_v_self->cright->minend);
+
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":197
+ *             self.maxend = imax2(self.end, self.cright.maxend)
+ *             self.minend = imin2(self.end, self.cright.minend)
+ *             self.minstart = imin2(self.start, self.cright.minstart)             # <<<<<<<<<<<<<<
+ *         elif self.cleft is not EmptyNode:
+ *             self.maxend = imax2(self.end, self.cleft.maxend)
+ */
+    __pyx_v_self->minstart = __pyx_f_2bx_9intervals_12intersection_imin2(__pyx_v_self->start, __pyx_v_self->cright->minstart);
+    goto __pyx_L3;
+  }
+
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":198
+ *             self.minend = imin2(self.end, self.cright.minend)
+ *             self.minstart = imin2(self.start, self.cright.minstart)
+ *         elif self.cleft is not EmptyNode:             # <<<<<<<<<<<<<<
+ *             self.maxend = imax2(self.end, self.cleft.maxend)
+ *             self.minend = imin2(self.end, self.cleft.minend)
+ */
+  __pyx_1 = (__pyx_v_self->cleft != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
+  if (__pyx_1) {
+
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":199
+ *             self.minstart = imin2(self.start, self.cright.minstart)
+ *         elif self.cleft is not EmptyNode:
+ *             self.maxend = imax2(self.end, self.cleft.maxend)             # <<<<<<<<<<<<<<
+ *             self.minend = imin2(self.end, self.cleft.minend)
+ *             self.minstart = imin2(self.start, self.cleft.minstart)
+ */
+    __pyx_v_self->maxend = __pyx_f_2bx_9intervals_12intersection_imax2(__pyx_v_self->end, __pyx_v_self->cleft->maxend);
+
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":200
+ *         elif self.cleft is not EmptyNode:
+ *             self.maxend = imax2(self.end, self.cleft.maxend)
+ *             self.minend = imin2(self.end, self.cleft.minend)             # <<<<<<<<<<<<<<
+ *             self.minstart = imin2(self.start, self.cleft.minstart)
+ * 
+ */
+    __pyx_v_self->minend = __pyx_f_2bx_9intervals_12intersection_imin2(__pyx_v_self->end, __pyx_v_self->cleft->minend);
+
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":201
+ *             self.maxend = imax2(self.end, self.cleft.maxend)
+ *             self.minend = imin2(self.end, self.cleft.minend)
+ *             self.minstart = imin2(self.start, self.cleft.minstart)             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_v_self->minstart = __pyx_f_2bx_9intervals_12intersection_imin2(__pyx_v_self->start, __pyx_v_self->cleft->minstart);
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+}
+
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":204
+ * 
+ * 
+ *     def intersect( self, int start, int end, sort=True ):             # <<<<<<<<<<<<<<
+ *         """
+ *         given a start and a end, return a list of features
+ */
+
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_intersect(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_2bx_9intervals_12intersection_12IntervalNode_intersect[] = "\n        given a start and a end, return a list of features\n        falling within that range\n        ";
+static PyObject *__pyx_pf_2bx_9intervals_12intersection_12IntervalNode_intersect(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  int __pyx_v_start;
+  int __pyx_v_end;
+  PyObject *__pyx_v_sort = 0;
+  PyObject *__pyx_v_results = 0;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_start,&__pyx_kp_end,&__pyx_kp_sort,0};
+  __pyx_v_sort = __pyx_k_3;
+  if (unlikely(__pyx_kwds)) {
+    PyObject* values[3] = {0,0,0};
+    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
+    switch (PyTuple_GET_SIZE(__pyx_args)) {
+      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      case  0: break;
+      default: goto __pyx_L5_argtuple_error;
+    }
+    switch (PyTuple_GET_SIZE(__pyx_args)) {
+      case  0:
+      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_start);
+      if (likely(values[0])) kw_args--;
+      else goto __pyx_L5_argtuple_error;
+      case  1:
+      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_end);
+      if (likely(values[1])) kw_args--;
+      else {
+        __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    }
+    if (unlikely(kw_args > 0)) {
+      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "intersect") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    }
+    __pyx_v_start = __pyx_PyInt_int(values[0]); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    __pyx_v_end = __pyx_PyInt_int(values[1]); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     if (values[2]) {
       __pyx_v_sort = values[2];
     }
       case  3:
       __pyx_v_sort = PyTuple_GET_ITEM(__pyx_args, 2);
       case  2:
-      __pyx_v_end = __pyx_PyInt_int(PyTuple_GET_ITEM(__pyx_args, 1)); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      __pyx_v_start = __pyx_PyInt_int(PyTuple_GET_ITEM(__pyx_args, 0)); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_end = __pyx_PyInt_int(PyTuple_GET_ITEM(__pyx_args, 1)); if (unlikely((__pyx_v_end == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_start = __pyx_PyInt_int(PyTuple_GET_ITEM(__pyx_args, 0)); if (unlikely((__pyx_v_start == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       break;
       default: goto __pyx_L5_argtuple_error;
     }
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("intersect", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.intersect");
   return NULL;
   __pyx_L4_argument_unpacking_done:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":229
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":209
  *         falling within that range
  *         """
  *         cdef list results = []             # <<<<<<<<<<<<<<
  *         self._intersect( start, end, results )
  *         return results
  */
-  __pyx_1 = PyList_New(0); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_1 = PyList_New(0); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __pyx_v_results = __pyx_1;
   __pyx_1 = 0;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":230
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":210
  *         """
  *         cdef list results = []
  *         self._intersect( start, end, results )             # <<<<<<<<<<<<<<
  */
   ((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->__pyx_vtab)->_intersect(((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self), __pyx_v_start, __pyx_v_end, __pyx_v_results);
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":231
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":211
  *         cdef list results = []
  *         self._intersect( start, end, results )
  *         return results             # <<<<<<<<<<<<<<
   return __pyx_r;
 }
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":235
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":215
  *     find = intersect
  * 
  *     cdef void _intersect( IntervalNode self, int start, int end, list results ):             # <<<<<<<<<<<<<<
   int __pyx_1;
   int __pyx_2;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":237
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":217
  *     cdef void _intersect( IntervalNode self, int start, int end, list results ):
  *         # Left subtree
  *         if self.cleft is not EmptyNode and self.cleft.maxend > start:             # <<<<<<<<<<<<<<
   }
   if (__pyx_1) {
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":238
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":218
  *         # Left subtree
  *         if self.cleft is not EmptyNode and self.cleft.maxend > start:
  *             self.cleft._intersect( start, end, results )             # <<<<<<<<<<<<<<
   }
   __pyx_L3:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":240
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":220
  *             self.cleft._intersect( start, end, results )
  *         # This interval
  *         if ( self.end > start ) and ( self.start < end ):             # <<<<<<<<<<<<<<
   }
   if (__pyx_1) {
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":241
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":221
  *         # This interval
  *         if ( self.end > start ) and ( self.start < end ):
  *             results.append( self.interval )             # <<<<<<<<<<<<<<
  *         # Right subtree
  *         if self.cright is not EmptyNode and self.start < end:
  */
-    __pyx_2 = PyList_Append(((PyObject *)__pyx_v_results), __pyx_v_self->interval); if (unlikely(__pyx_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_2 = PyList_Append(((PyObject *)__pyx_v_results), __pyx_v_self->interval); if (unlikely(__pyx_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 221; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     goto __pyx_L4;
   }
   __pyx_L4:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":243
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":223
  *             results.append( self.interval )
  *         # Right subtree
  *         if self.cright is not EmptyNode and self.start < end:             # <<<<<<<<<<<<<<
   }
   if (__pyx_1) {
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":244
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":224
  *         # Right subtree
  *         if self.cright is not EmptyNode and self.start < end:
  *             self.cright._intersect( start, end, results )             # <<<<<<<<<<<<<<
   __pyx_L0:;
 }
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":247
+/* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":227
  * 
  * 
  *     cdef void _seek_left(IntervalNode self, int position, list results, int n, int max_dist):             # <<<<<<<<<<<<<<
   int __pyx_1;
   int __pyx_2;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":249
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":229
  *     cdef void _seek_left(IntervalNode self, int position, list results, int n, int max_dist):
  *         # we know we can bail in these 2 cases.
  *         if self.maxend + max_dist < position:             # <<<<<<<<<<<<<<
   __pyx_1 = ((__pyx_v_self->maxend + __pyx_v_max_dist) < __pyx_v_position);
   if (__pyx_1) {
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":250
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":230
  *         # we know we can bail in these 2 cases.
  *         if self.maxend + max_dist < position:
  *             return             # <<<<<<<<<<<<<<
   }
   __pyx_L3:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":251
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":231
  *         if self.maxend + max_dist < position:
  *             return
  *         if self.minstart > position:             # <<<<<<<<<<<<<<
   __pyx_1 = (__pyx_v_self->minstart > __pyx_v_position);
   if (__pyx_1) {
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":252
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":232
  *             return
  *         if self.minstart > position:
  *             return             # <<<<<<<<<<<<<<
   }
   __pyx_L4:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":256
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":236
  *         # the ordering of these 3 blocks makes it so the results are
  *         # ordered nearest to farest from the query position
  *         if self.cright is not EmptyNode:             # <<<<<<<<<<<<<<
   __pyx_1 = (__pyx_v_self->cright != __pyx_v_2bx_9intervals_12intersection_EmptyNode);
   if (__pyx_1) {
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":257
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":237
  *         # ordered nearest to farest from the query position
  *         if self.cright is not EmptyNode:
  *             self.cright._seek_left(position, results, n, max_dist)             # <<<<<<<<<<<<<<
   }
   __pyx_L5:;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":259
+  /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":239
  *             self.cright._seek_left(position, results, n, max_dist)
  * 
  *         if -1 < position - self.end < max_dist:             # <<<<<<<<<<<<<<
   }
   if (__pyx_1) {
 
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":260
+    /* "/Users/james/projects/bx-python/code/bx-python/lib/bx/intervals/intersection.pyx":240
  * 
  *         if -1 < position - self.end < max_dist:
  *             results.append(self.interval)             # <<<<<<<<<<<<<<
  * 
  *         # TODO: can these conditionals be more stringent?
  */
-    __pyx_2 = PyList_Append(((PyObject *)__pyx_v_results), __pyx_v_self->interval); if (unlikely(__pyx_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}