U
    
W[n¤  ã                   @   sÖ  d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	 ddl
mZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZmZ ddlZddl Zddl!Zddl"Zddl#Zddl$ZG dd„ dej%ƒZ&G dd„ dej'j(ƒZ)G dd„ dƒZ*G dd„ dƒZ+G dd„ dej,ƒZ-G dd„ dej%ƒZ.G dd„ dej/ƒZ0G dd „ d ej1ƒZ2G d!d"„ d"ej%ƒZ3eej4ƒG d#d$„ d$ƒƒZ5G d%d&„ d&ƒZ6d'd(„ Z7G d)d*„ d*ej%ƒZ8G d+d,„ d,ej%ƒZ9G d-d.„ d.ƒZ:G d/d0„ d0ej%ƒZ;G d1d2„ d2ƒZ<d3Z=ej>e=e?d4Z@d5ZAej>eAe?d4ZBG d6d7„ d7e<ej%ƒZCG d8d9„ d9e<ej%ƒZDG d:d;„ d;e2ƒZEG d<d=„ d=eCƒZFG d>d?„ d?eDƒZGG d@dA„ dAe2ƒZHG dBdC„ dCeCƒZIG dDdE„ dEeDƒZJG dFdG„ dGej%ƒZKdS )Hz,
Test cases for Ltwisted.mail.pop3} module.
é    )Úprint_functionN)ÚOrderedDict)ÚBytesIO)Úimplementer)Úcred)Úinternet)Úmail)Údefer)Úpop3)Úloopback)Úfailure)Ú
intToBytes)ÚLineSendingProtocol)ÚunittestÚutilc                   @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )ÚUtilityTestszl
    Test the various helper functions and classes used by the POP3 server
    protocol implementation.
    c                 C   sº   g }t t ddddddg¡ƒ}t |j|d¡}t |ƒ}|  |g ¡ t|ƒ |  |g ¡ t|ƒ |  |g ¡ t|ƒ |  |dddg¡ tdƒD ]}t|ƒ qŒ|  |ddddddddg¡ d	S )
zº
        Test creating a LineBuffer and feeding it some lines.  The lines should
        build up in its internal buffer for a while and then get spat out to
        the writer.
        Z012Z345Ú6Ú7Ú8Ú9é   é   N)	ÚiterÚ	itertoolsÚcycler
   Ú_IteratorBufferÚextendÚassertEqualÚnextÚrange)ÚselfÚoutputÚinputÚcÚiÚn© r&   ú=/usr/lib/python3/dist-packages/twisted/mail/test/test_pop3.pyÚtest_LineBuffering+   s     
ÿzUtilityTests.test_LineBufferingc                 C   sB   g }t dddgƒ}t |j|d¡}|D ]}q&|  |dddg¡ dS )z„
        Test that a LineBuffer flushes everything when its iterator is
        exhausted, and itself raises StopIteration.
        ÚaÚbr#   r   N)r   r
   r   r   r   )r    r!   r"   r#   r$   r&   r&   r'   Útest_FinishLineBufferingB   s    z%UtilityTests.test_FinishLineBufferingc                 C   s   |   t d¡d¡ dS )zb
        Test that the thing that spits out POP3 'success responses' works
        right.
        s   Great.s   +OK Great.
N)r   r
   ZsuccessResponse©r    r&   r&   r'   Útest_SuccessResponseFormatterO   s    þz*UtilityTests.test_SuccessResponseFormatterc                 C   sH   t t g ¡ƒd }|  |d¡ t t ddddg¡ƒd }|  |d¡ dS )	zX
        Test that the function which formats stat lines does so appropriately.
        éÿÿÿÿs	   +OK 0 0
é
   é   r   iu'  s   +OK 4 10142
N)Úlistr
   ZformatStatResponser   )r    ZstatLiner&   r&   r'   Útest_StatLineFormatterY   s    z#UtilityTests.test_StatLineFormatterc              	   C   sP   t t g ¡ƒ}|  |ddg¡ t t ddddg¡ƒ}|  |ddd	d
ddg¡ dS )z}
        Test that the function which formats the lines in response to a LIST
        command does so appropriately.
        ó   +OK 0
ó   .
é   é   é   éd   s   +OK 4
s   1 1
s   2 2
s   3 3
s   4 100
N)r1   r
   ZformatListResponser   )r    Ú	listLinesr&   r&   r'   Útest_ListLineFormatterd   s    þ
ÿþz#UtilityTests.test_ListLineFormatterc                 C   sŠ   dddg}t t g |j¡ƒ}|  |ddg¡ t t dddg|j¡ƒ}|  |dd	d
ddg¡ t t dddg|j¡ƒ}|  |dd	ddg¡ dS )zy
        Test that the function which formats lines in response to a UIDL
        command does so appropriately.
        ÚabcÚdefZghis   +OK 
r4   é{   i¯  iO  s   1 abc
s   2 def
s   3 ghi
r   N)r1   r
   ZformatUIDListResponseÚ__getitem__r   )r    Zuidsr9   r&   r&   r'   Útest_UIDListLineFormatteru   s(    
þÿþÿ
þz&UtilityTests.test_UIDListLineFormatterN)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r(   r+   r-   r2   r:   r?   r&   r&   r&   r'   r   %   s   
r   c                   @   s   e Zd ZdZdZdd„ ZdS )ÚMyVirtualPOP3z2
    A virtual-domain-supporting POP3 server.
    ó   <moshez>c                 C   s(   |   |¡\}}| jjd  ||| j|¡S )a7  
        Authenticate against a user against a virtual domain.

        @param user: The username.
        @param digest: The digested password.

        @return: A three-tuple like the one returned by
            L{IRealm.requestAvatar}.  The mailbox will be for the user given
            by C{user}.
        ó   baz.com)ZlookupDomainÚserviceÚdomainsÚauthenticateUserAPOPÚmagic)r    ÚuserÚdigestÚdomainr&   r&   r'   rI   ”   s       ÿz"MyVirtualPOP3.authenticateUserAPOPN©r@   rA   rB   rC   rJ   rI   r&   r&   r&   r'   rD   Ž   s   rD   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚDummyDomainz-
    A virtual domain for a POP3 server.
    c                 C   s
   i | _ d S ©N©Úusersr,   r&   r&   r'   Ú__init__ª   s    zDummyDomain.__init__c                 C   s   g | j |< dS )zV
        Create a mailbox for a new user.

        @param name: The username.
        NrQ   )r    Únamer&   r&   r'   ÚaddUser®   s    zDummyDomain.addUserc                 C   s   | j |  |¡ dS )zš
        Add a message to the mailbox of the named user.

        @param name: The username.
        @param message: The contents of the message.
        N)rR   Úappend)r    rT   Úmessager&   r&   r'   Ú
