<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[2317] 2013/codebykat/post-by-email/trunk/include/Horde: Upgraded to horde_imap_client-2.15.2</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://gsoc.trac.wordpress.org/changeset/2317">2317</a></dd>
<dt>Author</dt> <dd>codebykat</dd>
<dt>Date</dt> <dd>2013-09-16 02:11:45 +0000 (Mon, 16 Sep 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>Upgraded to horde_imap_client-2.15.2</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientBaseConnectionphp">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Base/Connection.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientBasephp">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Base.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientCacheBackendDbphp">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Cache/Backend/Db.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientDataFetchphp">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Data/Fetch.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientInteractionCommandContinuationphp">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Interaction/Command/Continuation.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientMailboxListphp">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Mailbox/List.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientMailboxphp">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Mailbox.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientSocketConnectionPop3php">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Connection/Pop3.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientSocketConnectionSocketphp">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Connection/Socket.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientSocketConnectionphp">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Connection.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientSocketPop3php">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Pop3.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientSocketphp">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientphp">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeMailRfc822Addressphp">2013/codebykat/post-by-email/trunk/include/Horde/Mail/Rfc822/Address.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeMailRfc822Listphp">2013/codebykat/post-by-email/trunk/include/Horde/Mail/Rfc822/List.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeMimeHeadersphp">2013/codebykat/post-by-email/trunk/include/Horde/Mime/Headers.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeMimePartphp">2013/codebykat/post-by-email/trunk/include/Horde/Mime/Part.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeStreamFilterEolphp">2013/codebykat/post-by-email/trunk/include/Horde/Stream/Filter/Eol.php</a></li>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeSupportStubphp">2013/codebykat/post-by-email/trunk/include/Horde/Support/Stub.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#2013codebykatpostbyemailtrunkincludeHordeImapClientBasePasswordphp">2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Base/Password.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientBaseConnectionphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Base/Connection.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Base/Connection.php 2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Base/Connection.php    2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -61,8 +61,13 @@
</span><span class="cx">      */
</span><span class="cx">     public function __construct(Horde_Imap_Client_Base $base, $debug)
</span><span class="cx">     {
</span><del>-        if ($base->getParam('secure') && !extension_loaded('openssl')) {
-            throw new InvalidArgumentException('Secure connections require the PHP openssl extension.');
</del><ins>+        if (($secure = $base->getParam('secure')) &&
+            !extension_loaded('openssl')) {
+            if ($secure !== true) {
+                throw new InvalidArgumentException('Secure connections require the PHP openssl extension.');
+            }
+
+            $base->setParam('secure', false);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         $this->_debug = $debug;
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientBasePasswordphp"></a>
<div class="addfile"><h4>Added: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Base/Password.php (0 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Base/Password.php                           (rev 0)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Base/Password.php      2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+<?php
+/**
+ * Copyright 2013 Horde LLC (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.horde.org/licenses/lgpl21.
+ *
+ * @category  Horde
+ * @copyright 2013 Horde LLC
+ * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
+ * @package   Imap_Client
+ */
+
+/**
+ * Interface to allow dynamic generation of server password.
+ *
+ * @author    Michael Slusarz <slusarz@horde.org>
+ * @category  Horde
+ * @copyright 2013 Horde LLC
+ * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
+ * @package   Imap_Client
+ * @since     2.14.0
+ */
+interface Horde_Imap_Client_Base_Password
+{
+    /**
+     * Return the password to use for the server connection.
+     *
+     * @return string  The password.
+     */
+    public function getPassword();
+
+}
</ins></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientBasephp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Base.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Base.php    2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Base.php       2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -57,6 +57,19 @@
</span><span class="cx">     public $changed = false;
</span><span class="cx"> 
</span><span class="cx">     /**
</span><ins>+     * Horde_Imap_Client is optimized for short (i.e. 1 seconds) scripts. It
+     * makes heavy use of mailbox caching to save on server accesses. This
+     * property should be set to false for long-running scripts, or else
+     * status() data may not reflect the current state of the mailbox on the
+     * server.
+     *
+     * @since 2.14.0
+     *
+     * @var boolean
+     */
+    public $statuscache = true;
+
+    /**
</ins><span class="cx">      * The Horde_Imap_Client_Cache object.
</span><span class="cx">      *
</span><span class="cx">      * @var Horde_Imap_Client_Cache
</span><span class="lines">@@ -78,6 +91,14 @@
</span><span class="cx">     protected $_debug = null;
</span><span class="cx"> 
</span><span class="cx">     /**
</span><ins>+     * The default ports to use for a connection.
+     * First element is non-secure, second is SSL.
+     *
+     * @var array
+     */
+    protected $_defaultPorts = array();
+
+    /**
</ins><span class="cx">      * The fetch data object type to return.
</span><span class="cx">      *
</span><span class="cx">      * @var string
</span><span class="lines">@@ -136,7 +157,9 @@
</span><span class="cx">      * <ul>
</span><span class="cx">      *  <li>REQUIRED Parameters
</span><span class="cx">      *   <ul>
</span><del>-     *    <li>password: (string) The IMAP user password.</li>
</del><ins>+     *    <li>password: (mixed) The IMAP user password. Either a string or
+     *                  a Horde_Imap_Client_Base_Password object (since
+     *                  2.14.0).</li>
</ins><span class="cx">      *    <li>username: (string) The IMAP username.</li>
</span><span class="cx">      *   </ul>
</span><span class="cx">      *  </li>
</span><span class="lines">@@ -153,10 +176,6 @@
</span><span class="cx">      *                Backend cache driver (as of 2.9.0).
</span><span class="cx">      *      </li>
</span><span class="cx">      *      <li>
</span><del>-     *       cacheob: [REQUIRED (or backend)] (Horde_Cache) The cache object to
-     *                use (DEPRECATED).
-     *      </li>
-     *      <li>
</del><span class="cx">      *       fetch_ignore: (array) A list of mailboxes to ignore when storing
</span><span class="cx">      *                     fetch data.
</span><span class="cx">      *      </li>
</span><span class="lines">@@ -205,12 +224,6 @@
</span><span class="cx">      *            DEFAULT: No debug output
</span><span class="cx">      *    </li>
</span><span class="cx">      *    <li>
</span><del>-     *     encryptKey: (array) A callback to a function that returns the key
-     *                 used to encrypt the password. This function MUST be
-     *                 static.
-     *                 DEFAULT: No encryption
-     *    </li>
-     *    <li>
</del><span class="cx">      *     hostspec: (string) The hostname or IP address of the server.
</span><span class="cx">      *               DEFAULT: 'localhost'
</span><span class="cx">      *    </li>
</span><span class="lines">@@ -234,13 +247,14 @@
</span><span class="cx">      *     secure: (string) Use SSL or TLS to connect.
</span><span class="cx">      *             VALUES:
</span><span class="cx">      *     <ul>
</span><del>-     *      <li>false</li>
</del><ins>+     *      <li>false (No encryption)</li>
</ins><span class="cx">      *      <li>'ssl' (Auto-detect SSL version)</li>
</span><span class="cx">      *      <li>'sslv2' (Force SSL version 3)</li>
</span><span class="cx">      *      <li>'sslv3' (Force SSL version 2)</li>
</span><del>-     *      <li>'tls'</li>
</del><ins>+     *      <li>'tls' (TLS)</li>
+     *      <li>true (TLS if available/necessary) [since 2.15.0]</li>
</ins><span class="cx">      *     </ul>
</span><del>-     *             DEFAULT: No encryption</li>
</del><ins>+     *             DEFAULT: false</li>
</ins><span class="cx">      *    </li>
</span><span class="cx">      *    <li>
</span><span class="cx">      *     timeout: (integer)  Connection timeout, in seconds.
</span><span class="lines">@@ -266,14 +280,10 @@
</span><span class="cx">             'timeout' => 30
</span><span class="cx">         ), array_filter($params));
</span><span class="cx"> 
</span><del>-        if ($params['secure'] === true) {
-            $params['secure'] = 'tls';
-        }
-
</del><span class="cx">         if (!isset($params['port'])) {
</span><del>-            $params['port'] = (isset($params['secure']) && in_array($params['secure'], array('ssl', 'sslv2', 'sslv3')))
-                ? 993
-                : 143;
</del><ins>+            $params['port'] = (!empty($params['secure']) && in_array($params['secure'], array('ssl', 'sslv2', 'sslv3'), true))
+                ? $this->_defaultPorts[1]
+                : $this->_defaultPorts[0];
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (empty($params['cache'])) {
</span><span class="lines">@@ -298,6 +308,8 @@
</span><span class="cx">     /**
</span><span class="cx">      * Get encryption key.
</span><span class="cx">      *
</span><ins>+     * @deprecated  Pass callable into 'password' parameter instead.
+     *
</ins><span class="cx">      * @return string  The encryption key.
</span><span class="cx">      */
</span><span class="cx">     protected function _getEncryptKey()
</span><span class="lines">@@ -498,13 +510,22 @@
</span><span class="cx">     public function getParam($key)
</span><span class="cx">     {
</span><span class="cx">         /* Passwords may be stored encrypted. */
</span><del>-        if (($key == 'password') && !empty($this->_params['_passencrypt'])) {
-            try {
-                $secret = new Horde_Secret();
-                return $secret->read($this->_getEncryptKey(), $this->_params['password']);
-            } catch (Exception $e) {
-                return null;
</del><ins>+        switch ($key) {
+        case 'password':
+            if ($this->_params[$key] instanceof Horde_Imap_Client_Base_Password) {
+                return $this->_params[$key]->getPassword();
</ins><span class="cx">             }
</span><ins>+
+            // DEPRECATED
+            if (!empty($this->_params['_passencrypt'])) {
+                try {
+                    $secret = new Horde_Secret();
+                    return $secret->read($this->_getEncryptKey(), $this->_params['password']);
+                } catch (Exception $e) {
+                    return null;
+                }
+            }
+            break;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         return isset($this->_params[$key])
</span><span class="lines">@@ -522,7 +543,11 @@
</span><span class="cx">     {
</span><span class="cx">         switch ($key) {
</span><span class="cx">         case 'password':
</span><del>-            // Encrypt password.
</del><ins>+            if ($val instanceof Horde_Imap_Client_Base_Password) {
+                break;
+            }
+
+            // DEPRECATED: Encrypt password.
</ins><span class="cx">             try {
</span><span class="cx">                 $encrypt_key = $this->_getEncryptKey();
</span><span class="cx">                 if (strlen($encrypt_key)) {
</span><span class="lines">@@ -530,9 +555,7 @@
</span><span class="cx">                     $val = $secret->write($encrypt_key, $val);
</span><span class="cx">                     $this->_params['_passencrypt'] = true;
</span><span class="cx">                 }
</span><del>-            } catch (Exception $e) {
-                $this->_params['_passencrypt'] = false;
-            }
</del><ins>+            } catch (Exception $e) {}
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -693,7 +716,7 @@
</span><span class="cx">         if (!empty($to_process)) {
</span><span class="cx">             foreach ($this->listMailboxes($to_process, Horde_Imap_Client::MBOX_ALL, array('delimiter' => true)) as $val) {
</span><span class="cx">                 $ns[$val] = array(
</span><del>-                    'delimiter' => $first['delimiter'],
</del><ins>+                    'delimiter' => $val['delimiter'],
</ins><span class="cx">                     'hidden' => true,
</span><span class="cx">                     'name' => $val,
</span><span class="cx">                     'translation' => '',
</span><span class="lines">@@ -829,8 +852,7 @@
</span><span class="cx">             throw new Horde_Imap_Client_Exception_NoSupportExtension('ID');
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        /* Modified for WordPress inclusion: The shorthand ternary operator ?: was introduced in PHP 5.3. */
-        $this->_sendID(is_null($info) ? ($this->getParam('id') ? $this->getParam('id') : array()) : $info);
</del><ins>+        $this->_sendID(is_null($info) ? ($this->getParam('id') ?: array()) : $info);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="lines">@@ -1358,8 +1380,7 @@
</span><span class="cx"> 
</span><span class="cx">         if (!empty($options['status']) &&
</span><span class="cx">             !$this->queryCapability('LIST-STATUS')) {
</span><del>-            $status = $this->statusMultiple($this->_selected, $options['status']);
-            foreach ($status as $key => $val) {
</del><ins>+            foreach ($this->status(array_keys($ret), $options['status']) as $key => $val) {
</ins><span class="cx">                 $ret[$key]['status'] = $val;
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="lines">@@ -1605,6 +1626,19 @@
</span><span class="cx">      *   </ul>
</span><span class="cx">      *  </li>
</span><span class="cx">      *  <li>
</span><ins>+     *   Horde_Imap_Client::STATUS_FORCE_REFRESH
+     *   <ul>
+     *    <li>
+     *     Normally, the status information will be cached for a given
+     *     mailbox. Since most PHP requests are generally less than a second,
+     *     this is fine. However, if your script is long running, the status
+     *     information may not be up-to-date. Specifying this flag will ensure
+     *     that the server is always polled for the current mailbox status
+     *     before results are returned. (since 2.14.0)
+     *    </li>
+     *   </ul>
+     *  </li>
+     *  <li>
</ins><span class="cx">      *   Horde_Imap_Client::STATUS_ALL (DEFAULT)
</span><span class="cx">      *   <ul>
</span><span class="cx">      *    <li>
</span><span class="lines">@@ -1659,6 +1693,10 @@
</span><span class="cx">             'unseen' => Horde_Imap_Client::STATUS_UNSEEN
</span><span class="cx">         );
</span><span class="cx"> 
</span><ins>+        if (!$this->statuscache) {
+            $flags |= Horde_Imap_Client::STATUS_FORCE_REFRESH;
+        }
+
</ins><span class="cx">         if ($flags & Horde_Imap_Client::STATUS_ALL) {
</span><span class="cx">             foreach ($unselected_flags as $val) {
</span><span class="cx">                 $flags |= $val;
</span><span class="lines">@@ -1689,19 +1727,26 @@
</span><span class="cx">             $name = strval($val);
</span><span class="cx">             $tmp_flags = $flags;
</span><span class="cx"> 
</span><del>-            /* A list of STATUS options (other than those handled directly
-             * below) that require the mailbox to be explicitly opened. */
-            $opened = ($flags & Horde_Imap_Client::STATUS_FIRSTUNSEEN) ||
-                ($flags & Horde_Imap_Client::STATUS_FLAGS) ||
-                ($flags & Horde_Imap_Client::STATUS_PERMFLAGS) ||
-                ($flags & Horde_Imap_Client::STATUS_UIDNOTSTICKY) ||
</del><ins>+            if ($val->equals($this->_selected)) {
</ins><span class="cx">                 /* Check if already in mailbox. */
</span><del>-                $val->equals($this->_selected) ||
-                /* Force mailboxes containing wildcards to be accessed via
-                 * STATUS so that wildcards do not return a bunch of
-                 * mailboxes in the LIST-STATUS response. */
-                (strpbrk($name, '*%') !== false);
</del><ins>+                $opened = true;
</ins><span class="cx"> 
</span><ins>+                if ($flags & Horde_Imap_Client::STATUS_FORCE_REFRESH) {
+                    $this->noop();
+                }
+            } else {
+                /* A list of STATUS options (other than those handled directly
+                 * below) that require the mailbox to be explicitly opened. */
+                $opened = ($flags & Horde_Imap_Client::STATUS_FIRSTUNSEEN) ||
+                    ($flags & Horde_Imap_Client::STATUS_FLAGS) ||
+                    ($flags & Horde_Imap_Client::STATUS_PERMFLAGS) ||
+                    ($flags & Horde_Imap_Client::STATUS_UIDNOTSTICKY) ||
+                    /* Force mailboxes containing wildcards to be accessed via
+                     * STATUS so that wildcards do not return a bunch of
+                     * mailboxes in the LIST-STATUS response. */
+                    (strpbrk($name, '*%') !== false);
+            }
+
</ins><span class="cx">             $ret[$name] = $master;
</span><span class="cx">             $ptr = &$ret[$name];
</span><span class="cx"> 
</span><span class="lines">@@ -2200,6 +2245,8 @@
</span><span class="cx">                 Horde_Imap_Client::SEARCH_RESULTS_MATCH,
</span><span class="cx">                 Horde_Imap_Client::SEARCH_RESULTS_COUNT
</span><span class="cx">             );
</span><ins>+        } elseif (!in_array(Horde_Imap_Client::SEARCH_RESULTS_COUNT, $options['results'])) {
+            $options['results'][] = Horde_Imap_Client::SEARCH_RESULTS_COUNT;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Default to an ALL search.
</span><span class="lines">@@ -2318,12 +2365,14 @@
</span><span class="cx"> 
</span><span class="cx">             $ret = $this->_search($query, $options);
</span><span class="cx">         } else {
</span><del>-            $ret = array(
-                'count' => 0
-            );
</del><ins>+            $ret = array();
</ins><span class="cx"> 
</span><span class="cx">             foreach ($options['results'] as $val) {
</span><span class="cx">                 switch ($val) {
</span><ins>+                case Horde_Imap_Client::SEARCH_RESULTS_COUNT:
+                    $ret['count'] = 0;
+                    break;
+
</ins><span class="cx">                 case Horde_Imap_Client::SEARCH_RESULTS_MATCH:
</span><span class="cx">                     $ret['match'] = $this->getIdsOb();
</span><span class="cx">                     break;
</span><span class="lines">@@ -3567,7 +3616,9 @@
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             $convert = 2;
</span><del>-        } elseif (!$convert || (!$ids->sequence && ($convert == 1))) {
</del><ins>+        } elseif (!$convert ||
+                  (!$ids->sequence && ($convert == 1)) ||
+                  $ids->isEmpty()) {
</ins><span class="cx">             return clone $ids;
</span><span class="cx">         } else {
</span><span class="cx">             /* Do an all or nothing: either we have all the numbers/UIDs in
</span><span class="lines">@@ -3601,7 +3652,7 @@
</span><span class="cx">                 return $res['match'];
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            $map->update(array_combine($ids->ids, $res['match']->ids));
</del><ins>+            $map->update(array_combine(array_slice($ids->ids, 0, count($res['match'])), $res['match']->ids));
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         return $res['match'];
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientCacheBackendDbphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Cache/Backend/Db.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Cache/Backend/Db.php        2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Cache/Backend/Db.php   2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -89,9 +89,9 @@
</span><span class="cx">             $columns = $this->_db->columns(self::MSG_TABLE);
</span><span class="cx">             $res = $this->_db->select($query[0], $query[1]);
</span><span class="cx"> 
</span><del>-            while (($row = $res->fetchObject()) !== false) {
-                $out[$row->msguid] = @unserialize($compress->decompress(
-                    $columns['data']->binaryToString($row->data)
</del><ins>+            foreach ($res as $row) {
+                $out[$row['msguid']] = @unserialize($compress->decompress(
+                    $columns['data']->binaryToString($row['data'])
</ins><span class="cx">                 ));
</span><span class="cx">             }
</span><span class="cx">         } catch (Horde_Db_Exception $e) {}
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientDataFetchphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Data/Fetch.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Data/Fetch.php      2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Data/Fetch.php 2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -564,4 +564,5 @@
</span><span class="cx">             : $this->_msgText(false, $this->_data[$key][$id]);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> }
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientInteractionCommandContinuationphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Interaction/Command/Continuation.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Interaction/Command/Continuation.php        2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Interaction/Command/Continuation.php   2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -25,6 +25,14 @@
</span><span class="cx"> class Horde_Imap_Client_Interaction_Command_Continuation
</span><span class="cx"> {
</span><span class="cx">     /**
</span><ins>+     * Is this an optional continuation request?
+     *
+     * @since 2.13.0
+     * @var boolean
+     */
+    public $optional = false;
+
+    /**
</ins><span class="cx">      * Closure function to run after continuation response.
</span><span class="cx">      *
</span><span class="cx">      * @var Closure
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientMailboxListphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Mailbox/List.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Mailbox/List.php    2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Mailbox/List.php       2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -98,9 +98,9 @@
</span><span class="cx">     {
</span><span class="cx">         /* Always return INBOX as "smaller". */
</span><span class="cx">         if ($this->_sortinbox) {
</span><del>-            if (strcasecmp($a, 'INBOX') == 0) {
</del><ins>+            if (strcasecmp($a, 'INBOX') === 0) {
</ins><span class="cx">                 return -1;
</span><del>-            } elseif (strcasecmp($b, 'INBOX') == 0) {
</del><ins>+            } elseif (strcasecmp($b, 'INBOX') === 0) {
</ins><span class="cx">                 return 1;
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="lines">@@ -116,8 +116,8 @@
</span><span class="cx">                 /* If only one of the folders is under INBOX, return it as
</span><span class="cx">                  * "smaller". */
</span><span class="cx">                 if ($this->_sortinbox && ($i == 0)) {
</span><del>-                    $a_base = (strcasecmp($a_parts[0], 'INBOX') == 0);
-                    $b_base = (strcasecmp($b_parts[0], 'INBOX') == 0);
</del><ins>+                    $a_base = (strcasecmp($a_parts[0], 'INBOX') === 0);
+                    $b_base = (strcasecmp($b_parts[0], 'INBOX') === 0);
</ins><span class="cx">                     if ($a_base && !$b_base) {
</span><span class="cx">                         return -1;
</span><span class="cx">                     } elseif (!$a_base && $b_base) {
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientMailboxphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Mailbox.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Mailbox.php 2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Mailbox.php    2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -68,6 +68,10 @@
</span><span class="cx">      */
</span><span class="cx">     public function __construct($mbox, $utf7imap = false)
</span><span class="cx">     {
</span><ins>+        if (strcasecmp($mbox, 'INBOX') === 0) {
+            $mbox = 'INBOX';
+        }
+
</ins><span class="cx">         if ($utf7imap) {
</span><span class="cx">             $this->_utf7imap = $mbox;
</span><span class="cx">         } else {
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientSocketConnectionPop3php"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Connection/Pop3.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Connection/Pop3.php  2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Connection/Pop3.php     2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -60,13 +60,13 @@
</span><span class="cx">             $this->close();
</span><span class="cx">             $this->_debug->info("ERROR: Server closed the connection.");
</span><span class="cx">             throw new Horde_Imap_Client_Exception(
</span><del>-                Horde_Imap_Client_Translation::t("POP3 Server closed the connection unexpectedly."),
</del><ins>+                Horde_Imap_Client_Translation::t("Server closed the connection unexpectedly."),
</ins><span class="cx">                 Horde_Imap_Client_Exception::DISCONNECT
</span><span class="cx">             );
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (($read = fgets($this->_stream)) === false) {
</span><del>-            $this->_debug->info("ERROR: IMAP read/timeout error.");
</del><ins>+            $this->_debug->info("ERROR: read/timeout error.");
</ins><span class="cx">             throw new Horde_Imap_Client_Exception(
</span><span class="cx">                 Horde_Imap_Client_Translation::t("Error when communicating with the mail server."),
</span><span class="cx">                 Horde_Imap_Client_Exception::SERVER_READERROR
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientSocketConnectionSocketphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Connection/Socket.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Connection/Socket.php        2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Connection/Socket.php   2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -197,7 +197,7 @@
</span><span class="cx">         } while (true);
</span><span class="cx"> 
</span><span class="cx">         if (!$got_data) {
</span><del>-            $this->_debug->info("ERROR: IMAP read/timeout error.");
</del><ins>+            $this->_debug->info("ERROR: read/timeout error.");
</ins><span class="cx">             throw new Horde_Imap_Client_Exception(
</span><span class="cx">                 Horde_Imap_Client_Translation::t("Error when communicating with the mail server."),
</span><span class="cx">                 Horde_Imap_Client_Exception::SERVER_READERROR
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientSocketConnectionphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Connection.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Connection.php       2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Connection.php  2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -54,7 +54,7 @@
</span><span class="cx">     {
</span><span class="cx">         parent::__construct($base, $debug);
</span><span class="cx"> 
</span><del>-        switch ($secure = $base->getParam('secure')) {
</del><ins>+        switch (strval($secure = $base->getParam('secure'))) {
</ins><span class="cx">         case 'ssl':
</span><span class="cx">         case 'sslv2':
</span><span class="cx">         case 'sslv3':
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientSocketPop3php"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Pop3.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Pop3.php     2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket/Pop3.php        2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -61,7 +61,8 @@
</span><span class="cx">  *   - RFC 2595/4616: PLAIN authentication
</span><span class="cx">  *   - RFC 2831: DIGEST-MD5 SASL Authentication (obsoleted by RFC 6331)
</span><span class="cx">  *   - RFC 3206: AUTH/SYS response codes
</span><del>- *   - RFC 1734/5034: POP3 SASL
</del><ins>+ *   - RFC 4616: AUTH=PLAIN
+ *   - RFC 5034: POP3 SASL
</ins><span class="cx">  *
</span><span class="cx">  * @author    Richard Heyes <richard@phpguru.org>
</span><span class="cx">  * @author    Michael Slusarz <slusarz@horde.org>
</span><span class="lines">@@ -74,6 +75,13 @@
</span><span class="cx"> class Horde_Imap_Client_Socket_Pop3 extends Horde_Imap_Client_Base
</span><span class="cx"> {
</span><span class="cx">     /**
</span><ins>+     * The default ports to use for a connection.
+     *
+     * @var array
+     */
+    protected $_defaultPorts = array(110, 995);
+
+    /**
</ins><span class="cx">      * The list of deleted messages.
</span><span class="cx">      *
</span><span class="cx">      * @var array
</span><span class="lines">@@ -89,17 +97,6 @@
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">      */
</span><del>-    public function __construct(array $params = array())
-    {
-        parent::__construct($params);
-
-        if (empty($params['port'])) {
-            $this->setParam('port', in_array($this->getParam('secure'), array('ssl', 'sslv2', 'sslv3')) ? 995 : 110);
-        }
-    }
-
-    /**
-     */
</del><span class="cx">     protected function _initCache($current = false)
</span><span class="cx">     {
</span><span class="cx">         return parent::_initCache($current) &&
</span><span class="lines">@@ -133,23 +130,25 @@
</span><span class="cx">                     : true;
</span><span class="cx">             }
</span><span class="cx">         } catch (Horde_Imap_Client_Exception $e) {
</span><ins>+            $this->_temp['no_capa'] = true;
+
</ins><span class="cx">             /* Need to probe for capabilities if CAPA command is not
</span><span class="cx">              * available. */
</span><del>-            $capability = array('USER', 'SASL');
</del><ins>+            $capability = array('USER' => true);
</ins><span class="cx"> 
</span><del>-            try {
-                $this->_sendLine('UIDL', array(
-                    'multiline' => 'none'
-                ));
-                $capability[] = 'UIDL';
-            } catch (Horde_Imap_Client_Exception $e) {}
</del><ins>+            /* Capability sniffing only guaranteed after authentication is
+             * completed (if any). */
+            if (!empty($this->_init['authmethod'])) {
+                $this->_pop3Cache('uidl');
+                if (empty($this->_temp['no_uidl'])) {
+                    $capability['UIDL'] = true;
+                }
</ins><span class="cx"> 
</span><del>-            try {
-                $this->_sendLine('TOP 1 0', array(
-                    'multiline' => 'none'
-                ));
-                $capability[] = 'TOP';
-            } catch (Horde_Imap_Client_Exception $e) {}
</del><ins>+                $this->_pop3Cache('top', 1);
+                if (empty($this->_temp['no_top'])) {
+                    $capability['TOP'] = true;
+                }
+            }
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         $this->_setInit('capability', $capability);
</span><span class="lines">@@ -183,25 +182,33 @@
</span><span class="cx">     {
</span><span class="cx">         $this->_connect();
</span><span class="cx"> 
</span><ins>+        $secure = $this->getParam('secure');
+
</ins><span class="cx">         // Switch to secure channel if using TLS.
</span><span class="cx">         if (!$this->isSecureConnection() &&
</span><del>-            ($this->getParam('secure') == 'tls')) {
</del><ins>+            (($secure === 'tls') || $secure === true)) {
</ins><span class="cx">             // Switch over to a TLS connection.
</span><span class="cx">             if (!$this->queryCapability('STLS')) {
</span><del>-                throw new Horde_Imap_Client_Exception(
-                    Horde_Imap_Client_Translation::t("Could not open secure connection to the POP3 server.") . ' ' . Horde_Imap_Client_Translation::t("Server does not support secure connections."),
-                    Horde_Imap_Client_Exception::LOGIN_TLSFAILURE
-                );
-            }
</del><ins>+                if ($secure === 'tls') {
+                    throw new Horde_Imap_Client_Exception(
+                        Horde_Imap_Client_Translation::t("Could not open secure connection to the POP3 server.") . ' ' . Horde_Imap_Client_Translation::t("Server does not support secure connections."),
+                        Horde_Imap_Client_Exception::LOGIN_TLSFAILURE
+                    );
+                } else {
+                    $this->setParam('secure', false);
+                }
+            } else {
+                $this->_sendLine('STLS');
</ins><span class="cx"> 
</span><del>-            $this->_sendLine('STLS');
</del><ins>+                $this->setParam('secure', 'tls');
</ins><span class="cx"> 
</span><del>-            if (!$this->_connection->startTls()) {
-                $this->logout();
-                throw new Horde_Imap_Client_Exception(
-                    Horde_Imap_Client_Translation::t("Could not open secure connection to the POP3 server."),
-                    Horde_Imap_Client_Exception::LOGIN_TLSFAILURE
-                );
</del><ins>+                if (!$this->_connection->startTls()) {
+                    $this->logout();
+                    throw new Horde_Imap_Client_Exception(
+                        Horde_Imap_Client_Translation::t("Could not open secure connection to the POP3 server."),
+                        Horde_Imap_Client_Exception::LOGIN_TLSFAILURE
+                    );
+                }
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             // Expire cached CAPABILITY information
</span><span class="lines">@@ -226,6 +233,12 @@
</span><span class="cx">             try {
</span><span class="cx">                 $this->_tryLogin($method);
</span><span class="cx">                 $this->_setInit('authmethod', $method);
</span><ins>+
+                if (!empty($this->_temp['no_capa']) ||
+                    !$this->queryCapability('UIDL')) {
+                    $this->_capability();
+                }
+
</ins><span class="cx">                 return true;
</span><span class="cx">             } catch (Horde_Imap_Client_Exception $e) {
</span><span class="cx">                 if (!empty($this->_init['authmethod'])) {
</span><span class="lines">@@ -312,7 +325,7 @@
</span><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case 'LOGIN':
</span><del>-            // RFC 5034
</del><ins>+            // RFC 4616 (AUTH=PLAIN) & 5034 (POP3 SASL)
</ins><span class="cx">             $this->_sendLine('AUTH LOGIN');
</span><span class="cx">             $this->_sendLine(base64_encode($username), array(
</span><span class="cx">                 'debug' => sprintf('[AUTH LOGIN Command - username: %s]', $username)
</span><span class="lines">@@ -324,7 +337,11 @@
</span><span class="cx"> 
</span><span class="cx">         case 'PLAIN':
</span><span class="cx">             // RFC 5034
</span><del>-            $this->_sendLine('AUTH PLAIN ' . base64_encode(implode("\0", array($username, $this->getParam('password')))), array(
</del><ins>+            $this->_sendLine('AUTH PLAIN ' . base64_encode(implode("\0", array(
+                $username,
+                $username,
+                $password
+            ))), array(
</ins><span class="cx">                 'debug' => sprintf('[AUTH PLAIN Command - username: %s]', $username)
</span><span class="cx">             ));
</span><span class="cx">             break;
</span><span class="lines">@@ -400,7 +417,7 @@
</span><span class="cx">      */
</span><span class="cx">     protected function _openMailbox(Horde_Imap_Client_Mailbox $mailbox, $mode)
</span><span class="cx">     {
</span><del>-        if (strcasecmp($mailbox, 'INBOX') !== 0) {
</del><ins>+        if ($mailbox != 'INBOX') {
</ins><span class="cx">             throw new Horde_Imap_Client_Exception_NoSupportPop3('Mailboxes other than INBOX');
</span><span class="cx">         }
</span><span class="cx">         $this->_changeSelected($mailbox, $mode);
</span><span class="lines">@@ -465,8 +482,7 @@
</span><span class="cx">      */
</span><span class="cx">     protected function _status($mboxes, $flags)
</span><span class="cx">     {
</span><del>-        if ((count($mboxes) > 1) ||
-            (strcasecmp(reset($mboxes), 'INBOX') !== 0)) {
</del><ins>+        if ((count($mboxes) > 1) || (reset($mboxes) != 'INBOX')) {
</ins><span class="cx">             throw new Horde_Imap_Client_Exception_NoSupportPop3('Mailboxes other than INBOX');
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -805,7 +821,7 @@
</span><span class="cx">      * Retrieve locally cached message data.
</span><span class="cx">      *
</span><span class="cx">      * @param string $type    Either 'hdr', 'hdrob', 'msg', 'size', 'stat',
</span><del>-     *                        or 'uidl'.
</del><ins>+     *                        'top', or 'uidl'.
</ins><span class="cx">      * @param integer $index  The message index.
</span><span class="cx">      * @param mixed $data     Additional information needed.
</span><span class="cx">      *
</span><span class="lines">@@ -825,8 +841,9 @@
</span><span class="cx"> 
</span><span class="cx">         switch ($type) {
</span><span class="cx">         case 'hdr':
</span><ins>+        case 'top':
</ins><span class="cx">             $data = null;
</span><del>-            if ($this->queryCapability('TOP')) {
</del><ins>+            if ($this->queryCapability('TOP') || ($type == 'top')) {
</ins><span class="cx">                 try {
</span><span class="cx">                     $res = $this->_sendLine('TOP ' . $index . ' 0', array(
</span><span class="cx">                         'multiline' => 'stream'
</span><span class="lines">@@ -834,7 +851,12 @@
</span><span class="cx">                     rewind($res['data']);
</span><span class="cx">                     $data = stream_get_contents($res['data']);
</span><span class="cx">                     fclose($res['data']);
</span><del>-                } catch (Horde_Imap_Client_Exception $e) {}
</del><ins>+                } catch (Horde_Imap_Client_Exception $e) {
+                    $this->_temp['no_top'] = true;
+                    if ($type == 'top') {
+                        return null;
+                    }
+                }
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             if (is_null($data)) {
</span><span class="lines">@@ -865,7 +887,11 @@
</span><span class="cx">                     $resp_data = explode(' ', $val, 2);
</span><span class="cx">                     $data[$resp_data[0]] = $resp_data[1];
</span><span class="cx">                 }
</span><del>-            } catch (Horde_Imap_Client_Exception $e) {}
</del><ins>+            } catch (Horde_Imap_Client_Exception $e) {
+                if ($type == 'uidl') {
+                    $this->_temp['no_uidl'] = true;
+                }
+            }
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case 'stat':
</span><span class="lines">@@ -1048,6 +1074,25 @@
</span><span class="cx">         return null;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    /**
+     */
+    public function resolveIds(Horde_Imap_Client_Mailbox $mailbox,
+                               Horde_Imap_Client_Ids $ids, $convert = 0)
+    {
+        if (!$ids->special &&
+            (!$convert ||
+             (!$ids->sequence && ($convert == 1)) ||
+             $ids->isEmpty())) {
+            return clone $ids;
+        }
+
+        $uids = $this->_pop3Cache('uidl');
+
+        return $this->getIdsOb(
+            $ids->all ? array_values($uids) : array_intersect_keys($uids, $ids->ids)
+        );
+    }
+
</ins><span class="cx">     /* Internal functions. */
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="lines">@@ -1105,7 +1150,7 @@
</span><span class="cx">         $ob = array('resp' => '');
</span><span class="cx"> 
</span><span class="cx">         $read = explode(' ', rtrim($this->_connection->read(), "\r\n"), 2);
</span><del>-        if (!in_array($read[0], array('+OK', '-ERR'))) {
</del><ins>+        if (!in_array($read[0], array('+OK', '-ERR', '+'))) {
</ins><span class="cx">             $this->_debug->info("ERROR: IMAP read/timeout error.");
</span><span class="cx">             throw new Horde_Imap_Client_Exception(
</span><span class="cx">                 Horde_Imap_Client_Translation::t("Error when communicating with the mail server."),
</span><span class="lines">@@ -1122,6 +1167,7 @@
</span><span class="cx"> 
</span><span class="cx">         switch ($read[0]) {
</span><span class="cx">         case '+OK':
</span><ins>+        case '+':
</ins><span class="cx">             if ($respcode) {
</span><span class="cx">                 $ob['resp'] = $respcode->text;
</span><span class="cx">             } elseif (isset($read[1])) {
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientSocketphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket.php  2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client/Socket.php     2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -76,6 +76,11 @@
</span><span class="cx">  *    </li>
</span><span class="cx">  *   </ul>
</span><span class="cx">  *  </li>
</span><ins>+ *  <li>AUTH=XOAUTH2
+ *   <ul>
+ *    <li>https://developers.google.com/gmail/xoauth2_protocol</li>
+ *   </ul>
+ *  </li>
</ins><span class="cx">  * </ul>
</span><span class="cx">  *
</span><span class="cx">  * TODO (or not necessary?):
</span><span class="lines">@@ -125,6 +130,13 @@
</span><span class="cx">     protected $_cmdQueue = array();
</span><span class="cx"> 
</span><span class="cx">     /**
</span><ins>+     * The default ports to use for a connection.
+     *
+     * @var array
+     */
+    protected $_defaultPorts = array(143, 993);
+
+    /**
</ins><span class="cx">      * Mapping of status fields to IMAP names.
</span><span class="cx">      *
</span><span class="cx">      * @var array
</span><span class="lines">@@ -161,6 +173,11 @@
</span><span class="cx">      *   - envelope_string: (integer) The maximum length of string fields
</span><span class="cx">      *                      returned by the FETCH ENVELOPE command.
</span><span class="cx">      *                      DEFAULT: 2048
</span><ins>+     *   - xoauth2_token: (mixed) If set, will authenticate via the XOAUTH2
+     *                    mechanism (if available) with this token. Either a
+     *                    string (since 2.13.0) or a
+     *                    Horde_Imap_Client_Base_Password object (since
+     *                    2.14.0).
</ins><span class="cx">      */
</span><span class="cx">     public function __construct(array $params = array())
</span><span class="cx">     {
</span><span class="lines">@@ -173,6 +190,21 @@
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">      */
</span><ins>+    public function getParam($key)
+    {
+        switch ($key) {
+        case 'xoauth2_token':
+            if ($this->_params[$key] instanceof Horde_Imap_Client_Base_Password) {
+                return $this->_params[$key]->getPassword();
+            }
+            break;
+        }
+
+        return parent::getParam($key);
+    }
+
+    /**
+     */
</ins><span class="cx">     protected function _capability()
</span><span class="cx">     {
</span><span class="cx">         // Need to use connect call here or else we run into loop issues
</span><span class="lines">@@ -202,12 +234,9 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        /* Assume capabilities are additive. */
-        $c = empty($this->_init['capability'])
-            ? array()
-            : $this->_init['capability'];
</del><ins>+        $pipeline->data['capability_set'] = true;
</ins><span class="cx"> 
</span><del>-        $pipeline->data['capabilties_set'] = true;
</del><ins>+        $c = array();
</ins><span class="cx"> 
</span><span class="cx">         foreach ($data as $val) {
</span><span class="cx">             $cap_list = explode('=', $val);
</span><span class="lines">@@ -338,13 +367,15 @@
</span><span class="cx">         $this->_connect();
</span><span class="cx"> 
</span><span class="cx">         $first_login = empty($this->_init['authmethod']);
</span><ins>+        $secure = $this->getParam('secure');
</ins><span class="cx"> 
</span><span class="cx">         // Switch to secure channel if using TLS.
</span><span class="cx">         if (!$this->isSecureConnection() &&
</span><del>-            ($this->getParam('secure') == 'tls')) {
</del><ins>+            (($secure === 'tls') ||
+             (($secure === true) && $this->queryCapability('LOGINDISABLED')))) {
</ins><span class="cx">             if ($first_login && !$this->queryCapability('STARTTLS')) {
</span><del>-                // We should never hit this - STARTTLS is required pursuant
-                // to RFC 3501 [6.2.1].
</del><ins>+                /* We should never hit this - STARTTLS is required pursuant to
+                 * RFC 3501 [6.2.1]. */
</ins><span class="cx">                 throw new Horde_Imap_Client_Exception(
</span><span class="cx">                     Horde_Imap_Client_Translation::t("Server does not support TLS connections."),
</span><span class="cx">                     Horde_Imap_Client_Exception::LOGIN_TLSFAILURE
</span><span class="lines">@@ -353,7 +384,7 @@
</span><span class="cx"> 
</span><span class="cx">             // Switch over to a TLS connection.
</span><span class="cx">             // STARTTLS returns no untagged response.
</span><del>-            $this->_sendCmd($this->_Command('STARTTLS'));
</del><ins>+            $this->_sendCmd($this->_command('STARTTLS'));
</ins><span class="cx"> 
</span><span class="cx">             if (!$this->_connection->startTls()) {
</span><span class="cx">                 $this->logout();
</span><span class="lines">@@ -363,6 +394,8 @@
</span><span class="cx">                 );
</span><span class="cx">             }
</span><span class="cx"> 
</span><ins>+            $this->setParam('secure', 'tls');
+
</ins><span class="cx">             if ($first_login) {
</span><span class="cx">                 // Expire cached CAPABILITY information (RFC 3501 [6.2.1])
</span><span class="cx">                 $this->_setInit('capability');
</span><span class="lines">@@ -378,45 +411,54 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if ($first_login) {
</span><del>-            $imap_auth_mech = array();
</del><ins>+            // Add authentication methods.
+            $auth_mech = array();
</ins><span class="cx"> 
</span><del>-            $auth_methods = $this->queryCapability('AUTH');
-            if (!empty($auth_methods)) {
-                // Add SASL methods. Prefer CRAM-MD5 over DIGEST-MD5, as the
-                // latter has been obsoleted (RFC 6331).
-                $imap_auth_mech = array_intersect(array('CRAM-MD5', 'DIGEST-MD5'), $auth_methods);
</del><ins>+            $auth = ($auth = $this->queryCapability('AUTH'))
+                ? array_flip($auth)
+                : array();
</ins><span class="cx"> 
</span><del>-                // Next, try 'PLAIN' authentication.
-                if (in_array('PLAIN', $auth_methods)) {
-                    $imap_auth_mech[] = 'PLAIN';
-                }
</del><ins>+            // XOAUTH2
+            if (isset($auth['XOAUTH2']) && $this->getParam('xoauth2_token')) {
+                $auth_mech[] = 'XOAUTH2';
+                unset($auth['XOAUTH2']);
</ins><span class="cx">             }
</span><span class="cx"> 
</span><ins>+            // 'PLAIN' authentication always exists if under TLS. Use it over
+            // all over authentication methods.
+            if ($this->isSecureConnection()) {
+                $auth_mech[] = 'PLAIN';
+                unset($auth['PLAIN']);
+            }
+
+            // Prefer CRAM-MD5 over DIGEST-MD5, as the latter has been
+            // obsoleted (RFC 6331).
+            if (isset($auth['CRAM-MD5'])) {
+                $auth_mech[] = 'CRAM-MD5';
+            } elseif (isset($auth['DIGEST-MD5'])) {
+                $auth_mech[] = 'DIGEST-MD5';
+            }
+            unset($auth['CRAM-MD5'], $auth['DIGEST-MD5']);
+
</ins><span class="cx">             // Fall back to 'LOGIN' if available.
</span><ins>+            $auth_mech = array_merge($auth_mech, array_keys($auth));
</ins><span class="cx">             if (!$this->queryCapability('LOGINDISABLED')) {
</span><del>-                $imap_auth_mech[] = 'LOGIN';
</del><ins>+                $auth_mech[] = 'LOGIN';
</ins><span class="cx">             }
</span><span class="cx"> 
</span><del>-            if (empty($imap_auth_mech)) {
</del><ins>+            if (empty($auth_mech)) {
</ins><span class="cx">                 throw new Horde_Imap_Client_Exception(
</span><span class="cx">                     Horde_Imap_Client_Translation::t("No supported IMAP authentication method could be found."),
</span><span class="cx">                     Horde_Imap_Client_Exception::LOGIN_NOAUTHMETHOD
</span><span class="cx">                 );
</span><span class="cx">             }
</span><del>-
-            /* Use MD5 authentication first, if available. But no need to use
-             * special authentication if we are already using an encrypted
-             * connection. */
-            if ($this->isSecureConnection()) {
-                $imap_auth_mech = array_reverse($imap_auth_mech);
-            }
</del><span class="cx">         } else {
</span><del>-            $imap_auth_mech = array($this->_init['authmethod']);
</del><ins>+            $auth_mech = array($this->_init['authmethod']);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         $login_err = null;
</span><span class="cx"> 
</span><del>-        foreach ($imap_auth_mech as $method) {
</del><ins>+        foreach ($auth_mech as $method) {
</ins><span class="cx">             try {
</span><span class="cx">                 $resp = $this->_tryLogin($method);
</span><span class="cx">                 $data = $resp->data;
</span><span class="lines">@@ -505,8 +547,7 @@
</span><span class="cx">             $this->_temp['no_cap'] = true;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        /* Get greeting information.  This is untagged so we need to specially
-         * deal with it here. */
</del><ins>+        /* Get greeting information (untagged response). */
</ins><span class="cx">         try {
</span><span class="cx">             $this->_getLine($this->_pipeline());
</span><span class="cx">         } catch (Horde_Imap_Client_Exception_ServerResponse $e) {
</span><span class="lines">@@ -556,6 +597,8 @@
</span><span class="cx">         $username = $this->getParam('username');
</span><span class="cx">         $password = $this->getParam('password');
</span><span class="cx"> 
</span><ins>+        $authenticate_cmd = false;
+
</ins><span class="cx">         switch ($method) {
</span><span class="cx">         case 'CRAM-MD5':
</span><span class="cx">         case 'CRAM-SHA1':
</span><span class="lines">@@ -635,38 +678,46 @@
</span><span class="cx">                 $username,
</span><span class="cx">                 $password
</span><span class="cx">             )));
</span><del>-            $cmd = $this->_command('AUTHENTICATE')->add('PLAIN');
</del><ins>+            $authenticate_cmd = true;
+            break;
</ins><span class="cx"> 
</span><ins>+        case 'XOAUTH2':
+            // Google XOAUTH2
+            $auth = $this->getParam('xoauth2_token');
+            $authenticate_cmd = true;
+            break;
+
+        default:
+            throw new Horde_Imap_Client_Exception(
+                sprintf(Horde_Imap_Client_Translation::t("Unknown authentication method: %s"), $method),
+                Horde_Imap_Client_Exception::SERVER_CONNECT
+            );
+        }
+
+        if ($authenticate_cmd) {
+            $cmd = $this->_command('AUTHENTICATE')->add($method);
+
</ins><span class="cx">             if ($this->queryCapability('SASL-IR')) {
</span><span class="cx">                 // IMAP Extension for SASL Initial Client Response (RFC 4959)
</span><span class="cx">                 $cmd->add($auth);
</span><del>-                $cmd->debug = sprintf('[SASL-IR AUTHENTICATE Command - username: %s]', $username);
</del><ins>+                $cmd->debug = sprintf('[SASL-IR AUTHENTICATE Command - method: %s, username: %s]', $method, $username);
</ins><span class="cx">             } else {
</span><span class="cx">                 $cmd->add(new Horde_Imap_Client_Interaction_Command_Continuation(function($ob) use ($auth) {
</span><span class="cx">                     return new Horde_Imap_Client_Data_Format_List($auth);
</span><span class="cx">                 }));
</span><del>-                $cmd->debug = sprintf('[AUTHENTICATE Command - username: %s]', $username);
</del><ins>+                $cmd->debug = sprintf('[AUTHENTICATE Command - method: %s, username: %s]', $method, $username);
</ins><span class="cx">             }
</span><del>-            break;
</del><span class="cx"> 
</span><del>-        default:
-            throw new Horde_Imap_Client_Exception(
-                sprintf(Horde_Imap_Client_Translation::t("Unknown authentication method: %s"), $method),
-                Horde_Imap_Client_Exception::SERVER_CONNECT
-            );
</del><ins>+            /* This is an optional command continuation. E.g. XOAUTH2 will
+             * return error information in continuation response. */
+            $error_continuation = new Horde_Imap_Client_Interaction_Command_Continuation(function($ob) {
+                return new Horde_Imap_Client_Data_Format_List();
+            });
+            $error_continuation->optional = true;
+            $cmd->add($error_continuation);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        $pipeline = $this->_pipeline($cmd);
-
-        /* Set a flag indicating whether we have received a CAPABILITY
-         * response after we successfully login. Since capabilities may
-         * be different after login, we need to merge this information into
-         * the current CAPABILITY array (since some servers, e.g. Cyrus,
-         * may not include authentication capabilities that are still
-         * needed in the event this object is eventually serialized). */
-        $pipeline->data['in_login'] = true;
-
-        return $this->_sendCmd($pipeline);
</del><ins>+        return $this->_sendCmd($this->_pipeline($cmd));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="lines">@@ -675,7 +726,7 @@
</span><span class="cx">      * @param boolean $firstlogin  Is this the first login?
</span><span class="cx">      * @param array $resp          The data response from the login command.
</span><span class="cx">      *                             May include:
</span><del>-     *   - logincapset: (boolean) True if CAPABILITY sent after login.
</del><ins>+     *   - capability_set: (boolean) True if CAPABILITY was set after login.
</ins><span class="cx">      *   - proxyreuse: (boolean) True if re-used connection via imapproxy.
</span><span class="cx">      *
</span><span class="cx">      * @return boolean  True if global login tasks should be performed.
</span><span class="lines">@@ -700,7 +751,7 @@
</span><span class="cx"> 
</span><span class="cx">         /* If we logged in for first time, and server did not return
</span><span class="cx">          * capability information, we need to mark for retrieval. */
</span><del>-        if ($firstlogin && empty($resp['capabilities_set'])) {
</del><ins>+        if ($firstlogin && empty($resp['capability_set'])) {
</ins><span class="cx">             $this->_setInit('capability');
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -1745,11 +1796,17 @@
</span><span class="cx">                 // RFC 3691 defines 'UNSELECT' for precisely this purpose
</span><span class="cx">                 $this->_sendCmd($this->_command('UNSELECT'));
</span><span class="cx">             } else {
</span><del>-                // RFC 3501 [6.4.2]: to close a mailbox without expunge,
-                // select a non-existent mailbox. Selecting a null mailbox
-                // should do the trick.
</del><ins>+                /* RFC 3501 [6.4.2]: to close a mailbox without expunge,
+                 * select a non-existent mailbox. */
</ins><span class="cx">                 try {
</span><del>-                    $this->_sendCmd($this->_command('SELECT')->add(''));
</del><ins>+                    $this->_sendCmd($this->_command('EXAMINE')->add(
+                        new Horde_Imap_Client_Data_Format_Mailbox("\24nonexist\24")
+                    ));
+
+                    /* Not pipelining, since the odds that this CLOSE is even
+                     * needed is tiny; and it returns BAD, which should be
+                     * avoided, if possible. */
+                    $this->_sendCmd($this->_command('CLOSE'));
</ins><span class="cx">                 } catch (Horde_Imap_Client_Exception_ServerResponse $e) {
</span><span class="cx">                     // Ignore error; it is expected.
</span><span class="cx">                 }
</span><span class="lines">@@ -1778,7 +1835,7 @@
</span><span class="cx">         $use_cache = $this->_initCache(true);
</span><span class="cx"> 
</span><span class="cx">         if ($ids->all) {
</span><del>-            if (!$uidplus && ($list_msgs || $use_cache)) {
</del><ins>+            if (!$uidplus || $list_msgs || $use_cache) {
</ins><span class="cx">                 $ids = $this->resolveIds($this->_selected, $ids, 2);
</span><span class="cx">             }
</span><span class="cx">         } elseif ($uidplus) {
</span><span class="lines">@@ -3628,7 +3685,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     /**
</span><del>-     * Parse a METADATA response (RFC 5464 [4.4]).
</del><ins>+     * Parse an ANNOTATION response (ANNOTATEMORE/ANNOTATEMORE2).
</ins><span class="cx">      *
</span><span class="cx">      * @param Horde_Imap_Client_Interaction_Pipeline $pipeline  Pipeline
</span><span class="cx">      *                                                          object.
</span><span class="lines">@@ -3636,52 +3693,61 @@
</span><span class="cx">      *
</span><span class="cx">      * @throws Horde_Imap_Client_Exception
</span><span class="cx">      */
</span><del>-    protected function _parseMetadata(
</del><ins>+    protected function _parseAnnotation(
</ins><span class="cx">         Horde_Imap_Client_Interaction_Pipeline $pipeline,
</span><span class="cx">         Horde_Imap_Client_Tokenize $data
</span><span class="cx">     )
</span><span class="cx">     {
</span><del>-        switch ($data->current()) {
-        case 'ANNOTATION':
-            $mbox = $data->next();
-            $entry = $data->next();
</del><ins>+        // Mailbox name is in UTF7-IMAP.
+        $mbox = Horde_Imap_Client_Mailbox::get($data->next(), true);
+        $entry = $data->next();
</ins><span class="cx"> 
</span><del>-            // Ignore unsolicited responses.
-            if ($data->next() !== true) {
</del><ins>+        // Ignore unsolicited responses.
+        if ($data->next() !== true) {
+            return;
+        }
+
+        while (($type = $data->next()) !== false) {
+            switch ($type) {
+            case 'value.priv':
+                $pipeline->data['metadata'][strval($mbox)]['/private' . $entry] = $data->next();
</ins><span class="cx">                 break;
</span><del>-            }
</del><span class="cx"> 
</span><del>-            while (($type = $data->next()) !== false) {
-                switch ($type) {
-                case 'value.priv':
-                    $pipeline->data['metadata'][$mbox]['/private' . $entry] = $data->next();
-                    break;
</del><ins>+            case 'value.shared':
+                $pipeline->data['metadata'][strval($mbox)]['/shared' . $entry] = $data->next();
+                break;
</ins><span class="cx"> 
</span><del>-                case 'value.shared':
-                    $pipeline->data['metadata'][$mbox]['/shared' . $entry] = $data->next();
-                    break;
-
-                default:
-                    throw new Horde_Imap_Client_Exception(
-                        sprintf(Horde_Imap_Client_Translation::t("Invalid METADATA value type \"%s\"."), $type),
-                        Horde_Imap_Client_Exception::METADATA_INVALID
-                    );
-                }
</del><ins>+            default:
+                throw new Horde_Imap_Client_Exception(
+                    sprintf(Horde_Imap_Client_Translation::t("Invalid METADATA value type \"%s\"."), $type),
+                    Horde_Imap_Client_Exception::METADATA_INVALID
+                );
</ins><span class="cx">             }
</span><del>-            break;
</del><ins>+        }
+    }
</ins><span class="cx"> 
</span><del>-        case 'METADATA':
-            $mbox = $data->next();
</del><ins>+    /**
+     * Parse a METADATA response (RFC 5464 [4.4]).
+     *
+     * @param Horde_Imap_Client_Interaction_Pipeline $pipeline  Pipeline
+     *                                                          object.
+     * @param Horde_Imap_Client_Tokenize $data  The server response.
+     *
+     * @throws Horde_Imap_Client_Exception
+     */
+    protected function _parseMetadata(
+        Horde_Imap_Client_Interaction_Pipeline $pipeline,
+        Horde_Imap_Client_Tokenize $data
+    )
+    {
+        // Mailbox name is in UTF7-IMAP.
+        $mbox = Horde_Imap_Client_Mailbox::get($data->next(), true);
</ins><span class="cx"> 
</span><del>-            // Ignore unsolicited responses.
-            if ($data->next() !== true) {
-                break;
-            }
-
</del><ins>+        // Ignore unsolicited responses.
+        if ($data->next() === true) {
</ins><span class="cx">             while (($entry = $data->next()) !== false) {
</span><del>-                $pipeline->data['metadata'][$mbox][$entry] = $data->next();
</del><ins>+                $pipeline->data['metadata'][strval($mbox)][$entry] = $data->next();
</ins><span class="cx">             }
</span><del>-            break;
</del><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -3803,8 +3869,11 @@
</span><span class="cx">                     $this->_debug->raw($val->tag . ' ' . $val->debug . "\n");
</span><span class="cx">                     $this->_debug->debug = false;
</span><span class="cx">                 }
</span><del>-                $this->_processCmd($pipeline, $val, $val);
-                $this->_connection->write('', true);
</del><ins>+                if ($this->_processCmd($pipeline, $val, $val)) {
+                    $this->_connection->write('', true);
+                } else {
+                    $cmd_count = 0;
+                }
</ins><span class="cx">                 $this->_debug->debug = $old_debug;
</span><span class="cx">             } catch (Horde_Imap_Client_Exception $e) {
</span><span class="cx">                 $this->_debug->debug = $old_debug;
</span><span class="lines">@@ -3862,6 +3931,7 @@
</span><span class="cx">      * @param Horde_Imap_Client_Interaction_Command $cmd  The master command.
</span><span class="cx">      * @param Horde_Imap_Client_Data_Format_List $data    Commands to send.
</span><span class="cx">      *
</span><ins>+     * @return boolean  True if EOL needed to finish command.
</ins><span class="cx">      * @throws Horde_Imap_Client_Exception
</span><span class="cx">      * @throws Horde_Imap_Client_Exception_NoSupport
</span><span class="cx">      */
</span><span class="lines">@@ -3871,10 +3941,16 @@
</span><span class="cx">             if ($val instanceof Horde_Imap_Client_Interaction_Command_Continuation) {
</span><span class="cx">                 $this->_connection->write('', true);
</span><span class="cx"> 
</span><ins>+                /* Check for optional continuation responses when the command
+                 * has already finished. */
+                if (!$cmd_continuation = $this->_processCmdContinuation($pipeline, $val->optional)) {
+                    return false;
+                }
+
</ins><span class="cx">                 $this->_processCmd(
</span><span class="cx">                     $pipeline,
</span><span class="cx">                     $cmd,
</span><del>-                    $val->getCommands($this->_processCmdContinuation($pipeline))
</del><ins>+                    $val->getCommands($cmd_continuation)
</ins><span class="cx">                 );
</span><span class="cx">                 continue;
</span><span class="cx">             }
</span><span class="lines">@@ -3916,24 +3992,35 @@
</span><span class="cx">                 $this->_connection->write($val->escape());
</span><span class="cx">             }
</span><span class="cx">         }
</span><ins>+
+        return true;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">      * Process a command continuation response.
</span><span class="cx">      *
</span><del>-     * @param Horde_Imap_Client_Interaction_Pipeline $pipeline The pipeline
-     *                                                         object.
</del><ins>+     * @param Horde_Imap_Client_Interaction_Pipeline $pipeline  The pipeline
+     *                                                          object.
+     * @param boolean $noexception                              Don't throw
+     *                                                          exception if
+     *                                                          continuation
+     *                                                          does not occur.
</ins><span class="cx">      *
</span><del>-     * @return Horde_Imap_Client_Interaction_Server_Continuation  Continuation
-     *                                                            object.
</del><ins>+     * @return mixed  A Horde_Imap_Client_Interaction_Server_Continuation
+     *                object or false.
</ins><span class="cx">      *
</span><span class="cx">      * @throws Horde_Imap_Client_Exception
</span><span class="cx">      */
</span><del>-    protected function _processCmdContinuation($pipeline)
</del><ins>+    protected function _processCmdContinuation($pipeline, $noexception = false)
</ins><span class="cx">     {
</span><del>-        $ob = $this->_getLine($pipeline);
</del><ins>+        do {
+            $ob = $this->_getLine($pipeline);
+        } while ($ob instanceof Horde_Imap_Client_Interaction_Server_Untagged);
+
</ins><span class="cx">         if ($ob instanceof Horde_Imap_Client_Interaction_Server_Continuation) {
</span><span class="cx">             return $ob;
</span><ins>+        } elseif ($noexception) {
+            return false;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         $this->_debug->info("ERROR: Unexpected response from server while waiting for a continuation request.");
</span><span class="lines">@@ -4176,8 +4263,12 @@
</span><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case 'ANNOTATION':
</span><ins>+            // Parse an ANNOTATION response.
+            $this->_parseAnnotation($pipeline, $token);
+            break;
+
</ins><span class="cx">         case 'METADATA':
</span><del>-            // Parse a ANNOTATEMORE/METADATA response.
</del><ins>+            // Parse a METADATA response.
</ins><span class="cx">             $this->_parseMetadata($pipeline, $token);
</span><span class="cx">             break;
</span><span class="cx"> 
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeImapClientphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client.php 2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Imap/Client.php    2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -52,6 +52,8 @@
</span><span class="cx">     const STATUS_SYNCVANISHED = 16384;
</span><span class="cx">     /* @since 2.12.0 */
</span><span class="cx">     const STATUS_RECENT_TOTAL = 32768;
</span><ins>+    /* @since 2.14.0 */
+    const STATUS_FORCE_REFRESH = 65536;
</ins><span class="cx"> 
</span><span class="cx">     /* Constants for search() */
</span><span class="cx">     const SORT_ARRIVAL = 1;
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeMailRfc822Addressphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Mail/Rfc822/Address.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Mail/Rfc822/Address.php 2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Mail/Rfc822/Address.php    2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -21,6 +21,8 @@
</span><span class="cx">  * @package   Mail
</span><span class="cx">  *
</span><span class="cx">  * @property-read string $bare_address  The bare mailbox@host address.
</span><ins>+ * @property-read string $bare_address_idn  The bare mailbox@host address (IDN
+ *                                          encoded). (@since 2.1.0)
</ins><span class="cx">  * @property-read string $encoded  The full MIME/IDN encoded address (UTF-8).
</span><span class="cx">  * @property string $host  Returns the host part (UTF-8).
</span><span class="cx">  * @property-read string $host_idn  Returns the IDN encoded host part.
</span><span class="lines">@@ -111,6 +113,13 @@
</span><span class="cx">                 ? $this->mailbox
</span><span class="cx">                 : $this->mailbox . '@' . $this->host;
</span><span class="cx"> 
</span><ins>+        case 'bare_address_idn':
+            $personal = $this->_personal;
+            $this->_personal = null;
+            $res = $this->encoded;
+            $this->_personal = $personal;
+            return $res;
+
</ins><span class="cx">         case 'encoded':
</span><span class="cx">             return $this->writeAddress(true);
</span><span class="cx"> 
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeMailRfc822Listphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Mail/Rfc822/List.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Mail/Rfc822/List.php    2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Mail/Rfc822/List.php       2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -23,6 +23,9 @@
</span><span class="cx">  * @property-read array $addresses  The list of all addresses (address
</span><span class="cx">  *                                  w/personal parts).
</span><span class="cx">  * @property-read array $bare_addresses  The list of all addresses (mail@host).
</span><ins>+ * @property-read array $bare_addresses_idn  The list of all addresses
+ *                                           (mail@host; IDN encoded).
+ *                                           (@since 2.1.0)
</ins><span class="cx">  * @property-read array $base_addresses  The list of ONLY base addresses
</span><span class="cx">  *                                       (Address objects).
</span><span class="cx">  * @property-read array $raw_addresses  The list of all addresses (Address
</span><span class="lines">@@ -74,6 +77,7 @@
</span><span class="cx">         switch ($name) {
</span><span class="cx">         case 'addresses':
</span><span class="cx">         case 'bare_addresses':
</span><ins>+        case 'bare_addresses_idn':
</ins><span class="cx">         case 'base_addresses':
</span><span class="cx">         case 'raw_addresses':
</span><span class="cx">             $old = $this->_filter;
</span><span class="lines">@@ -93,6 +97,10 @@
</span><span class="cx">                     $out[] = $val->bare_address;
</span><span class="cx">                     break;
</span><span class="cx"> 
</span><ins>+                case 'bare_addresses_idn':
+                    $out[] = $val->bare_address_idn;
+                    break;
+
</ins><span class="cx">                 case 'base_addresses':
</span><span class="cx">                 case 'raw_addresses':
</span><span class="cx">                     $out[] = clone $val;
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeMimeHeadersphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Mime/Headers.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Mime/Headers.php        2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Mime/Headers.php   2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -302,7 +302,7 @@
</span><span class="cx">     public function getUserAgent()
</span><span class="cx">     {
</span><span class="cx">         if (is_null($this->_agent)) {
</span><del>-            $this->_agent = 'Horde Application Framework 4';
</del><ins>+            $this->_agent = 'Horde Application Framework 5';
</ins><span class="cx">         }
</span><span class="cx">         return $this->_agent;
</span><span class="cx">     }
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeMimePartphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Mime/Part.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Mime/Part.php   2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Mime/Part.php      2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -535,11 +535,10 @@
</span><span class="cx">      *
</span><span class="cx">      * @param resource $fp      A stream containing the data to encode.
</span><span class="cx">      * @param string $encoding  The encoding to use.
</span><del>-     * @param string $eol       EOL string.
</del><span class="cx">      *
</span><span class="cx">      * @return resource  A new file resource with the encoded data.
</span><span class="cx">      */
</span><del>-    protected function _transferEncode($fp, $encoding, $eol)
</del><ins>+    protected function _transferEncode($fp, $encoding)
</ins><span class="cx">     {
</span><span class="cx">         $this->_temp['transferEncodeClose'] = true;
</span><span class="cx"> 
</span><span class="lines">@@ -549,20 +548,24 @@
</span><span class="cx">             return $this->_writeStream($fp, array(
</span><span class="cx">                 'filter' => array(
</span><span class="cx">                     'convert.base64-encode' => array(
</span><del>-                        'line-break-chars' => $eol,
</del><ins>+                        'line-break-chars' => $this->getEOL(),
</ins><span class="cx">                         'line-length' => 76
</span><span class="cx">                     )
</span><span class="cx">                 )
</span><span class="cx">             ));
</span><span class="cx"> 
</span><span class="cx">         case 'quoted-printable':
</span><ins>+            $stream = new Horde_Stream_Existing(array(
+                'stream' => $fp
+            ));
+
</ins><span class="cx">             /* Quoted-Printable Encoding: See RFC 2045, section 6.7 */
</span><span class="cx">             return $this->_writeStream($fp, array(
</span><span class="cx">                 'filter' => array(
</span><del>-                    'convert.quoted-printable-encode' => array(
-                        'line-break-chars' => $eol,
</del><ins>+                    'convert.quoted-printable-encode' => array_filter(array(
+                        'line-break-chars' => $stream->getEOL(),
</ins><span class="cx">                         'line-length' => 76
</span><del>-                    )
</del><ins>+                    ))
</ins><span class="cx">                 )
</span><span class="cx">             ));
</span><span class="cx"> 
</span><span class="lines">@@ -1222,11 +1225,7 @@
</span><span class="cx">                         break;
</span><span class="cx">                     }
</span><span class="cx"> 
</span><del>-                    $parts[] = $this->_transferEncode(
-                        $this->_contents,
-                        $encoding,
-                        (empty($options['canonical']) ? $this->getEOL() : self::RFC_EOL)
-                    );
</del><ins>+                    $parts[] = $this->_transferEncode($this->_contents, $encoding);
</ins><span class="cx"> 
</span><span class="cx">                     /* If not using $this->_contents, we can close the stream
</span><span class="cx">                      * when finished. */
</span><span class="lines">@@ -1410,10 +1409,12 @@
</span><span class="cx">             $eol = $this->getEOL();
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        $fp = $this->_writeStream($text);
-
</del><span class="cx">         stream_filter_register('horde_eol', 'Horde_Stream_Filter_Eol');
</span><del>-        stream_filter_append($fp, 'horde_eol', STREAM_FILTER_READ, array('eol' => $eol));
</del><ins>+        $fp = $this->_writeStream($text, array(
+            'filter' => array(
+                'horde_eol' => array('eol' => $eol)
+            )
+        ));
</ins><span class="cx"> 
</span><span class="cx">         return $stream ? $fp : $this->_readStream($fp, true);
</span><span class="cx">     }
</span><span class="lines">@@ -1559,7 +1560,8 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if ($rfc822) {
</span><del>-            if (empty($this->_parts)) {
</del><ins>+            if (empty($this->_parts) &&
+                ($this->getPrimaryType() != 'multipart')) {
</ins><span class="cx">                 $this->setMimeId($id . '1');
</span><span class="cx">             } else {
</span><span class="cx">                 if (empty($id) && ($this->getType() == 'message/rfc822')) {
</span><span class="lines">@@ -1689,10 +1691,10 @@
</span><span class="cx">         $old_basepart = $this->_basepart;
</span><span class="cx">         $this->_basepart = true;
</span><span class="cx"> 
</span><del>-        /* Does the SMTP backend support 8BITMIME (RFC 1652) or
-         * BINARYMIME (RFC 3030) extensions? Requires Net_SMTP version
-         * 1.3+. */
</del><ins>+        /* Does the SMTP backend support 8BITMIME (RFC 1652)? */
+        $canonical = true;
</ins><span class="cx">         $encode = self::ENCODE_7BIT;
</span><ins>+
</ins><span class="cx">         if (isset($opts['encode'])) {
</span><span class="cx">             /* Always allow 7bit encoding. */
</span><span class="cx">             $encode |= $opts['encode'];
</span><span class="lines">@@ -1702,34 +1704,24 @@
</span><span class="cx">                 if (isset($smtp_ext['8BITMIME'])) {
</span><span class="cx">                     $encode |= self::ENCODE_8BIT;
</span><span class="cx">                 }
</span><del>-                if (isset($smtp_ext['BINARYMIME'])) {
-                    $encode |= self::ENCODE_BINARY;
</del><ins>+            } catch (Horde_Mail_Exception $e) {}
+            $canonical = false;
+        } elseif ($mailer instanceof Horde_Mail_Transport_Smtphorde) {
+            try {
+                if ($mailer->getSMTPObject()->data_8bit) {
+                    $encode |= self::ENCODE_8BIT;
</ins><span class="cx">                 }
</span><span class="cx">             } catch (Horde_Mail_Exception $e) {}
</span><ins>+            $canonical = false;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         $msg = $this->toString(array(
</span><del>-            'canonical' => true,
</del><ins>+            'canonical' => $canonical,
</ins><span class="cx">             'encode' => $encode,
</span><span class="cx">             'headers' => false,
</span><span class="cx">             'stream' => true
</span><span class="cx">         ));
</span><span class="cx"> 
</span><del>-        /* Make sure the message has a trailing newline. */
-        fseek($msg, -1, SEEK_END);
-        switch (fgetc($msg)) {
-        case "\r":
-            if (fgetc($msg) != "\n") {
-                fputs($msg, "\n");
-            }
-            break;
-
-        default:
-            fputs($msg, "\r\n");
-            break;
-        }
-        rewind($msg);
-
</del><span class="cx">         /* Add MIME Headers if they don't already exist. */
</span><span class="cx">         if (!$headers->getValue('MIME-Version')) {
</span><span class="cx">             $headers = $this->addMimeHeaders(array('encode' => $encode, 'headers' => $headers));
</span><span class="lines">@@ -1738,12 +1730,12 @@
</span><span class="cx">         if (!empty($this->_temp['toString'])) {
</span><span class="cx">             $headers->replaceHeader('Content-Transfer-Encoding', $this->_temp['toString']);
</span><span class="cx">             switch ($this->_temp['toString']) {
</span><del>-            case 'binary':
-                $mailer->addServiceExtensionParameter('BODY', 'BINARYMIME');
-                break;
-
</del><span class="cx">             case '8bit':
</span><del>-                $mailer->addServiceExtensionParameter('BODY', '8BITMIME');
</del><ins>+                if ($mailer instanceof Horde_Mail_Transport_Smtp) {
+                    $mailer->addServiceExtensionParameter('BODY', '8BITMIME');
+                } elseif ($mailer instanceof Horde_Mail_Transport_Smtphorde) {
+                    $mailer->send8bit = true;
+                }
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="lines">@@ -1755,7 +1747,7 @@
</span><span class="cx">                 'encode' => $this->getHeaderCharset(),
</span><span class="cx">                 'idn' => true
</span><span class="cx">             )), $headers->toArray(array(
</span><del>-                'canonical' => true,
</del><ins>+                'canonical' => $canonical,
</ins><span class="cx">                 'charset' => $this->getHeaderCharset()
</span><span class="cx">             )), $msg);
</span><span class="cx">         } catch (Horde_Mail_Exception $e) {
</span><span class="lines">@@ -2083,6 +2075,9 @@
</span><span class="cx">             $boundary = $ob->getContentTypeParameter('boundary');
</span><span class="cx">             if (!is_null($boundary)) {
</span><span class="cx">                 foreach (self::_findBoundary($body, 0, $boundary) as $val) {
</span><ins>+                    if (!isset($val['length'])) {
+                        break;
+                    }
</ins><span class="cx">                     $subpart = substr($body, $val['start'], $val['length']);
</span><span class="cx">                     list($hdr_pos, $eol) = self::_findHeader($subpart);
</span><span class="cx">                     $ob->addPart(self::_getStructure(substr($subpart, 0, $hdr_pos), substr($subpart, $hdr_pos + $eol), array(
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeStreamFilterEolphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Stream/Filter/Eol.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Stream/Filter/Eol.php   2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Stream/Filter/Eol.php      2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -33,25 +33,34 @@
</span><span class="cx"> class Horde_Stream_Filter_Eol extends php_user_filter
</span><span class="cx"> {
</span><span class="cx">     /**
</span><ins>+     * Replacement data
+     *
+     * @var mixed
+     */
+    protected $_replace;
+
+    /**
</ins><span class="cx">      * Search array.
</span><span class="cx">      *
</span><del>-     * @param mixed
</del><ins>+     * @var mixed
</ins><span class="cx">      */
</span><span class="cx">     protected $_search;
</span><span class="cx"> 
</span><span class="cx">     /**
</span><del>-     * Replacement data
</del><ins>+     * First character of a multi-character EOL.
</ins><span class="cx">      *
</span><del>-     * @param mixed
</del><ins>+     * @var string
</ins><span class="cx">      */
</span><del>-    protected $_replace;
</del><ins>+    protected $_split = null;
</ins><span class="cx"> 
</span><span class="cx">     /**
</span><span class="cx">      * @see stream_filter_register()
</span><span class="cx">      */
</span><span class="cx">     public function onCreate()
</span><span class="cx">     {
</span><del>-        $eol = isset($this->params['eol']) ? $this->params['eol'] : "\r\n";
</del><ins>+        $eol = isset($this->params['eol'])
+            ? $this->params['eol']
+            : "\r\n";
</ins><span class="cx"> 
</span><span class="cx">         if (!strlen($eol)) {
</span><span class="cx">             $this->_search = array("\r", "\n");
</span><span class="lines">@@ -62,6 +71,9 @@
</span><span class="cx">         } else {
</span><span class="cx">             $this->_search = array("\r\n", "\r", "\n");
</span><span class="cx">             $this->_replace = array("\n", "\n", $eol);
</span><ins>+            if (strlen($eol) > 1) {
+                $this->_split = $eol[0];
+            }
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         return true;
</span><span class="lines">@@ -73,6 +85,11 @@
</span><span class="cx">     public function filter($in, $out, &$consumed, $closing)
</span><span class="cx">     {
</span><span class="cx">         while ($bucket = stream_bucket_make_writeable($in)) {
</span><ins>+            if (!is_null($this->_split) &&
+                ($bucket->data[$bucket->datalen - 1] == $this->_split)) {
+                $bucket->data = substr($bucket->data, 0, -1);
+            }
+
</ins><span class="cx">             $bucket->data = str_replace($this->_search, $this->_replace, $bucket->data);
</span><span class="cx">             $consumed += $bucket->datalen;
</span><span class="cx">             stream_bucket_append($out, $bucket);
</span></span></pre></div>
<a id="2013codebykatpostbyemailtrunkincludeHordeSupportStubphp"></a>
<div class="modfile"><h4>Modified: 2013/codebykat/post-by-email/trunk/include/Horde/Support/Stub.php (2316 => 2317)</h4>
<pre class="diff"><span>
<span class="info">--- 2013/codebykat/post-by-email/trunk/include/Horde/Support/Stub.php        2013-09-16 02:11:18 UTC (rev 2316)
+++ 2013/codebykat/post-by-email/trunk/include/Horde/Support/Stub.php   2013-09-16 02:11:45 UTC (rev 2317)
</span><span class="lines">@@ -16,7 +16,7 @@
</span><span class="cx">  * @license   http://www.horde.org/licenses/bsd BSD
</span><span class="cx">  * @package   Support
</span><span class="cx">  */
</span><del>-class Horde_Support_Stub
</del><ins>+class Horde_Support_Stub implements ArrayAccess, Countable, IteratorAggregate
</ins><span class="cx"> {
</span><span class="cx">     /**
</span><span class="cx">      * Cooerce to an empty string.
</span><span class="lines">@@ -91,4 +91,50 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    /* ArrayAccess methods. */
+
+     /**
+      */
+     public function offsetGet($offset)
+     {
+         return null;
+     }
+
+    /**
+     */
+    public function offsetSet($offset, $value)
+    {
+    }
+
+    /**
+     */
+    public function offsetExists($offset)
+    {
+        return false;
+    }
+
+    /**
+     */
+    public function offsetUnset($offset)
+    {
+    }
+
+    /* Countable methods. */
+
+    /**
+     */
+    public function count()
+    {
+        return 0;
+    }
+
+    /* IteratorAggregate method. */
+
+    /**
+     */
+    public function getIterator()
+    {
+        return new ArrayIterator(array());
+    }
+
</ins><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>