static function merge($a, $b, $cmp, $offset)
    {
        if ($a === 0) {
            $head = $b;
        } elseif ($b === 0) {
            $head = $a;
        } else {
            if (call_user_func($cmp, $a, $b) < 0) {
                $ptr = $a;
                $a = $a->$offset;
            } else {
                $ptr = $b;
                $b = $b->$offset;
            }
            $head = $ptr;
            while ($a && $b) {
                if (call_user_func($cmp, $a, $b) < 0) {
                    $ptr->$offset = $a;
                    $ptr = $a;
                    $a = $a->$offset;
                } else {
                    $ptr->$offset = $b;
                    $ptr = $b;
                    $b = $b->$offset;
                }
            }
            if ($a !== 0) {
                $ptr->$offset = $a;
            } else {
                $ptr->$offset = $b;
            }
        }
        return $head;
    }