addMessage·   s    zDummyDomain.addMessagec                 C   s   t jt| j| ƒdd„ fS )ae  
        Succeed with a L{ListMailbox}.

        @param name: The name of the user authenticating.
        @param digest: ignored
        @param magic: ignored
        @param domain: ignored

        @return: A three-tuple like the one returned by
            L{IRealm.requestAvatar}.  The mailbox will be for the user given
            by C{name}.
        c                   S   s   d S rP   r&   r&   r&   r&   r'   Ú<lambda>Î   ó    z2DummyDomain.authenticateUserAPOP.<locals>.<lambda>)r
   ÚIMailboxÚListMailboxrR   )r    rT   rL   rJ   rM   r&   r&   r'   rI   Á   s    z DummyDomain.authenticateUserAPOPN)r@   rA   rB   rC   rS   rU   rX   rI   r&   r&   r&   r'   rO   ¥   s
   	
rO   c                   @   sB   e Zd ZdZdd„ Zddd„Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dS )r\   z@
    A simple in-memory list implementation of L{IMailbox}.
    c                 C   s
   || _ dS )z,
        @param list: The messages.
        N©r1   )r    r1   r&   r&   r'   rS   Ö   s    zListMailbox.__init__Nc                 C   s&   |dkrdd„ | j D ƒS t| j | ƒS )ú™
        Get some message information.

        @param i: See L{pop3.IMailbox.listMessages}.
        @return: See L{pop3.IMailbox.listMessages}.
        Nc                 S   s   g | ]}t |ƒ‘qS r&   ©Úlen)Ú.0Úlr&   r&   r'   Ú
<listcomp>å   s     z,ListMailbox.listMessages.<locals>.<listcomp>)r1   r`   ©r    r$   r&   r&   r'   ÚlistMessagesÝ   s    zListMailbox.listMessagesc                 C   s   t | j| ƒS ©z
        Get the message content.

        @param i: See L{pop3.IMailbox.getMessage}.
        @return: See L{pop3.IMailbox.getMessage}.
        )r   r1   rd   r&   r&   r'   Ú
getMessageé   s    zListMailbox.getMessagec                 C   s   |S )z¡
        Construct a UID by using the given index value.

        @param i: See L{pop3.IMailbox.getUidl}.
        @return: See L{pop3.IMailbox.getUidl}.
        r&   rd   r&   r&   r'   ÚgetUidló   s    zListMailbox.getUidlc                 C   s   d| j |< dS ©zm
        Wipe the message at the given index.

        @param i: See L{pop3.IMailbox.deleteMessage}.
        rZ   Nr]   rd   r&   r&   r'   ÚdeleteMessageý   s    zListMailbox.deleteMessagec                 C   s   dS )z=
        No-op.

        @see: L{pop3.IMailbox.sync}
        Nr&   r,   r&   r&   r'   Úsync  s    zListMailbox.sync)N)
r@   rA   rB   rC   rS   re   rg   rh   rj   rk   r&   r&   r&   r'   r\   Ò   s   


	r\   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )ÚMyPOP3DownloaderzE
    A POP3 client which downloads all messages from the server.
    c                 C   s   t j | |¡ |  dd¡ dS )zK
        Authenticate.

        @param line: The welcome response.
        s   hello@baz.coms   worldN)r
   Ú
POP3ClientÚhandle_WELCOMEZapop©r    Úliner&   r&   r'   rn     s    zMyPOP3Downloader.handle_WELCOMEc                 C   s<   |  ¡ }|d }|dkr(td||f ƒ‚g | _|  d¡ dS )zc
        Require an I{OK} response to I{APOP}.

        @param line: The I{APOP} response.
        r   ó   +OKzcode is: %s , parts is: %s r5   N)ÚsplitÚAssertionErrorÚlinesZretr)r    rp   ÚpartsÚcoder&   r&   r'   Úhandle_APOP  s    zMyPOP3Downloader.handle_APOPc                 C   s   | j  |¡ dS )zh
        Record one line of message information.

        @param line: A I{RETR} response line.
        N)rt   rV   ro   r&   r&   r'   Úhandle_RETR_continue+  s    z%MyPOP3Downloader.handle_RETR_continuec                 C   s   d  | j¡d | _|  ¡  dS )z:
        Record the received message information.
        ó   
N)Újoinrt   rW   Úquitr,   r&   r&   r'   Úhandle_RETR_end4  s    z MyPOP3Downloader.handle_RETR_endc                 C   s    |dd… dkrt d| ƒ‚dS )zc
        Require an I{OK} response to I{QUIT}.

        @param line: The I{QUIT} response.
        Nr7   rq   s   code is )rs   ro   r&   r&   r'   Úhandle_QUIT<  s    zMyPOP3Downloader.handle_QUITN)	r@   rA   rB   rC   rn   rw   rx   r|   r}   r&   r&   r&   r'   rl     s   
	rl   c                   @   sX   e Zd ZdZdZdeeeƒƒ d Zdd„ Zdd„ Z	d	d
„ Z
ejddge
_dd„ ZdS )Ú	POP3Testsz!
    Tests for L{pop3.POP3}.
    s-   Subject: urgent

Someone set up us the bomb!
s>   +OK <moshez>
+OK Authentication succeeded
+OK 
1 0
.
+OK s;   
Subject: urgent

Someone set up us the bomb!
.
+OK 
c                 C   sN   t j ¡ | _i | j_tƒ | jjd< | jjd  d¡ | jjd  d| j¡ dS )zC
        Set up a POP3 server with virtual domain support.
        rF   s   helloN)	r   ÚprotocolÚFactoryÚfactoryrH   rO   rU   rX   rW   r,   r&   r&   r'   ÚsetUp`  s
    zPOP3Tests.setUpc                    s>   t ddddgƒ‰ tƒ }ˆj|_‡ ‡fdd„}t |ˆ ¡ |¡S )zL
        Messages can be downloaded over a loopback TCP connection.
        s   APOP hello@baz.com worldó   UIDLó   RETR 1ó   QUITc                    s"   d  ˆ j¡d }ˆ |ˆj¡ d S )Nó   
)rz   Úresponser   ÚexpectedOutput)Úignoredr!   ©Úclientr    r&   r'   Úcheckw  s    z&POP3Tests.test_messages.<locals>.check)r   rD   r   rG   r   ZloopbackTCPÚaddCallback)r    ÚserverrŒ   r&   rŠ   r'   Útest_messagesk  s    üzPOP3Tests.test_messagesc                    s:   t ƒ ‰ˆjˆ_tƒ ‰ ‡ ‡‡fdd„}t ˆˆ ¡}| |¡S )zH
        Messages can be downloaded over a loopback connection.
        c                    s(   ˆ  ˆ jˆj¡ ˆ t tdƒ¡¡ d S )NúTest harness disconnect)r   rW   ÚconnectionLostr   ÚFailureÚ	Exception)r‰   ©ZclientProtocolr   r    r&   r'   rŒ   „  s    ÿz&POP3Tests.test_loopback.<locals>.check)rD   r   rG   rl   r   ÚloopbackAsyncr   )r    rŒ   Údr&   r”   r'   Útest_loopback}  s    zPOP3Tests.test_loopbackz*twisted.mail.pop3.POP3Client is deprecated)rW   c                 C   sR   t j ¡ }i |_tƒ |jd< tƒ }||_|  tj	|j
