public function fromDelta($text1, $delta)
    {
        $diffs = array();
        // Cursor in text1
        $pointer = 0;
        $tokens = explode("\t", $delta);
        foreach ($tokens as $token) {
            if ($token == '') {
                // Blank tokens are ok (from a trailing \t).
                continue;
            }
            // Each token begins with a one character parameter which specifies the
            // operation of this token (delete, insert, equality).
            $op = mb_substr($token, 0, 1);
            $param = mb_substr($token, 1);
            switch ($op) {
                case '+':
                    $diffs[] = array(
                        self::INSERT,
                        Utils::unescapeString($param),
                    );
                    break;
                case '-':
                case '=':
                    if (!is_numeric($param)) {
                        throw new \InvalidArgumentException('Invalid number in delta: ' . $param);
                    } elseif ($param < 0) {
                        throw new \InvalidArgumentException('Negative number in delta: ' . $param);
                    } else {
                        $n = (int) $param;
                    }
                    $text = mb_substr($text1, $pointer, $n);
                    $pointer += $n;
                    $diffs[] = array(
                        $op == '=' ? self::EQUAL : self::DELETE,
                        $text,
                    );
                    break;
                default:
                    // Anything else is an error.
                    throw new \InvalidArgumentException('Invalid diff operation in delta: ' . $op);
            }
        }
        if ($pointer != mb_strlen($text1)) {
            throw new \InvalidArgumentException('Delta length (' . $pointer . ') does not equal source text length (' . mb_strlen($text1) . ').');
        }
        $this->setChanges($diffs);

        return $this;
    }