The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 015
MANIFEST 01
META.yml 23
Makefile.PL 01
SIGNATURE 1617
certs/server-cert.pem 4662
certs/server-key.pem 1528
inc/Module/Install/ReadmeFromPod.pm 11101
lib/Net/IMAP/Server/Command/Authenticate.pm 12
lib/Net/IMAP/Server/Command.pm 79
lib/Net/IMAP/Server/Connection.pm 911
lib/Net/IMAP/Server.pm 11
t/lib/Net/IMAP/Server/Test.pm 17
t/rfc-6.3.10-status.t 041
14 files changed (This is a version diff) 109299
@@ -1,5 +1,20 @@
 Revision history for Net-IMAP-Server
 
+1.38   Sun Jan 26 20:16:17 2014
+        * Pass tests with IO::Socket::SSL 1.950 and above, which verify
+          server SSL certificates by default.
+
+1.37   Sun Jan 26 19:14:17 2014
+        * Fix parsing par parenthesized expressions with recent
+          Regexp::Common
+
+1.36   Thu Jan 17 08:09:17 2012
+        * Fix string literals (such as for APPEND), which have counted
+          characters incorrectly since 1.32 due to newline trimming.
+
+1.35   Mon Nov 12 03:22:17 2012
+        * Switch to AnyEvent, from EV
+
 1.34   Sat Jul 28 15:49:17 2012
         * Don't rely on $" being set to the default " " during UID
           SEARCH
@@ -65,6 +65,7 @@ t/rfc-6.2.1-starttls.t
 t/rfc-6.2.2-authenticate.t
 t/rfc-6.2.3-login.t
 t/rfc-6.3.1-select.t
+t/rfc-6.3.10-status.t
 t/rfc-6.3.3-create.t
 t/rfc-6.3.4-delete.t
 t/rfc-6.3.5-rename.t
@@ -9,7 +9,7 @@ configure_requires:
   ExtUtils::MakeMaker: 6.59
 distribution_type: module
 dynamic_config: 1
-generated_by: 'Module::Install version 1.01'
+generated_by: 'Module::Install version 1.06'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -20,6 +20,7 @@ no_index:
     - inc
     - t
 requires:
+  AnyEvent: 0
   Class::Accessor: 0
   Coro: 0
   DateTime: 0
@@ -40,4 +41,4 @@ requires:
 resources:
   license: http://dev.perl.org/licenses/
   repository: http://github.com/bestpractical/net-imap-server/
-version: 1.34
+version: 1.38
@@ -10,6 +10,7 @@ license('perl');
 readme_from('lib/Net/IMAP/Server.pm');
 sign;
 
+requires('AnyEvent');
 requires('Class::Accessor');
 requires('Coro');
 requires('DateTime');
@@ -1,5 +1,5 @@
 This file contains message digests of all files listed in MANIFEST,
-signed via the Module::Signature module, version 0.68.
+signed via the Module::Signature module, version 0.69.
 
 To verify the content in this distribution, first make sure you have
 Module::Signature installed, then type:
@@ -14,13 +14,13 @@ not run its Makefile.PL or Build.PL.
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-SHA1 b49418ece465b27a4b2caf0d8426b0150adcc283 Changes
-SHA1 85dec096dfdc00929a305878278d5662ec47a2c6 MANIFEST
-SHA1 cb765774f1f81657b7694b3f4f28e55bc5a649fb META.yml
-SHA1 af0737be80a4de325a176f409892e0e2ec8287cb Makefile.PL
+SHA1 889a6d05f550724bdc198d478d714d222ddea00f Changes
+SHA1 78d00cafaa16819731b7d3a78ac2339856d6d446 MANIFEST
+SHA1 2225ee6da840d426c4c009a5ffe648df5d77988e META.yml
+SHA1 d8f0a10455ed27ff5e122d3a33c52e5c2fdf6854 Makefile.PL
 SHA1 20803052ac485820a77f4443fb75a376dab3b371 README
-SHA1 f5333026061a6f347e7f2a3ce8bb6847081c200c certs/server-cert.pem
-SHA1 4b963cd4c2b0a7e073241b4bac727cb6f96276f8 certs/server-key.pem
+SHA1 9697a36f4420842b5bb48432ac9101984eecddf8 certs/server-cert.pem
+SHA1 e4b88ae14bd5e2386a06315492cdfa66ceb6b774 certs/server-key.pem
 SHA1 4dff4d838079dad5d13fa4e91db21e3a3e038c4e ex/trivial-server.pl
 SHA1 8a924add836b60fb23b25c8506d45945e02f42f4 inc/Module/Install.pm
 SHA1 2d0fad3bf255f8c1e7e1e34eafccc4f595603ddc inc/Module/Install/Base.pm
