/*****************************************************************
JADE - Java Agent DEvelopment Framework is a framework to develop
multi-agent systems in compliance with the FIPA specifications.
Copyright (C) 2000 CSELT S.p.A.

The updating of this file to JADE 2.0 has been partially supported by the
IST-1999-10211 LEAP Project

This file refers to parts of the FIPA 99/00 Agent Message Transport
Implementation Copyright (C) 2000, Laboratoire d'Intelligence
Artificielle, Ecole Polytechnique Federale de Lausanne

GNU Lesser General Public License

This library is free software; you can redistribute it sand/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation,
version 2.1 of the License.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA  02111-1307, USA.
*****************************************************************/

/**
 * XMLCodec.java
 *
 *
 * @author Jose Antonio Exposito
 * @author MARISM-A Development group ( marisma-info@ccd.uab.es )
 * @version 0.1
 * @author Nicolas Lhuillier
 * @author Joan Ametller
 * @version 1.0
 */


package jade.mtp.http;

import java.io.*;
//import java.net.*;

import jade.util.leap.Iterator;

import jade.mtp.MTPException;
import jade.domain.FIPAAgentManagement.Envelope;
import jade.domain.FIPAAgentManagement.ReceivedObject;
import jade.domain.FIPAAgentManagement.Property;
import jade.core.AID;
import jade.util.Logger;

//#DOTNET_EXCLUDE_BEGIN
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
//#DOTNET_EXCLUDE_END

import org.apache.commons.codec.binary.Base64;

/*#DOTNET_INCLUDE_BEGIN
import System.Xml.*;
import System.Collections.ArrayList;
#DOTNET_INCLUDE_END*/


public class XMLCodec extends DefaultHandler 
{
    
  // Constants
  public final static String PREAMBUL = "<?xml version=\"1.0\"?>\n";
  public final static String ENVELOPE_TAG = "envelope";
  public final static String PARAMS_TAG = "params";
  public final static String INDEX = "index";
  public final static String INDEX_ATTR = " index=\"";
  public final static String TO_TAG = "to";
  public final static String AID_TAG = "agent-identifier";
  public final static String AID_NAME = "name";
  public final static String AID_ADDRESSES = "addresses";
  public final static String AID_ADDRESS = "url";
  public final static String FROM_TAG = "from";
  public final static String COMMENTS_TAG = "comments";
  public final static String REPRESENTATION_TAG = "acl-representation";
  public final static String LENGTH_TAG = "payload-length";
  public final static String ENCODING_TAG = "payload-encoding";
  public final static String DATE_TAG = "date";
  //public final static String ENCRYPTED_TAG = "encrypted";
  public final static String INTENDED_TAG = "intended-receiver"; 
  public final static String RECEIVED_TAG = "received";
  public final static String RECEIVED_DATE = "received-date"; 
  public final static String RECEIVED_BY = "received-by";
  public final static String RECEIVED_FROM = "received-from"; 
  public final static String RECEIVED_ID = "received-id"; 
  public final static String RECEIVED_VIA = "received-via";
  public final static String RECEIVED_ATTR = "value";
  public final static String PROP_TAG = "user-defined";
  public final static String PROP_ATTR = "href";
  public final static String PROP_ATTR_TYPE = "type";
  public final static String PROP_STRING_TYPE ="string";
  public final static String PROP_BYTE_TYPE="byte-array";
  public final static String PROP_SER_TYPE="serialized";
  public final static String OT = "<";
  public final static String ET = "</";
  public final static String CT = ">";
  public final static String NULL = "";
  
	/*#DOTNET_INCLUDE_BEGIN
	public final static char[] badChars  = { '\r', '\n', ' ' };
	public final static String CHARS_CODEC = "ISO-8859-1";
	#DOTNET_INCLUDE_END*/

	//#DOTNET_EXCLUDE_BEGIN
	private XMLReader		 parser	= null;
	//#DOTNET_EXCLUDE_END
	/*#DOTNET_INCLUDE_BEGIN
	private XmlTextReader  parser = null;
	#DOTNET_INCLUDE_END*/

  private Envelope       env = null;
  private ReceivedObject ro  = null;
  private AID            aid = null;
  private Property       prop = null;
  // Accumulate parsed text
  private StringBuffer   accumulator;
  private String         propType;  
  //logging
  private static Logger logger = Logger.getMyLogger(XMLCodec.class.getName());

