private static OperatorDeclarationSyntax BuildEqualsOperator(SyntaxToken typeName, GeneratedPropertyInfo[] propertySources)
 => OperatorDeclaration(_boolTypeName, Token(SyntaxKind.EqualsEqualsToken))
 .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword))
 .AddParameterListParameters
 (
     Parameter(_xToken).WithType(ParseTypeName(typeName.Text)),
     Parameter(_yToken).WithType(ParseTypeName(typeName.Text))
 )
 .WithExpressionBody
 (
     ArrowExpressionClause
     (
         BinaryExpression
         (
             SyntaxKind.LogicalOrExpression,
             ReferenceEqualsCall.Equal(IdentifierName(_xToken), IdentifierName(_yToken)),
             BinaryExpression
             (
                 SyntaxKind.LogicalAndExpression,
                 ReferenceEqualsCall.IsNotNull(IdentifierName(_xToken)),
                 InvocationExpression
                 (
                     MemberAccessExpression
                     (
                         SyntaxKind.SimpleMemberAccessExpression, IdentifierName(_xToken), IdentifierName(nameof(IEquatable <object> .Equals))
                     ),
                     ArgumentList().AddArguments(Argument(IdentifierName(_yToken)))
                 )
             )
         )
     )
 )
 .WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
 private static ExpressionSyntax BuildEqualsBodyExpression(GeneratedPropertyInfo[] properties)
 => properties
 .Select(property => BuildFieldEqualityCall(property))
 .Aggregate
 (
     ReferenceEqualsCall.IsNotNull(IdentifierName(_otherArg)),
     (old, current) => BinaryExpression(SyntaxKind.LogicalAndExpression, old, current)
 );