@@ -28,13 +28,13 @@ SHA1 f0e01fff7d73cd145fbf22331579918d4628ddb0 inc/Module/Install/Can.pm
 SHA1 7328966e4fda0c8451a6d3850704da0b84ac1540 inc/Module/Install/Fetch.pm
 SHA1 b62ca5e2d58fa66766ccf4d64574f9e1a2250b34 inc/Module/Install/Makefile.pm
 SHA1 1aa925be410bb3bfcd84a16985921f66073cc1d2 inc/Module/Install/Metadata.pm
-SHA1 d3a33569b41077d6a836f95bb63484c51e9d0a52 inc/Module/Install/ReadmeFromPod.pm
+SHA1 79f5b4199f622e8b05aac266b0c39f6a85bb303f inc/Module/Install/ReadmeFromPod.pm
 SHA1 e4196994fa75e98bdfa2be0bdeeffef66de88171 inc/Module/Install/Win32.pm
 SHA1 c3a6d0d5b84feb3280622e9599e86247d58b0d18 inc/Module/Install/WriteAll.pm
-SHA1 7fd85ecf8eb2b07ab2558d1bffc2b82c6cce7ede lib/Net/IMAP/Server.pm
-SHA1 6c989236bade55bbfe767e33d3566cc2ab3a43bf lib/Net/IMAP/Server/Command.pm
+SHA1 c965441adee0853d43376ed5ce909fcbeb48a096 lib/Net/IMAP/Server.pm
+SHA1 ac5060c7ab18a94e375131e611c20404262c23d9 lib/Net/IMAP/Server/Command.pm
 SHA1 4528753566f748a9b5525fa51ae22d7cc9fdc6b3 lib/Net/IMAP/Server/Command/Append.pm
-SHA1 e73ef8ec47bb5b0f80df51e5a0cf24b59a2f592c lib/Net/IMAP/Server/Command/Authenticate.pm
+SHA1 d1976ad0d92b1ea13672bf6895091ee84e908bf1 lib/Net/IMAP/Server/Command/Authenticate.pm
 SHA1 70f2aeb901dde845183ef6b70f56b4d777641a5d lib/Net/IMAP/Server/Command/Capability.pm
 SHA1 de6607dec53f35b3b3fd41ad12191a83c59ae21b lib/Net/IMAP/Server/Command/Check.pm
 SHA1 514b741e13d400a6c44215ab9bd66b77a16ef18c lib/Net/IMAP/Server/Command/Close.pm
@@ -60,7 +60,7 @@ SHA1 5a71e10cec65fe7f933354b0323b026de92df9ce lib/Net/IMAP/Server/Command/Store.
 SHA1 3fbb8ce46e696eeb62a97264cb564924a7ccfb57 lib/Net/IMAP/Server/Command/Subscribe.pm
 SHA1 d6993c8ad9b65501d3e878a6400a6ca77b43925d lib/Net/IMAP/Server/Command/Uid.pm
 SHA1 4591be8d501ea8877f3b4d4418620cce094256ab lib/Net/IMAP/Server/Command/Unsubscribe.pm
-SHA1 4c444f4a0ef3bbe5df8f80509a2d773945a06bc5 lib/Net/IMAP/Server/Connection.pm
+SHA1 67655d3e7575a301a210b28207d4fefb888840c3 lib/Net/IMAP/Server/Connection.pm
 SHA1 3d57329808a2c9c656dd3ea9184c58e1fa863406 lib/Net/IMAP/Server/DefaultAuth.pm
 SHA1 035fbedbfa85c6dcf04740083b2fcfcd46ae77cd lib/Net/IMAP/Server/DefaultModel.pm
 SHA1 688651b7e624fe1d4bf29e320b05d0872fb54dd0 lib/Net/IMAP/Server/Error.pm
@@ -68,7 +68,7 @@ SHA1 686d0e65b737ebdbab4ce2db0c0fb64ba88f1c55 lib/Net/IMAP/Server/Mailbox.pm
 SHA1 40253dbf44247f869ebf2eedda8d87ff6639808f lib/Net/IMAP/Server/Message.pm
 SHA1 2e67e318edc490da7367ebcc789d35d0810e00e6 t/00.load.t
 SHA1 fd24a4a3ac43bfbd98c3cca72d26f38af7b4c533 t/01-connect.t