dd¡}|  |jd d¡ dS )zP
        Look up a user in a domain which this server does not support.
        s   twistedmatrix.coms   nobody@baz.coms   passwordr   zno such domain baz.comN)r   r   r€   rH   rO   rD   rG   ZassertRaisesr
   Ú	POP3ErrorrI   r   Úargs)r    r   rŽ   Úexcr&   r&   r'   Útest_incorrectDomainŽ  s    
  ÿzPOP3Tests.test_incorrectDomainN)r@   rA   rB   rC   rW   r   r`   rˆ   r‚   r   r—   r   Úsuppressr›   r&   r&   r&   r'   r~   G  s   
úúÿ
r~   c                   @   s   e Zd ZdZdZdd„ ZdS )Ú	DummyPOP3zF
    A simple POP3 server with a hard-coded mailbox for any user.
    rE   c                 C   s   t jttƒdd„ fS )zÎ
        Succeed with a L{DummyMailbox}.

        @param user: ignored
        @param password: ignored

        @return: A three-tuple like the one returned by
            L{IRealm.requestAvatar}.
        c                   S   s   d S rP   r&   r&   r&   r&   r'   rY   ®  rZ   z0DummyPOP3.authenticateUserAPOP.<locals>.<lambda>)r
   r[   ÚDummyMailboxÚ
ValueError)r    rK   Zpasswordr&   r&   r'   rI   ¤  s    
zDummyPOP3.authenticateUserAPOPNrN   r&   r&   r&   r'   r   ž  s   r   c                   @   s@   e Zd ZdZdgZdd„ Zddd„Zdd	„ Zd
d„ Zdd„ Z	dS )rž   zý
    An in-memory L{pop3.IMailbox} implementation.

    @ivar messages: A sequence of L{bytes} defining the messages in this
        mailbox.

    @ivar exceptionType: The type of exception to raise when an out-of-bounds
        index is addressed.
    s,   From: moshe
To: moshe

How are you, friend?
c                 C   s   t jd d … | _|| _d S rP   )rž   ÚmessagesÚexceptionType)r    r¡   r&   r&   r'   rS   ¾  s    zDummyMailbox.__init__Nc                 C   s<   |dkrdd„ | j D ƒS |t| j ƒkr.|  ¡ ‚t| j | ƒS )r^   Nc                 S   s   g | ]}t |ƒ‘qS r&   r_   )ra   Úmr&   r&   r'   rc   Ë  s     z-DummyMailbox.listMessages.<locals>.<listcomp>)r    r`   r¡   rd   r&   r&   r'   re   Ã  s
    zDummyMailbox.listMessagesc                 C   s   t | j| ƒS rf   )r   r    rd   r&   r&   r'   rg   Ñ  s    zDummyMailbox.getMessagec                 C   s   |t | jƒkr|  ¡ ‚t|ƒS )zÇ
        Construct a UID which is simply the string representation of the given
        index.

        @param i: See L{pop3.IMailbox.getUidl}.
        @return: See L{pop3.IMailbox.getUidl}.
        )r`   r    r¡   r   rd   r&   r&   r'   rh   Û  s    zDummyMailbox.getUidlc                 C   s   d| j |< dS ri   )r    rd   r&   r&   r'   rj   è  s    zDummyMailbox.deleteMessage)N)
r@   rA   rB   rC   r    rS   re   rg   rh   rj   r&   r&   r&   r'   rž   ²  s   	

rž   c                   @   sh   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ ZdS )ÚAnotherPOP3Testsz(
    Additional L{pop3.POP3} tests.
    c                 C   s,   t ƒ }t|ƒ}t ||¡}| | j|||¡S )aÅ  
        Assert that when C{lines} are delivered to L{pop3.POP3} it responds
        with C{expectedOutput}.

        @param lines: A sequence of L{bytes} representing lines to deliver to
            the server.

        @param expectedOutput: A sequence of L{bytes} representing the
            expected response from the server.

        @return: A L{Deferred} that fires when the lines have been delivered
            and the output checked.
        )r   r   r   r•   r   Ú
_cbRunTest)r    rt   rˆ   Údummyr‹   r–   r&   r&   r'   ÚrunTestö  s    zAnotherPOP3Tests.runTestc                 C   s2   |   d |¡d |j¡¡ | t tdƒ¡¡ |S )Nr†   r   ©r   rz   r‡   r‘   r   r’   r“   ©r    r‰   r‹   r¥   rˆ   r&   r&   r'   r¤   
  s    
ÿÿzAnotherPOP3Tests._cbRunTestc                 C   s@   |   ddddddddgdd	d
dddddddddddddddg¡S )a4  
        Test a lot of different POP3 commands in an extremely pipelined
        scenario.

        This test may cover legitimate behavior, but the intent and
        granularity are not very good.  It would likely be an improvement to
        split it into a number of smaller, more focused tests.
        s   APOP moshez dummyó   LISTrƒ   r„   ó   RETR 2s   DELE 1r…   ó   +OK <moshez>ó   +OK Authentication succeededs   +OK 1s   1 44ó   .ó   +OK s   1 0s   +OK 44s   From: moshes	   To: mosherZ   s   How are you, friend?s    -ERR Bad message number arguments   -ERR message deleted©r¦   r,   r&   r&   r'   Útest_buffer  s<    	ùï÷zAnotherPOP3Tests.test_bufferc                 C   s   |   dddgddddg¡S )z)
        Test the no-op command.
        s   APOP spiv dummys   NOOPr…   r«   r¬   r®   r¯   r,   r&   r&   r'   Ú	test_noop8  s    þýüzAnotherPOP3Tests.test_noopc                 C   sH   t ƒ }tj ¡ |_ddddœ|j_tddgƒ}t ||¡}| 	| j
|¡S )zš
        L{pop3.POP3} responds to an I{AUTH} command with a list of supported
        authentication types based on its factory's C{challengers}.
        N)s   Auth1s
   secondAuths   authLasts   AUTHr…   )r   r   r   r€   r   Úchallengersr   r   r•   r   Ú_cbTestAuthListing)r    Úpr‹   r–   r&   r&   r'   Útest_authListingF  s    ÿ
þz!AnotherPOP3Tests.test_authListingc                 C   sL   |   |jd  d¡¡ |  t|jdd… ƒdddg¡ |  |jd d¡ d S )	Nr5   rq   r6   r   s   AUTH1s   AUTHLASTs
   SECONDAUTHr­   )Ú
assertTruer‡   Ú
startswithr   Úsorted)r    r‰   r‹   r&   r&   r'   r³   X  s
    ÿz#AnotherPOP3Tests._cbTestAuthListingc                 C   s.   t ƒ }tddgƒ}t ||¡}| | j||¡S )z‘
        L{pop3.POP3} handles a I{PASS} command before a I{USER} command with an
        error indicating the out-of-sequence operation.
        s	   PASS foozr…   )r   r   r   r•   r   Ú_cbTestIllegalPASS©r    r¥   r‹   r–   r&   r&   r'   Útest_illegalPASS_  s    þz!AnotherPOP3Tests.test_illegalPASSc                 C   s4   d}|   |d |j¡d ¡ | t tdƒ¡¡ d S ©Ns4   +OK <moshez>
-ERR USER required before PASS
+OK 
r†   r   r§   r¨   r&   r&   r'   r¹   m  s    ÿÿÿz#AnotherPOP3Tests._cbTestIllegalPASSc                 C   s.   t ƒ }tddgƒ}t ||¡}| | j||¡S )z|
        L{pop3.POP3} handles a I{PASS} command with a password equal to C{""}
        as it would any other value.
        s   PASS r…   )r   r   r   r•   r   Ú_cbTestEmptyPASSrº   r&   r&   r'   Útest_emptyPASSv  s    þzAnotherPOP3Tests.test_emptyPASSc                 C   s4   d}|   |d |j¡d ¡ | t tdƒ¡¡ d S r¼   r§   r¨   r&   r&   r'   r½   „  s    ÿÿÿz!AnotherPOP3Tests._cbTestEmptyPASSc                 C   sV   t dƒ}t|tƒs| d¡}|  ddgdd| dg¡}|  tj¡}|  t	|ƒd¡ |S )	zi
        Sending a command with invalid UTF-8 characters
        will raise a L{pop3.POP3Error}.
        s&   not authenticated yet: cannot do PASSzutf-8s   PASSr…   r«   s(   -ERR bad protocol or server: POP3Error: r®   r5   )
ÚstrÚ
isinstanceÚbytesÚencoder¦   ZflushLoggedErrorsr
   r˜   r   r`   )r    Úerrorr–   Úerrorsr&   r&   r'   Útest_badUTF8CharactersInCommand  s"    

