protected override Expression VisitTry(TryExpression node)
 => VisitIfEqual(node, other => ExpressionEqualityComparer.NullsOrEquals(node.Handlers, other.Handlers, (n, o) => n.Select(h => h.Test).SequenceEqual(o.Select(h => h.Test))),
                 other => Visit((node.Handlers ?? Enumerable.Empty <CatchBlock>()).Select(n => n.Body).ToList(), (other.Handlers ?? Enumerable.Empty <CatchBlock>()).Select(n => n.Body).ToList()),
                 other => Visit((node.Handlers ?? Enumerable.Empty <CatchBlock>()).Select(n => n.Filter).ToList(), (other.Handlers ?? Enumerable.Empty <CatchBlock>()).Select(n => n.Filter).ToList()),
                 other => Visit((node.Handlers ?? Enumerable.Empty <CatchBlock>()).Select(n => n.Variable).ToList(), (other.Handlers ?? Enumerable.Empty <CatchBlock>()).Select(n => n.Variable).ToList()),
                 other => Visit(node.Body, other.Body),
                 other => Visit(node.Fault, other.Fault),
                 other => Visit(node.Finally, other.Finally));
 protected override Expression VisitDebugInfo(DebugInfoExpression node)
 => VisitIfEqual(node, other => node.EndColumn == other.EndColumn &&
                 node.EndLine == other.EndLine &&
                 node.IsClear == other.IsClear &&
                 node.StartColumn == other.StartColumn &&
                 node.StartLine == other.StartLine &&
                 ExpressionEqualityComparer.NullsOrEquals(node.Document, other.Document, (n, o) =>
                                                          n.DocumentType == o.DocumentType &&
                                                          n.FileName == o.FileName &&
                                                          n.Language == o.Language &&
                                                          n.LanguageVendor == o.LanguageVendor));
 private void Visit <TExpression>(ICollection <TExpression> nodes, ICollection <TExpression> otherNodes)
     where TExpression : Expression
 {
     if (AreEqual)
     {
         if (!(ExpressionEqualityComparer.NullsOrEquals(nodes, otherNodes, (n, o) => n.Count == o.Count)))
         {
             Break(nodes, otherNodes);
         }
         else if (nodes != null && otherNodes != null)
         {
             foreach (var pair in nodes.Zip(otherNodes, (node, other) => new { node, other }))
             {
                 Visit(pair.node, pair.other);
             }
         }
     }
 }
 private static bool Equals(MemberListBinding binding, MemberListBinding other)
 => ExpressionEqualityComparer.NullsOrEquals(binding.Initializers, other.Initializers, (n, o) => n.Select(i => i.AddMethod).SequenceEqual(o.Select(i => i.AddMethod)));
 private static bool Equals(MemberBinding binding, MemberBinding other)
 => ExpressionEqualityComparer.NullsOrEquals(binding, other, (n, o) => n.BindingType == o.BindingType &&
                                             n.Member == o.Member &&
                                             (EqualsIfType <MemberMemberBinding>(n, o, Equals)
                                              ?? EqualsIfType <MemberListBinding>(n, o, Equals)
                                              ?? false));
 private static bool Equals(ICollection <MemberBinding> binding, ICollection <MemberBinding> other)
 => ExpressionEqualityComparer.NullsOrEquals(binding, other, (n, o) => n.Count == o.Count && n.Zip(o, Equals).All(b => b));
 private static bool Equals(LabelTarget target, LabelTarget other)
 => ExpressionEqualityComparer.NullsOrEquals(target, other, (n, o) => n.Name == o.Name && n.Type == o.Type);
 protected override Expression VisitListInit(ListInitExpression node)
 => VisitIfEqual(node, other => ExpressionEqualityComparer.NullsOrEquals(node.Initializers, other.Initializers, (n, o) => n.Count == o.Count && n.Select(i => i.AddMethod).Zip(o.Select(i => i.AddMethod), memberEquals).All(b => b)),
                 other => Visit((node.Initializers ?? Enumerable.Empty <ElementInit>()).SelectMany(n => n.Arguments).ToList(), (other.Initializers ?? Enumerable.Empty <ElementInit>()).SelectMany(n => n.Arguments).ToList()),
                 other => Visit(node.NewExpression, other.NewExpression));
 protected override Expression VisitSwitch(SwitchExpression node)
 => VisitIfEqual(node, other => memberEquals(node.Comparison, other.Comparison) && ExpressionEqualityComparer.NullsOrEquals(node.Cases, other.Cases, (n, o) => n.Count == o.Count),
                 other => Visit((node.Cases ?? Enumerable.Empty <SwitchCase>()).SelectMany(n => n.TestValues).ToList(), (other.Cases ?? Enumerable.Empty <SwitchCase>()).SelectMany(n => n.TestValues).ToList()),
                 other => Visit((node.Cases ?? Enumerable.Empty <SwitchCase>()).Select(n => n.Body).ToList(), (other.Cases ?? Enumerable.Empty <SwitchCase>()).Select(n => n.Body).ToList()),
                 other => Visit(node.DefaultBody, other.DefaultBody),
                 other => Visit(node.SwitchValue, other.SwitchValue));
 protected override Expression VisitNew(NewExpression node)
 => VisitIfEqual(node, other => memberEquals(node.Constructor, other.Constructor) && ExpressionEqualityComparer.NullsOrEquals(node.Members, other.Members, (n, o) => n.Count == o.Count && n.Zip(o, memberEquals).All(b => b)), other => Visit(node.Arguments, other.Arguments));
 protected override Expression VisitDynamic(DynamicExpression node)
 => VisitIfEqual(node, other => typeEquals(node.DelegateType, other.DelegateType) && ExpressionEqualityComparer.NullsOrEquals(node.Binder, other.Binder, (n, o) => n.Equals(o)), other => Visit(node.Arguments, other.Arguments));