-SHA1 9b509c59bdc4718896b2c1ac47642a2342979791 t/lib/Net/IMAP/Server/Test.pm
+SHA1 a35f7b19e0a0f985909fcad15d86a990e1a0991e t/lib/Net/IMAP/Server/Test.pm
 SHA1 2f55d5c59bafec029c3e450185e17a6225eede59 t/lib/Net/IMAP/Server/Test/Auth.pm
 SHA1 d0a930ff8a15e59ecc9810136b1991211c1f68a8 t/lib/Net/IMAP/Server/Test/Server.pm
 SHA1 ec035a09e3f370620874e9c706d6c8ae4bdfa6a1 t/pod-coverage.t
@@ -80,13 +80,14 @@ SHA1 74b2514b72437c33909e8883606e910b9c295200 t/rfc-6.2.1-starttls.t
 SHA1 6b0eb113c254410e882a08ee5ef1c11f5b4d5a0f t/rfc-6.2.2-authenticate.t
 SHA1 d36bdc220d322cb4cdcf465140df4e7223b1c5fa t/rfc-6.2.3-login.t
 SHA1 74c5f43316fffb99560addf29d3554d13155df8d t/rfc-6.3.1-select.t
+SHA1 ec68ddd0a68e41ab7c6628024865119aabef54c8 t/rfc-6.3.10-status.t
 SHA1 111f381b2d28337e4a7683104838121f05d23186 t/rfc-6.3.3-create.t
 SHA1 d92f07dd21632fb8975d9771fb81c46c9860bb86 t/rfc-6.3.4-delete.t
 SHA1 fb48a77a25da2dc2ea821e9c0a79877e845cf974 t/rfc-6.3.5-rename.t
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
-iEYEARECAAYFAlAWCx0ACgkQMflWJZZAbqCOqACeLWsBAIJLnmozlFxvN/v9wKlG
-rSkAoJ0EC6O1XcIiGLxz96y4L8l1YU9C
-=ZDO3
+iEYEARECAAYFAlLltCcACgkQMflWJZZAbqAFAACgr+i2qrG1zL1ht00+POu0PZs3
+0MQAn3q8HL2cWX922QTBL5ewqZvDzWy6
+=P7oD
 -----END PGP SIGNATURE-----
@@ -1,62 +1,78 @@
 Certificate:
     Data:
         Version: 3 (0x2)
-        Serial Number:
-            c2:fa:b9:08:d7:a1:e1:a5
-        Signature Algorithm: sha1WithRSAEncryption
-        Issuer: C=US, ST=Local Host, O=Internet Widgits Pty Ltd, CN=localhost
+        Serial Number: 9589475111614655190 (0x8514a8ce8a3daad6)
+    Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd
         Validity
-            Not Before: Feb 18 02:25:22 2007 GMT
-            Not After : Mar 20 02:25:22 2007 GMT
-        Subject: C=US, ST=Local Host, O=Internet Widgits Pty Ltd, CN=localhost
+            Not Before: Jan 27 01:06:54 2014 GMT
+            Not After : Jan 25 01:06:54 2024 GMT
+        Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd
         Subject Public Key Info:
             Public Key Algorithm: rsaEncryption
-            RSA Public Key: (1024 bit)
-                Modulus (1024 bit):
-                    00:ab:5c:51:5d:69:66:75:22:2b:d7:4b:5c:63:d3:
-                    f4:5e:ab:56:59:41:ac:41:5b:7c:89:42:8e:3b:44:
-                    88:cf:b4:0b:45:46:9e:ac:be:ab:cd:29:31:6b:6c:
-                    98:d6:67:5e:4b:7c:ec:66:6a:34:b8:20:84:21:fd:
-                    63:c5:da:f8:1c:63:68:f0:a4:2d:ca:e0:53:2d:9d:
-                    73:a7:90:88:eb:84:3e:c5:86:34:e1:4b:59:6c:f3:
-                    24:a0:4d:cb:27:85:b2:a2:f2:01:e2:e5:84:78:17:
-                    8a:45:02:41:4c:1a:43:d4:7b:b1:a7:be:b0:0c:db:
-                    e4:b3:8b:fa:41:2a:b7:b0:59
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:d7:46:9c:27:4f:9c:7a:18:57:3b:6f:24:ac:b7:
+                    76:90:11:2a:f0:ff:70:9c:35:89:c3:a5:e2:3c:17:
+                    06:18:7c:e5:b3:e4:4f:c2:0d:0d:09:80:61:e5:4b:
+                    f5:25:2f:d2:ad:4d:3d:53:69:09:be:e0:af:fa:4c:
+                    e6:d9:3a:ad:94:f1:b2:5e:67:d9:7a:12:e9:b8:07:
+                    a3:cf:68:17:6b:1d:b1:44:99:ba:8c:7d:82:e0:d3:
+                    ee:b0:19:e7:4d:03:a2:6c:53:e7:c5:eb:4b:a8:a1:
+                    8e:e6:41:50:27:63:8f:5a:54:55:63:ed:a1:cf:95:
+                    66:97:2b:47:ca:8b:0f:8e:a0:00:1e:05:e4:11:35:
+                    f7:b9:fa:08:89:15:b5:7e:0b:a0:25:14:4b:d0:28:
+                    b7:eb:8f:4b:06:de:da:9b:e9:ca:83:9f:6b:73:18:
+                    1d:1b:e1:71:9d:92:4a:1c:9d:76:92:08:2b:d3:ef:
+                    4e:66:cc:be:f1:bb:b1:f4:75:a9:66:f1:bb:85:8e:
+                    b1:be:5d:c8:12:ea:1f:40:b0:2e:79:0e:08:ec:11:
+                    06:1a:52:f8:5d:1f:5c:95:32:a0:0e:a0:3c:21:86:
+                    2f:93:b2:af:c9:b3:ad:12:1d:a5:04:5c:6c:b6:09:
+                    ac:60:4c:5a:40:10:d8:28:24:87:c5:b8:6a:b4:f1:
+                    8e:7d
                 Exponent: 65537 (0x10001)
         X509v3 extensions:
             X509v3 Subject Key Identifier: 
