/// <summary>
        /// If there is a MemberInitExpression 'new Person { ID = p.ID, Friend = new Person { ID = p.Friend.ID }}'
        /// or a NewExpression 'new { ID = p.ID, Friend = new { ID = p.Friend.ID }}',
        /// this method validates against the RHS of the member assignment, the expression "p.ID" for example.
        /// </summary>
        /// <param name="expressionToAssign">The expression to validate.</param>
        /// <param name="initType">Type of the MemberInit or the New expression.</param>
        /// <param name="previousNested">The outer nested initializer of the current initializer we are checking.</param>
        /// <returns>true if the expression to assign is fine; false otherwise.</returns>
        private bool CheckCompatibleAssignmentExpression(Expression expressionToAssign, Type initType, ref MemberAssignmentAnalysis previousNested)
        {
            MemberAssignmentAnalysis nested = MemberAssignmentAnalysis.Analyze(this.entity, expressionToAssign);

            if (nested.MultiplePathsFound)
            {
                this.multiplePathsFound = true;
                return(false);
            }

            // When we're visiting a nested entity initializer, we're exactly one level above that.
            Exception incompatibleException = nested.CheckCompatibleAssignments(initType, ref previousNested);

            if (incompatibleException != null)
            {
                this.incompatibleAssignmentsException = incompatibleException;
                return(false);
            }

            if (this.pathFromEntity.Count == 0)
            {
                this.pathFromEntity.AddRange(nested.GetExpressionsToTargetEntity());
            }

            return(true);
        }
        /// <summary>
        /// Checks whether the this and a <paramref name="previous"/>
        /// paths for assignments are compatible.
        /// </summary>
        /// <param name="targetType">Type being initialized.</param>
        /// <param name="previous">Previously seen member accesses (null if this is the first).</param>
        /// <returns>An exception to be thrown if assignments are not compatible; null otherwise.</returns>
        /// <remarks>
        /// This method does not set the IncompatibleAssignmentsException property on either
        /// analysis instance.
        /// </remarks>
        internal Exception CheckCompatibleAssignments(Type targetType, ref MemberAssignmentAnalysis previous)
        {
            if (previous == null)
            {
                previous = this;
                return(null);
            }

            Expression[] previousExpressions  = previous.GetExpressionsToTargetEntity();
            Expression[] candidateExpressions = this.GetExpressionsToTargetEntity();
            return(CheckCompatibleAssignments(targetType, previousExpressions, candidateExpressions));
        }
        /// <summary>
        /// Checks whether the this and a <paramref name="previous"/>
        /// paths for assignments are compatible.
        /// </summary>
        /// <param name="targetType">Type being initialized.</param>
        /// <param name="previous">Previously seen member accesses (null if this is the first).</param>
        /// <returns>An exception to be thrown if assignments are not compatible; null otherwise.</returns>
        /// <remarks>
        /// This method does not set the IncompatibleAssignmentsException property on either
        /// analysis instance.
        /// </remarks>
        internal Exception CheckCompatibleAssignments(Type targetType, ref MemberAssignmentAnalysis previous)
        {
            if (previous == null)
            {
                previous = this;
                return null;
            }

            Expression[] previousExpressions = previous.GetExpressionsToTargetEntity();
            Expression[] candidateExpressions = this.GetExpressionsToTargetEntity();
            return CheckCompatibleAssignments(targetType, previousExpressions, candidateExpressions);
        }