@Test
  public void testByteArrayToSMIME() {
    try {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      TEST_CASE1.writeTo(out);
      ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());

      ByteArraytoSMIME transformer = new ByteArraytoSMIME();

      Object object = transformer.transformMimeMessage(in, null);
      assertNotNull(object);
      assertTrue(object instanceof MimeMultipart);

      MimeMultipart mime = (MimeMultipart) object;

      assertEquals(TEST_CASE1.getBodyPart(0).getContent(), mime.getBodyPart(0).getContent());
      assertEquals(TEST_CASE1.getBodyPart(1).getContent(), mime.getBodyPart(1).getContent());

    } catch (TransformerException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      fail();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      fail();
    } catch (MessagingException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      fail();
    }
  }
 @Override
 public synchronized void writeTo(OutputStream os) throws IOException, MessagingException {
   if (ZPARSER) {
     InputStream is =
         parent instanceof JavaMailShim
             ? zmultipart.getInputStream()
             : zmultipart.getRawContentStream();
     JavaMailMimeBodyPart.writeTo(is, os);
   } else {
     super.writeTo(os);
   }
 }
  /**
   * Encrypts a mulit part MIME entity using the provided certificates.
   *
   * @param entity The entity that will be encrypted.
   * @param encryptingCertificates The public certificates that will be used to encrypt the message.
   * @return A MimeEntity containing the encrypted part.
   */
  public MimeEntity encrypt(
      MimeMultipart mmEntity, Collection<X509Certificate> encryptingCertificates) {
    MimeEntity entToEncrypt = null;

    ByteArrayOutputStream oStream = new ByteArrayOutputStream();
    try {
      mmEntity.writeTo(oStream);
      oStream.flush();
      InternetHeaders headers = new InternetHeaders();
      headers.addHeader(MimeStandard.ContentTypeHeader, mmEntity.getContentType());

      entToEncrypt = new MimeEntity(headers, oStream.toByteArray());
      oStream.close();
    } catch (Exception e) {
      throw new MimeException(MimeError.InvalidMimeEntity, e);
    }

    return this.encrypt(entToEncrypt, encryptingCertificates);
  }
  /**
   * Sends nested multipart response. Outer multipart wraps all the keys requested. Each key has a
   * separate multipart for the versioned values.
   */
  @Override
  public void sendResponse(StoreStats performanceStats, boolean isFromLocalZone, long startTimeInMs)
      throws Exception {

    // multiPartKeys is the outer multipart
    MimeMultipart multiPartKeys = new MimeMultipart();
    ByteArrayOutputStream keysOutputStream = new ByteArrayOutputStream();

    for (Entry<ByteArray, List<Versioned<byte[]>>> entry : versionedResponses.entrySet()) {
      ByteArray key = entry.getKey();
      String contentLocationKey =
          "/" + this.storeName + "/" + new String(Base64.encodeBase64(key.get()));

      // Create the individual body part - for each key requested
      MimeBodyPart keyBody = new MimeBodyPart();
      try {
        // Add the right headers
        keyBody.addHeader(CONTENT_TYPE, "application/octet-stream");
        keyBody.addHeader(CONTENT_TRANSFER_ENCODING, "binary");
        keyBody.addHeader(CONTENT_LOCATION, contentLocationKey);
      } catch (MessagingException me) {
        logger.error("Exception while constructing key body headers", me);
        keysOutputStream.close();
        throw me;
      }
      // multiPartValues is the inner multipart
      MimeMultipart multiPartValues = new MimeMultipart();
      for (Versioned<byte[]> versionedValue : entry.getValue()) {

        byte[] responseValue = versionedValue.getValue();

        VectorClock vectorClock = (VectorClock) versionedValue.getVersion();
        String eTag = RestUtils.getSerializedVectorClock(vectorClock);

        // Create the individual body part - for each versioned value of
        // a key
        MimeBodyPart valueBody = new MimeBodyPart();
        try {
          // Add the right headers
          valueBody.addHeader(CONTENT_TYPE, "application/octet-stream");
          valueBody.addHeader(CONTENT_TRANSFER_ENCODING, "binary");
          valueBody.addHeader(RestMessageHeaders.X_VOLD_VECTOR_CLOCK, eTag);
          valueBody.setContent(responseValue, "application/octet-stream");

          multiPartValues.addBodyPart(valueBody);
        } catch (MessagingException me) {
          logger.error("Exception while constructing value body part", me);
          keysOutputStream.close();
          throw me;
        }
      }
      try {
        // Add the inner multipart as the content of the outer body part
        keyBody.setContent(multiPartValues);
        multiPartKeys.addBodyPart(keyBody);
      } catch (MessagingException me) {
        logger.error("Exception while constructing key body part", me);
        keysOutputStream.close();
        throw me;
      }
    }
    try {
      multiPartKeys.writeTo(keysOutputStream);
    } catch (Exception e) {
      logger.error("Exception while writing mutipart to output stream", e);
      throw e;
    }

    ChannelBuffer responseContent = ChannelBuffers.dynamicBuffer();
    responseContent.writeBytes(keysOutputStream.toByteArray());

    // Create the Response object
    HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);

    // Set the right headers
    response.setHeader(CONTENT_TYPE, "multipart/binary");
    response.setHeader(CONTENT_TRANSFER_ENCODING, "binary");

    // Copy the data into the payload
    response.setContent(responseContent);
    response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes());

    // Write the response to the Netty Channel
    this.messageEvent.getChannel().write(response);

    if (performanceStats != null && isFromLocalZone) {
      recordStats(performanceStats, startTimeInMs, Tracked.GET_ALL);
    }

    keysOutputStream.close();
  }
    protected SignerInformation createSignerInformation() throws Exception {
      X509CertificateEx internalCert = TestUtils.getInternalCert("user1");
      String testMessage = TestUtils.readResource("MultipartMimeMessage.txt");

      MimeMessage entity = EntitySerializer.Default.deserialize(testMessage);
      Message message = new Message(entity);

      MimeEntity entityToSig = message.extractEntityForSignature(true);

      byte[] messageBytes =
          EntitySerializer.Default.serializeToBytes(entityToSig); // Serialize message out as
      // ASCII encoded...

      MimeBodyPart partToSign = null;

      try {
        partToSign = new MimeBodyPart(new ByteArrayInputStream(messageBytes));
      } catch (Exception e) {
      }

      SMIMESignedGenerator gen = new SMIMESignedGenerator();

      ASN1EncodableVector signedAttrs = new ASN1EncodableVector();
      SMIMECapabilityVector caps = new SMIMECapabilityVector();

      caps.addCapability(SMIMECapability.dES_EDE3_CBC);
      caps.addCapability(SMIMECapability.rC2_CBC, 128);
      caps.addCapability(SMIMECapability.dES_CBC);
      caps.addCapability(new DERObjectIdentifier("1.2.840.113549.1.7.1"));
      caps.addCapability(PKCSObjectIdentifiers.x509Certificate);
      signedAttrs.add(new SMIMECapabilitiesAttribute(caps));

      List<X509Certificate> certList = new ArrayList<X509Certificate>();

      gen.addSigner(
          internalCert.getPrivateKey(),
          internalCert,
          SMIMESignedGenerator.DIGEST_SHA1,
          new AttributeTable(signedAttrs),
          null);
      certList.add(internalCert);

      theGetCertificates = certList;

      MimeMultipart retVal = null;

      CertStore certsAndcrls =
          CertStore.getInstance(
              "Collection",
              new CollectionCertStoreParameters(certList),
              CryptoExtensions.getJCEProviderName());
      gen.addCertificatesAndCRLs(certsAndcrls);

      retVal = gen.generate(partToSign, CryptoExtensions.getJCEProviderName());

      ByteArrayOutputStream oStream = new ByteArrayOutputStream();
      retVal.writeTo(oStream);
      oStream.flush();
      byte[] serialzedBytes = oStream.toByteArray();

      ByteArrayDataSource dataSource =
          new ByteArrayDataSource(serialzedBytes, retVal.getContentType());

      MimeMultipart verifyMM = new MimeMultipart(dataSource);

      CMSSignedData signeddata =
          new CMSSignedData(
              new CMSProcessableBodyPartInbound(partToSign),
              verifyMM.getBodyPart(1).getInputStream());
      SignerInformationStore signers = signeddata.getSignerInfos();
      Collection c = signers.getSigners();
      Iterator it = c.iterator();
      while (it.hasNext()) {
        SignerInformation signer = (SignerInformation) it.next();
        return signer;
      }
      return null;
    }