private void TestUnaryIntrinsicSymbol(
            UnaryOperatorKind op,
            TypeSymbol type,
            CSharpCompilation compilation,
            SemanticModel semanticModel,
            ExpressionSyntax node1,
            ExpressionSyntax node2,
            ExpressionSyntax node3,
            ExpressionSyntax node4
        )
        {
            SymbolInfo info1 = semanticModel.GetSymbolInfo(node1);
            Assert.Equal(type.IsDynamic() ? CandidateReason.LateBound : CandidateReason.None, info1.CandidateReason);
            Assert.Equal(0, info1.CandidateSymbols.Length);

            var symbol1 = (MethodSymbol)info1.Symbol;
            var symbol2 = semanticModel.GetSymbolInfo(node2).Symbol;
            var symbol3 = (MethodSymbol)semanticModel.GetSymbolInfo(node3).Symbol;
            var symbol4 = semanticModel.GetSymbolInfo(node4).Symbol;

            Assert.Equal(symbol1, symbol3);

            if ((object)symbol1 != null)
            {
                Assert.NotSame(symbol1, symbol3);
                Assert.Equal(symbol1.GetHashCode(), symbol3.GetHashCode());

                Assert.Equal(symbol1.Parameters[0], symbol3.Parameters[0]);
                Assert.Equal(symbol1.Parameters[0].GetHashCode(), symbol3.Parameters[0].GetHashCode());
            }

            Assert.Equal(symbol2, symbol4);

            TypeSymbol underlying = type;

            if (op == UnaryOperatorKind.BitwiseComplement ||
                op == UnaryOperatorKind.PrefixDecrement || op == UnaryOperatorKind.PrefixIncrement ||
                op == UnaryOperatorKind.PostfixDecrement || op == UnaryOperatorKind.PostfixIncrement)
            {
                underlying = type.EnumUnderlyingType();
            }

            UnaryOperatorKind result = OverloadResolution.UnopEasyOut.OpKind(op, underlying);
            UnaryOperatorSignature signature;

            if (result == UnaryOperatorKind.Error)
            {
                if (type.IsDynamic())
                {
                    signature = new UnaryOperatorSignature(op | UnaryOperatorKind.Dynamic, type, type);
                }
                else if (type.IsPointerType() &&
                    (op == UnaryOperatorKind.PrefixDecrement || op == UnaryOperatorKind.PrefixIncrement ||
                        op == UnaryOperatorKind.PostfixDecrement || op == UnaryOperatorKind.PostfixIncrement))
                {
                    signature = new UnaryOperatorSignature(op | UnaryOperatorKind.Pointer, type, type);
                }
                else
                {
                    Assert.Null(symbol1);
                    Assert.Null(symbol2);
                    Assert.Null(symbol3);
                    Assert.Null(symbol4);
                    return;
                }
            }
            else
            {
                signature = compilation.builtInOperators.GetSignature(result);

                if ((object)underlying != (object)type)
                {
                    Assert.Equal(underlying, signature.OperandType);
                    Assert.Equal(underlying, signature.ReturnType);

                    signature = new UnaryOperatorSignature(signature.Kind, type, type);
                }
            }

            Assert.NotNull(symbol1);

            string containerName = signature.OperandType.ToTestDisplayString();
            string returnName = signature.ReturnType.ToTestDisplayString();

            if (op == UnaryOperatorKind.LogicalNegation && type.IsEnumType())
            {
                containerName = type.ToTestDisplayString();
                returnName = containerName;
            }

            Assert.Equal(String.Format("{2} {0}.{1}({0} value)",
                                       containerName,
                                       OperatorFacts.UnaryOperatorNameFromOperatorKind(op),
                                       returnName),
                         symbol1.ToTestDisplayString());

            Assert.Equal(MethodKind.BuiltinOperator, symbol1.MethodKind);
            Assert.True(symbol1.IsImplicitlyDeclared);

            bool expectChecked = false;

            switch (op)
            {
                case UnaryOperatorKind.UnaryMinus:
                    expectChecked = (type.IsDynamic() || symbol1.ContainingType.EnumUnderlyingType().SpecialType.IsIntegralType());
                    break;

                case UnaryOperatorKind.PrefixDecrement:
                case UnaryOperatorKind.PrefixIncrement:
                case UnaryOperatorKind.PostfixDecrement:
                case UnaryOperatorKind.PostfixIncrement:
                    expectChecked = (type.IsDynamic() || type.IsPointerType() ||
                                     symbol1.ContainingType.EnumUnderlyingType().SpecialType.IsIntegralType() ||
                                     symbol1.ContainingType.SpecialType == SpecialType.System_Char);
                    break;

                default:
                    expectChecked = type.IsDynamic();
                    break;
            }

            Assert.Equal(expectChecked, symbol1.IsCheckedBuiltin);

            Assert.False(symbol1.IsGenericMethod);
            Assert.False(symbol1.IsExtensionMethod);
            Assert.False(symbol1.IsExtern);
            Assert.False(symbol1.CanBeReferencedByName);
            Assert.Null(symbol1.DeclaringCompilation);
            Assert.Equal(symbol1.Name, symbol1.MetadataName);
            Assert.Same(symbol1.ContainingSymbol, symbol1.Parameters[0].Type);
            Assert.Equal(0, symbol1.Locations.Length);
            Assert.Null(symbol1.GetDocumentationCommentId());
            Assert.Equal("", symbol1.GetDocumentationCommentXml());

            Assert.True(symbol1.HasSpecialName);
            Assert.True(symbol1.IsStatic);
            Assert.Equal(Accessibility.Public, symbol1.DeclaredAccessibility);
            Assert.False(symbol1.HidesBaseMethodsByName);
            Assert.False(symbol1.IsOverride);
            Assert.False(symbol1.IsVirtual);
            Assert.False(symbol1.IsAbstract);
            Assert.False(symbol1.IsSealed);
            Assert.Equal(1, symbol1.ParameterCount);
            Assert.Equal(0, symbol1.Parameters[0].Ordinal);

            var otherSymbol = (MethodSymbol)semanticModel.GetSymbolInfo(node1).Symbol;
            Assert.Equal(symbol1, otherSymbol);

            if (type.IsValueType && !type.IsPointerType())
            {
                Assert.Equal(symbol1, symbol2);
                return;
            }

            Assert.Null(symbol2);
        }