public function findOrMakeTab($tabName, $title = null)
    {
        $parts = explode('.', $tabName);
        $last_idx = count($parts) - 1;
        // We could have made this recursive, but I've chosen to keep all the logic code within FieldList rather than
        // add it to TabSet and Tab too.
        $currentPointer = $this;
        foreach ($parts as $k => $part) {
            $parentPointer = $currentPointer;
            /** @var FormField $currentPointer */
            $currentPointer = $currentPointer->fieldByName($part);
            // Create any missing tabs
            if (!$currentPointer) {
                if ($parentPointer instanceof TabSet) {
                    // use $title on the innermost tab only
                    if ($k == $last_idx) {
                        $currentPointer = isset($title) ? new Tab($part, $title) : new Tab($part);
                    } else {
                        $currentPointer = new TabSet($part);
                    }
                    $parentPointer->push($currentPointer);
                } else {
                    $withName = $parentPointer instanceof FormField
                        ? " named '{$parentPointer->getName()}'"
                        : null;
                    $parentPointerClass = get_class($parentPointer);
                    user_error(
                        "FieldList::addFieldToTab() Tried to add a tab to object"
                        . " '{$parentPointerClass}'{$withName} - '{$part}' didn't exist.",
                        E_USER_ERROR
                    );
                }
            }
        }

        return $currentPointer;
    }