public static function parse($string, array $styles)
    {
        // style the entire string if no tags are found
        if (false === strpos($string, '{')) {
            return self::style($string, reset($styles));
        }

        $i = 0;

        // loop through each tag in the string
        while (false !== $openTag = strpos($string, '{')) {
            $style = array_key_exists($i, $styles) ? $styles[$i] : end($styles);

            $escapeSequence = ($style instanceof Style) ? $style->getEscapeSequence() : self::getEscapeSequence($style);
            $resetSequence = ($style instanceof Style) ? Style::getResetSequence() : self::getResetSequence($style);

            // replace opening tag
            $string = substr_replace($string, $escapeSequence, $openTag, 1);

            if (false === $closeTag = strpos($string, '}')) {
                $closeTag = strlen($string);
            }

            // don't produce multiple identical reset tags next to each other
            if (substr($string, $closeTag - strlen($resetSequence), strlen($resetSequence)) !== $resetSequence) {
                $string = substr_replace($string, $resetSequence, $closeTag, 1);
            }

            $i++;
        }

        return $string;
    }