package org.apache.james.smtpserver.protocol.core;

import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.apache.james.smtpserver.protocol.LineHandler;
import org.apache.james.smtpserver.protocol.SMTPSession;
import org.apache.mailet.base.RFC2822Headers;
import org.apache.mailet.base.RFC822DateFormat;

public class ReceivedDataLineFilter implements DataLineFilter{

    private final static String SOFTWARE_TYPE = "JAMES SMTP Server ";
    	
    // Replace this with something usefull
    // + Constants.SOFTWARE_VERSION;  

    /**
     * Static RFC822DateFormat used to generate date headers
     */
    private final static RFC822DateFormat rfc822DateFormat = new RFC822DateFormat();
	private final static String HEADERS_WRITTEN = "HEADERS_WRITTEN";
	
	/**
	 * @see org.apache.james.smtpserver.protocol.core.DataLineFilter#onLine(org.apache.james.smtpserver.protocol.SMTPSession, byte[], org.apache.james.smtpserver.protocol.LineHandler)
	 */
	public void onLine(SMTPSession session, byte[] line, LineHandler next) {
		if (session.getState().containsKey(HEADERS_WRITTEN) == false) {
			addNewReceivedMailHeaders(session, next);
			session.getState().put(HEADERS_WRITTEN, true);
		} 
		next.onLine(session, line);
	}

 
    private void addNewReceivedMailHeaders(SMTPSession session, LineHandler next) {
        StringBuilder headerLineBuffer = new StringBuilder();
        
        String heloMode = (String) session.getConnectionState().get(SMTPSession.CURRENT_HELO_MODE);
        String heloName = (String) session.getConnectionState().get(SMTPSession.CURRENT_HELO_NAME);

        // Put our Received header first
        headerLineBuffer.append(RFC2822Headers.RECEIVED + ": from ")
                        .append(session.getRemoteHost());
        
        if (heloName != null) {
            headerLineBuffer.append(" (")
                            .append(heloMode)
                            .append(" ")
                            .append(heloName)
                            .append(") ");
        }
        
        headerLineBuffer.append(" ([")
                        .append(session.getRemoteIPAddress())
                        .append("])");
        
        next.onLine(session,headerLineBuffer.toString().getBytes());
        headerLineBuffer.delete(0, headerLineBuffer.length());
        
        headerLineBuffer.append("          by ")
                        .append(session.getHelloName())
                        .append(" (")
                        .append(SOFTWARE_TYPE)
                        .append(") with ");
     
        // Check if EHLO was used 
        if ("EHLO".equals(heloMode)) {
            // Not successful auth
            if (session.getUser() == null) {
                headerLineBuffer.append("ESMTP");  
            } else {
                // See RFC3848
                // The new keyword "ESMTPA" indicates the use of ESMTP when the SMTP
                // AUTH [3] extension is also used and authentication is successfully
                // achieved.
                headerLineBuffer.append("ESMTPA");
            }
        } else {
            headerLineBuffer.append("SMTP");
        }
        
        headerLineBuffer.append(" ID ")
                        .append(session.getSessionID());

        if (((Collection) session.getState().get(SMTPSession.RCPT_LIST)).size() == 1) {
            // Only indicate a recipient if they're the only recipient
            // (prevents email address harvesting and large headers in
            //  bulk email)
            
            next.onLine(session,headerLineBuffer.toString().getBytes());
            headerLineBuffer.delete(0, headerLineBuffer.length());
            
            headerLineBuffer.delete(0, headerLineBuffer.length());
            headerLineBuffer.append("          for <")
                            .append(((List) session.getState().get(SMTPSession.RCPT_LIST)).get(0).toString())
                            .append(">;");            
            
            next.onLine(session,headerLineBuffer.toString().getBytes());
            headerLineBuffer.delete(0, headerLineBuffer.length());
            
            headerLineBuffer.delete(0, headerLineBuffer.length());
        } else {
            // Put the ; on the end of the 'by' line
            headerLineBuffer.append(";");
            
            next.onLine(session,headerLineBuffer.toString().getBytes());
            headerLineBuffer.delete(0, headerLineBuffer.length());
        }
        headerLineBuffer = null;
        next.onLine(session,("          " + rfc822DateFormat.format(new Date())).getBytes());
    }
}

@@ -2246,17 +2246,16 @@
 nd(%22%5D)%22)
-;
 %0D%0A      
@@ -2248,32 +2248,52 @@
 (%22%5D)%22)%0D%0A        
+%09%09%09%09.append(%22%5Cr%5Cn%22);
 %0D%0A        next.o
@@ -3651,36 +3651,65 @@
 email)%0D%0A        
-    
+%09headerLineBuffer.append(%22%5Cr%5Cn%22);
 %0D%0A            ne
@@ -4130,21 +4130,54 @@
 %3E;%22)
-;            
+%0D%0A                            .append(%22%5Cr%5Cn%22);
 %0D%0A  
@@ -4531,32 +4531,64 @@
 );%0D%0A            
+headerLineBuffer.append(%22%5Cr%5Cn%22);
 %0D%0A            ne
@@ -4760,16 +4760,16 @@
  null;%0D%0A
-
         
@@ -4839,16 +4839,25 @@
  Date())
+ + %22%5Cr%5Cn%22
 ).getByt

Add \r\n in the headers..