  //var for detected tag to then origin=0, or tag from then origin=1
  //private int origin;

  
	/*#DOTNET_INCLUDE_BEGIN
	 //To XML reading
	 private boolean found			= false;
	 private String aidStr			= "";
	 private String addressStr		= "";
	 private String mts			= "";
	 private ReceivedObject recObj = null;
	 private int diffInPayLoad		= 0;
	 #DOTNET_INCLUDE_END*/
  

	//#DOTNET_EXCLUDE_BEGIN
	/**
	 * Constructor:
	 * @param parserClass the SAX parser class to use
	 */
  public XMLCodec(String parserClass) throws MTPException {
    try{ 
			parser = (XMLReader)Class.forName(parserClass).newInstance();
			parser.setContentHandler(this);
			parser.setErrorHandler(this);
		}
    catch(Exception e) {
			throw new MTPException(e.toString());
		}
	}
	//#DOTNET_EXCLUDE_END

	/*#DOTNET_INCLUDE_BEGIN
	 //Constructor:
	 //For dotnet is used the System.Xml.XmlTextReader parser.
	 //Nothing to do in the constructor
	public XMLCodec() throws MTPException {}
	#DOTNET_INCLUDE_END*/
  
  // ***************************************************
  // *               Encoding methods                  *
  // ***************************************************

  /** Encode the information of Agent, Tags To and From **/ 
  private static void encodeAid(StringBuffer sb, AID aid) {
    sb.append(OT).append(AID_TAG).append(CT);
    encodeTag(sb,AID_NAME,aid.getName());
    sb.append(OT).append(AID_ADDRESSES).append(CT);
    
    String[] addresses = aid.getAddressesArray();
    for (int i=0; i<addresses.length ; i++) {
      encodeTag(sb,AID_ADDRESS,addresses[i]);
    }
    sb.append(ET).append(AID_ADDRESSES).append(CT);
    sb.append(ET).append(AID_TAG).append(CT);
  }       

  /**
   * This does the following:
   * < tag >
   * content
   * </ tag >
   */
  private static void encodeTag(StringBuffer sb, String tag, String content) {
    sb.append(OT).append(tag).append(CT);
    sb.append(content);
    sb.append(ET).append(tag).append(CT);
  }
  
  /** 
   * A user-defined property (String name, Object value) is encoded the following way:
   * <user-defined href="name" type="type">value</user-defined>
   * 
   */
  private static void encodeProp(StringBuffer sb, Property p) {
    String v = null;
    Object o = p.getValue();
    String type = PROP_STRING_TYPE;
    if (o instanceof String) {
      v = (String)o;
    }
    else if (o instanceof byte[]) {
      type = PROP_BYTE_TYPE;
      try {
		v = new String(Base64.encodeBase64((byte[])o), "US-ASCII");
	} catch (UnsupportedEncodingException e) {
		e.printStackTrace();
	}
    }
    else if (o instanceof Serializable) {
      type = PROP_SER_TYPE;
      try{
	  ByteArrayOutputStream bos = new ByteArrayOutputStream();
	  ObjectOutputStream oos = new ObjectOutputStream(bos);
	  oos.writeObject(o);
	  oos.close();
	  byte[] bytes = bos.toByteArray();
	  if(bytes != null)
	      v = new String(Base64.encodeBase64(bytes), "US-ASCII");
      }catch(IOException ioe){
	  return;
      }
    }
    else {
      return;
    }
    sb.append(OT).append(PROP_TAG).append(" ");
    sb.append(PROP_ATTR).append("=\"").append(p.getName()).append("\" ");
    sb.append(PROP_ATTR_TYPE).append("=\"").append(type).append("\"");
    sb.append(CT);
    sb.append(v);
    sb.append(ET).append(PROP_TAG).append(CT);
  }

  private void decodeProp(StringBuffer acc, Property p) {
    if(propType.equals(PROP_SER_TYPE)){
      try{
        byte[] serdata = acc.toString().getBytes("US-ASCII");
        ObjectInputStream ois = new ObjectInputStream( 
          new ByteArrayInputStream(Base64.decodeBase64(serdata)));
        p.setValue((Serializable)ois.readObject());
      }catch(Exception e){
	  // nothing, we leave value of this property as null;
      }
    }else if(propType.equals(PROP_BYTE_TYPE)){
      byte[] bytes=null;
	try {
		bytes = acc.toString().getBytes("US-ASCII");
	} catch (UnsupportedEncodingException e) {
		e.printStackTrace();
	}
      p.setValue(Base64.decodeBase64(bytes));
    }else{
      p.setValue(acc.toString());
    }
    propType = null;
  }