ÿÿýýz0AnotherPOP3Tests.test_badUTF8CharactersInCommandN)r@   rA   rB   rC   r¦   r¤   r°   r±   rµ   r³   r»   r¹   r¾   r½   rÅ   r&   r&   r&   r'   r£   ò  s   &		r£   c                   @   sL   e Zd ZdZdd„ Zdd„ ZeddgƒZdd	„ Zd
Z	dd„ Z
d
Zdd„ ZdS )ÚTestServerFactoryz÷
    A L{pop3.IServerFactory} implementation, for use by the test suite, with
    some behavior controlled by the values of (settable) public attributes and
    other behavior based on values hard-coded both here and in some test
    methods.
    c                 C   s   dS )úW
        Return the hard-coded value.

        @return: L{pop3.IServerFactory}
        zTest Implementation Stringr&   r,   r&   r&   r'   Úcap_IMPLEMENTATIONª  s    z$TestServerFactory.cap_IMPLEMENTATIONc                 C   s   dS )rÇ   é<   r&   r,   r&   r&   r'   Ú
cap_EXPIRE³  s    zTestServerFactory.cap_EXPIRE)s   SCHEME_1N)s   SCHEME_2Nc                 C   s   dS )rÇ   éx   r&   r,   r&   r&   r'   Úcap_LOGIN_DELAY½  s    z!TestServerFactory.cap_LOGIN_DELAYTc                 C   s   | j S ©rÇ   )Úpuer,   r&   r&   r'   ÚperUserExpirationÆ  s    z#TestServerFactory.perUserExpirationc                 C   s   | j S rÍ   )Úpuldr,   r&   r&   r'   ÚperUserLoginDelayÏ  s    z#TestServerFactory.perUserLoginDelayN)r@   rA   rB   rC   rÈ   rÊ   r   r²   rÌ   rÎ   rÏ   rÐ   rÑ   r&   r&   r&   r'   rÆ   ¢  s   	rÆ   c                   @   s   e Zd ZdZdZdZdS )ÚTestMailboxz×
    An incomplete L{IMailbox} implementation with certain per-user values
    hard-coded and known by tests in this module.


    This is useful for testing the server's per-user capability
    implementation.
    r8   é   N)r@   rA   rB   rC   Z
