private static ParagraphProperties GetParagraphProperties(Model.Paragraph paragraph)
        {
            ParagraphProperties paraProps = new ParagraphProperties();

            SpacingBetweenLines paraSpacing = new SpacingBetweenLines()
            {
                Before = Utilities.GetDxaFromPoints(paragraph.SpacingBefore),
                After = Utilities.GetDxaFromPoints(paragraph.SpacingAfter),
                LineRule = LineSpacingRuleValues.Auto,
                //If the value of the lineRule attribute is auto, then the value of the line attribute shall be interpreted as 240ths of a line
                Line = (paragraph.Leading * 240).ToString()
            };

            Justification justification = new Justification();
            switch (paragraph.Justification)
            {
                case DocGen.ObjectModel.Justification.Left:
                    justification.Val = JustificationValues.Left;
                    break;
                case DocGen.ObjectModel.Justification.Center:
                    justification.Val = JustificationValues.Center;
                    break;
                case DocGen.ObjectModel.Justification.Right:
                    justification.Val = JustificationValues.Right;
                    break;
                case DocGen.ObjectModel.Justification.Justified:
                    justification.Val = JustificationValues.Both;
                    break;
            }

            paraProps.Append(justification);
            paraProps.Append(paraSpacing);

            return paraProps;
        }
        private static OpenXmlElement GetImage(Model.Image image, string id)
        {
            //TODO: Calculating From EMU - Should see
            Int64Value width = (Int64Value)image.Width * 1530350 / 72;
            Int64Value height = (Int64Value)image.Width * 1530350 / 72;
            FileInfo file = new FileInfo(image.ImageURL);

            var element = new Drawing(
              new DW.Inline(
              new DW.Extent() { Cx = width, Cy = height },
              new DW.EffectExtent()
              {
                  LeftEdge = 0L,
                  TopEdge = 0L,
                  RightEdge = 0L,
                  BottomEdge = 0L
              },
              new DW.DocProperties()
              {
                  Id = (UInt32Value)1U,
                  Name = file.Name
              },
              new DW.NonVisualGraphicFrameDrawingProperties(
                  new A.GraphicFrameLocks() { NoChangeAspect = true }),
              new A.Graphic(
                  new A.GraphicData(
                      new PIC.Picture(
                          new PIC.NonVisualPictureProperties(
                              new PIC.NonVisualDrawingProperties()
                              {
                                  Id = (UInt32Value)0U,
                                  Name = file.Name
                              },
                              new PIC.NonVisualPictureDrawingProperties()),
                          new PIC.BlipFill(
                              new A.Blip()
                              {
                                  Embed = id,
                                  CompressionState = A.BlipCompressionValues.Print
                              },
                              new A.Stretch(
                                  new A.FillRectangle())),
                          new PIC.ShapeProperties(
                              new A.Transform2D(
                                  new A.Offset() { X = 0L, Y = 0L },
                                  new A.Extents() { Cx = width, Cy = height }),
                              new A.PresetGeometry(
                                  new A.AdjustValueList()
                              ) { Preset = A.ShapeTypeValues.Rectangle }))
                  ) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })
              )
              {
              DistanceFromTop = (UInt32Value)0U,
              DistanceFromBottom = (UInt32Value)0U,
              DistanceFromLeft = (UInt32Value)0U,
              DistanceFromRight = (UInt32Value)0U,
              });

            return element;
        }
        /// <summary>
        /// Returns a OpenXMl paragraph representing formatted listItem.
        /// </summary>
        /// <param name="item">listItem object</param>
        /// <param name="numStyleId">style id to use</param>
        /// <returns></returns>
        private static Paragraph GetListItem(Model.ListItem item, int numStyleId)
        {
            Paragraph listItemPara = new Paragraph();

            ParagraphProperties paraProps = new ParagraphProperties();

            NumberingProperties numberingProps = new NumberingProperties();
            NumberingLevelReference numberingLevelReference = new NumberingLevelReference() { Val = 0 };

            NumberingId numberingId = new NumberingId() { Val = numStyleId };

            numberingProps.Append(numberingLevelReference);
            numberingProps.Append(numberingId);
            paraProps.Append(numberingProps);

            Run listRun = new Run();
            Text listItemText = new Text()
            {
                Text = item.Body
            };
            listRun.Append(listItemText);

            listItemPara.Append(paraProps);
            listItemPara.Append(listRun);

            return listItemPara;
        }
        public static OpenXmlElement GetFormattedElement(Model.Text text)
        {
            Text docText = new Text(text.TextContent);
            Run run = new Run();
            RunProperties runProp = CreateRun(text);

            if (runProp != null) run.Append(runProp);
            run.Append(docText);

            return run;
        }
        /// <summary>
        /// Adds the style for provided heading type if it's not already added.
        /// </summary>
        /// <param name="headingType"></param>
        public static void AddHeadingStyle(Model.HeadingType headingType)
        {
            if (IsStylePresent(StyleIds.GetStyleId(headingType))) {
                return;
            }

            int outlineLevel;

            switch (headingType)
            {
                case DocGen.ObjectModel.HeadingType.H1:
                    outlineLevel = 0;
                    break;
                case DocGen.ObjectModel.HeadingType.H2:
                    outlineLevel = 1;
                    break;
                case DocGen.ObjectModel.HeadingType.H3:
                    outlineLevel = 2;
                    break;
                case DocGen.ObjectModel.HeadingType.H4:
                    outlineLevel = 3;
                    break;
                case DocGen.ObjectModel.HeadingType.H5:
                    outlineLevel = 4;
                    break;
                case DocGen.ObjectModel.HeadingType.H6:
                    outlineLevel = 5;
                    break;
                default:
                    throw new NotImplementedException(headingType + ": Enum value not added");
            }

            Word.Styles styles =  DocumentPackager.GetInstance().GetStylePart().Styles;

            Word.Style style1 = new Word.Style() { Type = Word.StyleValues.Paragraph, StyleId = StyleIds.GetStyleId(headingType) };
            Word.BasedOn basedOn1 = new Word.BasedOn() { Val = "Normal" };

            Word.StyleParagraphProperties styleParagraphProperties1 = new Word.StyleParagraphProperties();
            Word.KeepNext keepNext1 = new Word.KeepNext();
            Word.KeepLines keepLines1 = new Word.KeepLines();
            Word.SpacingBetweenLines spacingBetweenLines1 = new Word.SpacingBetweenLines() { Before = "480", After = "0" };
            Word.OutlineLevel outlineLevel1 = new Word.OutlineLevel() { Val = outlineLevel };

            styleParagraphProperties1.Append(keepNext1);
            styleParagraphProperties1.Append(keepLines1);
            styleParagraphProperties1.Append(spacingBetweenLines1);
            styleParagraphProperties1.Append(outlineLevel1);

            style1.Append(basedOn1);
            style1.Append(styleParagraphProperties1);

            // Add the style to the styles part.
            styles.Append(style1);
        }
        public static OpenXmlElement GetFormattedElement(Model.Heading heading)
        {
            OpenXmlElement formattedPara = ParagraphFormatter.GetFormattedElement(heading);

            IEnumerable<ParagraphProperties> list = formattedPara.Elements<ParagraphProperties>();

            ParagraphProperties tmp = list.FirstOrDefault();

            StyleCreator.AddHeadingStyle(heading.HeadingType);

            ParagraphStyleId style = new ParagraphStyleId()
            {
                Val = StyleIds.GetStyleId(heading.HeadingType)
            };

            tmp.InsertAt(style,1);

            return formattedPara;
        }
        public static OpenXmlElement GetFormattedElement(Model.Paragraph paragraph)
        {
            Paragraph para = new Paragraph();
            para.Append(GetParagraphProperties(paragraph));

            foreach (Model.Element element in paragraph.SubElements)
            {
                if (element is Model.Text)
                {
                    Model.Text text = (Model.Text)element;
                    if (paragraph.Font != null && text.Font == null) text.Font = paragraph.Font;
                    para.Append(TextFormatter.GetFormattedElement(text));
                }
                else {
                    throw new InvalidSubFeatureException(paragraph.GetElementType().ToString(), element.GetElementType().ToString());
                }
            }

            return para;
        }
        /// <summary>
        /// Returns formatted OpenXmlElement[] representing given List instance
        /// </summary>
        /// <param name="list">List object</param>
        /// <returns></returns>
        public static IEnumerable<OpenXmlElement> GetFormattedElement(Model.List list)
        {
            List<OpenXmlElement> result = new List<OpenXmlElement>();

            int numStyleId = StyleCreator.AddNumberingStyle(list.Ordered, list.Label);

            foreach (Model.Element element in list.SubElements)
            {
                if (element.GetElementType() == Model.ElementType.ListItem)
                {
                    result.Add( GetListItem((Model.ListItem)element, numStyleId) );
                }
                else {
                    throw new InvalidSubFeatureException( list.GetElementType().ToString(), element.GetElementType().ToString());
                }
            }

            result.Add(new Paragraph());
            return result.AsEnumerable();
        }
        public static OpenXmlElement GetFormattedElement(Model.Image image)
        {
            MainDocumentPart mainPart = DocumentPackager.GetInstance().GetMainPart();

            //Adding image part to main document part
            ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);

            if (image.ImageURL == null) throw new InvalidInputException("Input XML error : image location not provided for Image element.");

            using (FileStream stream = new FileStream(image.ImageURL, FileMode.Open))
            {
                imagePart.FeedData(stream);
            }

            var imageContent = GetImage(image, mainPart.GetIdOfPart(imagePart));

            var drawing = GetImage(image, mainPart.GetIdOfPart(imagePart));

            Model.Paragraph tmpImagePara = new Model.Paragraph();

            switch (image.HorizontalAlignment)
            {
                case DocGen.ObjectModel.HorizontalAlignment.Left:
                    tmpImagePara.Justification = Model.Justification.Left;
                    break;
                case DocGen.ObjectModel.HorizontalAlignment.Center:
                    tmpImagePara.Justification = Model.Justification.Center;
                    break;
                case DocGen.ObjectModel.HorizontalAlignment.Right:
                    tmpImagePara.Justification = Model.Justification.Right;
                    break;
            }

            Run imageRun = new Run();
            imageRun.Append(drawing);
            var imagePara = ParagraphFormatter.GetFormattedElement(tmpImagePara);
            imagePara.Append(imageRun);

            return imagePara;
        }
        private static RunProperties CreateRun(Model.Text text)
        {
            RunProperties runProperties = new RunProperties();
            if (text.Font == null) return null;

            FontSize size = new FontSize()
            {
                Val = Utilities.GetHPSValue(text.Font.Size)
            };

            runProperties.Append(size);

            foreach (var format in text.Font.Formats)
            {
                switch (format)
                {
                    case Model.FontFormats.Bold: runProperties.Append(new Bold()); break;
                    case Model.FontFormats.Italic: runProperties.Append(new Italic()); break;
                    case Model.FontFormats.Underlined: runProperties.Append(new Underline() { Val = UnderlineValues.Single}); break;
                }
            }

            return runProperties;
        }