  private static void encodeOneLineTag(StringBuffer sb, String tag1, String tag2, String value) {
    sb.append(OT).append(tag1).append(" ");
    sb.append(tag2).append("=\"").append(value).append("\"/>"); 
  }
  
  /** General Encoding of the envelope */ 
  public static synchronized String encodeXML(Envelope env)  {
     
    //Create the message XML
    StringBuffer sb = new StringBuffer(PREAMBUL);
    sb.append(OT).append(ENVELOPE_TAG).append(CT);
    sb.append(OT).append(PARAMS_TAG).append(INDEX_ATTR).append(1).append("\"").append(CT);
    
    //Create tag TO
    Iterator i;
    for (i=env.getAllTo(); i.hasNext(); ) {
      sb.append(OT).append(TO_TAG).append(CT);
      encodeAid(sb,(AID)i.next());
      sb.append(ET).append(TO_TAG).append(CT);
    }		
    
	  //Create tag from	     
	  if (env.getFrom() != null) {
      sb.append(OT).append(FROM_TAG).append(CT);
      encodeAid(sb,env.getFrom());
      sb.append(ET).append(FROM_TAG).append(CT);
	  }
    
    //Create tag comments
    if ((env.getComments() != null) && 
        (env.getComments().length() > 0)) {
      encodeTag(sb,COMMENTS_TAG,env.getComments());
    }
    
    //Create tag acl-representation
    if (env.getAclRepresentation() != null) {
      encodeTag(sb,REPRESENTATION_TAG,env.getAclRepresentation());
    }
    
    //Create tag payload-length
    if (env.getPayloadLength() != null) {
      //System.out.println("Length: "+env.getPayloadLength());
      encodeTag(sb,LENGTH_TAG,String.valueOf(env.getPayloadLength()));
    }
    
    //Create tag payload-encoding
    if ((env.getPayloadEncoding() != null) && 
        (env.getPayloadEncoding().length() > 0)) { 
      encodeTag(sb,ENCODING_TAG,env.getPayloadEncoding());
    }
    
    //Create tag date
    //Create object BAsicFipaDateTime
    BasicFipaDateTime date = new BasicFipaDateTime(env.getDate());
    if( date != null ) {
      encodeTag(sb,DATE_TAG,date.toString());
    }
    
    //Create tag encrypted (NL: not sure it is still in FIPA)
    /*
      for (i=env.getAllEncrypted();i.hasNext();) {
      encodeTag(sb,ENCRYPTED_TAG,i.next().toString());  
      }
    */
    
	  //Create tag intended-receiver
    for (i = env.getAllIntendedReceiver();i.hasNext();) {
      sb.append(OT).append(INTENDED_TAG).append(CT);
      encodeAid(sb,(AID)i.next());
      sb.append(ET).append(INTENDED_TAG).append(CT);
    }
	  
    //Create tags for user properties
    for (i=env.getAllProperties();i.hasNext();) {
      encodeProp(sb,(Property)i.next());
    }

    //Create tag received
    ReceivedObject ro = env.getReceived();
    if (ro != null) {
      //Create tag received
      sb.append(OT).append(RECEIVED_TAG).append(CT); 
      //Date  
      String value = new BasicFipaDateTime(ro.getDate()).toString();
      if (value != null) {
        encodeOneLineTag(sb, RECEIVED_DATE,RECEIVED_ATTR,value);
      }	
      //By
      if (((value=ro.getBy()) != null)&&(!value.equals(NULL))) {
        encodeOneLineTag(sb, RECEIVED_BY,RECEIVED_ATTR,value);
      }
      //From
      if (((value=ro.getFrom()) != null)&&(!value.equals(NULL))) {
        encodeOneLineTag(sb, RECEIVED_FROM,RECEIVED_ATTR,value);
      }
      //Id
      if (((value=ro.getId()) != null)&&(!value.equals(NULL))) {
        encodeOneLineTag(sb, RECEIVED_ID,RECEIVED_ATTR,value);
      }
      //Via
      if (((value=ro.getVia()) != null)&&(!value.equals(NULL))) {
        encodeOneLineTag(sb, RECEIVED_VIA,RECEIVED_ATTR,value);
      }
      sb.append(ET).append(RECEIVED_TAG).append(CT); 
	  }
    sb.append(ET).append(PARAMS_TAG).append(CT); 
    sb.append(ET).append(ENVELOPE_TAG).append(CT); 
    
    return sb.toString();
  }
	
