/*public List< FlatChainRuleProcessingItem > TryGetItemsChain( FlatChainRuleProcessingItem processingItem,
             *                                                           List< FlatChainRuleProcessingItem > tempResultList )
             * {
             *  //var tempResultList = new List< FlatChainRuleProcessingItem >();
             *  foreach ( var item in Items )
             *  {
             *      if ( processingItem == null )
             *      {
             *          tempResultList.Clear();
             *          return (null);
             *      }
             *
             *      if ( !item.IsEquality( processingItem ) )
             *      {
             *          tempResultList.Clear();
             *          return (null);
             *      }
             *
             *      tempResultList.Add( processingItem );
             *      processingItem = processingItem.NextSiblingFlatChain;
             *  }
             *
             *  if ( Items.Length != tempResultList.Count )
             *  {
             *      tempResultList.Clear();
             *      return (null);
             *  }
             *
             *  return (tempResultList);
             * }
             */
            public bool TryGetItemsChain(FlatChainRuleProcessingItem processingItem,
                                         List <FlatChainRuleProcessingItem> tempResultList)
            {
                foreach (var item in Items)
                {
                    if (processingItem == null)
                    {
                        tempResultList.Clear();
                        return(false);
                    }

                    if (!item.IsEquality(processingItem))
                    {
                        tempResultList.Clear();
                        return(false);
                    }

                    tempResultList.Add(processingItem);
                    processingItem = processingItem.NextSiblingFlatChain;
                }

                if (Items.Length != tempResultList.Count)
                {
                    tempResultList.Clear();
                    return(false);
                }

                return(true);
            }
                public bool IsEquality(FlatChainRuleProcessingItem processingItem)
                {
                    if (this.TypeOfXmlElement != processingItem.TypeOfXmlElement)
                    {
                        return(false);
                    }

                    var result = default(bool);

                    switch (this.TypeOfXmlElement)
                    {
                    case TypeOfXmlElement.U:
                        #region
                        if (MatchStringsCETorU.Length == 0)
                        {
                            return(processingItem.Uvalue.Length == 0);
                        }
                        return(processingItem.Uvalue.SearchForSubsequence(MatchStringsCETorU));

                        #endregion
                    case TypeOfXmlElement.CET:
                        #region
                        result = true;
                        if (TypeENTITYorVERB.HasValue)
                        {
                            result &= (TypeENTITYorVERB == processingItem.TYPE);
                        }

                        if (MatchStringsCETorU.Length == 0)
                        {
                            return(result);     // && processingItem.VALUE.Trim().IsEmptyOrNull());
                                                //processingItem.VALUE.SplitBySpace().Length == 0);
                        }
                        return(result && processingItem.CETvalue.SequenceEqual(MatchStringsCETorU));

                        #endregion

                    default:
                        #region
                        result = true;
                        if (RoleENTITYorVERB.HasValue)
                        {
                            result &= (RoleENTITYorVERB == processingItem.Role);
                        }
                        if (TypeENTITYorVERB.HasValue)
                        {
                            result &= (TypeENTITYorVERB == processingItem.TYPE);
                        }
                        if (MatchStringENTITYorVERB != null)
                        {
                            result &= (MatchStringENTITYorVERB == processingItem.VALUE);
                        }
                        return(result);

                        #endregion
                    }
                }
        /*private List< FlatChainRuleProcessingItem > TryGetItemsChain( FlatChainRuleProcessingItem processingItem )
         * {
         *  var tempResultList = new List< FlatChainRuleProcessingItem >();
         *  foreach ( var pattern in Patterns )
         *  {
         *      var itemsChain = pattern.TryGetItemsChain( processingItem, tempResultList );
         *      if ( itemsChain != null )
         *      {
         *          return (itemsChain);
         *      }
         *  }
         *  return (null);
         * }*/

        private bool ProcessInternal(XElement subsent)
        {
            var isSubsent = subsent.IsElementSUBSENT();

            var itemsChain = new List <FlatChainRuleProcessingItem>();

            foreach (XElement node in subsent.GetAllProcessingElementsInSubsent())
            {
                var processingItem = new FlatChainRuleProcessingItem(node);

                #region [.TryGetItemsChain.]
                foreach (var pattern in Patterns)
                {
                    if (pattern.TryGetItemsChain(processingItem, itemsChain))
                    {
                        break;
                    }
                }
                if (itemsChain.Count == 0)
                {
                    continue;
                }
                if (itemsChain.HasAncestorHomogeneous(isSubsent))
                {
                    continue;
                }
                #endregion

                MatchRuleDebugInfoOutput(subsent);

                foreach (var a in Actions)
                {
                    if (a.Exists(itemsChain))
                    {
                        #region
                        MatchActionDebugInfoOutput(a);

                        var role = a.ROLE.HasValue ? a.ROLE.Value :
                                   (a.determineattribute_ROLE.HasValue
                                                     ? itemsChain[extensions.ToIndex(a.determineattribute_ROLE.Value)].Role : null);
                        var inquiryItem = itemsChain.FirstOrDefault(_ => _.TYPE == TypeAttributeValue.Inquiry);
                        var type        = (inquiryItem != null) ? TypeAttributeValue.Inquiry :
                                          a.TYPE.HasValue
                                     ? a.TYPE.Value :
                                          (a.determineattribute_TYPE.HasValue
                                        ? itemsChain[extensions.ToIndex(a.determineattribute_TYPE.Value)].TYPE : null);

                        var frt = itemsChain.Sum(_ => _.XElement.GetAttributeFRT()) + a.FRT_toAdd;
                        if (frt < 0)
                        {
                            frt = 0;
                        }

                        var newNode = new XElement(a.CreateNewElementType.ToString());
                        newNode.SetAttributeSNT(a.SNT);
                        newNode.SetAttributeFRT(frt);
                        if (type.HasValue)
                        {
                            newNode.SetAttributeTYPE(type.Value);
                        }
                        if (role.HasValue)
                        {
                            newNode.SetAttributeROLE(role.Value);
                        }

                        #region [.if some-one item in chain is ENTITIES => put him @ID on new-created-parent.]
                        if (newNode.IsElementENTITIES())
                        {
                            var entitiesItemsChain = (from item in itemsChain
                                                      where item.XElement.IsElementENTITIES()
                                                      select item.XElement
                                                      )
                                                     .FirstOrDefault();
                            if (entitiesItemsChain != null)
                            {
                                newNode.SetAttributeID(entitiesItemsChain.GetAttributeID().Value);
                            }
                        }
                        #endregion

                        node.AddBeforeSelf(newNode);

                        foreach (var itemInChain in itemsChain)
                        {
                            itemInChain.XElement.Remove();
                            newNode.Add(itemInChain.XElement);
                        }
                        newNode.AddBeforeAndAfterEmptyU();

                        return(true);

                        #endregion
                    }
                }

                NomatchActionDebugInfoOutput();
            }
            return(false);
        }