protected void VisitMemberReferenceExpression()
        {
            MemberReferenceExpression memberReferenceExpression = MemberReferenceExpression;
            int  pos      = Emitter.Output.Length;
            bool isRefArg = Emitter.IsRefArg;

            Emitter.IsRefArg = false;

            ResolveResult resolveResult           = null;
            ResolveResult expressionResolveResult = null;
            string        targetVar     = null;
            string        valueVar      = null;
            bool          isStatement   = false;
            bool          isConstTarget = false;

            var targetrr = Emitter.Resolver.ResolveNode(memberReferenceExpression.Target);

            if (targetrr is ConstantResolveResult)
            {
                isConstTarget = true;
            }

            var memberTargetrr = targetrr as MemberResolveResult;

            if (memberTargetrr != null && memberTargetrr.Type.Kind == TypeKind.Enum && memberTargetrr.Member is DefaultResolvedField && Helpers.EnumEmitMode(memberTargetrr.Type) == 2)
            {
                isConstTarget = true;
            }

            if (memberReferenceExpression.Target is ParenthesizedExpression ||
                (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.Int64)) ||
                (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.UInt64)) ||
                (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.Decimal)))
            {
                isConstTarget = false;
            }

            var isInvoke = memberReferenceExpression.Parent is InvocationExpression && (((InvocationExpression)(memberReferenceExpression.Parent)).Target == memberReferenceExpression);

            if (isInvoke)
            {
                resolveResult           = Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent);
                expressionResolveResult = Emitter.Resolver.ResolveNode(memberReferenceExpression);

                if (expressionResolveResult is InvocationResolveResult)
                {
                    resolveResult = expressionResolveResult;
                }
                else if (expressionResolveResult is MemberResolveResult)
                {
                    if (((MemberResolveResult)expressionResolveResult).Member is IProperty)
                    {
                        resolveResult = expressionResolveResult;
                    }
                }
            }
            else
            {
                resolveResult = Emitter.Resolver.ResolveNode(memberReferenceExpression);
            }

            bool oldIsAssignment = Emitter.IsAssignment;
            bool oldUnary        = Emitter.IsUnaryAccessor;

            if (resolveResult == null)
            {
                Emitter.IsAssignment    = false;
                Emitter.IsUnaryAccessor = false;
                if (isConstTarget)
                {
                    Write("(");
                }
                memberReferenceExpression.Target.AcceptVisitor(Emitter);
                if (isConstTarget)
                {
                    Write(")");
                }
                Emitter.IsAssignment    = oldIsAssignment;
                Emitter.IsUnaryAccessor = oldUnary;
                WriteDot();
                string name = memberReferenceExpression.MemberName;
                Write(name.ToLowerCamelCase());

                return;
            }

            bool isDynamic = false;

            if (resolveResult is DynamicInvocationResolveResult dynamicResolveResult)
            {
                if (dynamicResolveResult.Target is MethodGroupResolveResult group && group.Methods.Count() > 1)
                {
                    var method = group.Methods.FirstOrDefault(m =>
                    {
                        if (dynamicResolveResult.Arguments.Count != m.Parameters.Count)
                        {
                            return(false);
                        }

                        for (int i = 0; i < m.Parameters.Count; i++)
                        {
                            var argType = dynamicResolveResult.Arguments[i].Type;

                            if (argType.Kind == TypeKind.Dynamic)
                            {
                                argType = Emitter.Resolver.Compilation.FindType(TypeCode.Object);
                            }

                            if (!m.Parameters[i].Type.Equals(argType))
                            {
                                return(false);
                            }
                        }

                        return(true);
                    }) ?? group.Methods.Last();

                    isDynamic     = true;
                    resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method);
                    resolveResult = new InvocationResolveResult(resolveResult, method, dynamicResolveResult.Arguments);
                }
            }

            if (resolveResult is MethodGroupResolveResult oldResult)
            {
                resolveResult = Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent);

                if (resolveResult is DynamicInvocationResolveResult)
                {
                    var method = oldResult.Methods.Last();
                    resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method);
                }
            }

            MemberResolveResult member = resolveResult as MemberResolveResult;
            var globalTarget           = member != null?Emitter.IsGlobalTarget(member.Member) : null;

            if (member != null &&
                member.Member.Attributes.Any(a => a.AttributeType.FullName == "H5.NonScriptableAttribute"))
            {
                throw new EmitterException(MemberReferenceExpression, "Member " + member.ToString() + " is marked as not usable from script");
            }

            if (globalTarget != null && globalTarget.Item1)
            {
                var target = globalTarget.Item2;

                if (!string.IsNullOrWhiteSpace(target))
                {
                    bool assign           = false;
                    var  memberExpression = member.Member is IMethod ? memberReferenceExpression.Parent.Parent : memberReferenceExpression.Parent;
                    var  targetExpression = member.Member is IMethod ? memberReferenceExpression.Parent : memberReferenceExpression;
                    if (memberExpression is AssignmentExpression assignment && assignment.Right == targetExpression)
                    {
                        assign = true;
                    }
                    else
                    {
                        if (memberExpression is VariableInitializer varInit && varInit.Initializer == targetExpression)
                        {
                            assign = true;
                        }
                        else if (memberExpression is InvocationExpression targetInvocation)
                        {
                            if (targetInvocation.Arguments.Any(a => a == targetExpression))
                            {
                                assign = true;
                            }
                        }
                    }