-                49:71:2C:CC:28:DA:84:6C:D7:42:E1:8C:1D:28:BD:0A:CB:4E:7D:38
+                BD:27:38:21:D3:6A:61:E0:70:3F:05:A4:B1:19:B6:43:63:94:EA:EC
             X509v3 Authority Key Identifier: 
-                keyid:49:71:2C:CC:28:DA:84:6C:D7:42:E1:8C:1D:28:BD:0A:CB:4E:7D:38
-                DirName:/C=US/ST=Local Host/O=Internet Widgits Pty Ltd/CN=localhost
-                serial:C2:FA:B9:08:D7:A1:E1:A5
+                keyid:BD:27:38:21:D3:6A:61:E0:70:3F:05:A4:B1:19:B6:43:63:94:EA:EC
 
             X509v3 Basic Constraints: 
                 CA:TRUE
     Signature Algorithm: sha1WithRSAEncryption
-        2b:8a:5a:04:15:2c:52:dd:09:e3:5a:2a:8e:37:29:d4:f1:fe:
-        6d:88:fe:bf:91:84:b9:25:ba:ac:8d:ad:27:30:96:00:79:eb:
-        cb:fa:a0:df:4d:66:ee:9a:96:80:c1:81:49:db:37:86:c8:7c:
-        16:04:8c:3d:4c:25:c4:0a:94:f5:32:f3:59:67:2c:74:8f:93:
-        f6:b0:8e:3f:d6:49:49:48:a6:49:d1:c8:e6:01:5b:ca:89:a0:
-        5d:f3:6a:8e:2d:4a:87:31:81:93:93:4d:b2:4d:46:62:f8:35:
-        c1:03:7a:fc:2e:8f:60:59:ff:14:29:52:e2:52:5b:97:50:ab:
-        a7:24
+         64:9d:4a:e0:77:da:6b:ce:e6:6c:79:74:10:77:d8:39:1b:5c:
+         15:b3:cc:45:4e:d1:99:14:3b:45:19:d1:f8:6e:13:a8:33:de:
+         ef:42:cd:9d:4b:ab:c8:0e:c4:cf:49:ff:cd:6a:e3:68:94:68:
+         ef:32:19:ac:f2:2e:87:d1:24:3f:3b:73:1a:bf:ac:e8:ff:5d:
+         9a:c8:3d:d1:3a:e7:ce:ec:53:a9:b2:43:4d:2c:f8:1f:3c:97:
+         3e:fd:7d:dc:db:9b:10:06:ae:e8:99:07:60:0e:83:b9:e9:1c:
+         13:72:78:bb:3a:ca:69:93:64:bb:d6:72:4c:af:f8:d3:c2:25:
+         94:59:12:0a:97:c9:ba:62:9d:1b:4f:46:ff:76:c4:4a:81:48:
+         0f:d3:0f:20:d0:63:52:8c:ad:7b:13:3e:76:de:05:6a:0c:b7:
+         dc:7a:09:7a:c7:aa:b9:c2:be:ad:e0:0e:88:4c:6e:a6:6c:e5:
+         5a:56:39:f4:67:d4:21:e2:9e:b3:89:74:ed:d5:f5:b2:07:7b:
+         9e:01:7f:31:9b:f4:0e:24:39:0a:a8:d0:e4:ac:bc:10:42:c4:
+         c3:38:1d:cf:fd:e5:f7:df:98:55:00:1d:b8:82:9f:67:d7:48:
+         e1:8c:1a:53:20:0d:39:18:ad:b7:77:4a:30:16:d7:86:a1:1e:
+         51:b0:96:eb
 -----BEGIN CERTIFICATE-----
