{"action":"created","comment":{"url":"https://api.github.com/repos/wso2/esb-connectors/pulls/comments/47462617","id":47462617,"diff_hunk":"@@ -0,0 +1,836 @@\n+package org.wso2.carbon.connector;/*\n+ * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n+ *\n+ *   WSO2 Inc. licenses this file to you under the Apache License,\n+ *   Version 2.0 (the \"License\"); you may not use this file except\n+ *   in compliance with the License.\n+ *   You may obtain a copy of the License at\n+ *\n+ *     http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ *  Unless required by applicable law or agreed to in writing,\n+ *  software distributed under the License is distributed on an\n+ *  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n+ *  KIND, either express or implied.  See the License for the\n+ *  specific language governing permissions and limitations\n+ *  under the License.\n+ */\n+import org.apache.axiom.om.OMAbstractFactory;\n+import org.apache.axiom.om.OMElement;\n+import org.apache.axiom.om.OMFactory;\n+import org.apache.axiom.om.OMNamespace;\n+import org.apache.commons.logging.Log;\n+import org.apache.commons.logging.LogFactory;\n+import org.apache.synapse.MessageContext;\n+import org.apache.synapse.SynapseConstants;\n+import org.apache.synapse.SynapseException;\n+import org.apache.synapse.SynapseLog;\n+import org.apache.synapse.core.axis2.Axis2MessageContext;\n+import org.wso2.carbon.connector.core.util.ConnectorUtils;\n+import javax.xml.namespace.QName;\n+import java.util.Map;\n+\n+import java.io.BufferedReader;\n+import java.io.IOException;\n+import java.io.InputStream;\n+import java.io.InputStreamReader;\n+import java.util.Arrays;\n+\n+import org.apache.axiom.om.OMAbstractFactory;\n+import org.apache.axiom.om.OMElement;\n+import org.apache.axiom.om.OMFactory;\n+import org.apache.axiom.om.OMNamespace;\n+import org.apache.axis2.context.OperationContext;\n+import org.apache.commons.io.IOUtils;\n+import org.apache.commons.logging.Log;\n+import org.apache.commons.logging.LogFactory;\n+import org.apache.synapse.MessageContext;\n+import org.apache.synapse.SynapseConstants;\n+import org.apache.synapse.core.axis2.Axis2MessageContext;\n+import org.wso2.carbon.connector.core.ConnectException;\n+import org.wso2.carbon.connector.core.util.ConnectorUtils;\n+import com.google.code.com.sun.mail.imap.IMAPFolder;\n+import com.google.code.com.sun.mail.imap.IMAPMessage;\n+import com.google.code.com.sun.mail.imap.IMAPStore;\n+import com.google.code.com.sun.mail.smtp.SMTPTransport;\n+import com.google.code.javax.activation.DataHandler;\n+import com.google.code.javax.mail.BodyPart;\n+import com.google.code.javax.mail.FetchProfile;\n+import com.google.code.javax.mail.Folder;\n+import com.google.code.javax.mail.Message;\n+import com.google.code.javax.mail.MessagingException;\n+import com.google.code.javax.mail.Session;\n+import com.google.code.javax.mail.Flags.Flag;\n+import com.google.code.javax.mail.Multipart;\n+import com.google.code.javax.mail.Part;\n+import com.google.code.javax.mail.internet.InternetAddress;\n+import com.google.code.javax.mail.internet.MimeBodyPart;\n+import com.google.code.javax.mail.internet.MimeMessage;\n+import com.google.code.javax.mail.internet.MimeMultipart;\n+import com.google.code.javax.mail.search.SearchTerm;\n+import com.google.code.javax.mail.util.ByteArrayDataSource;\n+\n+public  final class GmailUtils {\n+\n+    /**\n+     * Making the default constructor private since Utility classes should not\n+     * have a public constructors\n+     */\n+    private GmailUtils() {\n+    }\n+\n+    /**\n+     * Log instance.\n+     */\n+    private static Log log = LogFactory.getLog(GmailUtils.class);\n+\n+    /**\n+     * Extracts a given parameter from message context\n+     *\n+     * @param messageContext\n+     *            Input message context\n+     * @param paramName\n+     *            Name of the parameter to extract from the message context\n+     * @return extracted parameter as a {@link String}\n+     */\n+    public static String lookupFunctionParam(MessageContext messageContext, String paramName) {\n+        return (String) ConnectorUtils.lookupTemplateParamater(messageContext, paramName);\n+    }\n+\n+    /**\n+     * Stores error response in the message context\n+     *\n+     * @param messageContext\n+     *            Message Context where the error response should be stored\n+     * @param e\n+     *            Exception\n+     */\n+    public static void storeErrorResponseStatus(MessageContext messageContext, final Throwable e,\n+                                                int errorCode) {\n+        messageContext.setProperty(SynapseConstants.ERROR_EXCEPTION, e);\n+        messageContext.setProperty(SynapseConstants.ERROR_MESSAGE, e.getMessage());\n+\n+        if (messageContext.getEnvelope().getBody().getFirstElement() != null) {\n+            messageContext.getEnvelope().getBody().getFirstElement().detach();\n+        }\n+\n+        OMFactory factory = OMAbstractFactory.getOMFactory();\n+        OMNamespace ns = factory.createOMNamespace(\"http://org.wso2.esbconnectors.gmail\", \"ns\");\n+        OMElement result = factory.createOMElement(\"ErrorResponse\", ns);\n+        OMElement errorMessageElement = factory.createOMElement(\"ErrorMessage\", ns);\n+        result.addChild(errorMessageElement);\n+        errorMessageElement.setText(e.getMessage());\n+        messageContext.getEnvelope().getBody().addChild(result);\n+\n+        messageContext.setProperty(SynapseConstants.ERROR_CODE, errorCode);\n+        messageContext.setFaultResponse(true);\n+        log.info(\"Stored the error response\");\n+    }\n+\n+    /**\n+     * Read and list the e-mail messages searched from the IMAP store according\n+     * to the given search term\n+     *\n+     * @param messageContext\n+     *            Message context where the response should be stored\n+     * @param store\n+     *            IMAPStore\n+     * @param term\n+     *            Search term\n+     * @param batchNumber\n+     *            The batch number to return\n+     * @param responseElementName\n+     *            Name of the response element name\n+     * @throws MessagingException\n+     * @throws ConnectException\n+     *             if the folder does not exist\n+     */\n+    public static void listMails(MessageContext messageContext, IMAPStore store, SearchTerm term,\n+                                 int batchNumber, String responseElementName)\n+            throws MessagingException,\n+            ConnectException {\n+        FetchProfile fetchprofile = getFetchProfile();\n+        Message[] messages = null;\n+        try {\n+            log.info(\"Started reading messages\");\n+            IMAPFolder folder = getFolder(GmailConstants.GMAIL_ALL_MAIL, store);\n+            folder.open(Folder.READ_ONLY);\n+            if (term != null) {\n+                messages = GmailUtils.getBatch(folder.search(term), batchNumber);\n+            } else {\n+                messages = GmailUtils.getBatch(folder.getMessages(), batchNumber);\n+            }\n+            folder.fetch(messages, fetchprofile);\n+            log.info(\"Number of fetched messages:\" + messages.length);\n+            storeMailListInResponse(messages, messageContext, responseElementName, false);\n+            folder.close(true);\n+        } catch (MessagingException e) {\n+            log.error(\"Failure while fetching messages\");\n+            throw (e);\n+        }\n+    }\n+\n+    /**\n+     * Deletes the e-mail messages searched from the IMAP store according\n+     * to the given search term\n+     *\n+     * @param messageContext\n+     *            Message context where the response should be stored\n+     * @param store\n+     *            IMAPStore\n+     * @param term\n+     *            Search term\n+     * @param responseElementName\n+     *            Name of the response element name\n+     * @return an array of messages fetched from the IMAPStore\n+     * @throws MessagingException\n+     *             if any failure occur while deleting messages\n+     * @throws ConnectException\n+     *             if no messages are fetched to delete\n+     */\n+    public static void deleteMails(IMAPStore store, SearchTerm term, MessageContext messageContext,\n+                                   String responseElementName) throws MessagingException,\n+            ConnectException {\n+        FetchProfile fetchprofile = getFetchProfile();\n+        Message[] messages = null;\n+        try {\n+            log.info(\"Reading messages\");\n+            IMAPFolder folder = getFolder(GmailConstants.GMAIL_ALL_MAIL, store);\n+            IMAPFolder trash = getFolder(GmailConstants.GMAIL_TRASH, store);\n+            folder.open(Folder.READ_WRITE);\n+            messages = folder.search(term);\n+            if (messages.length == 0) {\n+                String errorLog =\n+                        \"No messages are found to delete. Please make sure the threda ID/ message ID is correct.\";\n+                log.error(errorLog);\n+                ConnectException connectException = new ConnectException(errorLog);\n+                throw (connectException);\n+            }\n+\n+            log.info(\"Fetching messages\");\n+            folder.fetch(messages, fetchprofile);\n+            log.info(\"Number of fetched messages:\" + messages.length);\n+            storeMailListInResponse(messages, messageContext, responseElementName, true);\n+            folder.copyMessages(messages, trash);\n+            folder.close(true);\n+        } catch (MessagingException e) {\n+            log.error(\"Error while deleting messages\");\n+            throw (e);\n+        }\n+    }\n+\n+    /**\n+     * Read and list the e-mail messages searched from the IMAP store according\n+     * to the given search term\n+     *\n+     * @param messageContext\n+     *            Message context where the response should be stored\n+     * @param store\n+     *            IMAPStore\n+     * @param term\n+     *            Search term\n+     * @param responseElementName\n+     *            Name of the response element name\n+     * @throws MessagingException\n+     *             if any failure occur while reading messages\n+     * @throws ConnectException\n+     *             if no messages are fetched to read\n+     */\n+    public static void readMails(MessageContext messageContext, IMAPStore store, SearchTerm term,\n+                                 String responseElementName) throws MessagingException,\n+            ConnectException {\n+        FetchProfile fetchprofile = getFetchProfile();\n+        Message[] messages = null;\n+        try {\n+//\t\t\tlog.info(\"Started reading messages\");\n+//\t\t\tIMAPFolder folder = getFolder(GmailConstants.GMAIL_ALL_MAIL, store);\n+//            log.info( \"11111111\");\n+//\t\t\tfolder.open(Folder.READ_WRITE);\n+//            log.info( \"22222222\");\n+//\t\t\tmessages = folder.search(term);\n+//            log.info( \"33333333\");\n+\n+            log.info( \"111111\");\n+            Folder ft = store.getFolder(\"inbox\");\n+            log.info( \"2222222\");\n+            ft.open(Folder.READ_ONLY);\n+            log.info( \"33333\");\n+            messages = ft.search(term);\n+            log.info( \"444444\");\n+\n+            if (messages.length == 0) {\n+                String errorLog =\n+                        \"No messages are found to read. Please make sure the threda ID/ message ID is correct.\";\n+                log.error(errorLog);\n+                ConnectException connectException = new ConnectException(errorLog);\n+                throw (connectException);\n+            }\n+            log.info(\"Fetching messages\");\n+            //folder.fetch(messages, fetchprofile);\n+            log.info(\"Number of fetched messages:\" + messages.length);\n+            storeMailListInResponse(messages, messageContext, responseElementName, true);\n+            //folder.close(true);\n+        } catch (MessagingException e) {\n+            log.error(\"Failure while fetching messages\");\n+            throw (e);\n+        }\n+    }\n+\n+    /**\n+     * Set labels to the e-mail messages which are searched from the IMAP store\n+     * according to the given search term\n+     *\n+     * @param messageContext\n+     *            Message context where the response should be stored\n+     * @param store\n+     *            IMAPStore\n+     * @param term\n+     *            Search term\n+     * @param responseElementName\n+     *            Name of the response element\n+     * @param labels\n+     *            comma separated list of label names\n+     * @throws MessagingException\n+     *             if any failure occur while setting labels\n+     * @throws ConnectException\n+     *             if no messages are fetched to set labels\n+     */\n+    public static void setLabels(IMAPStore store, SearchTerm term, MessageContext messageContext,\n+                                 String[] labels, String responseElementName)\n+            throws MessagingException,\n+            ConnectException {\n+        FetchProfile fetchprofile = getFetchProfile();\n+        IMAPMessage[] messages = null;\n+        try {\n+            IMAPFolder folder = getFolder(GmailConstants.GMAIL_ALL_MAIL, store);\n+            log.info(\"Reading messages\");\n+            folder.open(Folder.READ_WRITE);\n+            messages = (IMAPMessage[]) folder.search(term);\n+            if (messages.length == 0) {\n+                String errorLog =\n+                        \"No messages are found to set labels. Please make sure the threda ID/ message ID is correct.\";\n+                log.error(errorLog);\n+                ConnectException connectException = new ConnectException(errorLog);\n+                throw (connectException);\n+            }\n+            log.info(\"Fetching messages\");\n+            folder.fetch(messages, fetchprofile);\n+            log.info(\"Number of fetched messages:\" + messages.length);\n+            folder.setGoogleMessageLabels(messages, labels, true);\n+            GmailUtils.storeMailListInResponse(messages, messageContext, responseElementName, false);\n+            folder.close(true);\n+        } catch (MessagingException e) {\n+            log.error(\"Error while deleting messages\");\n+            throw (e);\n+        }\n+    }\n+\n+    /**\n+     * {@link FetchProfile} is created to fetch Gmail thread ID, Gmail message\n+     * ID, Gmail labels, flags and envelop of e-mail messages\n+     *\n+     * @return the {@link FetchProfile}\n+     */\n+    public static FetchProfile getFetchProfile() {\n+        FetchProfile fetchprofile = new FetchProfile();\n+        fetchprofile.add(IMAPFolder.FetchProfileItem.X_GM_THRID);\n+        fetchprofile.add(IMAPFolder.FetchProfileItem.X_GM_MSGID);\n+        fetchprofile.add(IMAPFolder.FetchProfileItem.X_GM_LABELS);\n+        fetchprofile.add(IMAPFolder.FetchProfileItem.ENVELOPE);\n+        fetchprofile.add(IMAPFolder.FetchProfileItem.FLAGS);\n+        return fetchprofile;\n+    }\n+\n+    /**\n+     * Store resulted e-mail messages in the response.\n+     *\n+     * @param messagesArray\n+     *            Array of {@link Message}\n+     * @param messageContext\n+     *            Message Context where the messages should be stored\n+     * @param resultElementName\n+     *            Name of the result element\n+     * @param storeContent\n+     *            Message context is stored in the response only if this flag is\n+     *            true\n+     */\n+    public static void storeMailListInResponse(Message[] messagesArray,\n+                                               MessageContext messageContext,\n+                                               String resultElementName, boolean storeContent) {\n+        log.info(\"Storing the response in the message context\");\n+        if (messageContext.getEnvelope().getBody().getFirstElement() != null) {\n+            messageContext.getEnvelope().getBody().getFirstElement().detach();\n+        }\n+\n+        OMFactory factory = OMAbstractFactory.getOMFactory();\n+        OMNamespace ns = factory.createOMNamespace(\"http://org.wso2.esbconnectors.gmail\", \"ns\");\n+        OMElement result = factory.createOMElement(resultElementName, ns);\n+\n+        OMElement messages = factory.createOMElement(\"messages\", ns);\n+        result.addChild(messages);\n+\n+        for (int i = messagesArray.length - 1; i >= 0; i--) {\n+            Message message = messagesArray[i];\n+            if (message != null) {\n+                OMElement messageElement = factory.createOMElement(\"message\", ns);\n+                messages.addChild(messageElement);\n+\n+                OMElement subject = factory.createOMElement(\"subject\", ns);\n+                messageElement.addChild(subject);\n+                try {\n+                    subject.setText(message.getSubject());\n+                } catch (MessagingException me) {\n+                    log.info(\"\\\"Subject\\\" cannot be resolved\");\n+                }\n+\n+                OMElement from = factory.createOMElement(\"from\", ns);\n+                messageElement.addChild(from);\n+                try {\n+                    from.setText(InternetAddress.toString(message.getFrom()));\n+                } catch (MessagingException e) {\n+                    log.info(\"\\\"From\\\" cannot be resolved\");\n+                }\n+\n+                OMElement to = factory.createOMElement(\"to\", ns);\n+                messageElement.addChild(to);\n+                try {\n+                    to.setText(InternetAddress.toString(message.getAllRecipients()));\n+                } catch (MessagingException e) {\n+                    log.info(\"\\\"To\\\" cannot be resolved\");\n+                }\n+\n+                OMElement date = factory.createOMElement(\"sentDate\", ns);\n+                messageElement.addChild(date);\n+                try {\n+                    date.setText(message.getSentDate().toString());\n+                } catch (MessagingException e) {\n+                    log.info(\"\\\"Sent date\\\" cannot be resolved\");\n+                }\n+\n+                OMElement labelsElement = factory.createOMElement(\"labels\", ns);\n+                messageElement.addChild(labelsElement);\n+                String[] labels = ((IMAPMessage) message).getGoogleMessageLabels();\n+                for (String label : labels) {\n+                    OMElement labelElement = factory.createOMElement(\"label\", ns);\n+                    labelsElement.addChild(labelElement);\n+                    labelElement.setText(label);\n+                }\n+\n+                OMElement msgId = factory.createOMElement(\"messageID\", ns);\n+                messageElement.addChild(msgId);\n+                String messageID = Long.toString(((IMAPMessage) message).getGoogleMessageId());\n+                msgId.setText(messageID);\n+\n+                OMElement threadId = factory.createOMElement(\"threadID\", ns);\n+                messageElement.addChild(threadId);\n+                threadId.setText(Long.toString(((IMAPMessage) message).getGoogleMessageThreadId()));\n+\n+                OMElement status = factory.createOMElement(\"Status\", ns);\n+                messageElement.addChild(status);\n+                try {\n+                    if (message.isSet(Flag.SEEN)) {\n+                        status.setText(\"READ\");\n+                    } else {\n+                        status.setText(\"UNREAD\");\n+                    }\n+                } catch (MessagingException e) {\n+                    log.info(\"\\\"Message Status\\\" cannot be resolved\");\n+                }\n+\n+                if (storeContent) {\n+                    OMElement content = factory.createOMElement(\"content\", ns);\n+                    messageElement.addChild(content);\n+                    StringBuilder attachmentContentIDs = new StringBuilder();\n+                    try {\n+\n+                        log.info(\"Processing message content\");\n+                        content.setText(\"\\n\" +\n+                                GmailUtils.processMessageBody(message, messageContext,\n+                                        attachmentContentIDs,\n+                                        messageID));\n+                    } catch (Exception e) {\n+                        log.info(\"Cannot retrive \\\"Message Content\\\".\");\n+                    }\n+\n+                    if (attachmentContentIDs.length() > 0) {\n+                        OMElement attachments = factory.createOMElement(\"attachemnts\", ns);\n+                        messageElement.addChild(attachments);\n+                        attachmentContentIDs.setLength(attachmentContentIDs.length() - 1);\n+                        attachments.setText(attachmentContentIDs.toString());\n+                    }\n+                }\n+            }\n+        }\n+        messageContext.getEnvelope().getBody().addChild(result);\n+    }\n+\n+    /**\n+     * Process message body.\n+     *\n+     * @param message\n+     *            Message to be processed.\n+     * @param messageContext\n+     *            Message Context\n+     * @param attachmentContentIDs\n+     *            file names as the content IDs of the attachments\n+     * @param messageID\n+     *            ID of the message.\n+     * @return\n+     * @throws IOException\n+     * @throws MessagingException\n+     */\n+    private static String processMessageBody(Message message, MessageContext messageContext,\n+                                             StringBuilder attachmentContentIDs, String messageID)\n+            throws IOException,\n+            MessagingException {\n+        Object content = message.getContent();\n+        if (content instanceof Multipart) {\n+            Multipart multiPart = (Multipart) content;\n+            StringBuilder builder = new StringBuilder();\n+            return procesMultiPart(builder, multiPart, messageContext, attachmentContentIDs,\n+                    messageID);\n+        } else if (content instanceof String) {\n+            return content.toString();\n+        } else if (content instanceof InputStream) {\n+            InputStream inStream = (InputStream) content;\n+            BufferedReader br = new BufferedReader(new InputStreamReader(inStream));\n+            String line;\n+            StringBuilder builder = new StringBuilder();\n+            while ((line = br.readLine()) != null) {\n+                builder.append(line);\n+            }\n+            br.close();\n+            inStream.close();\n+            return builder.toString();\n+        }\n+        log.error(\"invalid message content\");\n+        return null;\n+    }\n+\n+    /**\n+     * Reads the batch number from the input string.\n+     *\n+     * @param batchString\n+     *            input string\n+     * @return batch number\n+     * @throws NumberFormatException\n+     *             if the batch number is not an integer\n+     * @throws ConnectException\n+     *             if the batch number is not a positive integer\n+     */\n+    public static int getBatchNumber(String batchString) throws NumberFormatException,\n+            ConnectException {\n+        int batchNumber;\n+        if (batchString != null && !\"\".equals(batchString.trim())) {\n+            batchNumber = Integer.parseInt(batchString);\n+            if (batchNumber <= 0) {\n+                String errorLog = \"Batch number should be a positive integer\";\n+                log.error(errorLog);\n+                ConnectException connectException = new ConnectException(errorLog);\n+                throw (connectException);\n+            }\n+        } else {\n+            // Use first batch as the default batch.\n+            batchNumber = 1;\n+        }\n+\n+        return batchNumber;\n+    }\n+\n+    /**\n+     * Close and remove the already stored IMAP and SMTP connections\n+     *\n+     * @param operationContext\n+     *            where the connections are stored\n+     * @throws MessagingException\n+     */\n+    public static void closeConnection(org.apache.axis2.context.MessageContext axis2MessageContext)\n+            throws MessagingException {\n+        if (axis2MessageContext.getProperty(GmailConstants.GMAIL_LOGIN_MODE) == null) {\n+            return;\n+        }\n+\n+        OperationContext operationContext = axis2MessageContext.getOperationContext();\n+        if (operationContext.getProperty(GmailConstants.GMAIL_IMAP_STORE_INSTANCE) != null) {\n+            log.info(\"Closing the previously opened IMAP Store\");\n+            ((IMAPStore) operationContext.getProperty(GmailConstants.GMAIL_IMAP_STORE_INSTANCE)).close();\n+            operationContext.removeProperty(GmailConstants.GMAIL_IMAP_STORE_INSTANCE);\n+        }\n+\n+        if (operationContext.getProperty(GmailConstants.GMAIL_SMTP_CONNECTION_INSTANCE) != null) {\n+            log.info(\"Closing the previously opened SMTP transport\");\n+            ((GmailSMTPConnectionObject) operationContext.getProperty(GmailConstants.GMAIL_SMTP_CONNECTION_INSTANCE)).getTransport()\n+                    .close();\n+            operationContext.removeProperty(GmailConstants.GMAIL_SMTP_CONNECTION_INSTANCE);\n+        }\n+\n+        axis2MessageContext.removeProperty((String) axis2MessageContext.getProperty(GmailConstants.GMAIL_LOGIN_MODE));\n+    }\n+\n+    /**\n+     * Store the response for send mail operations.\n+     *\n+     * @param responseElementName\n+     *            Response element's name\n+     * @param subject\n+     *            Subject of the mail\n+     * @param textContent\n+     *            Text content of the mail\n+     * @param recipients\n+     *            A comma separated list of recipients\n+     * @param attachmentIDs\n+     *            A comma separated list of attachmentIDs\n+     * @param messageContext\n+     *            Message context where the response should be stored\n+     */\n+    public static void storeSentMailResponse(String responseElementName, String subject,\n+                                             String textContent, String recipients,\n+                                             String attachmentIDs, MessageContext messageContext) {\n+        log.info(\"Storing the response in the message context\");\n+        if (messageContext.getEnvelope().getBody().getFirstElement() != null) {\n+            messageContext.getEnvelope().getBody().getFirstElement().detach();\n+        }\n+        OMFactory factory = OMAbstractFactory.getOMFactory();\n+        OMNamespace ns = factory.createOMNamespace(\"http://org.wso2.esbconnectors.gmail\", \"ns\");\n+        OMElement result = factory.createOMElement(responseElementName, ns);\n+\n+        OMElement messageElement = factory.createOMElement(\"message\", ns);\n+        result.addChild(messageElement);\n+        OMElement subjectElement = factory.createOMElement(\"subject\", ns);\n+        subjectElement.setText(subject);\n+        messageElement.addChild(subjectElement);\n+        OMElement contentElement = factory.createOMElement(\"content\", ns);\n+        contentElement.setText(textContent);\n+        messageElement.addChild(contentElement);\n+        OMElement attachmentElement = factory.createOMElement(\"attachments\", ns);\n+        attachmentElement.setText(attachmentIDs);\n+        messageElement.addChild(attachmentElement);\n+        OMElement recipientsElement = factory.createOMElement(\"recipients\", ns);\n+        recipientsElement.setText(recipients);\n+        messageElement.addChild(recipientsElement);\n+        messageContext.getEnvelope().getBody().addChild(result);\n+    }\n+\n+    /**\n+     * Creates a new {@link Message}.\n+     *\n+     * @param session\n+     *            Mail {@link Session}.\n+     * @param subject\n+     *            Subject of the mail.\n+     * @param textContent\n+     *            Text content of the mail message.\n+     * @param toRecipients\n+     *            'To' recipients of the mail message.\n+     * @param ccRecipients\n+     *            'CC' recipients of the mail message.\n+     * @param bccRecipients\n+     *            'BCC' recipients of the mail message.\n+     * @param attachmentList\n+     *            Array of attachment file names.\n+     * @param axis2MsgCtx\n+     *            Axis2 message context where the attachment files are stored.\n+     * @return returns the created {@link #}\n+     * @throws ConnectException\n+     *             if invalid attachment IDs are provided.\n+     * @throws MessagingException\n+     * @throws IOException\n+     */\n+    public static Message createNewMessage(Session session, String subject, String textContent,\n+                                           String toRecipients, String ccRecipients,\n+                                           String bccRecipients, String[] attachmentList,\n+                                           org.apache.axis2.context.MessageContext axis2MsgCtx)\n+            throws ConnectException,\n+            MessagingException,\n+            IOException {\n+        log.info(\"Creating the mail message\");\n+        MimeMessage message = new MimeMessage(session);\n+        if (toRecipients != null) {\n+            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toRecipients));\n+        }\n+        if (ccRecipients != null) {\n+            message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(ccRecipients));\n+        }\n+        if (bccRecipients != null) {\n+            message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(bccRecipients));\n+        }\n+        message.setSubject(subject);\n+        MimeMultipart content = new MimeMultipart();\n+        MimeBodyPart mainPart = new MimeBodyPart();\n+        mainPart.setText(textContent);\n+        content.addBodyPart(mainPart);\n+\n+        for (String attachment : attachmentList) {\n+            javax.activation.DataHandler handler = axis2MsgCtx.getAttachment(attachment);\n+            if (handler != null) {\n+                InputStream inStream = handler.getInputStream();\n+                byte[] bytes = IOUtils.toByteArray(inStream);\n+                ByteArrayDataSource source =\n+                        new ByteArrayDataSource(bytes,\n+                                handler.getContentType());\n+                MimeBodyPart bodyPart = new MimeBodyPart();\n+                bodyPart.setDataHandler(new DataHandler(source));\n+                bodyPart.setFileName(attachment);\n+                content.addBodyPart(bodyPart);\n+            } else {\n+                String errorLog = \"Invalid attachemnt ID, \" + attachment;\n+                log.error(errorLog);\n+                ConnectException connectException = new ConnectException(errorLog);\n+                throw (connectException);\n+            }\n+        }\n+        message.setContent(content);\n+        return message;\n+    }\n+\n+    /**\n+     * Sends the given {@link Message} through the given {@link SMTPTransport}\n+     *\n+     * @param message\n+     *            The message to be sent\n+     * @param transport\n+     *            The {@link SMTPTransport} through which the message should be\n+     *            sent\n+     * @throws MessagingException\n+     *             as a result of failures in message transportation\n+     */\n+    public static void sendMessage(Message message, SMTPTransport transport)\n+            throws MessagingException {\n+        log.info(\"Sending the mail...\");\n+        transport.sendMessage(message, message.getAllRecipients());\n+        log.info(\"The mail is succesfully sent\");\n+    }\n+\n+    private static Message[] getBatch(Message[] messages, int batchNumber) {\n+        Message[] newMessages;\n+        if (messages.length > GmailConstants.GMAIL_BATCH_SIZE * batchNumber) {\n+            newMessages =\n+                    Arrays.copyOfRange(messages, messages.length -\n+                                    GmailConstants.GMAIL_BATCH_SIZE *\n+                                            batchNumber,\n+                            messages.length - GmailConstants.GMAIL_BATCH_SIZE *\n+                                    (batchNumber - 1));\n+        } else if (messages.length > GmailConstants.GMAIL_BATCH_SIZE * (batchNumber - 1)) {\n+            newMessages =\n+                    Arrays.copyOfRange(messages, 0, messages.length -\n+                            GmailConstants.GMAIL_BATCH_SIZE *\n+                                    (batchNumber - 1));","path":"gmail/gmail-connector/gmail-connector-2.0.0/org.wso2.carbon.connector/src/main/java/org/wso2/carbon/connector/GmailUtils.java","position":717,"original_position":717,"commit_id":"188ff39122ecc61b371828725d0e6e6c58553996","original_commit_id":"188ff39122ecc61b371828725d0e6e6c58553996","user":{"login":"RKathees","id":8066603,"avatar_url":"https://avatars.githubusercontent.com/u/8066603?v=3","gravatar_id":"","url":"https://api.github.com/users/RKathees","html_url":"https://github.com/RKathees","followers_url":"https://api.github.com/users/RKathees/followers","following_url":"https://api.github.com/users/RKathees/following{/other_user}","gists_url":"https://api.github.com/users/RKathees/gists{/gist_id}","starred_url":"https://api.github.com/users/RKathees/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RKathees/subscriptions","organizations_url":"https://api.github.com/users/RKathees/orgs","repos_url":"https://api.github.com/users/RKathees/repos","events_url":"https://api.github.com/users/RKathees/events{/privacy}","received_events_url":"https://api.github.com/users/RKathees/received_events","type":"User","site_admin":false},"body":"Please formate the code properly. Above 4 lines can be in one line. This should be fixed in entire PR.","created_at":"2015-12-14T05:30:46Z","updated_at":"2015-12-14T05:30:46Z","html_url":"https://github.com/wso2/esb-connectors/pull/69#discussion_r47462617","pull_request_url":"https://api.github.com/repos/wso2/esb-connectors/pulls/69","_links":{"self":{"href":"https://api.github.com/repos/wso2/esb-connectors/pulls/comments/47462617"},"html":{"href":"https://github.com/wso2/esb-connectors/pull/69#discussion_r47462617"},"pull_request":{"href":"https://api.github.com/repos/wso2/esb-connectors/pulls/69"}}},"pull_request":{"url":"https://api.github.com/repos/wso2/esb-connectors/pulls/69","id":30162934,"html_url":"https://github.com/wso2/esb-connectors/pull/69","diff_url":"https://github.com/wso2/esb-connectors/pull/69.diff","patch_url":"https://github.com/wso2/esb-connectors/pull/69.patch","issue_url":"https://api.github.com/repos/wso2/esb-connectors/issues/69","number":69,"state":"closed","locked":false,"title":"Gmail Connector","user":{"login":"ashalya","id":8655189,"avatar_url":"https://avatars.githubusercontent.com/u/8655189?v=3","gravatar_id":"","url":"https://api.github.com/users/ashalya","html_url":"https://github.com/ashalya","followers_url":"https://api.github.com/users/ashalya/followers","following_url":"https://api.github.com/users/ashalya/following{/other_user}","gists_url":"https://api.github.com/users/ashalya/gists{/gist_id}","starred_url":"https://api.github.com/users/ashalya/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ashalya/subscriptions","organizations_url":"https://api.github.com/users/ashalya/orgs","repos_url":"https://api.github.com/users/ashalya/repos","events_url":"https://api.github.com/users/ashalya/events{/privacy}","received_events_url":"https://api.github.com/users/ashalya/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-02-27T12:36:37Z","updated_at":"2015-12-14T05:30:46Z","closed_at":"2015-03-09T11:22:03Z","merged_at":"2015-03-09T11:22:03Z","merge_commit_sha":"6c0a76ec4435d463ed021dc9f2026dbc32eeccf8","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/wso2/esb-connectors/pulls/69/commits","review_comments_url":"https://api.github.com/repos/wso2/esb-connectors/pulls/69/comments","review_comment_url":"https://api.github.com/repos/wso2/esb-connectors/pulls/comments{/number}","comments_url":"https://api.github.com/repos/wso2/esb-connectors/issues/69/comments","statuses_url":"https://api.github.com/repos/wso2/esb-connectors/statuses/188ff39122ecc61b371828725d0e6e6c58553996","head":{"label":"ashalya:master","ref":"master","sha":"188ff39122ecc61b371828725d0e6e6c58553996","user":{"login":"ashalya","id":8655189,"avatar_url":"https://avatars.githubusercontent.com/u/8655189?v=3","gravatar_id":"","url":"https://api.github.com/users/ashalya","html_url":"https://github.com/ashalya","followers_url":"https://api.github.com/users/ashalya/followers","following_url":"https://api.github.com/users/ashalya/following{/other_user}","gists_url":"https://api.github.com/users/ashalya/gists{/gist_id}","starred_url":"https://api.github.com/users/ashalya/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ashalya/subscriptions","organizations_url":"https://api.github.com/users/ashalya/orgs","repos_url":"https://api.github.com/users/ashalya/repos","events_url":"https://api.github.com/users/ashalya/events{/privacy}","received_events_url":"https://api.github.com/users/ashalya/received_events","type":"User","site_admin":false},"repo":null},"base":{"label":"wso2:master","ref":"master","sha":"54cbc4704ad6646e610fa8a37d916356cd41da71","user":{"login":"wso2","id":533043,"avatar_url":"https://avatars.githubusercontent.com/u/533043?v=3","gravatar_id":"","url":"https://api.github.com/users/wso2","html_url":"https://github.com/wso2","followers_url":"https://api.github.com/users/wso2/followers","following_url":"https://api.github.com/users/wso2/following{/other_user}","gists_url":"https://api.github.com/users/wso2/gists{/gist_id}","starred_url":"https://api.github.com/users/wso2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wso2/subscriptions","organizations_url":"https://api.github.com/users/wso2/orgs","repos_url":"https://api.github.com/users/wso2/repos","events_url":"https://api.github.com/users/wso2/events{/privacy}","received_events_url":"https://api.github.com/users/wso2/received_events","type":"Organization","site_admin":false},"repo":{"id":14882706,"name":"esb-connectors","full_name":"wso2/esb-connectors","owner":{"login":"wso2","id":533043,"avatar_url":"https://avatars.githubusercontent.com/u/533043?v=3","gravatar_id":"","url":"https://api.github.com/users/wso2","html_url":"https://github.com/wso2","followers_url":"https://api.github.com/users/wso2/followers","following_url":"https://api.github.com/users/wso2/following{/other_user}","gists_url":"https://api.github.com/users/wso2/gists{/gist_id}","starred_url":"https://api.github.com/users/wso2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wso2/subscriptions","organizations_url":"https://api.github.com/users/wso2/orgs","repos_url":"https://api.github.com/users/wso2/repos","events_url":"https://api.github.com/users/wso2/events{/privacy}","received_events_url":"https://api.github.com/users/wso2/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/wso2/esb-connectors","description":"","fork":false,"url":"https://api.github.com/repos/wso2/esb-connectors","forks_url":"https://api.github.com/repos/wso2/esb-connectors/forks","keys_url":"https://api.github.com/repos/wso2/esb-connectors/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wso2/esb-connectors/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wso2/esb-connectors/teams","hooks_url":"https://api.github.com/repos/wso2/esb-connectors/hooks","issue_events_url":"https://api.github.com/repos/wso2/esb-connectors/issues/events{/number}","events_url":"https://api.github.com/repos/wso2/esb-connectors/events","assignees_url":"https://api.github.com/repos/wso2/esb-connectors/assignees{/user}","branches_url":"https://api.github.com/repos/wso2/esb-connectors/branches{/branch}","tags_url":"https://api.github.com/repos/wso2/esb-connectors/tags","blobs_url":"https://api.github.com/repos/wso2/esb-connectors/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wso2/esb-connectors/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wso2/esb-connectors/git/refs{/sha}","trees_url":"https://api.github.com/repos/wso2/esb-connectors/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wso2/esb-connectors/statuses/{sha}","languages_url":"https://api.github.com/repos/wso2/esb-connectors/languages","stargazers_url":"https://api.github.com/repos/wso2/esb-connectors/stargazers","contributors_url":"https://api.github.com/repos/wso2/esb-connectors/contributors","subscribers_url":"https://api.github.com/repos/wso2/esb-connectors/subscribers","subscription_url":"https://api.github.com/repos/wso2/esb-connectors/subscription","commits_url":"https://api.github.com/repos/wso2/esb-connectors/commits{/sha}","git_commits_url":"https://api.github.com/repos/wso2/esb-connectors/git/commits{/sha}","comments_url":"https://api.github.com/repos/wso2/esb-connectors/comments{/number}","issue_comment_url":"https://api.github.com/repos/wso2/esb-connectors/issues/comments{/number}","contents_url":"https://api.github.com/repos/wso2/esb-connectors/contents/{+path}","compare_url":"https://api.github.com/repos/wso2/esb-connectors/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wso2/esb-connectors/merges","archive_url":"https://api.github.com/repos/wso2/esb-connectors/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wso2/esb-connectors/downloads","issues_url":"https://api.github.com/repos/wso2/esb-connectors/issues{/number}","pulls_url":"https://api.github.com/repos/wso2/esb-connectors/pulls{/number}","milestones_url":"https://api.github.com/repos/wso2/esb-connectors/milestones{/number}","notifications_url":"https://api.github.com/repos/wso2/esb-connectors/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wso2/esb-connectors/labels{/name}","releases_url":"https://api.github.com/repos/wso2/esb-connectors/releases{/id}","created_at":"2013-12-03T03:43:53Z","updated_at":"2015-11-11T09:01:00Z","pushed_at":"2015-12-14T04:37:11Z","git_url":"git://github.com/wso2/esb-connectors.git","ssh_url":"git@github.com:wso2/esb-connectors.git","clone_url":"https://github.com/wso2/esb-connectors.git","svn_url":"https://github.com/wso2/esb-connectors","homepage":null,"size":296439,"stargazers_count":24,"watchers_count":24,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":183,"mirror_url":null,"open_issues_count":52,"forks":183,"open_issues":52,"watchers":24,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/wso2/esb-connectors/pulls/69"},"html":{"href":"https://github.com/wso2/esb-connectors/pull/69"},"issue":{"href":"https://api.github.com/repos/wso2/esb-connectors/issues/69"},"comments":{"href":"https://api.github.com/repos/wso2/esb-connectors/issues/69/comments"},"review_comments":{"href":"https://api.github.com/repos/wso2/esb-connectors/pulls/69/comments"},"review_comment":{"href":"https://api.github.com/repos/wso2/esb-connectors/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/wso2/esb-connectors/pulls/69/commits"},"statuses":{"href":"https://api.github.com/repos/wso2/esb-connectors/statuses/188ff39122ecc61b371828725d0e6e6c58553996"}}}}