private XElement ProcessElements(IEnumerable <RepeaterElement> elements, DataReader dataReader, XElement start, XElement parent, int index, ref XElement endIfElement, ref XElement nestedRepeaterEndElement, ref XElement currentEndItemTable, bool nested = false)
        {
            XElement result   = null;
            XElement previous = start;

            //if ((parent != null) && (!parent.Name.Equals(WordMl.TableCellName)))
            //{
            elements = elements.Where(el => !this.IsItemRepeaterElement(el.XElement)).ToList();
            //}
            foreach (var repeaterElement in elements) //elements.Where(el => !this.IsItemRepeaterElement(el.XElement)).ToList())
            {
                if (nestedRepeaterEndElement != null)
                {
                    if (repeaterElement.XElement.Equals(nestedRepeaterEndElement))
                    {
                        nestedRepeaterEndElement = null;
                    }
                    continue;
                }
                if (currentEndItemTable != null)
                {
                    if (repeaterElement.XElement.Equals(currentEndItemTable))
                    {
                        currentEndItemTable = null;
                    }
                    continue;
                }
                if (repeaterElement.IsEndItemIf /*&& repeaterElement.XElement.Equals(endIfElement)*/)
                {
                    //endIfElement = null;
                    if (repeaterElement.XElement.Equals(endIfElement))
                    {
                        endIfElement = null;
                    }
                    continue;
                }
                if ((endIfElement != null) && !repeaterElement.XElement.Name.Equals(WordMl.ParagraphName))
                {
                    continue;
                }
                if (repeaterElement.IsItemIf)
                {
                    this.ProcessItemIfElement(repeaterElement, dataReader, ref endIfElement);
                    continue;
                }

                if (repeaterElement.IsItemTable)
                {
                    /*currentEndItemTable = RepeaterParser.FindEndTag(repeaterElement.XElement, "itemtable",
                     *                                              "enditemtable");*/
                    currentEndItemTable = repeaterElement.EndTag;
                }

                /*
                 * if (repeaterElement.IsEndItemTable /*|| (repeaterElement.XElement.Name.Equals(WordMl.TableName) && repeaterElement.XElement.Descendants().Any(el => el.IsSdt())))
                 * {
                 *  continue;
                 * }*/
                if (repeaterElement.IsItemHtmlContent)
                {
                    result = HtmlContentProcessor.MakeHtmlContentProcessed(repeaterElement.XElement, dataReader.ReadText(repeaterElement.Expression), true);
                }
                else if (repeaterElement.IsItemTable)
                {
                    result = ItemTableGenerator.ProcessItemTableElement(repeaterElement.StartTag, repeaterElement.EndTag,
                                                                        dataReader);
                    if (nested)
                    {
                        previous.AddAfterSelf(result);
                        previous = result;
                        result   = null;
                    }
                }
                else if (repeaterElement.IsItemRepeater)
                {
                    var itemRepeaterTag = new ItemRepeaterTag()
                    {
                        StartItemRepeater = repeaterElement.StartTag,
                        EndItemRepeater   = repeaterElement.EndTag,
                        Source            = repeaterElement.Expression
                    };
                    var itemRepeaterGenerator = new ItemRepeaterGenerator();
                    previous = itemRepeaterGenerator.Generate(itemRepeaterTag,
                                                              dataReader.GetReaders(repeaterElement.Expression),
                                                              previous, parent, true);
                    result = null;
                    nestedRepeaterEndElement = repeaterElement.EndTag;
                }
                else if (repeaterElement.IsIndex)
                {
                    result = DocxHelper.CreateTextElement(repeaterElement.XElement, repeaterElement.XElement.Parent, index.ToString(CultureInfo.CurrentCulture));
                }
                else if (repeaterElement.IsItem && repeaterElement.HasExpression)
                {
                    result = DocxHelper.CreateTextElement(repeaterElement.XElement, repeaterElement.XElement.Parent, dataReader.ReadText(repeaterElement.Expression), dataReader.ReadAttribute(repeaterElement.Expression, "style"));
                }
                else
                {
                    var element = new XElement(repeaterElement.XElement);
                    element.RemoveNodes();
                    result = element;
                    if (repeaterElement.HasElements)
                    {
                        var parsedLastElement = this.ProcessElements(repeaterElement.Elements, dataReader, previous, result, index, ref endIfElement, ref nestedRepeaterEndElement, ref currentEndItemTable, true);
                        if (repeaterElement.Elements.Any(re => re.IsItemTable) || repeaterElement.Elements.Any(re => re.IsItemRepeater && !ItemRepeaterGenerator.CheckInlineWrappingMode(re.StartTag, re.EndTag)))
                        {
                            previous = parsedLastElement;
                            result   = null;
                        }
                    }
                    else
                    {
                        element.Value = repeaterElement.XElement.Value;
                    }
                }
                if (result != null)
                {
                    if (!nested)
                    {
                        previous.AddAfterSelf(result);
                        previous = result;
                    }
                    else
                    {
                        parent.Add(result);
                    }
                }
            }
            return(result ?? previous);
        }
        private void ProcessElements(IEnumerable <TableElement> tableElements, DataReader dataReader, int index, XElement start, bool isTopLevel)
        {
            var      tableElementsList = tableElements.ToList();
            XElement previous          = start;
            XElement firstCell         = null;

            foreach (var currentTableElement in tableElementsList)
            {
                if (currentTableElement.IsCellColor)
                {
                    this.SetCellColor(currentTableElement.StartTag.Ancestors(WordMl.TableCellName).First(), dataReader.ReadText(currentTableElement.Expression));
                    currentTableElement.StartTag.Remove();
                }
                else if (currentTableElement.IsItemTable)
                {
                    var tableCell = currentTableElement.StartTag.Ancestors(WordMl.TableCellName).Last();

                    var tableElement = TraverseUtils.SecondElementsBetween(currentTableElement.StartTag,
                                                                           currentTableElement.EndTag)
                                       .SingleOrDefault(el => el.Name.Equals(WordMl.TableName));
                    var parentCellWidth = GetCellWidth(tableCell);
                    SetTableWidth(tableElement, parentCellWidth);
                    XElement parentElement = null;
                    if (currentTableElement.StartTag.Parent.Name.Equals(WordMl.ParagraphName))
                    {
                        parentElement = currentTableElement.StartTag.Parent;
                    }
                    var itemTableGenerator = new ItemTableGenerator();
                    itemTableGenerator.Generate(currentTableElement.StartTag, currentTableElement.EndTag, dataReader);
                    if (parentElement != null)
                    {
                        parentElement.Remove();
                    }
                }
                else if (currentTableElement.IsItemHtmlContent)
                {
                    currentTableElement.StartTag = HtmlContentProcessor.MakeHtmlContentProcessed(currentTableElement.StartTag,
                                                                                                 dataReader.ReadText(
                                                                                                     currentTableElement.Expression));
                }
                else if (currentTableElement.IsItemIf)
                {
                    previous = this.ProcessItemIfElement(currentTableElement, dataReader, index, previous);
                    //TODO: this if need testing
                    if (firstCell == null)
                    {
                        firstCell = previous;
                    }
                }
                else if (currentTableElement.IsItemRepeater)
                {
                    this.ProcessItemRepeaterElement(currentTableElement, dataReader, index, previous);
                }
                else if (currentTableElement.IsItem || currentTableElement.IsIndex)
                {
                    var resultText = currentTableElement.IsIndex
                                         ? index.ToString(CultureInfo.CurrentCulture)
                                         : dataReader.ReadText(currentTableElement.Expression);

                    previous = this.ProcessCell(currentTableElement, previous, resultText);
                    if (firstCell == null)
                    {
                        firstCell = previous;
                    }

                    currentTableElement.StartTag.Remove();
                }
            }

            if (isTopLevel && firstCell != null)
            {
                ProcessStaticCells(firstCell, previous);
            }
        }
        private void ProcessElements(IEnumerable<TableElement> tableElements, DataReader dataReader, int index, XElement start, bool isTopLevel)
        {
            var tableElementsList = tableElements.ToList();
            XElement previous = start;
            XElement firstCell = null;
            foreach (var currentTableElement in tableElementsList)
            {
                if (currentTableElement.IsCellColor)
                {
                    this.SetCellColor(currentTableElement.StartTag.Ancestors(WordMl.TableCellName).First(), dataReader.ReadText(currentTableElement.Expression));
                    currentTableElement.StartTag.Remove();
                }
                else if (currentTableElement.IsItemTable)
                {                    
                    var tableCell = currentTableElement.StartTag.Ancestors(WordMl.TableCellName).Last();
                    
                    var tableElement = TraverseUtils.SecondElementsBetween(currentTableElement.StartTag,
                                                                           currentTableElement.EndTag)
                                                    .SingleOrDefault(el => el.Name.Equals(WordMl.TableName));
                    var parentCellWidth = GetCellWidth(tableCell);
                    SetTableWidth(tableElement, parentCellWidth);
                    XElement parentElement = null;
                    if (currentTableElement.StartTag.Parent.Name.Equals(WordMl.ParagraphName))
                    {
                        parentElement = currentTableElement.StartTag.Parent;
                    }
                    var itemTableGenerator = new ItemTableGenerator();
                    itemTableGenerator.Generate(currentTableElement.StartTag, currentTableElement.EndTag, dataReader);
                    if (parentElement != null)
                    {
                        parentElement.Remove();
                    }
             
                }
                else if (currentTableElement.IsItemHtmlContent)
                {                    
                    currentTableElement.StartTag = HtmlContentProcessor.MakeHtmlContentProcessed(currentTableElement.StartTag,
                                                                                                 dataReader.ReadText(
                                                                                                     currentTableElement.Expression));                    
                }
                else if (currentTableElement.IsItemIf)
                {
                    previous = this.ProcessItemIfElement(currentTableElement, dataReader, index, previous);
                    //TODO: this if need testing
                    if (firstCell == null)
                    {
                        firstCell = previous;
                    }
                }
                else if (currentTableElement.IsItemRepeater)
                {                                       
                    this.ProcessItemRepeaterElement(currentTableElement, dataReader, index, previous);
                }
                else if (currentTableElement.IsItem || currentTableElement.IsIndex)
                {
                    var resultText = currentTableElement.IsIndex
                                         ? index.ToString(CultureInfo.CurrentCulture)
                                         : dataReader.ReadText(currentTableElement.Expression);

                    previous = this.ProcessCell(currentTableElement, previous, resultText);
                    if (firstCell == null)
                    {
                        firstCell = previous;
                    }

                    currentTableElement.StartTag.Remove();
                }
            }

            if (isTopLevel && firstCell != null)
            {
                ProcessStaticCells(firstCell, previous);
            }
        }