James Taylor avatar James Taylor committed d3604a3

IntervalNode can now contain any value, not just Intervals. This eliminates the need for
WrapperInterval and makes the behavior more like the old implementation. The Intersecter
API should be unchanged.

Comments (0)

Files changed (3)

lib/bx/intervals/intersection.c

-/* Generated by Cython 0.10.3 on Thu Feb 19 18:09:07 2009 */
+/* Generated by Cython 0.10.3 on Thu Feb 26 12:44:08 2009 */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
     const char* function_name, int kw_allowed); /*proto*/
 
-static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
-    const char *name, int exact); /*proto*/
-
 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
 
 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
 
 typedef char *__pyx_t_2bx_9intervals_12intersection_char_star;
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":343
- *         return [left, right]
+/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":301
+ *     ##     return [left, right]
  * 
- *     cpdef left(self, Interval f, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
- *         """find n features with a start > than f.end
- *         f: a Interval object
+ *     cpdef left(self, f, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
+ *         """
+ *         find n features with a start > than f.end
  */
 
 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":357
+/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":316
  *         return r[:n]
  * 
- *     cpdef right(self, Interval f, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
+ *     cpdef right(self, f, int n=1, int max_dist=2500):             # <<<<<<<<<<<<<<
  *         """find n features with a end < than f.start
- *         f: a Interval object
+ *         f: a Interval object (or anything with a `start` attribute)
  */
 
 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":458
- *             self.intervals = self.intervals.insert( interval )
+/* "/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 ) )
   PyObject *value;
 };
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":412
- *     pass
- * 
- * cdef class Intersecter:             # <<<<<<<<<<<<<<
- *     cdef IntervalNode intervals
- *     """
- */
-
-struct __pyx_obj_2bx_9intervals_12intersection_Intersecter {
-  PyObject_HEAD
-  struct __pyx_vtabstruct_2bx_9intervals_12intersection_Intersecter *__pyx_vtab;
-  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *intervals;
-};
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":100
+/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":60
  * cdef float nlog = -1.0 / log(0.5)
  * 
  * cdef class IntervalNode:             # <<<<<<<<<<<<<<
   PyObject_HEAD
   struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *__pyx_vtab;
   float priority;
-  struct __pyx_obj_2bx_9intervals_12intersection_Interval *interval;
+  PyObject *interval;
   int start;
   int end;
   int minend;
   struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *croot;
 };
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":32
- * ctypedef char * char_star
+/* "/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_obj_2bx_9intervals_12intersection_Intersecter {
+  PyObject_HEAD
+  struct __pyx_vtabstruct_2bx_9intervals_12intersection_Intersecter *__pyx_vtab;
+  struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *intervals;
+};
+
+/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":370
+ * ## ---- Wrappers that retain the old interface -------------------------------
  * 
  * cdef class Interval:             # <<<<<<<<<<<<<<
  *     """
   int start;
   int end;
   int strand;
-  PyObject *info;
-  PyObject *name;
+  PyObject *value;
 };
 
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":409
- * ## ---- Wrappers that retain the old interface -------------------------------
- * 
- * cdef class WrapperInterval( Interval ):             # <<<<<<<<<<<<<<
- *     pass
- * 
- */
-
-struct __pyx_obj_2bx_9intervals_12intersection_WrapperInterval {
-  struct __pyx_obj_2bx_9intervals_12intersection_Interval __pyx_base;
-};
-
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":412
- *     pass
+
+/* "/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
 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":100
+/* "/Users/james/projects/bx-python/code/bx-python-central/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 *, struct __pyx_obj_2bx_9intervals_12intersection_Interval *);
+  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 *(*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 *);
   void (*_intersect)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, int, int, PyObject *);
   void (*_seek_left)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, int, PyObject *, int, int);
   void (*_seek_right)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, int, PyObject *, int, int);
-  PyObject *(*left)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, struct __pyx_obj_2bx_9intervals_12intersection_Interval *, int __pyx_skip_dispatch, struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_left *__pyx_optional_args);
-  PyObject *(*right)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, struct __pyx_obj_2bx_9intervals_12intersection_Interval *, int __pyx_skip_dispatch, struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_right *__pyx_optional_args);
+  PyObject *(*left)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_left *__pyx_optional_args);
+  PyObject *(*right)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_2bx_9intervals_12intersection_12IntervalNode_right *__pyx_optional_args);
   void (*_traverse)(struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *, PyObject *);
 };
 static struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *__pyx_vtabptr_2bx_9intervals_12intersection_IntervalNode;
 /* Module declarations from bx.intervals.intersection */
 
+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_IntervalNode = 0;
-static PyTypeObject *__pyx_ptype_2bx_9intervals_12intersection_WrapperInterval = 0;
 static PyTypeObject *__pyx_ptype_2bx_9intervals_12intersection_Intersecter = 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_2;
+static PyObject *__pyx_k_1;
 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 char __pyx_k_1[] = "";
 static PyObject *__pyx_int_0;
-static char __pyx_k___init__[] = "__init__";
-static PyObject *__pyx_kp___init__;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_neg_1;
 static char __pyx_k___repr__[] = "__repr__";
 static PyObject *__pyx_kp___repr__;
-static char __pyx_k___cmp__[] = "__cmp__";
-static PyObject *__pyx_kp___cmp__;
 static char __pyx_k___cinit__[] = "__cinit__";
 static PyObject *__pyx_kp___cinit__;
 static char __pyx_k_insert[] = "insert";
 static PyObject *__pyx_kp_intersect;
 static char __pyx_k_find[] = "find";
 static PyObject *__pyx_kp_find;
-static char __pyx_k_neighbors[] = "neighbors";
-static PyObject *__pyx_kp_neighbors;
 static char __pyx_k_left[] = "left";
 static PyObject *__pyx_kp_left;
 static char __pyx_k_right[] = "right";
 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_add_interval[] = "add_interval";
 static PyObject *__pyx_kp_add_interval;
 static char __pyx_k_add[] = "add";
 static PyObject *__pyx_kp_start;
 static char __pyx_k_end[] = "end";
 static PyObject *__pyx_kp_end;
-static char __pyx_k_strand[] = "strand";
-static PyObject *__pyx_kp_strand;
-static char __pyx_k_chr[] = "chr";
-static PyObject *__pyx_kp_chr;
-static char __pyx_k_name[] = "name";
-static PyObject *__pyx_kp_name;
-static char __pyx_k_info[] = "info";
-static PyObject *__pyx_kp_info;
-static char __pyx_k_other[] = "other";
-static PyObject *__pyx_kp_other;
 static char __pyx_k_interval[] = "interval";
 static PyObject *__pyx_kp_interval;
 static char __pyx_k_sort[] = "sort";
 static PyObject *__pyx_kp_func;
 static char __pyx_k_value[] = "value";
 static PyObject *__pyx_kp_value;
+static char __pyx_k_strand[] = "strand";
+static PyObject *__pyx_kp_strand;
+static char __pyx_k_other[] = "other";
+static PyObject *__pyx_kp_other;
 static char __pyx_k_operator[] = "operator";
 static PyObject *__pyx_kp_operator;
-static char __pyx_k_cmp[] = "cmp";
-static PyObject *__pyx_kp_cmp;
 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_11[] = "end";
-static PyObject *__pyx_kp_11;
+static char __pyx_k_3[] = "end";
+static PyObject *__pyx_kp_3;
 static char __pyx_k_reverse[] = "reverse";
 static PyObject *__pyx_kp_reverse;
-static char __pyx_k_12[] = "start";
-static PyObject *__pyx_kp_12;
-static char __pyx_k_range[] = "range";
-static PyObject *__pyx_kp_range;
-static PyObject *__pyx_kp_1;
+static char __pyx_k_4[] = "start";
+static PyObject *__pyx_kp_4;
+static char __pyx_k_cmp[] = "cmp";
+static PyObject *__pyx_kp_cmp;
 static PyObject *__pyx_builtin_cmp;
-static PyObject *__pyx_builtin_range;
-static PyObject *__pyx_kp_3;
-static char __pyx_k_3[] = "start must be less than end";
-static PyObject *__pyx_kp_4;
+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_7;
+static char __pyx_k_7[] = "start must be less than end";
 static PyObject *__pyx_kp_8;
 static PyObject *__pyx_kp_9;
-static char __pyx_k_4[] = "Interval(%d, %d";
-static char __pyx_k_5[] = ", strand=%d";
-static char __pyx_k_6[] = ", name=\"";
-static char __pyx_k_7[] = "\"";
-static char __pyx_k_8[] = ", ";
-static char __pyx_k_9[] = ")";
 static PyObject *__pyx_kp_10;
-static char __pyx_k_10[] = "IntervalNode(%i, %i)";
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":50
- *     cdef public object name
- * 
- *     def __init__(self, int start, int end, int strand=0, int chr=0, object name="", object info=None):             # <<<<<<<<<<<<<<
- *         assert start <= end, "start must be less than end"
- *         self.start  = start
- */
-
-static int __pyx_pf_2bx_9intervals_12intersection_8Interval___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_pf_2bx_9intervals_12intersection_8Interval___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  int __pyx_v_start;
-  int __pyx_v_end;
-  int __pyx_v_strand;
-  int __pyx_v_chr;
-  PyObject *__pyx_v_name = 0;
-  PyObject *__pyx_v_info = 0;
-  int __pyx_r;
-  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_start,&__pyx_kp_end,&__pyx_kp_strand,&__pyx_kp_chr,&__pyx_kp_name,&__pyx_kp_info,0};
-  __pyx_v_strand = 0;
-  __pyx_v_chr = 0;
-  __pyx_v_name = __pyx_kp_1;
-  __pyx_v_info = Py_None;
-  if (unlikely(__pyx_kwds)) {
-    PyObject* values[6] = {0,0,0,0,0,0};
-    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
-    switch (PyTuple_GET_SIZE(__pyx_args)) {
-      case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
-      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
-      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-      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("__init__", 0, 2, 6, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __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), "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __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 = 50; __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 = 50; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-    if (values[2]) {
-      __pyx_v_strand = __pyx_PyInt_int(values[2]); if (unlikely((__pyx_v_strand == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-    }
-    if (values[3]) {
-      __pyx_v_chr = __pyx_PyInt_int(values[3]); if (unlikely((__pyx_v_chr == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-    }
-    if (values[4]) {
-      __pyx_v_name = values[4];
-    }
-    if (values[5]) {
-      __pyx_v_info = values[5];
-    }
-  } else {
-    switch (PyTuple_GET_SIZE(__pyx_args)) {
-      case  6:
-      __pyx_v_info = PyTuple_GET_ITEM(__pyx_args, 5);
-      case  5:
-      __pyx_v_name = PyTuple_GET_ITEM(__pyx_args, 4);
-      case  4:
-      __pyx_v_chr = __pyx_PyInt_int(PyTuple_GET_ITEM(__pyx_args, 3)); if (unlikely((__pyx_v_chr == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      case  3:
-      __pyx_v_strand = __pyx_PyInt_int(PyTuple_GET_ITEM(__pyx_args, 2)); if (unlikely((__pyx_v_strand == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      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 = 50; __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 = 50; __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("__init__", 0, 2, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("bx.intervals.intersection.Interval.__init__");
-  return -1;
-  __pyx_L4_argument_unpacking_done:;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":51
- * 
- *     def __init__(self, int start, int end, int strand=0, int chr=0, object name="", object info=None):
- *         assert start <= end, "start must be less than end"             # <<<<<<<<<<<<<<
- *         self.start  = start
- *         self.end   = end
- */
-  #ifndef PYREX_WITHOUT_ASSERTIONS
-  if (unlikely(!(__pyx_v_start <= __pyx_v_end))) {
-    PyErr_SetObject(PyExc_AssertionError, __pyx_kp_3);
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  #endif
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":52
- *     def __init__(self, int start, int end, int strand=0, int chr=0, object name="", object info=None):
- *         assert start <= end, "start must be less than end"
- *         self.start  = start             # <<<<<<<<<<<<<<
- *         self.end   = end
- *         self.strand = strand
- */
-  ((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->start = __pyx_v_start;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":53
- *         assert start <= end, "start must be less than end"
- *         self.start  = start
- *         self.end   = end             # <<<<<<<<<<<<<<
- *         self.strand = strand
- *         self.name   = name
- */
-  ((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->end = __pyx_v_end;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":54
- *         self.start  = start
- *         self.end   = end
- *         self.strand = strand             # <<<<<<<<<<<<<<
- *         self.name   = name
- *         self.info   = info
- */
-  ((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->strand = __pyx_v_strand;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":55
- *         self.end   = end
- *         self.strand = strand
- *         self.name   = name             # <<<<<<<<<<<<<<
- *         self.info   = info
- * 
- */
-  Py_INCREF(__pyx_v_name);
-  Py_DECREF(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->name);
-  ((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->name = __pyx_v_name;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":56
- *         self.strand = strand
- *         self.name   = name
- *         self.info   = info             # <<<<<<<<<<<<<<
- * 
- *     def __repr__(self):
- */
-  Py_INCREF(__pyx_v_info);
-  Py_DECREF(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->info);
-  ((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->info = __pyx_v_info;
-
-  __pyx_r = 0;
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_AddTraceback("bx.intervals.intersection.Interval.__init__");
-  __pyx_r = -1;
-  __pyx_L0:;
-  return __pyx_r;
-}
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":58
- *         self.info   = info
- * 
- *     def __repr__(self):             # <<<<<<<<<<<<<<
- *         fstr = "Interval(%d, %d" % (self.start, self.end)
- *         if self.strand != 0:
- */
-
-static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval___repr__(PyObject *__pyx_v_self); /*proto*/
-static PyObject *__pyx_pf_2bx_9intervals_12intersection_8Interval___repr__(PyObject *__pyx_v_self) {
-  PyObject *__pyx_v_fstr;
-  PyObject *__pyx_r;
-  PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
-  int __pyx_4;
-  char *__pyx_5;
-  int __pyx_6;
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  __pyx_v_fstr = Py_None; Py_INCREF(Py_None);
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":59
- * 
- *     def __repr__(self):
- *         fstr = "Interval(%d, %d" % (self.start, self.end)             # <<<<<<<<<<<<<<
- *         if self.strand != 0:
- *             fstr += ", strand=%d" % self.strand
- */
-  __pyx_1 = PyInt_FromLong(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->start); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_2 = PyInt_FromLong(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->end); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_3 = PyTuple_New(2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __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_4, ((PyObject *)__pyx_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
-  Py_DECREF(__pyx_v_fstr);
-  __pyx_v_fstr = __pyx_t_1;
-  __pyx_t_1 = 0;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":60
- *     def __repr__(self):
- *         fstr = "Interval(%d, %d" % (self.start, self.end)
- *         if self.strand != 0:             # <<<<<<<<<<<<<<
- *             fstr += ", strand=%d" % self.strand
- *         if strlen(self.name) != 0:
- */
-  __pyx_4 = (((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->strand != 0);
-  if (__pyx_4) {
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":61
- *         fstr = "Interval(%d, %d" % (self.start, self.end)
- *         if self.strand != 0:
- *             fstr += ", strand=%d" % self.strand             # <<<<<<<<<<<<<<
- *         if strlen(self.name) != 0:
- *             fstr += ', name="' + str(self.name) + '"'
- */
-    __pyx_2 = PyInt_FromLong(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->strand); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_1 = PyNumber_Remainder(__pyx_kp_5, __pyx_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    Py_DECREF(__pyx_2); __pyx_2 = 0;
-    __pyx_1 = PyNumber_InPlaceAdd(__pyx_v_fstr, __pyx_t_1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    Py_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    Py_DECREF(__pyx_v_fstr);
-    __pyx_v_fstr = __pyx_1;
-    __pyx_1 = 0;
-    goto __pyx_L5;
-  }
-  __pyx_L5:;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":62
- *         if self.strand != 0:
- *             fstr += ", strand=%d" % self.strand
- *         if strlen(self.name) != 0:             # <<<<<<<<<<<<<<
- *             fstr += ', name="' + str(self.name) + '"'
- *         if not self.info is None:
- */
-  __pyx_5 = __Pyx_PyBytes_AsString(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->name); if (unlikely((!__pyx_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_4 = (strlen(__pyx_5) != 0);
-  if (__pyx_4) {
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":63
- *             fstr += ", strand=%d" % self.strand
- *         if strlen(self.name) != 0:
- *             fstr += ', name="' + str(self.name) + '"'             # <<<<<<<<<<<<<<
- *         if not self.info is None:
- *             fstr += ", " + str(self.info)
- */
-    __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    Py_INCREF(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->name);
-    PyTuple_SET_ITEM(__pyx_2, 0, ((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->name);
-    __pyx_1 = PyObject_Call(((PyObject *)((PyObject*)&PyString_Type)), ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
-    __pyx_t_1 = PyNumber_Add(__pyx_kp_6, __pyx_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    Py_DECREF(__pyx_1); __pyx_1 = 0;
-    __pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_kp_7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    Py_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_3 = PyNumber_InPlaceAdd(__pyx_v_fstr, __pyx_t_2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    Py_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    Py_DECREF(__pyx_v_fstr);
-    __pyx_v_fstr = __pyx_3;
-    __pyx_3 = 0;
-    goto __pyx_L6;
-  }
-  __pyx_L6:;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":64
- *         if strlen(self.name) != 0:
- *             fstr += ', name="' + str(self.name) + '"'
- *         if not self.info is None:             # <<<<<<<<<<<<<<
- *             fstr += ", " + str(self.info)
- *         fstr += ")"
- */
-  __pyx_4 = (((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->info == Py_None);
-  __pyx_6 = (!__pyx_4);
-  if (__pyx_6) {
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":65
- *             fstr += ', name="' + str(self.name) + '"'
- *         if not self.info is None:
- *             fstr += ", " + str(self.info)             # <<<<<<<<<<<<<<
- *         fstr += ")"
- *         return fstr
- */
-    __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    Py_INCREF(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->info);
-    PyTuple_SET_ITEM(__pyx_1, 0, ((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->info);
-    __pyx_3 = PyObject_Call(((PyObject *)((PyObject*)&PyString_Type)), ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
-    __pyx_t_2 = PyNumber_Add(__pyx_kp_8, __pyx_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    Py_DECREF(__pyx_3); __pyx_3 = 0;
-    __pyx_2 = PyNumber_InPlaceAdd(__pyx_v_fstr, __pyx_t_2); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    Py_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    Py_DECREF(__pyx_v_fstr);
-    __pyx_v_fstr = __pyx_2;
-    __pyx_2 = 0;
-    goto __pyx_L7;
-  }
-  __pyx_L7:;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":66
- *         if not self.info is None:
- *             fstr += ", " + str(self.info)
- *         fstr += ")"             # <<<<<<<<<<<<<<
- *         return fstr
- * 
- */
-  __pyx_1 = PyNumber_InPlaceAdd(__pyx_v_fstr, __pyx_kp_9); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  Py_DECREF(__pyx_v_fstr);
-  __pyx_v_fstr = __pyx_1;
-  __pyx_1 = 0;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":67
- *             fstr += ", " + str(self.info)
- *         fstr += ")"
- *         return fstr             # <<<<<<<<<<<<<<
- * 
- *     def __cmp__(self, other):
- */
-  Py_INCREF(__pyx_v_fstr);
-  __pyx_r = __pyx_v_fstr;
-  goto __pyx_L0;
-
-  __pyx_r = Py_None; Py_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  Py_XDECREF(__pyx_1);
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
-  __Pyx_AddTraceback("bx.intervals.intersection.Interval.__repr__");
-  __pyx_r = NULL;
-  __pyx_L0:;
-  Py_DECREF(__pyx_v_fstr);
-  return __pyx_r;
-}
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":69
- *         return fstr
- * 
- *     def __cmp__(self, other):             # <<<<<<<<<<<<<<
- *         return cmp( self.start, other.start ) or cmp( self.end, other.end )
- * 
- */
-
-static int __pyx_pf_2bx_9intervals_12intersection_8Interval___cmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other); /*proto*/
-static int __pyx_pf_2bx_9intervals_12intersection_8Interval___cmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other) {
-  int __pyx_r;
-  PyObject *__pyx_1 = 0;
-  PyObject *__pyx_2 = 0;
-  PyObject *__pyx_3 = 0;
-  PyObject *__pyx_4 = 0;
-  int __pyx_5;
-  int __pyx_6;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":70
- * 
- *     def __cmp__(self, other):
- *         return cmp( self.start, other.start ) or cmp( self.end, other.end )             # <<<<<<<<<<<<<<
- * 
- * cdef inline int imax2(int a, int b):
- */
-  __pyx_2 = PyInt_FromLong(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->start); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_3 = PyObject_GetAttr(__pyx_v_other, __pyx_kp_start); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_4 = PyTuple_New(2); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __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 = 0;
-  __pyx_3 = 0;
-  __pyx_1 = PyObject_Call(__pyx_builtin_cmp, ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
-  __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely(__pyx_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (!__pyx_5) {
-    Py_DECREF(__pyx_1); __pyx_1 = 0;
-    __pyx_2 = PyInt_FromLong(((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_self)->end); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_3 = PyObject_GetAttr(__pyx_v_other, __pyx_kp_end); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_4 = PyTuple_New(2); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __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 = 0;
-    __pyx_3 = 0;
-    __pyx_1 = PyObject_Call(__pyx_builtin_cmp, ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
-  }
-  __pyx_6 = __pyx_PyInt_int(__pyx_1); if (unlikely((__pyx_6 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  Py_DECREF(__pyx_1); __pyx_1 = 0;
-  __pyx_r = __pyx_6;
-  goto __pyx_L0;
-
-  __pyx_r = 0;
-  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.Interval.__cmp__");
-  __pyx_r = -1;
-  __pyx_L0:;
-  return __pyx_r;
-}
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":72
- *         return cmp( self.start, other.start ) or cmp( self.end, other.end )
+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
+ * ctypedef char * char_star
  * 
  * cdef inline int imax2(int a, int b):             # <<<<<<<<<<<<<<
  *     if b > a: return b
   int __pyx_r;
   int __pyx_1;
 
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":73
+  /* "/Users/james/projects/bx-python/code/bx-python-central/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":74
+  /* "/Users/james/projects/bx-python/code/bx-python-central/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":76
+/* "/Users/james/projects/bx-python/code/bx-python-central/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":77
+  /* "/Users/james/projects/bx-python/code/bx-python-central/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":78
+    /* "/Users/james/projects/bx-python/code/bx-python-central/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":79
+      /* "/Users/james/projects/bx-python/code/bx-python-central/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":80
+    /* "/Users/james/projects/bx-python/code/bx-python-central/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":81
+  /* "/Users/james/projects/bx-python/code/bx-python-central/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":82
+    /* "/Users/james/projects/bx-python/code/bx-python-central/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":83
+  /* "/Users/james/projects/bx-python/code/bx-python-central/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":85
+/* "/Users/james/projects/bx-python/code/bx-python-central/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":86
+  /* "/Users/james/projects/bx-python/code/bx-python-central/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":87
+    /* "/Users/james/projects/bx-python/code/bx-python-central/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":88
+      /* "/Users/james/projects/bx-python/code/bx-python-central/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":89
+    /* "/Users/james/projects/bx-python/code/bx-python-central/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":90
+  /* "/Users/james/projects/bx-python/code/bx-python-central/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":91
+    /* "/Users/james/projects/bx-python/code/bx-python-central/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":92
+  /* "/Users/james/projects/bx-python/code/bx-python-central/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":94
+/* "/Users/james/projects/bx-python/code/bx-python-central/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":95
+  /* "/Users/james/projects/bx-python/code/bx-python-central/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":96
+  /* "/Users/james/projects/bx-python/code/bx-python-central/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":180
+/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":132
  * 
  *     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":181
+  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":133
  *     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":183
+/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":135
  *             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":184
+  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":136
  *     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":186
+/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":138
  *             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":187
+  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":139
  *     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":189
+/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":141
  *             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":190
+  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":142
  * 
  *     def __repr__(self):
  *         return "IntervalNode(%i, %i)" % (self.start, self.end)             # <<<<<<<<<<<<<<
  * 
- *     def __cinit__(IntervalNode self, Interval interval):
+ *     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 = 190; __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 = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_3 = PyTuple_New(2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __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 = 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;}
   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_10, ((PyObject *)__pyx_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __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;}
   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":192
+/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":144
  *         return "IntervalNode(%i, %i)" % (self.start, self.end)
  * 
- *     def __cinit__(IntervalNode self, Interval interval):             # <<<<<<<<<<<<<<
+ *     def __cinit__(IntervalNode self, int start, int end, object interval):             # <<<<<<<<<<<<<<
  *         # Python lacks the binomial distribution, so we convert a
  *         # uniform into a binomial because it naturally scales with
  */
 
 static int __pyx_pf_2bx_9intervals_12intersection_12IntervalNode___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static int __pyx_pf_2bx_9intervals_12intersection_12IntervalNode___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_interval = 0;
-  int __pyx_r;
-  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_interval,0};
-  if (unlikely(__pyx_kwds)) {
-    PyObject* values[1] = {0};
-    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
-    switch (PyTuple_GET_SIZE(__pyx_args)) {
-      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_interval);
-      if (likely(values[0])) kw_args--;
-      else goto __pyx_L5_argtuple_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 = 192; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-    }
-    __pyx_v_interval = ((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)values[0]);
-  } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
-    goto __pyx_L5_argtuple_error;
-  } else {
-    __pyx_v_interval = ((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)PyTuple_GET_ITEM(__pyx_args, 0));
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.__cinit__");
-  return -1;
-  __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_interval), __pyx_ptype_2bx_9intervals_12intersection_Interval, 1, "interval", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":197
- *         # 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)))             # <<<<<<<<<<<<<<
- *         self.start      = interval.start
- *         self.end       = interval.end
- */
-  ((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":198
- *         # 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      = interval.start             # <<<<<<<<<<<<<<
- *         self.end       = interval.end
- *         self.interval   = interval
- */
-  ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->start = __pyx_v_interval->start;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":199
- *         self.priority   = ceil(nlog * log(-1.0/(1.0 * rand()/RAND_MAX - 1)))
- *         self.start      = interval.start
- *         self.end       = interval.end             # <<<<<<<<<<<<<<
- *         self.interval   = interval
- *         self.maxend    = interval.end
- */
-  ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->end = __pyx_v_interval->end;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":200
- *         self.start      = interval.start
- *         self.end       = interval.end
- *         self.interval   = interval             # <<<<<<<<<<<<<<
- *         self.maxend    = interval.end
- *         self.minstart   = interval.start
- */
-  Py_INCREF(((PyObject *)__pyx_v_interval));
-  Py_DECREF(((PyObject *)((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":201
- *         self.end       = interval.end
- *         self.interval   = interval
- *         self.maxend    = interval.end             # <<<<<<<<<<<<<<
- *         self.minstart   = interval.start
- *         self.minend    = interval.end
- */
-  ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->maxend = __pyx_v_interval->end;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":202
- *         self.interval   = interval
- *         self.maxend    = interval.end
- *         self.minstart   = interval.start             # <<<<<<<<<<<<<<
- *         self.minend    = interval.end
- *         self.cleft       = EmptyNode
- */
-  ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->minstart = __pyx_v_interval->start;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":203
- *         self.maxend    = interval.end
- *         self.minstart   = interval.start
- *         self.minend    = interval.end             # <<<<<<<<<<<<<<
- *         self.cleft       = EmptyNode
- *         self.cright      = EmptyNode
- */
-  ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->minend = __pyx_v_interval->end;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":204
- *         self.minstart   = interval.start
- *         self.minend    = interval.end
- *         self.cleft       = EmptyNode             # <<<<<<<<<<<<<<
- *         self.cright      = EmptyNode
- *         self.croot       = EmptyNode
- */
-  Py_INCREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_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":205
- *         self.minend    = interval.end
- *         self.cleft       = EmptyNode
- *         self.cright      = EmptyNode             # <<<<<<<<<<<<<<
- *         self.croot       = EmptyNode
- * 
- */
-  Py_INCREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_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":206
- *         self.cleft       = EmptyNode
- *         self.cright      = EmptyNode
- *         self.croot       = EmptyNode             # <<<<<<<<<<<<<<
- * 
- *     def insert(self, interval):
- */
-  Py_INCREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_EmptyNode));
-  Py_DECREF(((PyObject *)((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->croot));
-  ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->croot = __pyx_v_2bx_9intervals_12intersection_EmptyNode;
-
-  __pyx_r = 0;
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_AddTraceback("bx.intervals.intersection.IntervalNode.__cinit__");
-  __pyx_r = -1;
-  __pyx_L0:;
-  return __pyx_r;
-}
-
-/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":208
- *         self.croot       = EmptyNode
- * 
- *     def insert(self, interval):             # <<<<<<<<<<<<<<
- *         return self._insert(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;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":209
- * 
- *     def insert(self, interval):
- *         return self._insert(interval)             # <<<<<<<<<<<<<<
- * 
- *     cdef IntervalNode _insert(IntervalNode self, Interval interval):
- */
-  if (!(__Pyx_TypeTest(__pyx_v_interval, __pyx_ptype_2bx_9intervals_12intersection_Interval))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __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), ((struct __pyx_obj_2bx_9intervals_12intersection_Interval *)__pyx_v_interval))); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __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":211
- *         return self._insert(interval)
- * 
- *     cdef IntervalNode _insert(IntervalNode self, Interval 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, struct __pyx_obj_2bx_9intervals_12intersection_Interval *__pyx_v_interval) {
-  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_2 = 0;
-  PyObject *__pyx_3 = 0;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":212
- * 
- *     cdef IntervalNode _insert(IntervalNode self, Interval 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":215
- *         # 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 = interval.start             # <<<<<<<<<<<<<<
- *         if interval.start == self.start:
- *             decision_endpoint = interval.end
- */
-  __pyx_v_decision_endpoint = __pyx_v_interval->start;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":216
- *         # end, thus maintaining sortedness relative to start/end
- *         cdef int decision_endpoint = interval.start
- *         if interval.start == self.start:             # <<<<<<<<<<<<<<
- *             decision_endpoint = interval.end
- * 
- */
-  __pyx_1 = (__pyx_v_interval->start == __pyx_v_self->start);
-  if (__pyx_1) {
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":217
- *         cdef int decision_endpoint = interval.start
- *         if interval.start == self.start:
- *             decision_endpoint = interval.end             # <<<<<<<<<<<<<<
- * 
- *         if decision_endpoint > self.start:
- */
-    __pyx_v_decision_endpoint = __pyx_v_interval->end;
-    goto __pyx_L3;
-  }
-  __pyx_L3:;
-
-  /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":219
- *             decision_endpoint = interval.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":221
- *         if decision_endpoint > self.start:
- *             # insert to cright tree
- *             if self.cright is not EmptyNode:             # <<<<<<<<<<<<<<
- *                 self.cright = self.cright._insert(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":222
- *             # insert to cright tree
- *             if self.cright is not EmptyNode:
- *                 self.cright = self.cright._insert(interval )             # <<<<<<<<<<<<<<
- *             else:
- *                 self.cright = IntervalNode(interval)
- */
-      __pyx_2 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cright->__pyx_vtab)->_insert(__pyx_v_self->cright, __pyx_v_interval)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __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":224
- *                 self.cright = self.cright._insert(interval )
- *             else:
- *                 self.cright = IntervalNode(interval)             # <<<<<<<<<<<<<<
- *             # rebalance tree
- *             if self.priority < self.cright.priority:
- */
-      __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      Py_INCREF(((PyObject *)__pyx_v_interval));
-      PyTuple_SET_ITEM(__pyx_2, 0, ((PyObject *)__pyx_v_interval));
-      __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 = 224; __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 = 224; __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":226
- *                 self.cright = IntervalNode(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":227
- *             # rebalance tree
- *             if self.priority < self.cright.priority:
- *                 croot = self.rotate_left()             # <<<<<<<<<<<<<<
- *         else:
- *             # insert to cleft tree
- */
-      __pyx_2 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->__pyx_vtab)->rotate_left(__pyx_v_self)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      Py_DECREF(((PyObject *)__pyx_v_croot));
-      __pyx_v_croot = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_2);
-      __pyx_2 = 0;
-      goto __pyx_L6;
-    }
-    __pyx_L6:;
-    goto __pyx_L4;
-  }
-  /*else*/ {
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":230
- *         else:
- *             # insert to cleft tree
- *             if self.cleft is not EmptyNode:             # <<<<<<<<<<<<<<
- *                 self.cleft = self.cleft._insert(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":231
- *             # insert to cleft tree
- *             if self.cleft is not EmptyNode:
- *                 self.cleft = self.cleft._insert(interval)             # <<<<<<<<<<<<<<
- *             else:
- *                 self.cleft = IntervalNode(interval)
- */
-      __pyx_3 = ((PyObject *)((struct __pyx_vtabstruct_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self->cleft->__pyx_vtab)->_insert(__pyx_v_self->cleft, __pyx_v_interval)); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __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_3);
-      __pyx_3 = 0;
-      goto __pyx_L7;
-    }
-    /*else*/ {
-
-      /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":233
- *                 self.cleft = self.cleft._insert(interval)
- *             else:
- *                 self.cleft = IntervalNode(interval)             # <<<<<<<<<<<<<<
- *             # rebalance tree
- *             if self.priority < self.cleft.priority:
- */
-      __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      Py_INCREF(((PyObject *)__pyx_v_interval));
-      PyTuple_SET_ITEM(__pyx_2, 0, ((PyObject *)__pyx_v_interval));
-      __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 = 233; __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 = 233; __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_3);
-      __pyx_3 = 0;
-    }
-    __pyx_L7:;
-
-    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":235
- *                 self.cleft = IntervalNode(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":236
- *             # rebalance tree
- *             if self.priority < self.cleft.priority:
- *                 croot = self.rotate_right()             # <<<<<<<<<<<<<<
- * 
- *         croot.set_ends()
- */
-      __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 = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      Py_DECREF(((PyObject *)__pyx_v_croot));
-      __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":238
- *                 croot = self.rotate_right()
- * 
- *         croot.set_ends()             # <<<<<<<<<<<<<<
- *         self.cleft.croot  = croot
- *         self.cright.croot = croot
- */
-  ((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":239
- * 
- *         croot.set_ends()
- *         self.cleft.croot  = croot             # <<<<<<<<<<<<<<
- *         self.cright.croot = croot
- *         return croot
- */
-  Py_INCREF(((PyObject *)__pyx_v_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":240
- *         croot.set_ends()
- *         self.cleft.croot  = croot
- *         self.cright.croot = croot             # <<<<<<<<<<<<<<
- *         return croot
- * 
- */
-  Py_INCREF(((PyObject *)__pyx_v_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":241
- *         self.cleft.croot  = croot
- *         self.cright.croot = croot
- *         return croot             # <<<<<<<<<<<<<<
- * 
- *     cdef IntervalNode rotate_right(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);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  Py_XDECREF(__pyx_2);
-  Py_XDECREF(__pyx_3);
-  __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":243
- *         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-central/lib/bx/intervals/intersection.pyx":244
- * 
- *     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":245
- *     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":246
- *         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":247
- *         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":248
- *         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":250
- *         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":251
- * 
- *     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":252
- *     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":253
- *         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":254
- *         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":255
- *         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":257
- *         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":258
- * 
- *     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":259
- *     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":260
- *         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":261
- *             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":262
- *             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":263
- *             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":264
- *         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":265
- *             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":266
- *             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":267
- *             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":268
- *         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":269
- *             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":272
- * 
- * 
- *     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_2;
+  PyObject *__pyx_v_interval = 0;
+  int __pyx_r;
+  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 = 272; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __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;}
       }
     }
     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 = 272; __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 = 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 = 272; __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 = 272; __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_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_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_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
+ *         # 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)))             # <<<<<<<<<<<<<<
+ *         self.start      = start
+ *         self.end       = end
+ */
+  ((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
+ *         # 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             # <<<<<<<<<<<<<<
+ *         self.end       = end
+ *         self.interval   = interval
+ */
+  ((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
+ *         self.priority   = ceil(nlog * log(-1.0/(1.0 * rand()/RAND_MAX - 1)))
+ *         self.start      = start
+ *         self.end       = end             # <<<<<<<<<<<<<<
+ *         self.interval   = interval
+ *         self.maxend    = 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
+ *         self.start      = start
+ *         self.end       = end
+ *         self.interval   = interval             # <<<<<<<<<<<<<<
+ *         self.maxend    = end
+ *         self.minstart   = start
+ */
+  Py_INCREF(__pyx_v_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
+ *         self.end       = end
+ *         self.interval   = interval
+ *         self.maxend    = end             # <<<<<<<<<<<<<<
+ *         self.minstart   = start
+ *         self.minend    = 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
+ *         self.interval   = interval
+ *         self.maxend    = end
+ *         self.minstart   = start             # <<<<<<<<<<<<<<
+ *         self.minend    = end
+ *         self.cleft       = EmptyNode
+ */
+  ((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
+ *         self.maxend    = end
+ *         self.minstart   = start
+ *         self.minend    = end             # <<<<<<<<<<<<<<
+ *         self.cleft       = EmptyNode
+ *         self.cright      = EmptyNode
+ */
+  ((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
+ *         self.minstart   = start
+ *         self.minend    = end
+ *         self.cleft       = EmptyNode             # <<<<<<<<<<<<<<
+ *         self.cright      = EmptyNode
+ *         self.croot       = EmptyNode
+ */
+  Py_INCREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_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
+ *         self.minend    = end
+ *         self.cleft       = EmptyNode
+ *         self.cright      = EmptyNode             # <<<<<<<<<<<<<<
+ *         self.croot       = EmptyNode
+ * 
+ */
+  Py_INCREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_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
+ *         self.cleft       = EmptyNode
+ *         self.cright      = EmptyNode
+ *         self.croot       = EmptyNode             # <<<<<<<<<<<<<<
+ * 
+ *     def insert( self, interval ):
+ */
+  Py_INCREF(((PyObject *)__pyx_v_2bx_9intervals_12intersection_EmptyNode));
+  Py_DECREF(((PyObject *)((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->croot));
+  ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_v_self)->croot = __pyx_v_2bx_9intervals_12intersection_EmptyNode;
+
+  __pyx_r = 0;
+  return __pyx_r;
+}
+
+/* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":160
+ *         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):             # <<<<<<<<<<<<<<
+ *         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) {
+  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_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;}
+      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;}
+      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;}
+      Py_DECREF(((PyObject *)__pyx_v_self->cright));
+      __pyx_v_self->cright = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_2);
+      __pyx_2 = 0;
+    }
+    __pyx_L5:;
+
+    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":178
+ *                 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
+ *             # 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;}
+      Py_DECREF(((PyObject *)__pyx_v_croot));
+      __pyx_v_croot = ((struct __pyx_obj_2bx_9intervals_12intersection_IntervalNode *)__pyx_3);
+      __pyx_3 = 0;
+      goto __pyx_L6;
+    }
+    __pyx_L6:;
+    goto __pyx_L4;
+  }
+  /*else*/ {
+
+    /* "/Users/james/projects/bx-python/code/bx-python-central/lib/bx/intervals/intersection.pyx":182
+ *         else:
+ *             # insert to cleft tree
+ *             if self.cleft is not EmptyNode:             # <<<<<<<<<<<<<<
+ *                 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
+ *             # insert to cleft tree
+ *             if self.cleft is not EmptyNode:
+ *                 self.cleft = self.cleft._insert( start, end, interval)             # <<<<<<<<<<<<<<
+ *             else: