/// <summary>
        /// Applies null check and disposal scope tracking logic to an expression
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="request"></param>
        /// <param name="expression"></param>
        /// <param name="allowDisposableTracking"></param>
        /// <returns></returns>
        public static Expression ApplyNullCheckAndAddDisposal(IInjectionScope scope, IActivationExpressionRequest request, Expression expression, bool allowDisposableTracking)
        {
            if (expression.Type != request.ActivationType &&
                !ReflectionService.CheckTypeIsBasedOnAnotherType(expression.Type, request.ActivationType))
            {
                expression = Expression.Convert(expression, request.ActivationType);
            }

            if (!allowDisposableTracking)
            {
                if (request.DefaultValue != null)
                {
                    var method = typeof(ExpressionUtilities).GetRuntimeMethods()
                                 .FirstOrDefault(m => m.Name == "ValueOrDefault");

                    var closedMethod = method.MakeGenericMethod(request.ActivationType);

                    return(Expression.Call(closedMethod, expression, Expression.Constant(request.DefaultValue.DefaultValue, request.ActivationType)));
                }

                if (!scope.ScopeConfiguration.Behaviors.AllowInstanceAndFactoryToReturnNull &&
                    request.IsRequired)
                {
                    var closedMethod = CheckForNullMethodInfo.MakeGenericMethod(request.ActivationType);

                    return(Expression.Call(closedMethod,
                                           Expression.Constant(request.GetStaticInjectionContext()),
                                           expression));
                }

                return(expression);
            }
            if (request.DefaultValue != null)
            {
                var method = typeof(ExpressionUtilities).GetRuntimeMethods()
                             .FirstOrDefault(m => m.Name == "AddToDisposableScopeOrDefault");

                var closedMethod = method.MakeGenericMethod(request.ActivationType);

                return(Expression.Call(closedMethod, request.DisposalScopeExpression, expression, Expression.Constant(request.DefaultValue.DefaultValue, request.ActivationType)));
            }

            if (scope.ScopeConfiguration.Behaviors.AllowInstanceAndFactoryToReturnNull ||
                !request.IsRequired)
            {
                var closedMethod = AddToDisposalScopeMethodInfo.MakeGenericMethod(request.ActivationType);

                return(Expression.Call(closedMethod, request.DisposalScopeExpression, expression));
            }
            else
            {
                var closedMethod = CheckForNullAndAddToDisposalScopeMethodInfo.MakeGenericMethod(request.ActivationType);

                return(Expression.Call(closedMethod,
                                       request.DisposalScopeExpression,
                                       Expression.Constant(request.GetStaticInjectionContext()), expression));
            }
        }
        /// <summary>
        /// Applies null check and disposal scope tracking logic to an expression
        /// </summary>
        /// <param name="scope"></param>
        /// <param name="request"></param>
        /// <param name="expression"></param>
        /// <param name="allowDisposableTracking"></param>
        /// <returns></returns>
        public static Expression ApplyNullCheckAndAddDisposal(IInjectionScope scope, IActivationExpressionRequest request, Expression expression, bool allowDisposableTracking)
        {
            if (expression.Type != request.ActivationType &&
                !ReflectionService.CheckTypeIsBasedOnAnotherType(expression.Type, request.ActivationType))
            {
                expression = Expression.Convert(expression, request.ActivationType);
            }

            if (!allowDisposableTracking)
            {
                if (!scope.ScopeConfiguration.Behaviors.AllowInstanceAndFactoryToReturnNull)
                {
                    var closedMethod = CheckForNullMethodInfo.MakeGenericMethod(request.ActivationType);

                    return(Expression.Call(closedMethod,
                                           Expression.Constant(request.GetStaticInjectionContext()),
                                           expression));
                }
            }
            else
            {
                if (scope.ScopeConfiguration.Behaviors.AllowInstanceAndFactoryToReturnNull)
                {
                    var closedMethod = AddToDisposalScopeMethodInfo.MakeGenericMethod(request.ActivationType);

                    return(Expression.Call(closedMethod, request.DisposalScopeExpression, expression));
                }
                else
                {
                    var closedMethod =
                        CheckForNullAndAddToDisposalScopeMethodInfo.MakeGenericMethod(request.ActivationType);

                    return(Expression.Call(closedMethod,
                                           request.DisposalScopeExpression,
                                           Expression.Constant(request.GetStaticInjectionContext()), expression));
                }
            }

            return(expression);
        }