private ExpressionSyntax BuildFieldHashCodeCall(ISymbol fieldSymbol)
        {
            ITypeSymbol fieldType = (fieldSymbol as IFieldSymbol)?.Type ?? (fieldSymbol as IPropertySymbol).Type;
            MemberAccessExpressionSyntax defaultComparer          = DefaultEqualityComparer.AccessExpression(fieldType);
            MemberAccessExpressionSyntax defaultGetHashCodeMethod = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, defaultComparer, _getHashCodeName);
            MemberAccessExpressionSyntax fieldAccess     = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(fieldSymbol.Name));
            InvocationExpressionSyntax   getHashCodeCall = InvocationExpression(defaultGetHashCodeMethod).AddArgumentListArguments(Argument(fieldAccess));

            return(getHashCodeCall);
        }
        private static ExpressionSyntax BuildFieldEqualityCall(ISymbol fieldSymbol)
        {
            ITypeSymbol fieldType = (fieldSymbol as IFieldSymbol)?.Type ?? (fieldSymbol as IPropertySymbol).Type;
            bool        declaresEqualityOperator = fieldType
                                                   .GetMembers()
                                                   .OfType <IMethodSymbol>()
                                                   .Where(m => m.MethodKind == MethodKind.BuiltinOperator || m.MethodKind == MethodKind.UserDefinedOperator)
                                                   .Where(m => m.Name == "op_Equality")
                                                   .Any();

            //	If the field type declares == operator, we can safely use it.
            // This provides better readability in a lot of cases.
            if (declaresEqualityOperator)
            {
                return(BinaryExpression
                       (
                           SyntaxKind.EqualsExpression,
                           MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(fieldSymbol.Name)),
                           MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(_otherArg), IdentifierName(fieldSymbol.Name))
                       ));
            }

            //	Otherwise, we have to resort to EqualityComparer<T>.Default.Equals( this._field, other._field )
            MemberAccessExpressionSyntax defaultProperty = DefaultEqualityComparer.AccessExpression(fieldType);
            MemberAccessExpressionSyntax equalsMethod    = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, defaultProperty, IdentifierName("Equals"));
            InvocationExpressionSyntax   invocation      = InvocationExpression(equalsMethod);

            invocation = invocation
                         .AddArgumentListArguments
                         (
                Argument(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(fieldSymbol.Name))),
                Argument(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(_otherArg), IdentifierName(fieldSymbol.Name)))
                         );

            return(invocation);
        }