  // ***************************************************
  // *               Decoding methods                  *
  // ***************************************************
   
    /** This method is called when start the document XML*/
  public void startDocument() {
    env = new Envelope();
  }
  
  /** This method is called at the end of parsing */
  public void endDocument() {
    
    //Put the ro object in to envelope
    //env.setReceived(ro);
  }

  /** This method is called when jmp event of begin element.*/   
  public void startElement(String uri, String localName, String rawName, Attributes attributes) { 
    //Detection of the begin of to or from tags
    
    //Update the acumulator
    accumulator = new StringBuffer();
    
    if (TO_TAG.equalsIgnoreCase(localName))  {
      aid = new AID();
      env.addTo(aid);
    }
    else if (FROM_TAG.equalsIgnoreCase(localName))  {
      aid = new AID();
      env.setFrom(aid);
    }
    else if (INTENDED_TAG.equalsIgnoreCase(localName))  {
      aid = new AID();
      env.addIntendedReceiver(aid);
    } 
    else if (RECEIVED_TAG.equalsIgnoreCase(localName))  {
      ro = new ReceivedObject();
      env.addStamp(ro);
    }
    else if (RECEIVED_BY.equalsIgnoreCase(localName))  {
      ro.setBy(attributes.getValue(RECEIVED_ATTR));
    }
    else if (RECEIVED_FROM.equalsIgnoreCase(localName))  {
      ro.setFrom(attributes.getValue(RECEIVED_ATTR));
    }
    else if (RECEIVED_DATE.equalsIgnoreCase(localName))  {
      ro.setDate(new BasicFipaDateTime(attributes.getValue(RECEIVED_ATTR)).getTime());
    }
    else if (RECEIVED_ID.equalsIgnoreCase(localName))  {
      ro.setId(attributes.getValue(RECEIVED_ATTR));
    }
    else if (RECEIVED_VIA.equalsIgnoreCase(localName))  {
      ro.setVia(attributes.getValue(RECEIVED_ATTR));
    } 
    else if (PROP_TAG.equalsIgnoreCase(localName)) {
      prop = new Property();
      env.addProperties(prop); 
      prop.setName(attributes.getValue(PROP_ATTR));
      propType = attributes.getValue(PROP_ATTR_TYPE);
    }
  }
  
  /** This method is called the end of element */  
  public void endElement(String namespaceURL, String localName, String qname) { 
    
    //Capture the value the attributes of class
    if (AID_NAME.equalsIgnoreCase(localName)) {
      aid.setName(accumulator.toString());
    }
    else if (AID_ADDRESS.equalsIgnoreCase(localName)) {
      aid.addAddresses(accumulator.toString());
    }
    else if (COMMENTS_TAG.equalsIgnoreCase(localName)) {
      env.setComments(accumulator.toString());
    }
    else if (REPRESENTATION_TAG.equalsIgnoreCase(localName)) {
      env.setAclRepresentation(accumulator.toString());
    }
    else if (LENGTH_TAG.equalsIgnoreCase(localName)) {
      env.setPayloadLength(new Long(accumulator.toString()));
      if(logger.isLoggable(Logger.WARNING))
      	logger.log(Logger.FINE,"Length: "+env.getPayloadLength());
    }
    else if (ENCODING_TAG.equalsIgnoreCase(localName)) {
      env.setPayloadEncoding(accumulator.toString());
    }
    else if (DATE_TAG.equalsIgnoreCase(localName)) {
      env.setDate(new BasicFipaDateTime(accumulator.toString()).getTime());
    }
    else if (PROP_TAG.equalsIgnoreCase(localName)) {
      decodeProp(accumulator, prop);
      //prop.setValue(accumulator.toString());
    }
    /* 
       // Not sure it is still in FIPA
       else if (ENCRYPTED_TAG.equalsIgnoreCase(localName)) {
       env.addEncrypted(accumulator.toString());
       }
    */
  }
  
  /** This method is called when exist characters in the elements*/      
  public void characters(char[] buffer, int start, int length) {
    accumulator.append(buffer, start, length);
  }
  
