protected function castRecursive($source, $values, SplObjectStorage $list)
    {
        if (is_object($source)) {
            $list[$source] = null;
        }

        foreach ($values as $key => &$value) {
            if (!is_object($value) || !$list->contains($value)) {
                $value = $this->cast($value, $list); // Recursion
            } elseif ($list[$value] === null && is_object($values)) {
                unset($values->$key);
            } elseif ($list[$value] === null && is_array($values) && !is_int($key)) {
                unset($values[$key]);
            } else {
                $value = $list[$value];
            }
        }

        if (is_object($source)) {
            $list[$source] = $values;
        }

        return $values;
    }