private static function vcard_unquote($s, $sep = ';')
    {
        // break string into parts separated by $sep
        if (!empty($sep)) {
            // Handle properly backslash escaping (#1488896)
            $rep1 = array("\\\\" => "\010", "\\$sep" => "\007");
            $rep2 = array("\007" => "\\$sep", "\010" => "\\\\");

            if (count($parts = explode($sep, strtr($s, $rep1))) > 1) {
                foreach ($parts as $s) {
                    $result[] = self::vcard_unquote(strtr($s, $rep2));
                }
                return $result;
            }

            $s = trim(strtr($s, $rep2));
        }

        // some implementations (GMail) use non-standard backslash before colon (#1489085)
        // we will handle properly any backslashed character - removing dummy backslahes
        // return strtr($s, array("\r" => '', '\\\\' => '\\', '\n' => "\n", '\N' => "\n", '\,' => ',', '\;' => ';'));

        $s   = str_replace("\r", '', $s);
        $pos = 0;

        while (($pos = strpos($s, '\\', $pos)) !== false) {
            $next = substr($s, $pos + 1, 1);
            if ($next == 'n' || $next == 'N') {
                $s = substr_replace($s, "\n", $pos, 2);
            }
            else {
                $s = substr_replace($s, '', $pos, 1);
            }

            $pos += 1;
        }

        return $s;
    }