// note. pattern #1:
        // * ref = atom
        // * read(ref)
        // conditions:
        // 1) ref is read only once after it had been assigned
        // 2) atom isn't reassigned before read(ref) takes place
        // 3) if ref is CF$XXXX then atom can be of any node type (not only an atom)
        // transformed into:
        // * read(atom)
        private static bool TryMatchPattern1(DfaHelper dfa, Expression atom)
        {
            var p1_ref = atom as Ref;

            if (p1_ref == null)
            {
                return(false);
            }

            var p1_lastass = dfa.Writes(p1_ref).LastOrDefault();

            if (p1_lastass == null)
            {
                return(false);
            }

            var p1_ref_onlyread_afterass = dfa.Reads(p1_ref).SingleOrDefault2(
                r => dfa.ExecOrderOfStmt(r) >= dfa.ExecOrderOfStmt(p1_lastass));

            if (p1_ref_onlyread_afterass == null)
            {
                return(false);
            }

            var p1_atom = p1_lastass.Rhs;

            if (!p1_ref.Sym.Name.StartsWith("CF$") &&
                !p1_ref.Sym.Name.StartsWith("CS$"))
            {
                if (!p1_atom.IsAtom())
                {
                    return(false);
                }

                var p1_atom_reasses = dfa.Writes(p1_atom).Where(w =>
                                                                dfa.ExecOrderOfStmt(p1_lastass) <= dfa.ExecOrderOfStmt(w) &&
                                                                dfa.ExecOrderOfStmt(w) <= dfa.ExecOrderOfStmt(p1_ref_onlyread_afterass));
                if (p1_atom_reasses.IsNotEmpty())
                {
                    return(false);
                }
            }

            dfa.Remove(p1_lastass);
            var p1_ref_onlyread_stmt = p1_ref_onlyread_afterass.Stmt();

            dfa.ReplaceRecursive(p1_ref_onlyread_stmt, p1_ref, p1_atom);
            return(true);
        }
        // note. pattern #2:
        // * atom = atom op any
        // transformed into:
        // * atom [op=] any
        private static bool TryMatchPattern2(DfaHelper dfa, Expression atom)
        {
            var p2_atom = atom;

            foreach (var p2_ass in dfa.Writes(atom))
            {
                if (!(p2_ass.Rhs is BinaryOperator))
                {
                    continue;
                }
                var binary = p2_ass.Rhs as BinaryOperator;
                if (!p2_atom.Equiv(binary.Lhs))
                {
                    continue;
                }

                var p2_opeq = p2_atom.CreateOpPreAssign(binary.OperatorType, binary.Rhs);
                if (p2_opeq == null)
                {
                    return(false);
                }

                dfa.Replace(p2_ass, p2_opeq);
                return(true);
            }

            return(false);
        }