loginDelayZmessageExpirationr&   r&   r&   r'   rÒ   Ù  s   rÒ   c                 G   s   |D ]}|   ||¡ qdS )aG  
    Assert that the given capability is included in all of the capability
    sets.

    @param testcase: A L{unittest.TestCase} to use to make assertions.

    @param s: The capability for which to check.
    @type s: L{bytes}

    @param caps: The capability sets in which to check.
    @type caps: L{tuple} of iterable
    N)ÚassertIn)ZtestcaseÚsÚcapsr#   r&   r&   r'   Ú	containedç  s    r×   c                   @   sP   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ ZdS )ÚCapabilityTestsz@
    Tests for L{pop3.POP3}'s per-user capability handling.
    c                 C   s–   t ƒ }t ¡ }tƒ |_tj |¡|_| 	¡  | 
¡  | ¡ | _| ¡  ¡ | _t ƒ }tƒ |_tj |¡|_| 
¡  | ¡  ¡ | _| t tdƒ¡¡ dS )ú>
        Create a POP3 server with some capabilities.
        r   N)r   r
   ÚPOP3rÆ   r   r   r   ÚFileWrapperÚ	transportÚconnectionMadeÚdo_CAPAÚlistCapabilitiesrÖ   ÚgetvalueÚ
splitlinesÚpcapsrÒ   ÚmboxÚlpcapsr‘   r   r’   r“   ©r    rÕ   r´   r&   r&   r'   r‚   ý  s    
zCapabilityTests.setUpc                 C   s   t | d| j| j| jƒ dS )zB
        The server can advertise the I{UIDL} capability.
        rƒ   N©r×   rÖ   râ   rä   r,   r&   r&   r'   Ú	test_UIDL  s    zCapabilityTests.test_UIDLc                 C   s   t | d| j| j| jƒ dS )zA
        The server can advertise the I{TOP} capability.
        s   TOPNræ   r,   r&   r&   r'   Útest_TOP  s    zCapabilityTests.test_TOPc                 C   s   t | d| j| j| jƒ dS )zB
        The server can advertise the I{USER} capability.
        s   USERNræ   r,   r&   r&   r'   Ú	test_USER"  s    zCapabilityTests.test_USERc                 C   s$   t | d| j| jƒ t | d| jƒ dS )zj
        The server can advertise its per-user expiration as well as a global
        expiration.
        s   EXPIRE 60 USERs	   EXPIRE 25Nræ   r,   r&   r&   r'   Útest_EXPIRE)  s    zCapabilityTests.test_EXPIREc                 C   s   t | d| j| j| jƒ dS )zE
        The server can advertise its implementation string.
        s)   IMPLEMENTATION Test Implementation StringNræ   r,   r&   r&   r'   Útest_IMPLEMENTATION2  s      ýz#CapabilityTests.test_IMPLEMENTATIONc                 C   s   t | d| j| j| jƒ dS )zH
        The server can advertise the SASL schemes it supports.
        s   SASL SCHEME_1 SCHEME_2Nræ   r,   r&   r&   r'   Ú	test_SASL=  s      ýzCapabilityTests.test_SASLc                 C   s$   t | d| j| jƒ |  d| j¡ dS )zc
        The can advertise a per-user login delay as well as a global login
        delay.
        s   LOGIN-DELAY 120 USERs   LOGIN-DELAY 100N)r×   rÖ   râ   rÔ   rä   r,   r&   r&   r'   Útest_LOGIN_DELAYH  s    z CapabilityTests.test_LOGIN_DELAYN)r@   rA   rB   rC   r‚   rç   rè   ré   rê   rë   rì   rí   r&   r&   r&   r'   rØ   ù  s   	rØ   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚGlobalCapabilitiesTestsz>
    Tests for L{pop3.POP3}'s global capability handling.
    c                 C   s¦   t ƒ }t ¡ }tƒ |_d |j_|j_tj 	|¡|_
| ¡  | ¡  | ¡ | _| ¡  ¡ | _t ƒ }tƒ |_tj 	|¡|_
| ¡  | ¡  ¡ | _| t tdƒ¡¡ dS )rÙ   Fr   N)r   r
   rÚ   rÆ   r   rÎ   rÐ   r   r   rÛ   rÜ   rÝ   rÞ   rß   rÖ   rà   rá   râ   rÒ   rã   rä   r‘   r   r’   r“   rå   r&   r&   r'   r‚   V  s    
zGlobalCapabilitiesTests.setUpc                 C   s   t | d| j| j| jƒ dS )zG
        I{EXPIRE} is in the server's advertised capabilities.
        s	   EXPIRE 60Nræ   r,   r&   r&   r'   rê   n  s    z#GlobalCapabilitiesTests.test_EXPIREc                 C   s   t | d| j| j| jƒ dS )zL
        I{LOGIN-DELAY} is in the server's advertised capabilities.
        s   LOGIN-DELAY 120Nræ   r,   r&   r&   r'   rí   u  s    z(GlobalCapabilitiesTests.test_LOGIN_DELAYN)r@   rA   rB   rC   r‚   rê   rí   r&   r&   r&   r'   rî   R  s   rî   c                   @   s   e Zd ZdZdd„ ZdS )Ú	TestRealmzI
    An L{IRealm} which knows about a single test account's mailbox.
    c                 G   s(   |dkrt jttƒdd„ fS ds$t‚dS )aE  
        Retrieve a mailbox for I{testuser} or fail.

        @param avatarId: See L{IRealm.requestAvatar}.
        @param mind: See L{IRealm.requestAvatar}.
        @param interfaces: See L{IRealm.requestAvatar}.

        @raises: L{AssertionError} when requesting an C{avatarId} other than
            I{testuser}.
        ó   testuserc                   S   s   d S rP   r&   r&   r&   r&   r'   rY     rZ   z)TestRealm.requestAvatar.<locals>.<lambda>FN)r
   r[   rž   rŸ   rs   )r    ZavatarIdZmindZ
