/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.axis2.saaj;

import junit.framework.Assert;
import org.apache.axis2.saaj.util.SAAJDataSource;
import org.apache.axis2.transport.http.HTTPConstants;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import javax.activation.DataHandler;
import javax.mail.internet.ContentType;
import javax.xml.namespace.QName;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.stream.StreamSource;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.net.URL;
import java.util.Iterator;

/**
 * 
 */
@RunWith(SAAJTestRunner.class)
public class SOAPMessageTest extends Assert {
    private SOAPMessage msg;

//    static int port;
//    public static final QName SERVICE_NAME = new QName("Echo");
//    public static final QName OPERATION_NAME = new QName("echo");
//
//    public static final String SAAJ_REPO =
//            System.getProperty("basedir", ".") + "/" + "target/test-classes/saaj-repo";
//
//    public SOAPMessageTest(String name) {
//        super(name);
//    }
//
//    protected static String getAddress() {
//        return "http://127.0.0.1:" +
//                port +
//                "/axis2/services/Echo";
//    }
//    
//    public static Test suite() {
//        return new TestSetup(new TestSuite(IntegrationTest.class)) {
//            public void setUp() throws Exception {
//                port = UtilServer.start(SAAJ_REPO);
//                Parameter eneblemtom = new Parameter("enableMTOM", "true");
//                UtilServer.getConfigurationContext().getAxisConfiguration()
//                        .addParameter(eneblemtom);
//            }
//
//            public void tearDown() throws Exception {
//                UtilServer.stop();
//            }
//        };
//    }

    @Before
    public void setUp() throws Exception {
//        final AxisService service = Utils.createSimpleService(SERVICE_NAME,
//                                                              EchoService.class.getName(),
//                                                              OPERATION_NAME);
//        UtilServer.deployService(service);
        msg = MessageFactory.newInstance().createMessage();
    }

//    protected void tearDown() throws Exception {
//        UtilServer.unDeployService(SERVICE_NAME);
//        UtilServer.unDeployClientService();
//    }

    @Validated @Test
    public void testSaveRequired() {
        try {
            assertTrue("Save Required is False", msg.saveRequired());
        } catch (Exception e) {
            fail("Unexpected Exception : " + e);
        }
    }

    @Validated @Test
    public void testSaveRequired2() {
        try {
            msg.saveChanges();
            assertFalse("Save Required is True", msg.saveRequired());
        } catch (Exception e) {
            fail("Unexpected Exception : " + e);
        }
    }

    @Validated @Test
    public void testRemoveAttachements() {
        Iterator iterator = null;
        AttachmentPart ap1 = null;
        AttachmentPart ap2 = null;
        AttachmentPart ap3 = null;

        try {
            MessageFactory fac = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
            //MessageFactory fac = MessageFactory.newInstance();
            SOAPMessage msg = fac.createMessage();
            SOAPPart soapPart = msg.getSOAPPart();
            SOAPEnvelope envelope = soapPart.getEnvelope();
            SOAPBody body = envelope.getBody();
            SOAPFault sf = body.addFault();


            InputStream in1 = TestUtils.getTestFile("attach.xml");
            ap1 = msg.createAttachmentPart(in1, "text/xml");
            msg.addAttachmentPart(ap1);

            InputStream in2 = TestUtils.getTestFile("axis2.xml");
            ap2 = msg.createAttachmentPart(in2, "text/xml");
            msg.addAttachmentPart(ap2);

            InputStream in3 = TestUtils.getTestFile("axis2.xml");
            ap3 = msg.createAttachmentPart(in3, "text/plain");
            msg.addAttachmentPart(ap3);

            //get all attachments
            iterator = msg.getAttachments();

            int cnt = 0;
            while (iterator.hasNext()) {
                cnt++;
                iterator.next();
            }
            assertEquals(cnt, 3);
            //remove just the text/xml attachments
            MimeHeaders mhs = new MimeHeaders();
            mhs.addHeader("Content-Type", "text/xml");
            msg.removeAttachments(mhs);

            //get all attachments
            iterator = msg.getAttachments();
            cnt = 0;
            iterator = msg.getAttachments();
            while (iterator.hasNext()) {
                cnt++;
                iterator.next();
            }
            assertEquals(cnt, 1);
            iterator = msg.getAttachments();
            AttachmentPart ap = (AttachmentPart)iterator.next();
            String ctype = ap.getContentType();
            assertTrue(ctype.equals("text/plain"));

        } catch (Exception e) {
            fail("Exception: " + e);
        }
    }

