/*
 * 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.axiom.mime.ContentType;
import org.apache.axiom.mime.MediaType;
import org.apache.axis2.saaj.util.SAAJDataSource;
import org.apache.axis2.kernel.http.HTTPConstants;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import jakarta.activation.DataHandler;
import javax.xml.namespace.QName;
import jakarta.xml.soap.AttachmentPart;
import jakarta.xml.soap.MessageFactory;
import jakarta.xml.soap.MimeHeaders;
import jakarta.xml.soap.Name;
import jakarta.xml.soap.SOAPBody;
import jakarta.xml.soap.SOAPBodyElement;
import jakarta.xml.soap.SOAPConnection;
import jakarta.xml.soap.SOAPConstants;
import jakarta.xml.soap.SOAPElement;
import jakarta.xml.soap.SOAPEnvelope;
import jakarta.xml.soap.SOAPFactory;
import jakarta.xml.soap.SOAPFault;
import jakarta.xml.soap.SOAPHeader;
import jakarta.xml.soap.SOAPHeaderElement;
import jakarta.xml.soap.SOAPMessage;
import jakarta.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(MediaType.MULTIPART_RELATED, contentType.getMediaType());        
    }

    @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.getMediaType(), contentType2.getMediaType());
        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(MediaType.MULTIPART_RELATED, contentType.getMediaType());
        
        msg.removeAllAttachments();
        msg.saveChanges();

        assertNotNull(msg.getMimeHeaders().getHeader(HTTPConstants.HEADER_CONTENT_TYPE));
        contentType = new ContentType(msg.getMimeHeaders().getHeader(HTTPConstants.HEADER_CONTENT_TYPE)[0]);        
        assertEquals(MediaType.TEXT_XML, contentType.getMediaType());
    }

    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;
        }
    }
}
