private bool TryResolveConflictByHints(ParserState state, BnfTerm conflict)
        {
            var stateData = state.BuilderData;
            //reduce hints
            var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict);

            foreach (var reduceItem in reduceItems)
            {
                if (reduceItem.Core.Hints != null)
                {
                    foreach (var hint in reduceItem.Core.Hints)
                    {
                        if (hint.HintType == HintType.ResolveToReduce)
                        {
                            var newAction = ParserAction.CreateReduce(reduceItem.Core.Production);
                            state.Actions[conflict] = newAction; //replace/add reduce action
                            return(true);
                        }
                    }
                }
            }

            //Shift hints
            var shiftItems = stateData.ShiftItems.SelectByCurrent(conflict);

            foreach (var shiftItem in shiftItems)
            {
                if (shiftItem.Core.Hints != null)
                {
                    foreach (var hint in shiftItem.Core.Hints)
                    {
                        if (hint.HintType == HintType.ResolveToShift)
                        {
                            //shift action is already there
                            return(true);
                        }
                    }
                }
            }

            //code hints
            // first prepare data for conflict action: reduceProduction (for possible reduce) and newState (for possible shift)
            var         reduceProduction = reduceItems.First().Core.Production; //take first of reduce productions
            ParserState newState         = (state.Actions.ContainsKey(conflict) ? state.Actions[conflict].NewState : null);
            // Get all items that might contain hints; first take all shift items and reduce items in conflict;
            // we should also add lookahead sources of reduce items. Lookahead source is an LR item that produces the lookahead,
            // so if it contains a code hint right before the lookahead term, then it applies to this conflict as well.
            var allItems = new LRItemList();

            allItems.AddRange(shiftItems);
            foreach (var reduceItem in reduceItems)
            {
                allItems.Add(reduceItem);
                allItems.AddRange(reduceItem.ReducedLookaheadSources);
            }
            // Scan all items and try to find hint with resolution type Code
            foreach (var item in allItems)
            {
                if (item.Core.Hints != null)
                {
                    foreach (var hint in item.Core.Hints)
                    {
                        if (hint.HintType == HintType.ResolveInCode)
                        {
                            //found hint with resolution type "code" - this is instruction to use custom code here to resolve the conflict
                            // create new ConflictAction and place it into Actions table
                            var newAction = ParserAction.CreateCodeAction(newState, reduceProduction);
                            state.Actions[conflict] = newAction; //replace/add reduce action
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }