// This is used for the Cryptzone Secure Email Action
		// We can only support one Action that has this property and still function
		// in a reasonable fashion since we are allowing the Action to remove all 
		// attachments and replace then with completely new ones. JE 19.10.2011
		private static void RemoveAllAttachments(dynamic mailItem)
		{
			Redemption.SafeMailItem messageItem = new Redemption.SafeMailItemClass();
            using (new ComRelease(messageItem))
            {
                messageItem.Item = mailItem.UnSafeMailItem;
                Redemption.Attachments attachments = messageItem.Attachments;

                for (int index = attachments.Count; index > 0; --index)
                {
                    // TODO: The way OLE attachments are handled needs looking into.
                    // Currently OLE objects are not added back to the outgoing mail item
                    // as processed attachments, so we need to make sure we don't remove them here.
                    if (attachments[index].Type != (int) MsOutlook.OlAttachmentType.olOLE)
                    {
                        attachments.Remove(index);
                    }
                }
            }
		}
		// This is used for the Cryptzone Secure Email Action
		// We can only support one Action that has this property and still function
		// in a reasonable fashion since we are allowing the Action to remove all 
		// attachments and replace then with completely new ones. JE 19.10.2011
		public void ReplaceAttachments(dynamic mailItem, Workshare.PolicyContent.Attachment[] processedAttachments)
		{
			RemoveAllAttachments(mailItem);

            var rdMAPIUtils = new Redemption.MAPIUtilsClass();
			Redemption.SafeMailItem messageItem = new Redemption.SafeMailItemClass();
            using (new ComRelease(messageItem))
            {
                messageItem.Item = mailItem.UnSafeMailItem;
                int renderingPosition = 1;

                foreach (var attachment in processedAttachments)
                {
                    string fileName = attachment.FileName;
                    string displayName = attachment.Name;

                    Redemption.Attachment rdAttachment;

                    if (fileName.EndsWith(".msg", StringComparison.InvariantCultureIgnoreCase))
                    {
                        Redemption.MessageItem msgItem = rdMAPIUtils.GetItemFromMsgFile(fileName, false);

                        // Need to release "msgitem" before delete the file, as it holds reference to the file.
                        using (new ComRelease(msgItem))
                        {
                            // Attach .msg via "olEmbeddedItem" to avoid Unicode msg attachment being blocked
                            // by "Symantec anti-virus Outlook addin"
                            rdAttachment = messageItem.Attachments.Add(msgItem, OlAttachmentType.olEmbeddeditem,
                                                                        renderingPosition, displayName);

                            // Redemption does not set Unicode displayname properly, need to set manually.
                            rdAttachment.Fields[MapiDefines.PR_DISPLAY_NAME_W] = displayName;
                        }
                    }
                    else
                    {
                        rdAttachment = messageItem.Attachments.Add(fileName, OlAttachmentType.olByValue,
                                                                    renderingPosition, displayName);

                        // Redemption.dll (current version 4.6.0.924) didn't handle Unicode correctly for 
                        // Attachments.Add() function. It attempts to convert Unicode filename to Ansi code
                        // based on current System Locale ("Language for non-Unicode program"). 
                        // Attachment with "e.g. Chinese/Cyrillic" filename will appear as "????".
                        // Check whether filename can be encoded with current default code page.
                        Encoding ansiEncoding = Encoding.GetEncoding(Encoding.Default.CodePage,
                                                                        new EncoderExceptionFallback(),
                                                                        new DecoderExceptionFallback());
                        try
                        {
                            byte[] ansiBytes = ansiEncoding.GetBytes(displayName);
                        }
                        catch (EncoderFallbackException)
                        {
                            // If cannot convert using current system codepage, Redemption's Attachments.add() 
                            // will not behave correctly. Have to manually set the FileName and Displayname with Unicode string.
                            rdAttachment.Fields[MapiDefines.PR_ATTACH_LONG_FILENAME_W] = displayName;
                            rdAttachment.Fields[MapiDefines.PR_ATTACH_FILENAME_W] = displayName;
                            rdAttachment.Fields[MapiDefines.PR_DISPLAY_NAME_W] = displayName;
                        }
                    }

                    //We have an attachment that was not in the original collection.
                    //Dont have all the info but we at least know the attachment content id.
                    if (!string.IsNullOrEmpty(attachment.Id))
                    {
                        rdAttachment.Fields[MapiDefines.PR_ATTACH_CONTENT_ID] = attachment.Id;
                    }

                    ++renderingPosition;
                }
            }

			rdMAPIUtils.Cleanup();
            if (Marshal.IsComObject(rdMAPIUtils))
            {
			    Marshal.ReleaseComObject(rdMAPIUtils);
            }
		}