interfacesr&   r&   r'   ÚrequestAvatar  s    zTestRealm.requestAvatarN)r@   rA   rB   rC   rñ   r&   r&   r&   r'   rï   }  s   rï   c                   @   s   e Zd ZdZdd„ ZdS )Ú	SASLTestsz7
    Tests for L{pop3.POP3}'s SASL implementation.
    c                 C   s0  t  ¡ }tƒ |_dtjji|j_tj 	t
ƒ ¡|_tj ¡ }| dd¡ |j |¡ tƒ }tj |¡|_| ¡  | d¡ |  | ¡  d¡dk¡ | d¡ | ¡  ¡ d d	d
… }t |¡}t d|¡ ¡  d¡}| t  d| ¡ !d¡¡ |  |j"¡ |  | ¡  ¡ d  d¡dk¡ | #t$ %t&dƒ¡¡ d
S )z
        A CRAM-MD5-based SASL login attempt succeeds if it uses a username and
        a hashed password known to the server's credentials checker.
        s   CRAM-MD5rð   s   testpasswords   CAPAs   SASL CRAM-MD5r   s   AUTH CRAM-MD5r.   r6   NÚasciis	   testuser ry   rq   r   )'r
   rÚ   rÆ   r   r   ZcredentialsZCramMD5Credentialsr²   ZportalZPortalrï   ZcheckersZ'InMemoryUsernamePasswordDatabaseDontUserU   ZregisterCheckerr   r   r   rÛ   rÜ   rÝ   ÚlineReceivedr¶   rà   Úfindrá   Úbase64ZdecodestringÚhmacZHMACZ	hexdigestrÂ   ZencodestringÚrstriprã   r‘   r   r’   r“   )r    r´   ZchrÕ   Zchalr‡   r&   r&   r'   Útest_ValidLogin–  s0    ÿ



ÿ zSASLTests.test_ValidLoginN)r@   rA   rB   rC   rù   r&   r&   r&   r'   rò   ’  s   rò   c                   @   sœ   e Zd ZdZdZdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%S )&ÚCommandMixinzI
    Tests for all the commands a POP3 server is allowed to receive.
    s1   From: guy
To: fellow

More message text for you.
c                 C   s\   t  ¡ }|  | j¡|_t|_|| _tƒ }t	j
 |¡|_| ¡  | d¡ | d¡ || _dS )zŽ
        Make a POP3 server protocol instance hooked up to a simple mailbox and
        a transport that buffers output to a BytesIO.
        r   N)r
   rÚ   ÚmailboxTyper¡   rã   r1   ZscheduleÚ
pop3Serverr   r   r   rÛ   rÜ   rÝ   ÚseekÚtruncateÚpop3Transport©r    r´   rÕ   r&   r&   r'   r‚   Å  s    

zCommandMixin.setUpc                 C   s   | j  t tdƒ¡¡ dS )zo
        Disconnect the server protocol so it can clean up anything it might
        need to clean up.
        r   N)rü   r‘   r   r’   r“   r,   r&   r&   r'   ÚtearDown×  s    
ÿzCommandMixin.tearDownc                 C   s   | j j ¡  dS )zz
        Do some of the things that the reactor would take care of, if the
        reactor were actually running.
        N)rü   rÜ   Z_checkProducerr,   r&   r&   r'   Ú_flushà  s    zCommandMixin._flushc                 C   sh   | j }| j}| d¡ |  ¡  |  | ¡ d¡ | d¡ | d¡ | d¡ |  ¡  |  | ¡ d¡ dS )zé
        Test the two forms of list: with a message index number, which should
        return a short-form response, and without a message index number, which
        should return a long-form response, one line per message.
        s   LIST 1ó
   +OK 1 44
r   r©   s   +OK 1
1 44
.
N©rü   rÿ   rô   r  r   rà   rý   rþ   r   r&   r&   r'   Ú	test_LISTé  s    



zCommandMixin.test_LISTc                 C   sš   | j }| j}| d¡ |  | ¡ d¡ | d¡ | d¡ | d¡ |  | ¡ d¡ | d¡ | d¡ | d¡ |  | ¡ d¡ | d¡ | d¡ dS )	zo
        Test that non-integers and out-of-bound integers produce appropriate
        error responses.
        s   LIST as    -ERR Invalid message-number: a
r   s   LIST 0s    -ERR Invalid message-number: 0
s   LIST 2s    -ERR Invalid message-number: 2
N©rü   rÿ   rô   r   rà   rý   rþ   r   r&   r&   r'   Útest_LISTWithBadArgumentý  s.    
þ


þ