  /** This method is called when warning occur*/  
  //#DOTNET_EXCLUDE_BEGIN
  public void warning(SAXParseException exception) {
  //#DOTNET_EXCLUDE_END
  /*#DOTNET_INCLUDE_BEGIN
  public void warning(ParseException exception) {
  #DOTNET_INCLUDE_END*/
    if(logger.isLoggable(Logger.WARNING))
		//#DOTNET_EXCLUDE_BEGIN
    	logger.log(Logger.WARNING," line " + exception.getLineNumber() + ": "+
                       exception.getMessage());
	    //#DOTNET_EXCLUDE_END
	    /*#DOTNET_INCLUDE_BEGIN
    	logger.log(Logger.WARNING," line " + exception.getError() + ": " +
	                    exception.get_Message());
		#DOTNET_INCLUDE_END*/
  }
  
  /** This method is called when errors occur*/ 
  //#DOTNET_EXCLUDE_BEGIN
  public void error(SAXParseException exception) {
  //#DOTNET_EXCLUDE_END
  /*#DOTNET_INCLUDE_BEGIN
  public void error(ParseException exception) {
  #DOTNET_INCLUDE_END*/
    if(logger.isLoggable(Logger.WARNING))
		//#DOTNET_EXCLUDE_BEGIN
		logger.log(Logger.WARNING,"ERROR: line " + exception.getLineNumber() + ": " +
			exception.getMessage());
	  //#DOTNET_EXCLUDE_END
	  /*#DOTNET_INCLUDE_BEGIN
	   logger.log(Logger.WARNING,"ERROR: line " + exception.getError() + ": " +
	   exception.get_Message());
	   #DOTNET_INCLUDE_END*/
  }
  
  /** This method is called when non-recoverable errors occur.*/ 
  //#DOTNET_EXCLUDE_BEGIN
  public void fatalError(SAXParseException exception) throws SAXException{
  //#DOTNET_EXCLUDE_END
  /*#DOTNET_INCLUDE_BEGIN
  public void fatalError(ParseException exception) {
  #DOTNET_INCLUDE_END*/

    if(logger.isLoggable(Logger.WARNING))
		//#DOTNET_EXCLUDE_BEGIN
		logger.log(Logger.SEVERE,"FATAL: line " + exception.getLineNumber() + ": " +
			exception.getMessage());
      throw exception;
	  //#DOTNET_EXCLUDE_END
	  /*#DOTNET_INCLUDE_BEGIN
	   logger.log(Logger.SEVERE,"FATAL: line " + exception.getError() + ": " +
			exception.get_Message());
	   #DOTNET_INCLUDE_END*/
  }
  
	//#DOTNET_EXCLUDE_BEGIN
	// Main method
	public Envelope parse(Reader in) throws MTPException 
	{
		try 
		{ 
			parser.parse(new InputSource(in));
			return env;
		}
    catch (Exception ex) {
			throw new MTPException(ex.getMessage());
		}
	}
	//#DOTNET_EXCLUDE_END
  
