protected function packTimeLine(&$timeLine)
    {
        $epoch = $this->getEpoch();
        $data = [
            self::STORAGE_KEY_TIMELINE_INDEX => [],
            self::STORAGE_KEY_TIMELINE_TAGS => [],
            self::STORAGE_KEY_TIMELINE_POINTS => [],
            self::STORAGE_KEY_TIMELINE_EPOCH => $epoch,
        ];

        // Will split tags from the list of TimePoint, and put them into a dedicated index.
        // The other TimePoint info are put in a simple array with predictable order, this way: [target, type, timestamp].
        // To save more space a reference value is removed from each timestamp.
        $index = 0;
        foreach ($timeLine->getPoints() as &$point) {
            /** @var TimePoint $point */
            $data[self::STORAGE_KEY_TIMELINE_POINTS][$index] = [$point->getTarget(), $point->getType(), round($point->getTimestamp() - $epoch, 6)];

            foreach ($point->getTags() as &$tag) {
                $data[self::STORAGE_KEY_TIMELINE_INDEX][$tag][] = $index;
            }

            $index++;
        }

        // try to reduce the size of the index by simplifying those that target all TimePoint
        if ($index) {
            foreach ($data[self::STORAGE_KEY_TIMELINE_INDEX] as $tag => &$list) {
                if (count($list) == $index) {
                    unset($data[self::STORAGE_KEY_TIMELINE_INDEX][$tag]);
                    $data[self::STORAGE_KEY_TIMELINE_TAGS][] = $tag;
                }
            }
        } else {
            $data = [];
        }

        return $data;
    }