private static XElement ProcessImage(WordprocessingDocument wordDoc,
            XElement element, Func<ImageInfo, XElement> imageHandler)
        {
            if (element.Name == W.drawing)
            {
                XElement containerElement = element.Elements()
                    .Where(e => e.Name == WP.inline || e.Name == WP.anchor)
                    .FirstOrDefault();
                if (containerElement != null)
                {
                    int? extentCx = (int?)containerElement.Elements(WP.extent)
                        .Attributes(NoNamespace.cx).FirstOrDefault();
                    int? extentCy = (int?)containerElement.Elements(WP.extent)
                        .Attributes(NoNamespace.cy).FirstOrDefault();
                    string altText = (string)containerElement.Elements(WP.docPr)
                        .Attributes(NoNamespace.descr).FirstOrDefault();
                    if (altText == null)
                        altText = (string)containerElement.Elements(WP.docPr)
                            .Attributes(NoNamespace.name).FirstOrDefault();
                    if (altText == null)
                        altText = "";

                    XElement blipFill = containerElement.Elements(A.graphic)
                        .Elements(A.graphicData)
                        .Elements(Pic._pic).Elements(Pic.blipFill).FirstOrDefault();
                    if (blipFill != null)
                    {
                        string imageRid = (string)blipFill.Elements(A.blip).Attributes(R.embed)
                            .FirstOrDefault();
                        if (imageRid != null)
                        {
                            var pp3 = wordDoc.MainDocumentPart.Parts.FirstOrDefault(pp => pp.RelationshipId == imageRid);
                            if (pp3 == null)
                                return null;
                            ImagePart imagePart = (ImagePart)pp3.OpenXmlPart;
                            if (imagePart == null)
                                return null;
                            // if the image markup points to a NULL image, then following will throw an ArgumentOutOfRangeException
                            try
                            {
                                imagePart = (ImagePart)wordDoc.MainDocumentPart
                                    .GetPartById(imageRid);
                            }
                            catch (ArgumentOutOfRangeException)
                            {
                                return null;
                            }
                            string contentType = imagePart.ContentType;
                            if (contentType == "image/png" ||
                                contentType == "image/gif" ||
                                contentType == "image/tiff" ||
                                contentType == "image/jpeg")
                            {
                                using (Stream partStream = imagePart.GetStream())
                                using (Bitmap bitmap = new Bitmap(partStream))
                                {
                                    if (extentCx != null && extentCy != null)
                                    {
                                        ImageInfo imageInfo = new ImageInfo()
                                        {
                                            Bitmap = bitmap,
                                            ImgStyleAttribute = new XAttribute("style",
                                                string.Format("width: {0}in; height: {1}in",
                                                    (float)extentCx / (float)ImageInfo.EmusPerInch,
                                                    (float)extentCy / (float)ImageInfo.EmusPerInch)),
                                            ContentType = contentType,
                                            DrawingElement = element,
                                            AltText = altText,
                                        };
                                        return imageHandler(imageInfo);
                                    }
                                    ImageInfo imageInfo2 = new ImageInfo()
                                    {
                                        Bitmap = bitmap,
                                        ContentType = contentType,
                                        DrawingElement = element,
                                        AltText = altText,
                                    };
                                    return imageHandler(imageInfo2);
                                };
                            }
                        }
                    }
                }
            }
            if (element.Name == W.pict || element.Name == W._object)
            {
                string imageRid = (string)element.Elements(VML.shape)
                    .Elements(VML.imagedata).Attributes(R.id).FirstOrDefault();
                string style = (string)element.Elements(VML.shape)
                    .Attributes("style").FirstOrDefault();
                if (imageRid != null)
                {
                    try
                    {
                        var pp = wordDoc.MainDocumentPart.Parts.FirstOrDefault(pp2 => pp2.RelationshipId == imageRid);
                        if (pp == null)
                            return null;
                        ImagePart imagePart = (ImagePart)pp.OpenXmlPart;
                        if (imagePart == null)
                            return null;
                        string contentType = imagePart.ContentType;
                        if (contentType == "image/png"
                            || contentType == "image/gif"
                            || contentType == "image/tiff"
                            || contentType == "image/jpeg"
                            // don't process wmf files because GDI consumes huge amounts of memory when dealing with wmf
                            // perhaps because it loads a DLL to do the rendering?
                            // it actually works, but is not recommended
                            //  || contentType == "image/x-wmf"
                        )
                        {
                            //string style = element.
                            using (Stream partStream = imagePart.GetStream())
                                try
                                {
                                    using (Bitmap bitmap = new Bitmap(partStream))
                                    {
                                        ImageInfo imageInfo = new ImageInfo()
                                        {
                                            Bitmap = bitmap,
                                            ContentType = contentType,
                                            DrawingElement = element,
                                        };
                                        if (style != null)
                                        {
                                            float? widthInPoints = null;
                                            float? heightInPoints = null;
                                            string[] tokens = style.Split(';');
                                            var widthString = tokens
                                                .Select(t => new Atnv
                                                {
                                                    Name = t.Split(':').First(),
                                                    Value = t.Split(':').Skip(1)
                                                        .Take(1).FirstOrDefault(),
                                                })
                                                .Where(p => p.Name == "width")
                                                .Select(p => p.Value)
                                                .FirstOrDefault();
                                            if (widthString != null &&
                                                widthString.Length > 2 &&
                                                widthString.Substring(widthString.Length - 2) == "pt")
                                            {
                                                float w;
                                                if (float.TryParse(widthString.Substring(0,
                                                    widthString.Length - 2), out w))
                                                    widthInPoints = w;
                                            }
                                            var heightString = tokens
                                                .Select(t => new Atnv
                                                {
                                                    Name = t.Split(':').First(),
                                                    Value = t.Split(':').Skip(1).Take(1).FirstOrDefault(),
                                                })
                                                .Where(p => p.Name == "height")
                                                .Select(p => p.Value)
                                                .FirstOrDefault();
                                            if (heightString != null &&
                                                heightString.Substring(heightString.Length - 2) == "pt")
                                            {
                                                float h;
                                                if (float.TryParse(heightString.Substring(0,
                                                    heightString.Length - 2), out h))
                                                    heightInPoints = h;
                                            }
                                            if (widthInPoints != null && heightInPoints != null)
                                                imageInfo.ImgStyleAttribute = new XAttribute(
                                                    "style", string.Format(
                                                        "width: {0}pt; height: {1}pt",
                                                        widthInPoints, heightInPoints));
                                        }
                                        return imageHandler(imageInfo);
                                    };
                                }
                                // the Bitmap class can throw OutOfMemoryException, which means the bitmap is messed up, so punt.
                                catch (OutOfMemoryException)
                                {
                                    return null;
                                }
                                catch (ArgumentException)
                                {
                                    return null;
                                }
                        }
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        return null;
                    }
                }
            }
            return null;
        }
        private static XElement ProcessDrawing(WordprocessingDocument wordDoc,
            XElement element, Func<ImageInfo, XElement> imageHandler)
        {
            var containerElement = element.Elements()
                .FirstOrDefault(e => e.Name == WP.inline || e.Name == WP.anchor);
            if (containerElement == null) return null;

            var extentCx = (int?)containerElement.Elements(WP.extent)
                .Attributes(NoNamespace.cx).FirstOrDefault();
            var extentCy = (int?)containerElement.Elements(WP.extent)
                .Attributes(NoNamespace.cy).FirstOrDefault();
            var altText = (string)containerElement.Elements(WP.docPr).Attributes(NoNamespace.descr).FirstOrDefault() ??
                          ((string)containerElement.Elements(WP.docPr).Attributes(NoNamespace.name).FirstOrDefault() ?? "");

            var blipFill = containerElement.Elements(A.graphic)
                .Elements(A.graphicData)
                .Elements(Pic._pic).Elements(Pic.blipFill).FirstOrDefault();
            if (blipFill == null) return null;

            var imageRid = (string)blipFill.Elements(A.blip).Attributes(R.embed).FirstOrDefault();
            if (imageRid == null) return null;

            var pp3 = wordDoc.MainDocumentPart.Parts.FirstOrDefault(pp => pp.RelationshipId == imageRid);
            if (pp3 == null) return null;

            var imagePart = (ImagePart)pp3.OpenXmlPart;
            if (imagePart == null) return null;

            // If the image markup points to a NULL image, then following will throw an ArgumentOutOfRangeException
            try
            {
                imagePart = (ImagePart)wordDoc.MainDocumentPart.GetPartById(imageRid);
            }
            catch (ArgumentOutOfRangeException)
            {
                return null;
            }

            var contentType = imagePart.ContentType;
            if (!ImageContentTypes.Contains(contentType))
                return null;

            using (var partStream = imagePart.GetStream())
            using (var bitmap = new Bitmap(partStream))
            {
                if (extentCx != null && extentCy != null)
                {
                    var imageInfo = new ImageInfo()
                    {
                        Bitmap = bitmap,
                        ImgStyleAttribute = new XAttribute("style",
                            string.Format(NumberFormatInfo.InvariantInfo,
                                "width: {0}in; height: {1}in",
                                (float)extentCx / (float)ImageInfo.EmusPerInch,
                                (float)extentCy / (float)ImageInfo.EmusPerInch)),
                        ContentType = contentType,
                        DrawingElement = element,
                        AltText = altText,
                    };
                    return imageHandler(imageInfo);
                }

                var imageInfo2 = new ImageInfo()
                {
                    Bitmap = bitmap,
                    ContentType = contentType,
                    DrawingElement = element,
                    AltText = altText,
                };
                return imageHandler(imageInfo2);
            }
        }
        private static XElement ProcessPictureOrObject(WordprocessingDocument wordDoc,
            XElement element, Func<ImageInfo, XElement> imageHandler)
        {
            var imageRid = (string)element.Elements(VML.shape).Elements(VML.imagedata).Attributes(R.id).FirstOrDefault();
            if (imageRid == null) return null;

            try
            {
                var pp = wordDoc.MainDocumentPart.Parts.FirstOrDefault(pp2 => pp2.RelationshipId == imageRid);
                if (pp == null) return null;

                var imagePart = (ImagePart)pp.OpenXmlPart;
                if (imagePart == null) return null;

                var contentType = imagePart.ContentType;
                if (!ImageContentTypes.Contains(contentType))
                    return null;

                using (var partStream = imagePart.GetStream())
                {
                    try
                    {
                        using (var bitmap = new Bitmap(partStream))
                        {
                            var imageInfo = new ImageInfo()
                            {
                                Bitmap = bitmap,
                                ContentType = contentType,
                                DrawingElement = element
                            };

                            var style = (string)element.Elements(VML.shape).Attributes("style").FirstOrDefault();
                            if (style == null) return imageHandler(imageInfo);

                            var tokens = style.Split(';');
                            var widthInPoints = WidthInPoints(tokens);
                            var heightInPoints = HeightInPoints(tokens);
                            if (widthInPoints != null && heightInPoints != null)
                            {
                                imageInfo.ImgStyleAttribute = new XAttribute("style",
                                    string.Format(NumberFormatInfo.InvariantInfo,
                                        "width: {0}pt; height: {1}pt", widthInPoints, heightInPoints));
                            }
                            return imageHandler(imageInfo);
                        }
                    }
                    catch (OutOfMemoryException)
                    {
                        // the Bitmap class can throw OutOfMemoryException, which means the bitmap is messed up, so punt.
                        return null;
                    }
                    catch (ArgumentException)
                    {
                        return null;
                    }
                }
            }
            catch (ArgumentOutOfRangeException)
            {
                return null;
            }
        }
        private static XElement ProcessImage(WordprocessingDocument wordDoc,
            XElement element, Func<ImageInfo, XElement> imageHandler)
        {
            if (element.Name == W.drawing)
            {
                XElement containerElement = element.Elements()
                    .Where(e => e.Name == WP.inline || e.Name == WP.anchor)
                    .FirstOrDefault();
                if (containerElement != null)
                {
                    int? extentCx = (int?)containerElement.Elements(WP.extent)
                        .Attributes(NoNamespace.cx).FirstOrDefault();
                    int? extentCy = (int?)containerElement.Elements(WP.extent)
                        .Attributes(NoNamespace.cy).FirstOrDefault();
                    string altText = (string)containerElement.Elements(WP.docPr)
                        .Attributes(NoNamespace.descr).FirstOrDefault();
                    if (altText == null)
                        altText = (string)containerElement.Elements(WP.docPr)
                            .Attributes(NoNamespace.name).FirstOrDefault();
                    if (altText == null)
                        altText = "";

                    XElement blipFill = containerElement.Elements(A.graphic)
                        .Elements(A.graphicData)
                        .Elements(Pic._pic).Elements(Pic.blipFill).FirstOrDefault();
                    if (blipFill != null)
                    {
                        string imageRid = (string)blipFill.Elements(A.blip).Attributes(R.embed)
                            .FirstOrDefault();
                        ImagePart imagePart = (ImagePart)wordDoc.MainDocumentPart
                            .GetPartById(imageRid);
                        string contentType = imagePart.ContentType;
                        if (contentType == "image/png" ||
                            contentType == "image/gif" ||
                            contentType == "image/tiff" ||
                            contentType == "image/jpeg")
                        {
                            using (Stream partStream = imagePart.GetStream())
                            using (Bitmap bitmap = new Bitmap(partStream))
                            {
                                if (extentCx != null && extentCy != null)
                                {
                                    ImageInfo imageInfo = new ImageInfo()
                                    {
                                        Bitmap = bitmap,
                                        ImgStyleAttribute = new XAttribute(HtmlNoNamespace.style,
                                            string.Format("width: {0}in; height: {1}in",
                                                (float)extentCx / (float)ImageInfo.EmusPerInch,
                                                (float)extentCy / (float)ImageInfo.EmusPerInch)),
                                        ContentType = contentType,
                                        DrawingElement = element,
                                        AltText = altText,
                                    };
                                    return imageHandler(imageInfo);
                                }
                                ImageInfo imageInfo2 = new ImageInfo()
                                {
                                    Bitmap = bitmap,
                                    ContentType = contentType,
                                    DrawingElement = element,
                                    AltText = altText,
                                };
                                return imageHandler(imageInfo2);
                            };
                        }
                    }
                }
            }
            if (element.Name == W.pict)
            {
                string imageRid = (string)element.Elements(VML.shape)
                    .Elements(VML.imagedata).Attributes(R.id).FirstOrDefault();
                string style = (string)element.Elements(VML.shape)
                    .Attributes(HtmlNoNamespace.style).FirstOrDefault();
                if (imageRid != null)
                {
                    try
                    {
                        ImagePart imagePart = (ImagePart)wordDoc.MainDocumentPart
                            .GetPartById(imageRid);
                        string contentType = imagePart.ContentType;
                        if (contentType == "image/png" ||
                            contentType == "image/gif" ||
                            contentType == "image/tiff" ||
                            contentType == "image/jpeg")
                        {
                            //string style = element.
                            using (Stream partStream = imagePart.GetStream())
                            using (Bitmap bitmap = new Bitmap(partStream))
                            {
                                ImageInfo imageInfo = new ImageInfo()
                                {
                                    Bitmap = bitmap,
                                    ContentType = contentType,
                                    DrawingElement = element,
                                };
                                if (style != null)
                                {
                                    float? widthInPoints = null;
                                    float? heightInPoints = null;
                                    string[] tokens = style.Split(';');
                                    var widthString = tokens
                                        .Select(t => new
                                        {
                                            Name = t.Split(':').First(),
                                            Value = t.Split(':').Skip(1)
                                                .Take(1).FirstOrDefault(),
                                        })
                                        .Where(p => p.Name == "width")
                                        .Select(p => p.Value)
                                        .FirstOrDefault();
                                    if (widthString != null &&
                                        widthString.Substring(widthString.Length - 2) == "pt")
                                    {
                                        float w;
                                        if (float.TryParse(widthString.Substring(0,
                                            widthString.Length - 2), out w))
                                            widthInPoints = w;
                                    }
                                    var heightString = tokens
                                        .Select(t => new
                                        {
                                            Name = t.Split(':').First(),
                                            Value = t.Split(':').Skip(1).Take(1).FirstOrDefault(),
                                        })
                                        .Where(p => p.Name == "height")
                                        .Select(p => p.Value)
                                        .FirstOrDefault();
                                    if (heightString != null &&
                                        heightString.Substring(heightString.Length - 2) == "pt")
                                    {
                                        float h;
                                        if (float.TryParse(heightString.Substring(0,
                                            heightString.Length - 2), out h))
                                            heightInPoints = h;
                                    }
                                    if (widthInPoints != null && heightInPoints != null)
                                        imageInfo.ImgStyleAttribute = new XAttribute(
                                            HtmlNoNamespace.style, string.Format(
                                                "width: {0}pt; height: {1}pt",
                                                widthInPoints, heightInPoints));
                                }
                                return imageHandler(imageInfo);
                            };
                        }
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        return null;
                    }
                }
            }
            return null;
        }