public Workshare.PolicyContent.Attachment Repack(IAttachmentNode node, IEnumerable<Attachment> allModifiedAttachments)
		{
			if (!node.WasUnpacked)
			{
				//Non-msg - just give back the modified version of the attachment in this node.

				var attachList = new List<Workshare.PolicyContent.Attachment>(allModifiedAttachments);
				var modified = attachList.Find(delegate(Attachment current)
				{
					return 0 == string.Compare(node.Attachment.Id, current.Id, StringComparison.InvariantCultureIgnoreCase);
				});

				if (modified == null)
				{
					modified = node.Attachment;
				}

				if (modified == null)
				{
					throw new InvalidOperationException("The modified attachment does not have a matching node in the tree");
				}

				return modified;
			}

			OlBodyFormat bodyFormat = DetermineBodyFormat(node.Attachment);

			// Previous solution which using Redemption.MessageItem to handle standalone message
			// will result in Ansi encoded message. ( e.g.MessageItem.Subject encoding changes to Ansi
			// when adding any new attachment). Therefore Unicode message "Subject" will become question
			// marks "?????" as well as for the Unicode attachment file name.
			//
			// Using Redemption.SafeMailItem.Import() will avoid this problem.

			Redemption.SafeMailItem msg = RedemptionLoader.new_SafeMailItem();
			using (new ComRelease(msg))
			{
				WsMailItem mailitem = (WsMailItem) OutlookApp.CreateItem(OlItemType.olMailItem);
				using (new ComRelease(mailitem))
				{
                    msg.Item = mailitem.UnSafeMailItem;
                
					msg.Import(node.BackingByFile);

					RemoveAllAttachmentsFromMSGPreserveSignature(msg, bodyFormat);
					foreach (IAttachmentNode child in node.Children)
					{
						var attachment = Repack(child, allModifiedAttachments);

						int pos = _attachmentPositions[attachment.Id];
						if(!attachment.IsSignature)
						{
							AddAttachmentToMSG(attachment, msg, pos, child.WasUnpacked);
						}
					}

					RemoveReadyRedlineCategory(msg);

					//save msg to disc
					msg.SaveAs(node.Attachment.FileName, OlSaveAsType.olMSGUnicode);
				}
			}

			return node.Attachment;
		}
		public List<Attachment> Unpack(IAttachmentNode child)
		{
			List<int> positions = new List<int>();
			List<Attachment> unpackedItems = new List<Attachment>();
			string tempFile = child.Attachment.FileName;

			// store the msg file location and remove it if by chance it was being scheduled for deletion - case
			// of 2nd level nested msgs
			child.BackingByFile = tempFile;
			_msgFileBackingCopies.Add(tempFile);
			_unpackedTempCopies.Remove(tempFile);

			Redemption.MessageItem message = _mapIutils.GetItemFromMsgFile(tempFile, false);
			
			using (new ComRelease(message))
			{
				int bodyFormat = message.BodyFormat;
				Redemption.Attachments attachments = message.Attachments;
				using (new ComRelease(attachments))
				{
					for (int i = 1; i <= attachments.Count; ++i)
					{
						Redemption.Attachment redemptionAttachment = attachments.Item(i);
						// Don't insert any other code in between this 2 line of code, as redemptionAttachment.EmbeddedMsg
						// may be nulled in the way. why??
						Redemption.MessageItem embeddeditem = redemptionAttachment.EmbeddedMsg;
						positions.Add(redemptionAttachment.Position);

						using (new ComRelease(redemptionAttachment))
						{
							if (embeddeditem != null &&
								OlAttachmentType.olEmbeddeditem == (OlAttachmentType) redemptionAttachment.Type)
							{
								unpackedItems.Add(GetAttachment(embeddeditem));
							}
							else
							{
								unpackedItems.Add(GetAttachment(redemptionAttachment, bodyFormat));
							}


						}
					}
				}
			}

			child.WasUnpacked = true;
			for (int i = 0; i < unpackedItems.Count; i++)
			{
				_attachmentPositions.Add(unpackedItems[i].Id, positions[i]);
			}
			return unpackedItems;
		}
		private Attachment Repack(IAttachmentNode node, IEnumerable<Attachment> allModifiedAttachments)
		{
			return m_mat.Repack(node, allModifiedAttachments);
		}
		/// <summary>
		/// Extract the contents of a single MSG file into a flat list.
		/// </summary>
		/// <param name="attachment">the MSG attachment</param>
		/// <returns>A list of the top-level contents of the msg</returns>
		private List<Attachment> Unpack(IAttachmentNode child)
		{
			return m_mat.Unpack(child);
		}
		private void TraverseAttachments(IEnumerable<Attachment> attachments, IAttachmentNode parent, int depth)
		{
			List<Attachment> attachList = new List<Attachment>(attachments);

			foreach (Attachment attachment in attachList)
			{
				if (attachment.IgnoreForWorkshareActions)
				{
					m_flattenedList.Add(attachment);// Just add it & carry on, we want it in the list for sendlink etc to use, but don't want to do anything with it.
					continue;
				}

				AttachmentNode child = new AttachmentNode(attachment);
				parent.Children.Add(child);

				if (IsUnpackable(attachment) &&
					 depth < m_nestingLimit) //Only unpack if not already nested too deep. 
				{
					List<Attachment> unpackedStuff = Unpack(child);
					TraverseAttachments(unpackedStuff, child, depth + 1);
				}
				else
				{
					m_flattenedList.Add(attachment);
				}
			}

		}
		public List<Attachment> Unpack(IAttachmentNode child)
		{
			var positions = new List<int>();
			var unpackedItems = new List<Attachment>();
			var tempFile = child.Attachment.FileName;

			// store the msg file location and remove it if by chance it was being scheduled for deletion - case
			// of 2nd level nested msgs
			child.BackingByFile = tempFile;
			_msgFileBackingCopies.Add(tempFile);
			_unpackedTempCopies.Remove(tempFile);

            using (var mailitem = OutlookApp.CreateItemFromTemplate(tempFile))
            {
                if (mailitem == null)
                    return unpackedItems; // we end up in here for attached contacts, which aren't mail items

                OlBodyFormat bodyFormat = mailitem.BodyFormat;

                Interop.Logging.Logger.LogDebug("Mail Format:" + bodyFormat.ToString() +
                                                "Attachment container filename: " + tempFile);

                Attachments attachments = mailitem.Attachments;
                for (int i = 1; i <= attachments.Count; ++i)
                {
                    Microsoft.Office.Interop.Outlook.Attachment attachment = attachments[i];
                    if (bodyFormat == OlBodyFormat.olFormatRichText)
                    {
                        positions.Add(attachment.Position);
                    }
                    else
                    {
                        positions.Add(-1);
                    }

                    string attachmentName = attachment.FileName;
                    if (string.IsNullOrEmpty(attachmentName))
                    {
                        attachmentName = attachment.DisplayName;
                    }

                    string temp = LocalFileManager.GetLocalCopyOfFileTarget(attachmentName);
                    if (File.Exists(temp))
                    {
                        File.Delete(temp);
                    }

                    attachment.SaveAsFile(temp);
                    _unpackedTempCopies.Add(temp);

                    Interop.Logging.Logger.LogDebug("Unpacked attachment filename: " + temp);

                    string attname;
                    if ((attachment.Type == OlAttachmentType.olOLE) &&
                        (bodyFormat == OlBodyFormat.olFormatRichText))
                    {
                        attname = attachment.DisplayName;
                    }
                    else
                    {
                        attname = attachment.FileName;

                        // Remove the .msg extension for embedded messages.
                        // This code should be kept in line with that used to process the
                        // email via MAPI, for Office 2003/2007 - See RWSMailAttachmentTransform.
                        // (MAPI processing uses the subject field for the attachment name,
                        // so doesn't have a .msg extension)
                        if (attachment.Type == OlAttachmentType.olEmbeddeditem)
                        {
                            attname = RemoveMsgExtension(attname);
                        }
                    }

                    attname = LocalCopyOfFileManager.GetValidFileName_excl_invalid_chars(attname);
                    Attachment att = new Attachment(new FCS.Lite.Interface.File(temp, attname), string.Empty,
                                                    Guid.NewGuid().ToString(), string.Empty, false)
                                            {
                                                Properties =
                                                    new[]
                                                        {new CustomProperty(PropertyNames.LocalFileName, temp)},
                                                IsSignature =
                                                    OomSignatureInspector.IsSignature(attachment, bodyFormat)
                                            };
                    unpackedItems.Add(att);

                }
                mailitem.Close(OlInspectorClose.olDiscard);

                child.WasUnpacked = true;
                for (int i = 0; i < unpackedItems.Count; i++)
                {
                    _attachmentPositions.Add(unpackedItems[i].Id, positions[i]);
                }
                return unpackedItems;
            }
		}
		public Attachment Repack(IAttachmentNode node, IEnumerable<Attachment> allModifiedAttachments)
		{
		    if (!node.WasUnpacked)
		    {
		        //Non-msg - just give back the modified version of the attachment in this node.

		        List<Attachment> attachList = new List<Attachment>(allModifiedAttachments);
		        Attachment modified = attachList.Find(
		            delegate(Attachment current)
		                {
		                    return 0 ==
		                           string.Compare(node.Attachment.Id, current.Id, StringComparison.InvariantCultureIgnoreCase);
		                });

		        if (modified == null)
		        {
		            modified = node.Attachment;
		        }

		        if (modified == null)
		        {
		            throw new InvalidOperationException("The modified attachment does not have a matching node in the tree");
		        }

		        return modified;
		    }

            var mailitem = CreateMSGAttachmentCopy(node.BackingByFile);
			if (mailitem != null)
		    {
		        Attachments attachments = mailitem.Attachments;
		        RemoveAllAttachmentsFromMsg(attachments, mailitem.BodyFormat);
		        foreach (IAttachmentNode child in node.Children)
		        {
		            Attachment attachment = Repack(child, allModifiedAttachments);
		            int pos = _attachmentPositions[attachment.Id];
		            AddAttachmentToMsg(attachment, attachments, pos, child.WasUnpacked);
		        }

		        RemoveReadyRedlineCategory(mailitem);

		        //save msg to disc
		        mailitem.SaveAs(node.Attachment.FileName);
				try
				{
					mailitem.Delete();// Otherwise in O2010 we get a mailitem appearing im the inbox (TFS5232)
				}
				catch (Exception e)
				{
					Interop.Logging.Logger.LogError(e);
				} 
		    }

			return node.Attachment;
		}