-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
+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
+6w==
 -----END CERTIFICATE-----
@@ -1,15 +1,28 @@
------BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQCrXFFdaWZ1IivXS1xj0/Req1ZZQaxBW3yJQo47RIjPtAtFRp6s
-vqvNKTFrbJjWZ15LfOxmajS4IIQh/WPF2vgcY2jwpC3K4FMtnXOnkIjrhD7FhjTh
-S1ls8ySgTcsnhbKi8gHi5YR4F4pFAkFMGkPUe7GnvrAM2+Szi/pBKrewWQIDAQAB
-AoGAaEez1A6yJRH4b/oSbUWs7neCAqsuck+ER9tSxsp8HznHqg7BvQoDbsRkqKTb
-lY4uGe4ZxnFXR72x6yVSNDN+zHjP29aSDNRl4Pn8mrQIfAL9hjHVwoi8rmWYjrKa
-hRsfBX+uSyVvcRwum+1xmsEXIMaDLhqI3i7Dj3aEyUIgzAECQQDWCezB/xpGLUur
-GN58deg0a9i1I0MvzTdhiduqjUFUlnrBDcp12bBITpsE5MIwF/+qpIWX7wFr2DR5
-LFBSO/dBAkEAzPR7endHbnF9JQP782g3tN+w7p80QZQY5mfJe6EPjsmAt3hVQ4bY
-A2hxGtCHErbGxjdnkU1bpqz0momlDszLGQJAO5mN5MMtRMdOH7mQEmYen6I8OMw1
-5DSnrDBgC5DD1VMFoYY+jyxryuagge9VJ2E3XwPq81CpO6d7jRZK02tBQQJAKavn
-0z2fU3BVvonx10qwUOFOayYJjO/cpDQj/jQAIssLlcIsq98l2oOIw6f0XrS086Ze
-M2fkI5502Vr1KW4wOQJASDFHxVXz3zN/2d8By93EA1ZuXe5YcX3zzPmpKkIQtO62
-dINHo+M2BYP4Ku3wME++dp4E29BNsIopoLILWHSCow==
------END RSA PRIVATE KEY-----
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDXRpwnT5x6GFc7
+bySst3aQESrw/3CcNYnDpeI8FwYYfOWz5E/CDQ0JgGHlS/UlL9KtTT1TaQm+4K/6
+TObZOq2U8bJeZ9l6Eum4B6PPaBdrHbFEmbqMfYLg0+6wGedNA6JsU+fF60uooY7m
+QVAnY49aVFVj7aHPlWaXK0fKiw+OoAAeBeQRNfe5+giJFbV+C6AlFEvQKLfrj0sG
+3tqb6cqDn2tzGB0b4XGdkkocnXaSCCvT705mzL7xu7H0dalm8buFjrG+XcgS6h9A
+sC55DgjsEQYaUvhdH1yVMqAOoDwhhi+Tsq/Js60SHaUEXGy2CaxgTFpAENgoJIfF
+uGq08Y59AgMBAAECggEALTO9XB/CSnzL7EXlHIMVWSDRtHLecV5og/VT8Kwg8olf
+Lgu1l5hn8WPMqnntipZlFVCPnPEEQ9kn+lWlb117zzeE7X++0XwhKSwpgEZqDGra
+qv3ghtlf3teBWebGg4xM0ZQ4qX1DkLADsmNqcircken9WBMwk8baGMnUtDnI1Xhu
+lgeM2JJyrtVljYH7TEM063l1NXBSBVU7jOh1h4OKO29M3s89Vt+Novfjvqt3P6vW
+CeY245E2wRAbNWnlBb8xWj8Ws9XtHSzmvtqP15GIJVOC5/V7vpHd1M7o9grgqsWk
+7Im507QytqoEFDWF1TxrWXbXRGkqcAWMdSYuhlpqXQKBgQDtfFFDWOJ1nhE9td8T
+zZSTUvu3kc6xebzWbIy1mWIn4njHOUS6gGF7cEzBdFvUepBSKnrOOadEUoSicsvr
+NjooJjzzIeh84JM1F3JTgiQGWuWdFzoRhjbBRxHumc23jAtcp2zBnJ2DoUurDC1I
+TKNNejiAyDjvBFK3z0PmFLl8NwKBgQDoDwjdqYMzzXBr9/atVJeyCuKGFp+vnGG4
+vnxKoFJcMqfyhm6bvG3//Vu7nrC7zIOOnwOQYkaH9JHSLitmWilG9d4bf7RSmU74
++VBVhUc3xm/r/TrgeeY8kIvaPFO96D11EN9TjlzdgS10IhYQb67gHpJ8tRiUHo4b
+JO7SfUO46wKBgQDRG8fKDzfH7Nith7jXDQun9UejSYXAC7tU6tuzA03EZMuIUErO
+FUDAmg9bwAMjwo/VaYYck/NOW4JiL8aSY3st4w2D3/WAD5ZPB0gpc8wYtGy9t7fv
+ukf4Q4XsnAzhczSF7v36NNcVEi84e05b/O9Fxzp9Ws+W1i2nn57ftpvkXQKBgGlp
+evOF7u13ItxItSsjRA1CWIfkewFAnjtXfApCLWdoM1Y9rrzbqXQhWKwvd8S3MAN3
+RB0wJy3W8O5yvpAt4JY1VYFUT0s+DNuYFN/kPOefInQmgbo6ZVWZq42k3b1kY5Zr
+5aaFArYz2bvpR/CLavqvqIcxlEqkXpUB/+JpuHulAoGBANKmSkjRM8ssMPUmVFhx
+m5IwB5dOOcLLgLY81j4A0ui5xTgE2qbrQF+VXuAEQ1oZTOlAIgB+w76FrZ/1C8lo
+eb8uvXR+3rtmpt6L08QZCfosDBea9J8TtvxeEr5ZmbDBJ0rilTA5EXYt918+sjjB
+DykNAjSgO3/vCpC6i8AvbBnz
+-----END PRIVATE KEY-----
@@ -7,29 +7,119 @@ use warnings;
 use base qw(Module::Install::Base);
 use vars qw($VERSION);
 
