void DownloadEmailPartsCommand::RunImpl()
{
	m_emailParser->Begin();

	try{
		// determine part's original mime type first if this download request is for
		// on-demand download
		if (!m_request->GetPartId().null() && !m_request->GetPartId().undefined()) {
			EmailPartList parts =  m_email->GetPartList();
			EmailPartList::iterator itr;
			for (itr = parts.begin(); itr != parts.end(); itr++) {
				EmailPartPtr part = *itr;
				if (part->GetId() == m_request->GetPartId()) {
					m_partMimeType = part->GetMimeType();
					break;
				}
			}
		}

		// Command syntax: "RETR <msg_num>".
		std::ostringstream command;
		command << COMMAND_STRING << " " << m_msgNum;
		SendCommand(command.str());
	}
	catch (const std::exception& e) {
		MojLogError(m_log, "Exception in preparing download email parts request: '%s'", e.what());
		m_parseFailed = true;
		Failure(e);
	} catch (...) {
		MojLogError(m_log, "Unknown exception in preparing download email parts request");
		m_parseFailed = true;
		Failure(MailException("Unknown exception in preparing download email parts request", __FILE__, __LINE__));
	}
}
void EmailAdapter::SerializeParts(const EmailPartList& partsList, MojObject& partsArrayObj)
{
	EmailPartList::const_iterator it;
	
	for(it = partsList.begin(); it != partsList.end(); ++it) {
		EmailPartPtr emailPart = *it;
		if (!emailPart.get()) {
			throw MailException("Unable to serialize email: one of the parts is null", __FILE__, __LINE__);
		}

		MojObject partObj;
		MojErr err;
		
		// Add part information to the part object
		err = partObj.putString(Part::TYPE, GetPartTypeAsString(emailPart));
		ErrorToException(err);
		
		err = partObj.putString(Part::MIME_TYPE, emailPart->GetMimeType().c_str());
		ErrorToException(err);
		
		DatabaseAdapter::PutOptionalString(partObj, Part::PATH, emailPart->GetLocalFilePath());
		DatabaseAdapter::PutOptionalString(partObj, Part::NAME, emailPart->GetDisplayName());
		DatabaseAdapter::PutOptionalString(partObj, Part::CONTENT_ID, emailPart->GetContentId());
		DatabaseAdapter::PutOptionalString(partObj, Part::ENCODING, emailPart->GetEncoding());
		DatabaseAdapter::PutOptionalString(partObj, Part::CHARSET, emailPart->GetCharset());
		DatabaseAdapter::PutOptionalString(partObj, Part::SECTION, emailPart->GetSection());

		if(emailPart->GetEstimatedSize() >= 0) {
			err = partObj.put(Part::ESTIMATED_SIZE, emailPart->GetEstimatedSize());
			ErrorToException(err);
		}

		if(emailPart->GetEncodedSize() >= 0) {
			err = partObj.put(Part::ENCODED_SIZE, emailPart->GetEncodedSize());
			ErrorToException(err);
		}

		// Add to partsArrayObject
		err = partsArrayObj.push(partObj);
		ErrorToException(err);
	}
}
void DownloadEmailPartsCommand::CompleteDownloadListener()
{
	try{
		if (m_listener.get()) {
			if (m_parseFailed) {
				MojLogError(m_log, "Replying download body error back to caller");
				m_listener->ReportError("Failed to download email");
			} else {
				if (!m_email->IsDownloaded()) {
					// Get first text part's mime type as the mime type to complete
					// the download request in download listener.
					EmailPartList parts = m_email->GetPartList();
					EmailPartList::iterator itr;
					for (itr = parts.begin(); itr != parts.end(); itr++) {
						EmailPartPtr part = *itr;
						if (part->GetMimeType().find("text") != std::string::npos) {
							m_partMimeType = part->GetMimeType();
							m_partPath = part->GetLocalFilePath();
						}
					}
				}

				MojLogInfo(m_log, "Replying download email completion to caller");
				m_listener->ReportComplete(m_msgSize, m_msgSize, m_partPath, m_partMimeType);
			}
		}
	} catch (const std::exception& e) {
		MojLogError(m_log, "Encountered error in downloading email parts: '%s'", e.what());
		m_parseFailed = true;
		Failure(e);
	} catch (...) {
		MojLogError(m_log, "Encountered error in downloading email parts");
		m_parseFailed = true;
		Failure(MailException("Encountered error in downloading email parts", __FILE__, __LINE__));
	}
}