þ
z%CommandMixin.test_LISTWithBadArgumentc                 C   s`   | j }| j}| d¡ |  | ¡ d¡ | d¡ | d¡ | d¡ |  ¡  |  | ¡ d¡ dS )zy
        Test the two forms of the UIDL command.  These are just like the two
        forms of the LIST command.
        s   UIDL 1r3   r   rƒ   s   +OK 
1 0
.
N)rü   rÿ   rô   r   rà   rý   rþ   r  r   r&   r&   r'   rç     s    



zCommandMixin.test_UIDLc                 C   sš   | j }| j}| d¡ |  | ¡ d¡ | d¡ | d¡ | d¡ |  | ¡ d¡ | d¡ | d¡ | d¡ |  | ¡ d¡ | d¡ | d¡ dS )z€
        Test that UIDL with a non-integer or an out-of-bounds integer produces
        the appropriate error response.
        s   UIDL aó"   -ERR Bad message number argument
r   s   UIDL 0s   UIDL 2Nr  r   r&   r&   r'   Útest_UIDLWithBadArgument-  s.    
þ


þ


þ
z%CommandMixin.test_UIDLWithBadArgumentc                 C   s2   | j }| j}| d¡ |  ¡  |  | ¡ d¡ dS )z¦
        Test the single form of the STAT command, which returns a short-form
        response of the number of messages in the mailbox and their total size.
        s   STATr  N)rü   rÿ   rô   r  r   rà   r   r&   r&   r'   Ú	test_STATK  s
    
zCommandMixin.test_STATc                 C   sF   | j }| j}| d¡ |  ¡  |  | ¡ d¡ | d¡ | d¡ dS )z-
        Test downloading a message.
        r„   s;   +OK 44
From: moshe
To: moshe

How are you, friend?
.
r   Nr  r   r&   r&   r'   Ú	test_RETRX  s    
þ
zCommandMixin.test_RETRc                 C   sš   | j }| j}| d¡ |  | ¡ d¡ | d¡ | d¡ | d¡ |  | ¡ d¡ | d¡ | d¡ | d¡ |  | ¡ d¡ | d¡ | d¡ dS )z»
        Test that trying to download a message with a bad argument, either not
        an integer or an out-of-bounds integer, fails with the appropriate
        error response.
        s   RETR ar  r   s   RETR 0rª   Nr  r   r&   r&   r'   Útest_RETRWithBadArgumentm  s.    
þ


þ


þ
z%CommandMixin.test_RETRWithBadArgumentc                 C   sB   | j }| j}|jj | j¡ | d¡ |  ¡  |  | 	¡ d¡ dS )zQ
        Test downloading the headers and part of the body of a message.
        s   TOP 1 0s9   +OK Top of message follows
From: moshe
To: moshe

.
N)
rü   rÿ   rã   r    rV   ÚextraMessagerô   r  r   rà   r   r&   r&   r'   rè   Œ  s    
þzCommandMixin.test_TOPc                 C   s  | j }| j}|jj | j¡ | d¡ |  | ¡ d¡ | 	d¡ | 
d¡ | d¡ |  | ¡ d¡ | 	d¡ | 
d¡ | d¡ |  | ¡ d¡ | 	d¡ | 
d¡ | d¡ |  | ¡ d¡ | 	d¡ | 
d¡ | d¡ |  | ¡ d¡ | 	d¡ | 
d¡ d	S )
a$  
        Test that trying to download a message with a bad argument, either a
        message number which isn't an integer or is an out-of-bounds integer or
        a number of lines which isn't an integer or is a negative integer,
        fails with the appropriate error response.
        s   TOP 1 as   -ERR Bad line count argument
r   s   TOP 1 -1s   TOP a 1r  s   TOP 0 1s   TOP 3 1N©rü   rÿ   rã   r    rV   r  rô   r   rà   rý   rþ   r   r&   r&   r'   Útest_TOPWithBadArgumentŸ  sL    
þ


þ


þ


þ


þ
z$CommandMixin.test_TOPWithBadArgumentc                 C   sN   | j }| j}|jj | j¡ | d¡ |  | ¡ d¡ | 	d¡ | 
d¡ dS )z“
        Test the exceedingly pointless LAST command, which tells you the
        highest message index which you have already downloaded.
        ó   LASTr3   r   Nr  r   r&   r&   r'   Ú	test_LASTÎ  s    
þ
zCommandMixin.test_LASTc                 C   st   | j }| j}|jj | j¡ | d¡ |  ¡  | d¡ | 	d¡ | d¡ |  
| ¡ d¡ | d¡ | 	d¡ dS )zM
        Test that issuing a RETR command updates the LAST response.
        rª   r   r  ó   +OK 2
N©rü   rÿ   rã   r    rV   r  rô   r  rý   rþ   r   rà   r   r&   r&   r'   Útest_RetrieveUpdatesHighestß  s    



þ
z(CommandMixin.test_RetrieveUpdatesHighestc                 C   s`   | j }| j}|jj | j¡ | d¡ |  ¡  | d¡ | 	d¡ | d¡ |  
| ¡ d¡ dS )zL
        Test that issuing a TOP command updates the LAST response.
        s   TOP 2 10r   r  r  Nr  r   r&   r&   r'   Útest_TopUpdatesHighestó  s    



þz#CommandMixin.test_TopUpdatesHighestc                 C   sr   | j }| j}|jj | j¡ | d¡ |  ¡  | d¡ |  ¡  | d¡ | 	d¡ | d¡ |  
| ¡ d¡ dS )z
        Test that downloading a message with a smaller index than the current
        LAST response doesn't change the LAST response.
        rª   s   TOP 1 10r   r  r  Nr  r   r&   r&   r'   Útest_HighestOnlyProgresses  s    




þz'CommandMixin.test_HighestOnlyProgressesc                 C   sj   | j }| j}|jj | j¡ | d¡ |  ¡  | d¡ | d¡ | 	d¡ | d¡ |  
| ¡ d¡ dS )zH
        Test that issuing RSET changes the LAST response to 0.
        rª   s   RSETr   r  r3   Nr  r   r&   r&   r'   Útest_ResetClearsHighest  s    




þz$CommandMixin.test_ResetClearsHighestN)r@   rA   rB   rC   r  r‚   r  r  r  r  rç   r	  r
  r  r  rè   r  r  r  r  r  r  r&   r&   r&   r'   rú   ¸  s&   		/rú   z}twisted.mail.pop3.IMailbox.listMessages may not raise IndexError for out-of-bounds message numbers: raise ValueError instead.)rW   Úcategoryzxtwisted.mail.pop3.IMailbox.getUidl may not raise IndexError for out-of-bounds message numbers: raise ValueError instead.c                   @   sX   e Zd ZdZeZeZdd„ Ze	ge_
dd„ Zege_
dd„ Ze	ge_
dd	„ Ze	ge_
d
S )ÚIndexErrorCommandTestsz»
    Run all of the command tests against a mailbox which raises IndexError
    when an out of bounds request is made.  This behavior will be deprecated
    shortly and then removed.
    c                 C   s
   t  | ¡S )z·
        An attempt to get metadata about a message with a bad argument fails
        with an I{ERR} response even if the mailbox implementation raises
        L{IndexError}.
        )rú   r  r,   r&   r&   r'   r  G  s    z/IndexErrorCommandTests.test_LISTWithBadArgumentc                 C   s
   t  | ¡S )z·
        An attempt to look up the UID of a message with a bad argument fails
        with an I{ERR} response even if the mailbox implementation raises
        L{IndexError}.
        )rú   r	  r,   r&   r&   r'   r	  Q  s    z/IndexErrorCommandTests.test_UIDLWithBadArgumentc                 C   s
   t  | ¡S )zµ
        An attempt to download some of a message with a bad argument fails with
        an I{ERR} response even if the mailbox implementation raises
        L{IndexError}.
        )rú   r  r,   r&   r&   r'   r  [  s    z.IndexErrorCommandTests.test_TOPWithBadArgumentc                 C   s
   t  | ¡S )z­
        An attempt to download a message with a bad argument fails with an
        I{ERR} response even if the mailbox implementation raises
        L{IndexError}.
        )rú   r  r,   r&   r&   r'   r  e  s    z/IndexErrorCommandTests.test_RETRWithBadArgumentN)r@   rA   rB   rC   Ú