    @Validated @Test
    public void testGetContent() {
        try {
            MessageFactory fac = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
            //MessageFactory fac = MessageFactory.newInstance();
            SOAPMessage msg = fac.createMessage();
            SOAPPart soapPart = msg.getSOAPPart();
            SOAPEnvelope envelope = soapPart.getEnvelope();
            SOAPBody body = envelope.getBody();

            AttachmentPart ap;

            InputStream inputStream = TestUtils.getTestFile("attach.xml");
            ap = msg.createAttachmentPart(new StreamSource(inputStream), "text/xml");
            DataHandler dh =
                    new DataHandler(new SAAJDataSource(inputStream, 1000, "text/xml", true));

            StringBuffer sb1 = copyToBuffer(dh.getInputStream());
            assertNotNull(ap);

            //Verify attachment part is not empty and contents are correct
            try {
                Object o = ap.getContent();
                InputStream is = null;
                assertNotNull(o);
                if (o instanceof StreamSource) {
                    StreamSource ss = (StreamSource)o;
                    is = ss.getInputStream();
                } else {
                    fail("got object: " + o +
                            ", expected object: javax.xml.transform.stream.StreamSource");
                }
            }
            catch (Exception e) {
                fail("attachment has no content - unexpected");
            }
        } catch (Exception e) {
            fail("Exception: " + e);
        }
    }

    @Validated @Test
    public void testContentTypeGeneration() throws Exception{        
        MessageFactory fac = MessageFactory.newInstance();
        SOAPMessage msg = fac.createMessage();
        InputStream inputStream = TestUtils.getTestFile("attach.xml");
        AttachmentPart ap = msg.createAttachmentPart(new StreamSource(inputStream), "text/xml");        
        msg.addAttachmentPart(ap);
        msg.saveChanges();
        assertNotNull(msg.getMimeHeaders().getHeader(HTTPConstants.HEADER_CONTENT_TYPE));        
        String contentTypeValue = msg.getMimeHeaders().getHeader(HTTPConstants.HEADER_CONTENT_TYPE)[0];
        ContentType contentType = new ContentType(contentTypeValue);
        assertNotNull("boundary parameter should exist in the content-type header", contentType.getParameter("boundary"));
        //start parameter is not checked, due to it is optional parameter, and seems RI will not add this value
        //assertNotNull("start parameter should exist in the content-type header", contentType.getParameter("start"));
        assertNotNull("type parameter should exist in the content-type header", contentType.getParameter("type"));
        assertEquals(HTTPConstants.MEDIA_TYPE_MULTIPART_RELATED, contentType.getBaseType());        
    }

    @Validated @Test
    public void testCreateMessageWithMimeHeaders() throws Exception{
        MessageFactory fac = MessageFactory.newInstance();
        SOAPMessage msg = fac.createMessage();               
        InputStream inputStream = TestUtils.getTestFile("attach.xml");
        AttachmentPart ap = msg.createAttachmentPart(new StreamSource(inputStream), "text/xml");        
        msg.addAttachmentPart(ap);
        msg.saveChanges();
        ContentType contentType = new ContentType(msg.getMimeHeaders().getHeader(HTTPConstants.HEADER_CONTENT_TYPE)[0]);
        
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        msg.writeTo(out);
        SOAPMessage msg2 = fac.createMessage(msg.getMimeHeaders(), new ByteArrayInputStream(out.toByteArray()));
        msg2.saveChanges();
        ContentType contentType2 = new ContentType(msg2.getMimeHeaders().getHeader(HTTPConstants.HEADER_CONTENT_TYPE)[0]);

        assertEquals(contentType.getBaseType(), contentType2.getBaseType());
        assertEquals(contentType.getParameter("boundary"), contentType2.getParameter("boundary"));
        assertEquals(contentType.getParameter("type"), contentType2.getParameter("type"));
        //start parameter is not checked, due to it is an optional parameter, and seems RI will not add this value
        //assertEquals(contentType.getParameter("start"), contentType2.getParameter("start"));
    }
    
