'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'

def _insert_and_merge_core(self, pos, direction):

    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 (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):
        if (segment.sort == previous_segment.sort):
            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
        elif (segment.start == previous_segment.end):
            pass
        else:
            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:
                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))
            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
            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)