IndexErrorr¡   rž   rû   r  Ú_listMessageSuppressionrœ   r	  Ú_getUidlSuppressionr  r  r&   r&   r&   r'   r  >  s   r  c                   @   s   e Zd ZdZeZeZdS )ÚValueErrorCommandTestsa  
    Run all of the command tests against a mailbox which raises ValueError
    when an out of bounds request is made.  This is the correct behavior and
    after support for mailboxes which raise IndexError is removed, this will
    become just C{CommandTestCase}.
    N)r@   rA   rB   rC   rŸ   r¡   rž   rû   r&   r&   r&   r'   r  p  s   r  c                   @   s   e Zd ZdZddd„ZdS )ÚSyncDeferredMailboxzo
    Mailbox which has a listMessages implementation which returns a Deferred
    which has already fired.
    Nc                 C   s   t  t | |¡¡S )zÏ
        Synchronously list messages.

        @type n: L{int} or L{None}
        @param n: The 0-based index of the message.

        @return: A L{Deferred} which already has a message list result.
        )r	   Zsucceedrž   re   )r    r%   r&   r&   r'   re     s    	z SyncDeferredMailbox.listMessages)N)r@   rA   rB   rC   re   r&   r&   r&   r'   r  |  s   r  c                   @   s   e Zd ZdZeZdS )Ú"IndexErrorSyncDeferredCommandTestsz{
    Run all of the L{IndexErrorCommandTests} tests with a
    synchronous-Deferred returning IMailbox implementation.
    N©r@   rA   rB   rC   r  rû   r&   r&   r&   r'   r  Ž  s   r  c                   @   s   e Zd ZdZeZdS )Ú"ValueErrorSyncDeferredCommandTestsz{
    Run all of the L{ValueErrorCommandTests} tests with a
    synchronous-Deferred returning IMailbox implementation.
    Nr   r&   r&   r&   r'   r!  —  s   r!  c                   @   s"   e Zd ZdZdd„ Zddd„ZdS )ÚAsyncDeferredMailboxzo
    Mailbox which has a listMessages implementation which returns a Deferred
    which has not yet fired.
    c                 O   s   g | _ tj| f|ž|Ž d S rP   )Úwaitingrž   rS   )r    r)   Úkwr&   r&   r'   rS   ¥  s    zAsyncDeferredMailbox.__init__Nc                 C   s$   t  ¡ }| j |t | |¡f¡ |S )zÎ
        Record a new unfired L{Deferred} in C{self.waiting} and return it.

        @type n: L{int} or L{None}
        @param n: The 0-based index of the message.

        @return: The L{Deferred}
        )r	   ZDeferredr#  rV   rž   re   )r    r%   r–   r&   r&   r'   re   ª  s    	z!AsyncDeferredMailbox.listMessages)N)r@   rA   rB   rC   rS   re   r&   r&   r&   r'   r"     s   r"  c                   @   s   e Zd ZdZeZdd„ ZdS )Ú#IndexErrorAsyncDeferredCommandTestsú}
    Run all of the L{IndexErrorCommandTests} tests with an
    asynchronous-Deferred returning IMailbox implementation.
    c                 C   s6   | j jjr(| j jj ¡ \}}| |¡ q t | ¡ dS ©zH
        Fire whatever Deferreds we've built up in our mailbox.
        N)rü   rã   r#  ÚpopÚcallbackr  r  ©r    r–   r)   r&   r&   r'   r  Á  s    
z*IndexErrorAsyncDeferredCommandTests._flushN©r@   rA   rB   rC   r"  rû   r  r&   r&   r&   r'   r%  º  s   r%  c                   @   s   e Zd ZdZeZdd„ ZdS )Ú#ValueErrorAsyncDeferredCommandTestsr&  c                 C   s6   | j jjr(| j jj ¡ \}}| |¡ q t | ¡ dS r'  )rü   rã   r#  r(  r)  r  r  r*  r&   r&   r'   r  Ó  s    
z*ValueErrorAsyncDeferredCommandTests._flushNr+  r&   r&   r&   r'   r,  Ì  s   r,  c                   @   s   e Zd ZdZdd„ ZdS )ÚPOP3MiscTestsz}
    Miscellaneous tests more to do with module/package structure than
    anything to do with the Post Office Protocol.
    c                 C   s(   t jj}|jD ]}|  t||ƒ¡ qdS )z
        This test checks that all names listed in
        twisted.mail.pop3.__all__ are actually present in the module.
        N)Útwistedr   r
   Ú__all__r¶   Úhasattr)r    ÚmodÚattrr&   r&   r'   Útest_allã  s    
zPOP3MiscTests.test_allN)r@   rA   rB   rC   r3  r&   r&   r&   r'   r-  Þ  s   r-  )LrC   Z
__future__r   r÷   rö   r   Úcollectionsr   Úior   Zzope.interfacer   r.  r   r   r   Ztwisted.internetr	   Ztwisted.mailr
   Ztwisted.protocolsr   Ztwisted.pythonr   Ztwisted.python.compatr   Ztwisted.test.proto_helpersr   Ztwisted.trialr   r   Ztwisted.cred.checkersZtwisted.cred.credentialsZtwisted.cred.portalZtwisted.internet.protocolZtwisted.mail.pop3Ztwisted.mail.protocolsZTestCaser   Z	protocolsZVirtualPOP3rD   rO   r\   rm   rl   r~   rÚ   r   ZMailboxrž   r£   ZIServerFactoryrÆ   rÒ   r×   rØ   rî   rï   rò   rú   Z_listMessageDeprecationrœ   ÚPendingDeprecationWarningr  Z_getUidlDeprecationr  r  r  r  r  r!  r"  r%  r,  r-  r&   r&   r&   r'   Ú<module>   s‚   i-=8W@ 16Y+&  yÿþÿþ2		