    @Validated @Test
    public void testContentTypeUpdateWithAttachmentChanges() throws Exception{
        MessageFactory fac = MessageFactory.newInstance();
        SOAPMessage msg = fac.createMessage();               
        InputStream inputStream = TestUtils.getTestFile("attach.xml");
        AttachmentPart ap = msg.createAttachmentPart(new StreamSource(inputStream), "text/xml");        
        msg.addAttachmentPart(ap);
        msg.saveChanges();
        
        assertNotNull(msg.getMimeHeaders().getHeader(HTTPConstants.HEADER_CONTENT_TYPE));
        ContentType contentType = new ContentType(msg.getMimeHeaders().getHeader(HTTPConstants.HEADER_CONTENT_TYPE)[0]);        
        assertEquals(HTTPConstants.MEDIA_TYPE_MULTIPART_RELATED, contentType.getBaseType());
        
        msg.removeAllAttachments();
        msg.saveChanges();

        assertNotNull(msg.getMimeHeaders().getHeader(HTTPConstants.HEADER_CONTENT_TYPE));
        contentType = new ContentType(msg.getMimeHeaders().getHeader(HTTPConstants.HEADER_CONTENT_TYPE)[0]);        
        assertEquals("text/xml", contentType.getBaseType());
    }

    private StringBuffer copyToBuffer(InputStream inputStream) {
        if (inputStream == null) {
            return null;
        }
        StringWriter stringWriter = new StringWriter();
        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
        try {
            String s;
            while ((s = br.readLine()) != null)
                stringWriter.write(s);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return stringWriter.getBuffer();
    }

    /*
      * Do not add this test unless below mentioned resources are accessible
      */

    public void _testGetAttachmentsByHREF() {
        String NS_PREFIX = "mypre";
        String NS_URI = "http://myuri.org/";

        try {
            //MessageFactory fac = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
            SOAPMessage msg = MessageFactory.newInstance().createMessage();

            // Message creation takes care of creating the SOAPPart - a
            // required part of the message as per the SOAP 1.1 spec.
            SOAPPart sp = msg.getSOAPPart();
            SOAPEnvelope envelope = sp.getEnvelope();
            SOAPHeader hdr = envelope.getHeader();
            SOAPBody bdy = envelope.getBody();
            SOAPBodyElement sbe1 = bdy.addBodyElement(
                    envelope.createName("Body1", NS_PREFIX, NS_URI));
            sbe1.addChildElement(envelope.createName(
                    "TheGifAttachment", NS_PREFIX, NS_URI));
            sbe1.setAttribute("href", "cid:THEGIF");
            SOAPBodyElement sbe2 = bdy.addBodyElement(
                    envelope.createName("Body2", NS_PREFIX, NS_URI));
            sbe2.addChildElement(envelope.createName(
                    "TheXmlAttachment", NS_PREFIX, NS_URI));
            sbe2.setAttribute("href", "cid:THEXML");

            URL url1 = new URL("http://localhost:8080/SOAPMessage/attach.xml");
            URL url2 = new URL("http://localhost:8080/SOAPMessage/attach.gif");
            URL url3 = new URL("http://localhost:8080/SOAPMessage/attach.txt");
            URL url4 = new URL("http://localhost:8080/SOAPMessage/attach.html");
            URL url5 = new URL("http://localhost:8080/SOAPMessage/attach.jpeg");

            //Add various mime type attachments to SOAP message
            AttachmentPart ap1 = msg.createAttachmentPart(new DataHandler(url1));
            AttachmentPart ap2 = msg.createAttachmentPart(new DataHandler(url2));
            AttachmentPart ap3 = msg.createAttachmentPart(new DataHandler(url3));
            AttachmentPart ap4 = msg.createAttachmentPart(new DataHandler(url4));
            AttachmentPart ap5 = msg.createAttachmentPart(new DataHandler(url5));

            ap1.setContentType("text/xml");
            ap1.setContentId("<THEXML>");
            ap2.setContentType("image/gif");
            ap2.setContentId("<THEGIF>");
            ap3.setContentType("text/plain");
            ap3.setContentId("<THEPLAIN>");
            ap4.setContentType("text/html");
            ap4.setContentId("<THEHTML>");
            ap5.setContentType("image/jpeg");
            ap5.setContentId("<THEJPEG>");

            msg.addAttachmentPart(ap1);
            msg.addAttachmentPart(ap2);
            msg.addAttachmentPart(ap3);
            msg.addAttachmentPart(ap4);
            msg.addAttachmentPart(ap5);
            msg.saveChanges();

            //Retrieve attachment with href=cid:THEGIF
            AttachmentPart myap = msg.getAttachment(sbe1);
            if (myap == null) {
                fail("Returned null (unexpected)");
            } else if (!myap.getContentType().equals("image/gif")) {
                fail("Wrong attachment was returned: Got Content-Type of "
                        + myap.getContentType() + ", Expected Content-Type of image/gif");
            }
            //Retrieve attachment with href=cid:THEXML
            myap = msg.getAttachment(sbe2);
            if (myap == null) {
                fail("Returned null (unexpected)");
            } else if (!myap.getContentType().equals("text/xml")) {
                fail("Wrong attachment was returned: Got Content-Type of "
                        + myap.getContentType() + ", Expected Content-Type of text/xml");
            }
            //Retrieve attachment with href=cid:boo-hoo (expect null)
            QName myqname = new QName("boo-hoo");
            SOAPElement myse = SOAPFactoryImpl.newInstance().createElement(myqname);
            myse.addTextNode("<theBooHooAttachment href=\"cid:boo-hoo\"/>");
            myap = msg.getAttachment(myse);
            assertNull(myap);

        } catch (Exception e) {
            fail("Error :" + e);
        }
    }


    /*
      * Do not add this test unless below mentioned resources are accessible
      */
    public void _testGetAttachmentByHREF2() {
        String NS_PREFIX = "mypre";
        String NS_URI = "http://myuri.org/";

        try {
            MessageFactory fac = MessageFactory.newInstance();
            SOAPMessage msg = fac.createMessage();

            // Message creation takes care of creating the SOAPPart - a
            // required part of the message as per the SOAP 1.1 spec.
            SOAPPart sp = msg.getSOAPPart();
            SOAPEnvelope envelope = sp.getEnvelope();
            SOAPHeader hdr = envelope.getHeader();

            SOAPBody bdy = envelope.getBody();
            SOAPBodyElement sbe1 = bdy.addBodyElement(
                    envelope.createName("Body1", NS_PREFIX, NS_URI));
            sbe1.addChildElement(envelope.createName(
                    "TheGifAttachment", NS_PREFIX, NS_URI));

            SOAPBodyElement sbe2 = bdy.addBodyElement(
                    envelope.createName("Body2", NS_PREFIX, NS_URI));

            sbe2.addChildElement(envelope.createName(
                    "TheXmlAttachment", NS_PREFIX, NS_URI));

            URL url1 = new URL("http://localhost:8080/SOAPMessage/attach.xml");
            URL url2 = new URL("http://localhost:8080/SOAPMessage/attach.gif");
            URL url3 = new URL("http://localhost:8080/SOAPMessage/attach.txt");
            URL url4 = new URL("http://localhost:8080/SOAPMessage/attach.html");
            URL url5 = new URL("http://localhost:8080/SOAPMessage/attach.jpeg");

            // Set href on body elements using Content-Location headers and relative URI's
            sbe1.setAttribute("href", url2.toString());
            sbe2.setAttribute("href", url1.toString());

            AttachmentPart ap1 = msg.createAttachmentPart(new DataHandler(url1));
            AttachmentPart ap2 = msg.createAttachmentPart(new DataHandler(url2));
            AttachmentPart ap3 = msg.createAttachmentPart(new DataHandler(url3));
            AttachmentPart ap4 = msg.createAttachmentPart(new DataHandler(url4));
            AttachmentPart ap5 = msg.createAttachmentPart(new DataHandler(url5));

            ap1.setContentType("text/xml");
            ap1.setContentId("<THEXML>");
            ap1.setContentLocation(url1.toString());
            ap2.setContentType("image/gif");
            ap2.setContentId("<THEGIF>");
            ap2.setContentLocation(url2.toString());
            ap3.setContentType("text/plain");
            ap3.setContentId("<THEPLAIN>");
            ap3.setContentLocation(url3.toString());
            ap4.setContentType("text/html");
            ap4.setContentId("<THEHTML>");
            ap4.setContentLocation(url4.toString());
            ap5.setContentType("image/jpeg");
            ap5.setContentId("<THEJPEG>");
            ap5.setContentLocation(url5.toString());

            // Add the attachments to the message.
            msg.addAttachmentPart(ap1);
            msg.addAttachmentPart(ap2);
            msg.addAttachmentPart(ap3);
            msg.addAttachmentPart(ap4);
            msg.addAttachmentPart(ap5);
            msg.saveChanges();

            //Retrieve attachment with href=THEGIF
            AttachmentPart myap = msg.getAttachment(sbe1);
            if (myap == null) {
                fail("Returned null (unexpected)");
            } else if (!myap.getContentType().equals("image/gif")) {
                fail("Wrong attachment was returned: Got Content-Type of "
                        + myap.getContentType() + ", Expected Content-Type of image/gif");
            }

            //Retrieve attachment with href=THEXML
            myap = msg.getAttachment(sbe2);
            if (myap == null) {
                fail("Returned null (unexpected)");
            } else if (!myap.getContentType().equals("text/xml")) {
                fail("Wrong attachment was returned: Got Content-Type of "
                        + myap.getContentType() + ", Expected Content-Type of text/xml");
            }

            //Retrieve attachment with href=boo-hoo (expect null)
            QName myqname = new QName("boo-hoo");
            SOAPElement myse = SOAPFactory.newInstance().createElement(myqname);
            myse.addTextNode("<theBooHooAttachment href=\"boo-hoo\"/>");
            myap = msg.getAttachment(myse);
            assertNull(myap);
        } catch (Exception e) {
            fail("Exception: " + e);
        }
    }

    public void _testMessageCreation() {
        try {
            final String NS_PREFIX = "ns-prefix";
            final String NS_URI = "ns-uri";

            MessageFactory fac = MessageFactory.newInstance();
            SOAPMessage msg = fac.createMessage();

            SOAPPart sp = msg.getSOAPPart();
            SOAPEnvelope envelope = sp.getEnvelope();
            SOAPHeader hdr = envelope.getHeader();
            SOAPBody bdy = envelope.getBody();

            SOAPElement se = hdr.addHeaderElement(
                    envelope.createName("Header1", NS_PREFIX, NS_URI))
                    .addTextNode("This is Header1");
            SOAPHeaderElement she = (SOAPHeaderElement)se;
            she.setMustUnderstand(true);

            se = hdr.addHeaderElement(
                    envelope.createName("Header2", NS_PREFIX, NS_URI))
                    .addTextNode("This is Header2");
            she = (SOAPHeaderElement)se;
            she.setMustUnderstand(false);

            se = hdr.addHeaderElement(
                    envelope.createName("Header3", NS_PREFIX, NS_URI))
                    .addTextNode("This is Header3");
            she = (SOAPHeaderElement)se;
            she.setMustUnderstand(true);

            se = hdr.addHeaderElement(
                    envelope.createName("Header4", NS_PREFIX, NS_URI))
                    .addTextNode("This is Header4");
            she = (SOAPHeaderElement)se;
            she.setMustUnderstand(false);

            SOAPBodyElement sbe = bdy.addBodyElement(
                    envelope.createName("Body1", NS_PREFIX, NS_URI));

            sbe.addChildElement(envelope.createName(
                    "Child1", NS_PREFIX, NS_URI)).addTextNode("This is Child1");
            sbe.addChildElement(envelope.createName(
                    "Child2", NS_PREFIX, NS_URI)).addTextNode("This is Child2");


            URL url1 = new URL("http://localhost:8080/SOAPMessage/attach.xml");
            AttachmentPart ap = msg.createAttachmentPart(new DataHandler(url1));
            ap.setContentType("text/xml");
            msg.addAttachmentPart(ap);
            msg.saveChanges();

            // Create a url endpoint for the recipient of the message.
            URL urlEndpoint = new URL("http://localhost:8080/ReceivingSOAP11Servlet");

            // Send the message to the endpoint using the connection.
            SOAPConnection con = new SOAPConnectionImpl();
            SOAPMessage replymsg = con.call(msg, urlEndpoint);

            // Check if reply message
            if (!validateReplyMessage(replymsg, 1)) {
                //Reply message is correct
            } else {
                //TestUtil.logErr("Reply message is incorrect (FAILED)");
            }

        } catch (Exception e) {
            System.err.println("SendSyncReqRespMsgTest2 Exception: " + e);
            e.printStackTrace(System.err);
        }
    }

    private boolean validateReplyMessage(SOAPMessage msg, int num) {
        try {
            boolean pass = true;
            SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope();

            boolean foundHeader1 = false;
            boolean foundHeader2 = false;
            boolean foundHeader3 = false;
            boolean foundHeader4 = false;
            Iterator i = envelope.getHeader().examineAllHeaderElements();
            while (i.hasNext()) {
                SOAPElement se = (SOAPElement)i.next();
                Name name = se.getElementName();
                String value = se.getValue();
                if (value == null || name == null)
                    continue;
                else if (value.equals("This is Header1")
                        && name.getLocalName().equals("Header1"))
                    foundHeader1 = true;
                else if (value.equals("This is Header2")
                        && name.getLocalName().equals("Header2"))
                    foundHeader2 = true;
                else if (value.equals("This is Header3")
                        && name.getLocalName().equals("Header3"))
                    foundHeader3 = true;
                else if (value.equals("This is Header4")
                        && name.getLocalName().equals("Header4"))
                    foundHeader4 = true;
            }
            if (!foundHeader1 || !foundHeader2 ||
                    !foundHeader3 || !foundHeader4) {
                //expected soap headers in reply message
                pass = false;
            } else {
                //expected soap headers in reply message
            }
            boolean foundBody1 = false;
            boolean foundChild1 = false;
            boolean foundChild2 = false;
            SOAPBody bdy = envelope.getBody();
            i = bdy.getChildElements();
            while (i.hasNext()) {
                SOAPBodyElement sbe = (SOAPBodyElement)i.next();
                Name name = sbe.getElementName();
                if (name.getLocalName().equals("Body1"))
                    foundBody1 = true;
                Iterator c = sbe.getChildElements();
                while (c.hasNext()) {
                    SOAPElement se = (SOAPElement)c.next();
                    name = se.getElementName();
                    String value = se.getValue();
                    if (value.equals("This is Child1")
                            && name.getLocalName().equals("Child1"))
                        foundChild1 = true;
                    else if (value.equals("This is Child2")
                            && name.getLocalName().equals("Child2"))
                        foundChild2 = true;
                }
            }
            if (!foundBody1) {
                //expected soap body in reply message
                pass = false;
            } else
                if (!foundChild1 || !foundChild2) {
                    pass = false;
                } else {
                    //Did find expected soap body child
                }
            int count = msg.countAttachments();
            if (count == num) {
                //received expected number of attachments in reply message
                i = msg.getAttachments();
                boolean gifFound = false;
                boolean xmlFound = false;
                boolean textFound = false;
                boolean htmlFound = false;
                boolean jpegFound = false;
                while (i.hasNext()) {
                    AttachmentPart a = (AttachmentPart)i.next();
                    String type = a.getContentType();
                    if (type.equals("image/gif"))
                        gifFound = true;
                    else if (type.equals("text/xml"))
                        xmlFound = true;
                    else if (type.equals("text/plain"))
                        textFound = true;
                    else if (type.equals("text/html"))
                        htmlFound = true;
                    else if (type.equals("image/jpeg"))
                        jpegFound = true;
                    else {
                        //Got unexpected MIME type
                        pass = false;
                    }
                }
                if (num > 0) {
                    //Did not find expected MIME types in reply message
                    pass = false;
                }
                return pass;
            } else {
                //Got unexpected number of attachments in reply message
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }
}