-$VERSION = '0.12';
+$VERSION = '0.22';
 
 sub readme_from {
   my $self = shift;
   return unless $self->is_admin;
 
-  my $file = shift || $self->_all_from
+  # Input file
+  my $in_file  = shift || $self->_all_from
     or die "Can't determine file to make readme_from";
-  my $clean = shift;
 
-  print "Writing README from $file\n";
+  # Get optional arguments
+  my ($clean, $format, $out_file, $options);
+  my $args = shift;
+  if ( ref $args ) {
+    # Arguments are in a hashref
+    if ( ref($args) ne 'HASH' ) {
+      die "Expected a hashref but got a ".ref($args)."\n";
+    } else {
+      $clean    = $args->{'clean'};
+      $format   = $args->{'format'};
+      $out_file = $args->{'output_file'};
+      $options  = $args->{'options'};
+    }
+  } else {
+    # Arguments are in a list
+    $clean    = $args;
+    $format   = shift;
+    $out_file = shift;
+    $options  = \@_;
+  }
+
+  # Default values;
+  $clean  ||= 0;
+  $format ||= 'txt';
+
+  # Generate README
+  print "readme_from $in_file to $format\n";
+  if ($format =~ m/te?xt/) {
+    $out_file = $self->_readme_txt($in_file, $out_file, $options);
+  } elsif ($format =~ m/html?/) {
+    $out_file = $self->_readme_htm($in_file, $out_file, $options);
+  } elsif ($format eq 'man') {
+    $out_file = $self->_readme_man($in_file, $out_file, $options);
+  } elsif ($format eq 'pdf') {
+    $out_file = $self->_readme_pdf($in_file, $out_file, $options);
+  }
 
-  require Pod::Text;
-  my $parser = Pod::Text->new();
-  open README, '> README' or die "$!\n";
-  $parser->output_fh( *README );
-  $parser->parse_file( $file );
   if ($clean) {
-    $self->clean_files('README');
+    $self->clean_files($out_file);
   }
+
   return 1;
 }
 
