docs: def _insert_and_merge_core(self, pos, direction):
          """
          The core part of method _insert_and_merge.
  
          :param int pos:         The starting position.
          :param str direction:   If we are traversing forwards or backwards in the list. It determines where the "sort"
                                  of the overlapping memory block comes from. If everything works as expected, "sort" of
                                  the overlapping block is always equal to the segment occupied most recently.
          :return: A tuple of (merged (bool), new position to begin searching (int), change in total bytes (int)
          :rtype: tuple
          """
  
          bytes_changed = 0
  
          if direction == "forward":
              if pos == len(self._list) - 1:
                  return False, pos, 0
              previous_segment = self._list[pos]
              previous_segment_pos = pos
              segment = self._list[pos + 1]
              segment_pos = pos + 1
          else:  # if direction == "backward":
              if pos == 0:
                  return False, pos, 0
              segment = self._list[pos]
              segment_pos = pos
              previous_segment = self._list[pos - 1]
              previous_segment_pos = pos - 1
  
          merged = False
          new_pos = pos
  
          if segment.start <= previous_segment.end:
              # we should always have new_start+new_size >= segment.start
  
              if segment.sort == previous_segment.sort:
                  # They are of the same sort - we should merge them!
                  new_end = max(previous_segment.end, segment.start + segment.size)
                  new_start = min(previous_segment.start, segment.start)
                  new_size = new_end - new_start
                  self._list[segment_pos] = Segment(new_start, new_end, segment.sort)
                  self._list.pop(previous_segment_pos)
                  bytes_changed = -(segment.size + previous_segment.size - new_size)
  
                  merged = True
                  new_pos = previous_segment_pos
  
              else:
                  # Different sorts. It's a bit trickier.
                  if segment.start == previous_segment.end:
                      # They are adjacent. Just don't merge.
                      pass
                  else:
                      # They are overlapping. We will create one, two, or three different blocks based on how they are
                      # overlapping
                      new_segments = [ ]
                      if segment.start < previous_segment.start:
                          new_segments.append(Segment(segment.start, previous_segment.start, segment.sort))
  
                          sort = previous_segment.sort if direction == "forward" else segment.sort
                          new_segments.append(Segment(previous_segment.start, previous_segment.end, sort))
  
                          if segment.end < previous_segment.end:
                              new_segments.append(Segment(segment.end, previous_segment.end, previous_segment.sort))
                          elif segment.end > previous_segment.end:
                              new_segments.append(Segment(previous_segment.end, segment.end, segment.sort))
                      else:  # segment.start >= previous_segment.start
                          if segment.start > previous_segment.start:
                              new_segments.append(Segment(previous_segment.start, segment.start, previous_segment.sort))
                          sort = previous_segment.sort if direction == "forward" else segment.sort
                          if segment.end > previous_segment.end:
                              new_segments.append(Segment(segment.start, previous_segment.end, sort))
                              new_segments.append(Segment(previous_segment.end, segment.end, segment.sort))
                          elif segment.end < previous_segment.end:
                              new_segments.append(Segment(segment.start, segment.end, sort))
                              new_segments.append(Segment(segment.end, previous_segment.end, previous_segment.sort))
                          else:
                              new_segments.append(Segment(segment.start, segment.end, sort))
  
                      # merge segments in new_segments array if they are of the same sort
                      i = 0
                      while len(new_segments) > 1 and i < len(new_segments) - 1:
                          s0 = new_segments[i]
                          s1 = new_segments[i + 1]
                          if s0.sort == s1.sort:
                              new_segments = new_segments[ : i] + [ Segment(s0.start, s1.end, s0.sort) ] + new_segments[i + 2 : ]
                          else:
                              i += 1
  
                      # Put new segments into self._list
                      old_size = sum([ seg.size for seg in self._list[previous_segment_pos : segment_pos + 1] ])
                      new_size = sum([ seg.size for seg in new_segments ])
                      bytes_changed = new_size - old_size
  
                      self._list = self._list[ : previous_segment_pos] + new_segments + self._list[ segment_pos + 1 : ]
  
                      merged = True
  
                      if direction == "forward":
                          new_pos = previous_segment_pos + len(new_segments)
                      else:
                          new_pos = previous_segment_pos
  
          return merged, new_pos, bytes_changed