public function filter($tag = null, $target = TimePoint::TARGET_ALL, $type = TimePoint::TYPE_ALL)
    {
        // the tag criteria can be omitted
        $tags = null;
        if (isset($tag)) {
            $tags = is_array($tag) ? $tag : [$tag];
        }
        
        // create a another instance of the same class
        $subset = new static();
        
        // fill the new instance with filtered TimePoint
        foreach ($this->points as $idx => $point) {
            if ($point->match($tags, $target, $type)) {
                $subset->add($point);
            }
        }

        return $subset;
    }