	/*#DOTNET_INCLUDE_BEGIN
    // Main method
	public Envelope parse(System.IO.TextReader in) throws MTPException 
	{
		try
		{
			//Inizialization of variables used
			ArrayList elemList	= new ArrayList();
			String textStr		= "";
			env				= new Envelope();
			recObj			= new ReceivedObject();
			parser			= new XmlTextReader(in);

			while ( parser.Read() )
			{
				XmlNodeType myNType = parser.get_NodeType();
				if (myNType.Equals( XmlNodeType.Element ))
				{
					elemList.Add( parser.get_Name() );
					if ( parser.get_HasAttributes() )
					{
						while( parser.MoveToNextAttribute() )
						{
							compare	(parser.get_Name(), parser.get_Value());
						}//End WHILE block
					}//End IF block
					parser.MoveToElement();
				}
				else if (myNType.Equals( XmlNodeType.Text ))
				{
					textStr = parser.ReadString();

					int counter = elemList.get_Count()-1;
					found = false;
					while (counter >= 0 && !found)
					{
						compare(elemList.get_Item(counter).ToString(), textStr);
						counter--;
					}
					if (counter < 0)
						//Console.WriteLine("ERRORE");
						System.out.println("ERRORE");
					else
					{
						found = false;
						elemList.RemoveAt(elemList.get_Count()-1);
					}

				}
				else if ( myNType.Equals( XmlNodeType.EndElement ) )
				{
					int idx = elemList.LastIndexOf(parser.get_Name());
					elemList.RemoveAt(idx);
					if (elemList.get_Count() > 0)
						compare(elemList.get_Item(elemList.get_Count()-1).ToString(), "");
				}
			}//End WHILE block
			parser.Close();
		}
		catch (XmlException e)
		{
			env = new Envelope();
			throw new MTPException("Exception during parsing XML file.\nNested exception is: "+e.get_Message());
		}
		finally
		{
			return env;
		}
	}
	
	public void compare(String s, String r) throws MTPException
	{
		try 
		{
			this.found = true;
			if (s.equalsIgnoreCase(this.AID_NAME))
			{
				aidStr = r.Trim(badChars);
			}
			else if (s.equalsIgnoreCase(this.TO_TAG))
			{
				//aidStr = convertHostname(aidStr);
				AID newAID = new AID(aidStr, AID.ISGUID);
				newAID.addAddresses( addressStr );
				env.addTo( newAID );
				//reset values
				aidStr = "";
				addressStr = "";
			}
			else if (s.equalsIgnoreCase(this.FROM_TAG))
			{
				AID newAID = new AID(aidStr, AID.ISGUID);
				newAID.addAddresses( addressStr );
				env.setFrom( newAID );
				//reset values
				aidStr = "";
				addressStr = "";
			}
			else if (s.equalsIgnoreCase(this.AID_ADDRESS))
			{
				if (r != "")
					addressStr = r.Trim(badChars);
			}
			else if (s.equalsIgnoreCase(this.AID_ADDRESSES))
			{
				if (r != "")
					addressStr = r.Trim(badChars);
			}
			else if (s.equalsIgnoreCase(this.REPRESENTATION_TAG))
			{
				String aclStr = r.Trim(badChars);
				env.setAclRepresentation( aclStr );
			}
			else if (s.equalsIgnoreCase(this.DATE_TAG))
			{
				String dateStr = r.Trim(badChars);
				BasicFipaDateTime bfdt = new BasicFipaDateTime(dateStr);
				env.setDate( bfdt.getTime() );
			}
			else if (s.equalsIgnoreCase(this.INTENDED_TAG))
			{
				//aidStr = convertHostname(aidStr);
				AID newAID = new AID(aidStr, AID.ISGUID);
				newAID.addAddresses( addressStr );
				env.addIntendedReceiver( newAID );
				//reset values
				aidStr = "";
				addressStr = "";
			}
			else if (s.equalsIgnoreCase(this.ENCODING_TAG))
			{
				String payStr = r.Trim(badChars);
				env.setPayloadEncoding( payStr );
			}
			else if (s.equalsIgnoreCase(this.LENGTH_TAG))
			{
				String payStr = r.Trim(badChars);
				env.setPayloadLength( new java.lang.Long(payStr) );
			}
			else if (s.equalsIgnoreCase(this.COMMENTS_TAG))
			{
				String cmtStr = r.Trim(badChars);
				env.setComments( cmtStr );
			}
			else if (s.equalsIgnoreCase(this.RECEIVED_TAG))
			{
				env.setReceived( recObj );
			}
			else if (s.equalsIgnoreCase(this.RECEIVED_VIA))
			{
				String via = r.Trim(badChars);
				recObj.setVia( via );
			}
			else if (s.equalsIgnoreCase(this.RECEIVED_BY))
			{
				String mts = r.Trim(badChars);
				recObj.setBy( mts );
			}
			else if (s.equalsIgnoreCase(this.RECEIVED_DATE))
			{
				String aDate = r.Trim(badChars);
				BasicFipaDateTime bfdt = new BasicFipaDateTime(aDate);
				recObj.setDate( bfdt.getTime() );
			}
			else if (s.equalsIgnoreCase(this.RECEIVED_FROM))
			{
				String from = r.Trim(badChars);
				recObj.setFrom( from );
			}
			else if (s.equalsIgnoreCase(this.RECEIVED_ID))
			{
				String id = r.Trim(badChars);
				recObj.setId( id );
			}
			else if (s.equalsIgnoreCase(this.INDEX))
			{
				String index = r.Trim(badChars);
				Property prop = new Property();
				prop.setName(s);
				prop.setValue(index);
				env.addProperties( prop );
			}
			else
				found = false;
		}
		catch (Exception e)
		{
			throw new MTPException("Error during tags comparison");
		}
	}
	#DOTNET_INCLUDE_END*/

}//End of XMLCodec class