+
+sub _readme_txt {
+  my ($self, $in_file, $out_file, $options) = @_;
+  $out_file ||= 'README';
+  require Pod::Text;
+  my $parser = Pod::Text->new( @$options );
+  open my $out_fh, '>', $out_file or die "Could not write file $out_file:\n$!\n";
+  $parser->output_fh( *$out_fh );
+  $parser->parse_file( $in_file );
+  close $out_fh;
+  return $out_file;
+}
+
+
+sub _readme_htm {
+  my ($self, $in_file, $out_file, $options) = @_;
+  $out_file ||= 'README.htm';
+  require Pod::Html;
+  Pod::Html::pod2html(
+    "--infile=$in_file",
+    "--outfile=$out_file",
+    @$options,
+  );
+  # Remove temporary files if needed
+  for my $file ('pod2htmd.tmp', 'pod2htmi.tmp') {
+    if (-e $file) {
+      unlink $file or warn "Warning: Could not remove file '$file'.\n$!\n";
+    }
+  }
+  return $out_file;
+}
+
+
+sub _readme_man {
+  my ($self, $in_file, $out_file, $options) = @_;
+  $out_file ||= 'README.1';
+  require Pod::Man;
+  my $parser = Pod::Man->new( @$options );
+  $parser->parse_from_file($in_file, $out_file);
+  return $out_file;
+}
+
+
+sub _readme_pdf {
+  my ($self, $in_file, $out_file, $options) = @_;
+  $out_file ||= 'README.pdf';
+  eval { require App::pod2pdf; }
+    or die "Could not generate $out_file because pod2pdf could not be found\n";
+  my $parser = App::pod2pdf->new( @$options );
+  $parser->parse_from_file($in_file);
+  open my $out_fh, '>', $out_file or die "Could not write file $out_file:\n$!\n";
+  select $out_fh;
+  $parser->output;
+  select STDOUT;
+  close $out_fh;
+  return $out_file;
+}
+
+
 sub _all_from {
   my $self = shift;
   return unless $self->admin->{extensions};
@@ -44,5 +134,5 @@ sub _all_from {
 
 __END__
 
-#line 112
+#line 254
 
@@ -53,8 +53,9 @@ sub continue {
     $self->connection->pending(undef);
 
     return $self->bad_command("Login cancelled")
-        if not defined $line or $line =~ /^\*$/;
+        if not defined $line or $line =~ /^\*[\r\n]+$/;
 
+    $line =~ s/[\r\n]+$//;
     my $decoded = decode_base64($line);
     return $self->bad_command("Invalid base64")
         if encode_base64($decoded, "") ne $line;
@@ -137,14 +137,16 @@ sub parse_options {
     return $self->_parsed_options
         if not defined $str and not defined $self->options_str;
 
+    my $to_parse = defined $str ? $str : $self->options_str;
+
+    my $token = qr/^($RE{delimited}{-delim=>'"'}{-esc=>'\\'}
+                    |$RE{balanced}{-parens=>'()'}
+                    |\S+$RE{balanced}{-parens=>'()[]<>'}
+                    |\S+)\s*/x;
+
     my @parsed;
-    for my $term (
-        grep {/\S/}
-        split
-        /($RE{delimited}{-delim=>'"'}{-esc=>'\\'}|$RE{balanced}{-parens=>'()'}|\S+$RE{balanced}{-parens=>'()[]<>'}|\S+)/,
-        defined $str ? $str : $self->options_str
-        )
-    {
+    while ($to_parse =~ s/$token//) {
+        my $term = $1;
         if ( $term =~ /^$RE{delimited}{-delim=>'"'}{-esc=>'\\'}{-keep}$/ ) {
             my $value = $3;
             $value =~ s/\\([\\"])/$1/g;
@@ -6,6 +6,7 @@ use strict;
 use base 'Class::Accessor';
 
 use Coro;
+use AnyEvent;
 use Scalar::Util qw/weaken/;
 
 use Net::IMAP::Server::Error;
@@ -216,7 +217,6 @@ Updates the inactivity timer.
 
 sub update_timer {
     my $self = shift;
-    $self->timer->stop if $self->timer;
     $self->timer(undef);
     my $weakself = $self;
     weaken($weakself);
@@ -225,15 +225,15 @@ sub update_timer {
         $weakself->coro->ready;
     };
     if ( $self->is_unauth and $self->server->unauth_idle ) {
-        $self->timer( EV::timer $self->server->unauth_idle, 0, $timeout );
+        $self->timer( AnyEvent->timer( after => $self->server->unauth_idle, cb => $timeout ) );
     } elsif ( $self->server->auth_idle ) {
-        $self->timer( EV::timer $self->server->auth_idle, 0, $timeout );
+        $self->timer( AnyEvent->timer( after => $self->server->auth_idle, cb => $timeout ) );
     }
 }
 
-=head2 timer [EV watcher]
+=head2 timer [AnyEvent watcher]
 
-Returns the L<EV> watcher in charge of the inactivity timer.
+Returns the L<AnyEvent> watcher in charge of the inactivity timer.
 
 =head2 commands
 
@@ -259,9 +259,10 @@ sub handle_command {
     my $self    = shift;
     my $content = shift;
 
-    $content =~ s/[\r\n]+$//;
+    my $output = $content;
+    $output =~ s/[\r\n]+$//;
     $self->log( 4,
-        "C(@{[$self]},@{[$self->auth ? $self->auth->user : '???']},@{[$self->is_selected ? $self->selected->full_path : 'unselected']}): $content"
+        "C(@{[$self]},@{[$self->auth ? $self->auth->user : '???']},@{[$self->is_selected ? $self->selected->full_path : 'unselected']}): $output"
     );
 
     if ( $self->pending ) {
@@ -343,10 +344,10 @@ sub close {
         $self->io_handle->close;
         $self->io_handle(undef);
     }
-    $self->timer->stop     if $self->timer;
+    $self->timer( undef )  if $self->timer;
     $self->selected->close if $self->selected;
     $self->model->close    if $self->model;
-    $self->server->connection(undef);
+    $self->server->connection(undef) if $self->server;
     $self->coro(undef);
 }
 
@@ -360,6 +361,7 @@ undef if parsing fails for some reason.
 sub parse_command {
     my $self = shift;
     my $line = shift;
+    $line =~ s/[\r\n]+$//;
     my $TAG = qr/([^\(\)\{ \*\%"\\\+}]+)/;
     unless ( $line =~ /^$TAG\s+(\w+)(?:\s+(.+?))?$/ ) {
         if ( $line !~ /^$TAG\s+/ ) {
@@ -9,7 +9,7 @@ use UNIVERSAL::require;
 use Coro;
 use 5.008_008;
 
-our $VERSION = '1.34';
+our $VERSION = '1.38';
 
 =head1 NAME
 
@@ -5,6 +5,8 @@ use strict;
 use warnings;
 
 use Socket;
+use AnyEvent;
+AnyEvent::detect();
 use IO::Socket::SSL;
 use Time::HiRes qw();
 
@@ -64,6 +66,7 @@ sub connect {
         PeerAddr        => 'localhost',
         PeerPort        => SSL_PORT,
         Class           => "IO::Socket::SSL",
+        SSL_ca_file     => "certs/server-cert.pem",
         @_
     );
     my $socketclass = delete $args{Class};
@@ -116,7 +119,10 @@ sub connect_ok {
 
 sub start_tls {
     my $class = shift;
-    IO::Socket::SSL->start_SSL($class->get_socket);
+    IO::Socket::SSL->start_SSL(
+        $class->get_socket,
+        SSL_ca_file => "certs/server-cert.pem",
+    );
 }
 
 sub start_tls_ok {
@@ -0,0 +1,41 @@
+use lib 't/lib';
+use strict;
+use warnings;
+
+use Net::IMAP::Server::Test;
+my $t = "Net::IMAP::Server::Test";
+
+$t->start_server_ok;
+
+$t->connect_ok;
+$t->cmd_like( "STATUS INBOX (MESSAGES)", "tag BAD Log in first" );
+
+$t->cmd_ok("LOGIN username password");
+
+$t->cmd_like( "STATUS INBOX", "tag BAD Not enough options" );
+$t->cmd_like( "STATUS INBOX MESSAGES", "tag BAD Wrong second option" );
+
+my $test = sub {
+    my @res = split /\r\n/, $t->send_cmd( "STATUS INBOX (@_)" );
+    like( pop(@res), qr/^tag OK\b/);
+    my $untagged = pop(@res);
+    like( $untagged, qr/^\* STATUS "INBOX" \(.*?\)$/, "Got an untagged STATUS response" );
+    $untagged =~ qr/\((.*?)\)/;
+    return split ' ', $1;
+};
+
+my %ret = $test->("MESSAGES");
+is_deeply( \%ret, { MESSAGES => 0 },
+           "Asked for MESSAGES, got MESSAGES" );
+
+%ret = $test->(qw/MESSAGES UIDNEXT/);
+is_deeply( \%ret, { MESSAGES => 0, UIDNEXT => 1000 },
+           "Asked for MESSAGES and UIDNEXT, got both" );
+
+%ret = $test->(qw/MESSAGES UIDNEXT UNSEEN/);
+is_deeply( \%ret, { MESSAGES => 0, UIDNEXT => 1000, UNSEEN => 0 },
+           "Asked for MESSAGES, UIDNEXT and UNSEEN, got all" );
+
+$t->disconnect;
+
+done_testing;