internal unsafe bool AddMail(IMail mail,
                                 FolderModel folderModel) {
      byte[] rfc822Buffer = mail.Rfc822Buffer;
      Debug.Assert(rfc822Buffer.Length > 0 &&
          rfc822Buffer.Length <= GoogleEmailUploaderConfig.MaximumBatchSize);
      bool canAdd = (
          // If its multimail batch let it be almost default mail batch size
          this.mailCount > 0 &&
          this.MemoryStream.Length + rfc822Buffer.Length + 2048
            <= GoogleEmailUploaderConfig.NormalBatchSize &&
          this.mailCount < GoogleEmailUploaderConfig.MaximumMailsPerBatch
        ) || (
          // If this mail is HUGE then its ok to be in singleton batch.
          this.mailCount == 0 &&
          rfc822Buffer.Length <=
              GoogleEmailUploaderConfig.MaximumBatchSize);

      if (!canAdd) {
        return false;
      }

      this.batchXmlTextWriter.WriteStartElement(MailBatch.EntryElementName,
                                                MailBatch.AtomNS);
      {
        // Add the category element to the feed.
        this.batchXmlTextWriter.WriteStartElement("category",
                                                  MailBatch.AtomNS);
        this.batchXmlTextWriter.WriteAttributeString("scheme",
                                                     MailBatch.GDataKindURI);
        this.batchXmlTextWriter.WriteAttributeString("term",
                                                     MailBatch.AppsMailItemURI);
        this.batchXmlTextWriter.WriteEndElement();
      }
      // Write out batchId
      {
        this.batchXmlTextWriter.WriteStartElement(MailBatch.IdElementName,
                                                  MailBatch.GDataBatchNS);
        this.batchXmlTextWriter.WriteString(this.mailCount.ToString());
        this.batchXmlTextWriter.WriteEndElement();
      }
      // Write out rfc822...
      {
        bool containsNonPrintASCII = false;
        // This test is rough. utf8 is multi byte, so having the illegal xml
        // byte need not mean its illegal xml. We could send every thing as
        // base64. This just helps us to optimize saving bytes on the wire.
        for (int i = 0; i < rfc822Buffer.Length; ++i) {
          byte b = rfc822Buffer[i];
          if (b >= 0x80 ||
              !MailBatch.IsPrintableAscii[b]) {
            containsNonPrintASCII = true;
            break;
          }
        }
        this.batchXmlTextWriter.WriteStartElement("rfc822Msg",
                                                  MailBatch.AppsNS);
        if (containsNonPrintASCII) {
          // If the rfc822 contains illegal xml chars then
          // we use base64 encoding.
          this.batchXmlTextWriter.WriteAttributeString("encoding",
                                                       "base64");
          this.batchXmlTextWriter.WriteBase64(rfc822Buffer,
                                              0,
                                              rfc822Buffer.Length);
        } else {
          // Otherwise we embed the rfc as is.
          string rfcString = Encoding.UTF8.GetString(rfc822Buffer);
          this.batchXmlTextWriter.WriteString(rfcString);
        }
        this.batchXmlTextWriter.WriteEndElement();
      }
      // Write out mail item properties except IS_TRASH. We will not move
      // anything to Trash folder as it automatically empties the Trash.
      {
        if (!mail.IsRead) {
          this.batchXmlTextWriter.WriteStartElement("mailItemProperty",
                                                    MailBatch.AppsNS);
          this.batchXmlTextWriter.WriteAttributeString("value",
                                                       "IS_UNREAD");
          this.batchXmlTextWriter.WriteEndElement();
        }
        if (mail.IsStarred) {
          this.batchXmlTextWriter.WriteStartElement("mailItemProperty",
                                                    MailBatch.AppsNS);
          this.batchXmlTextWriter.WriteAttributeString("value",
                                                       "IS_STARRED");
          this.batchXmlTextWriter.WriteEndElement();
        }
        if (MailBatch.IsAncestor(mail.Folder, FolderKind.Inbox) &&
            !this.GoogleEmailUploaderModel.IsArchiveEverything) {
          this.batchXmlTextWriter.WriteStartElement("mailItemProperty",
                                                    MailBatch.AppsNS);
          this.batchXmlTextWriter.WriteAttributeString("value",
                                                       "IS_INBOX");
          this.batchXmlTextWriter.WriteEndElement();
        }
        if (MailBatch.IsAncestor(mail.Folder, FolderKind.Sent)) {
          this.batchXmlTextWriter.WriteStartElement("mailItemProperty",
                                                    MailBatch.AppsNS);
          this.batchXmlTextWriter.WriteAttributeString("value",
                                                       "IS_SENT");
          this.batchXmlTextWriter.WriteEndElement();
        }
        if (MailBatch.IsAncestor(mail.Folder, FolderKind.Draft)) {
          this.batchXmlTextWriter.WriteStartElement("mailItemProperty",
                                                    MailBatch.AppsNS);
          this.batchXmlTextWriter.WriteAttributeString("value",
                                                       "IS_DRAFT");
          this.batchXmlTextWriter.WriteEndElement();
        }
      }

      // Write out labels...
      {
        string[] labels = folderModel.Labels;
        for (int i = 0; i < labels.Length; ++i) {
          this.batchXmlTextWriter.WriteStartElement("label",
                                                    MailBatch.AppsNS);
          this.batchXmlTextWriter.WriteAttributeString("labelName",
                                                       labels[i]);
          this.batchXmlTextWriter.WriteEndElement();
        }
      }
      this.batchXmlTextWriter.WriteEndElement();

      this.mailCount++;
      this.lastAddedFolderModel = folderModel;
      MailBatchDatum batchData =
          new MailBatchDatum(folderModel,
                             mail.MailId,
                             MailBatch.GetMailHeader(mail));
      this.MailBatchData.Add(batchData);
      return true;
    }
    internal void CreateTestBatch() {
      this.MemoryStream.Position = 0;
      this.MemoryStream.SetLength(0);
      this.MailBatchData.Clear();
      this.mailCount = 1;
      byte[] uploadBuffer = new byte[MailBatch.UploadTestString.Length];
      uploadBuffer = Encoding.UTF8.GetBytes(MailBatch.UploadTestString);
      this.MemoryStream.Write(uploadBuffer,
                              0,
                              MailBatch.UploadTestString.Length);

      MailBatchDatum batchData =
          new MailBatchDatum(null,
                             String.Empty,
                             String.Empty);
      this.MailBatchData.Add(batchData);
    }