Esempio n. 1
0
        public List <Movie> DiscoverNewMovies(string action)
        {
            var    allMovies     = _movieService.GetAllMovies();
            var    allExclusions = _exclusionService.GetAllExclusions();
            string allIds        = string.Join(",", allMovies.Select(m => m.TmdbId));
            string ignoredIds    = string.Join(",", allExclusions.Select(ex => ex.TmdbId));

            List <MovieResult> results = new List <MovieResult>();

            try
            {
                results = _radarrAPI.DiscoverMovies(action, (request) =>
                {
                    request.AllowAutoRedirect   = true;
                    request.Method              = HttpMethod.POST;
                    request.Headers.ContentType = "application/x-www-form-urlencoded";
                    request.SetContent($"tmdbIds={allIds}&ignoredIds={ignoredIds}");
                    return(request);
                });

                results = results.Where(m => allMovies.None(mo => mo.TmdbId == m.id) && allExclusions.None(ex => ex.TmdbId == m.id)).ToList();
            }
            catch (RadarrAPIException exception)
            {
                _logger.Error(exception, "Failed to discover movies for action {0}!", action);
            }
            catch (Exception exception)
            {
                _logger.Error(exception, "Failed to discover movies for action {0}!", action);
            }

            return(results.SelectList(MapMovie));
        }
        /// <summary>
        /// Processes given inputs with on first level then optionally calls subset for second level
        /// </summary>
        /// <remarks>
        /// * Call first function in given inputs
        /// * Call specified inputs (based on first function results) with second function
        /// * Fix indices for results of second function
        /// * Merge the results
        /// </remarks>
        public static async Task <IReadOnlyList <TResult> > RunMultiLevelWithMergeAsync <TSource, TResult>(
            IReadOnlyList <TSource> inputs,
            Func <IReadOnlyList <TSource>, Task <IReadOnlyList <TResult> > > runFirstLevelAsync,
            Func <IReadOnlyList <TSource>, Task <IReadOnlyList <TResult> > > runSecondLevelAsync,
            Func <TResult, TResult, TResult> mergeResults,
            Func <TResult, bool> useFirstLevelResult)
        {
            TResult[] results = new TResult[inputs.Count];

            // Get results from first method
            IReadOnlyList <TResult> initialResults = await runFirstLevelAsync(inputs);

            // Determine which inputs can use the first level results based on useFirstLevelResult()
            List <Indexed <TResult> > indexedFirstLevelOnlyResults = new List <Indexed <TResult> >();
            List <int> nextLevelIndices = null;

            for (int i = 0; i < initialResults.Count; i++)
            {
                var result = initialResults[i];
                if (useFirstLevelResult(result))
                {
                    results[i] = result;
                }
                else
                {
                    nextLevelIndices = nextLevelIndices ?? new List <int>();
                    nextLevelIndices.Add(i);
                }
            }

            // Return early if no misses
            if (nextLevelIndices == null)
            {
                return(initialResults);
            }

            // Try fallback for items that failed in first attempt
            IReadOnlyList <TSource> missedInputs    = nextLevelIndices.SelectList(index => inputs[index]);
            IReadOnlyList <TResult> fallbackResults = await runSecondLevelAsync(missedInputs);

            for (int i = 0; i < nextLevelIndices.Count; i++)
            {
                var originalIndex = nextLevelIndices[i];
                var result        = fallbackResults[i];
                results[originalIndex] = mergeResults(initialResults[originalIndex], result);
            }

            return(results);
        }
Esempio n. 3
0
        public bool IsSatisfiedBy(List <Episode> episodes)
        {
            var episodeIds     = episodes.SelectList(e => e.Id);
            var episodeFileIds = episodes.Where(c => c.EpisodeFileId != 0).Select(c => c.EpisodeFileId).Distinct();

            foreach (var episodeFileId in episodeFileIds)
            {
                var episodesInFile = _episodeService.GetEpisodesByFileId(episodeFileId);

                if (episodesInFile.Select(e => e.Id).Except(episodeIds).Any())
                {
                    return(false);
                }
            }

            return(true);
        }
        public bool IsSatisfiedBy(List <Track> tracks)
        {
            var trackIds     = tracks.SelectList(e => e.Id);
            var trackFileIds = tracks.Where(c => c.TrackFileId != 0).Select(c => c.TrackFileId).Distinct();

            foreach (var trackFileId in trackFileIds)
            {
                var tracksInFile = _trackService.GetTracksByFileId(trackFileId);

                if (tracksInFile.Select(e => e.Id).Except(trackIds).Any())
                {
                    return(false);
                }
            }

            return(true);
        }
        public bool IsSatisfiedBy(List<Episode> episodes)
        {
            var episodeIds = episodes.SelectList(e => e.Id);
            var episodeFileIds = episodes.Where(c => c.EpisodeFileId != 0).Select(c => c.EpisodeFileId).Distinct();

            foreach (var episodeFileId in episodeFileIds)
            {
                var episodesInFile = _episodeService.GetEpisodesByFileId(episodeFileId);

                if (episodesInFile.Select(e => e.Id).Except(episodeIds).Any())
                {
                    return false;
                }
            }

            return true;
        }
        /// <nodoc />
        public void StoreResult(OperationContext context, string path, List <string> machines)
        {
            foreach (var machine in machines)
            {
                _knownMachines.GetOrAdd(machine, _ =>
                {
                    var machineId = new MachineId(Interlocked.Increment(ref _currentId));
                    _clusterState.AddMachine(machineId, new MachineLocation(machine));
                    return(machineId);
                });
            }

            var pathHash = ComputePathHash(path);

            var entry = ContentLocationEntry.Create(MachineIdSet.Empty.SetExistence(machines.SelectList(machine => _knownMachines[machine]), true), 0, DateTime.UtcNow);

            _database.Store(context, pathHash, entry);
        }
Esempio n. 7
0
        public ExpressionWithResolveResult Build(OpCode callOpCode, IMethod method, IReadOnlyList <ILInstruction> callArguments,
                                                 IType constrainedTo = null)
        {
            // Used for Call, CallVirt and NewObj
            var expectedTargetDetails = new ExpectedTargetDetails {
                CallOpCode = callOpCode
            };
            TranslatedExpression target;

            if (callOpCode == OpCode.NewObj)
            {
                target = default(TranslatedExpression);                 // no target
            }
            else
            {
                target = expressionBuilder.TranslateTarget(method, callArguments.FirstOrDefault(), callOpCode == OpCode.Call, constrainedTo);
                if (callOpCode == OpCode.CallVirt &&
                    constrainedTo == null &&
                    target.Expression is CastExpression cast &&
                    target.ResolveResult is ConversionResolveResult conversion &&
                    target.Type.IsKnownType(KnownTypeCode.Object) &&
                    conversion.Conversion.IsBoxingConversion)
                {
                    // boxing conversion on call target?
                    // let's see if we can make that implicit:
                    target = target.UnwrapChild(cast.Expression);
                    // we'll need to make sure the boxing effect is preserved
                    expectedTargetDetails.NeedsBoxingConversion = true;
                }
            }

            int firstParamIndex = (method.IsStatic || callOpCode == OpCode.NewObj) ? 0 : 1;

            // Translate arguments to the expected parameter types
            var arguments = new List <TranslatedExpression>(method.Parameters.Count);

            Debug.Assert(callArguments.Count == firstParamIndex + method.Parameters.Count);
            var  expectedParameters = method.Parameters.ToList();
            bool isExpandedForm     = false;

            for (int i = 0; i < method.Parameters.Count; i++)
            {
                var parameter = expectedParameters[i];
                var arg       = expressionBuilder.Translate(callArguments[firstParamIndex + i]);
                if (parameter.IsParams && i + 1 == method.Parameters.Count)
                {
                    // Parameter is marked params
                    // If the argument is an array creation, inline all elements into the call and add missing default values.
                    // Otherwise handle it normally.
                    if (arg.ResolveResult is ArrayCreateResolveResult acrr &&
                        acrr.SizeArguments.Count == 1 &&
                        acrr.SizeArguments[0].IsCompileTimeConstant &&
                        acrr.SizeArguments[0].ConstantValue is int length)
                    {
                        var expandedParameters = expectedParameters.Take(expectedParameters.Count - 1).ToList();
                        var expandedArguments  = new List <TranslatedExpression>(arguments);
                        if (length > 0)
                        {
                            var arrayElements = ((ArrayCreateExpression)arg.Expression).Initializer.Elements.ToArray();
                            var elementType   = ((ArrayType)acrr.Type).ElementType;
                            for (int j = 0; j < length; j++)
                            {
                                expandedParameters.Add(new DefaultParameter(elementType, parameter.Name + j));
                                if (j < arrayElements.Length)
                                {
                                    expandedArguments.Add(new TranslatedExpression(arrayElements[j]));
                                }
                                else
                                {
                                    expandedArguments.Add(expressionBuilder.GetDefaultValueExpression(elementType).WithoutILInstruction());
                                }
                            }
                        }
                        if (IsUnambiguousCall(expectedTargetDetails, method, target, Empty <IType> .Array, expandedArguments) == OverloadResolutionErrors.None)
                        {
                            isExpandedForm     = true;
                            expectedParameters = expandedParameters;
                            arguments          = expandedArguments.SelectList(a => new TranslatedExpression(a.Expression.Detach()));
                            continue;
                        }
                    }
                }

                arguments.Add(arg.ConvertTo(parameter.Type, expressionBuilder, allowImplicitConversion: true));

                if (parameter.IsOut && arguments[i].Expression is DirectionExpression dirExpr)
                {
                    dirExpr.FieldDirection = FieldDirection.Out;
                }
            }

            if (method is VarArgInstanceMethod)
            {
                int regularParameterCount = ((VarArgInstanceMethod)method).RegularParameterCount;
                var argListArg            = new UndocumentedExpression();
                argListArg.UndocumentedExpressionType = UndocumentedExpressionType.ArgList;
                int paramIndex = regularParameterCount;
                var builder    = expressionBuilder;
                argListArg.Arguments.AddRange(arguments.Skip(regularParameterCount).Select(arg => arg.ConvertTo(expectedParameters[paramIndex++].Type, builder).Expression));
                var argListRR = new ResolveResult(SpecialType.ArgList);
                arguments = arguments.Take(regularParameterCount)
                            .Concat(new[] { argListArg.WithoutILInstruction().WithRR(argListRR) }).ToList();
                method             = (IMethod)method.MemberDefinition;
                expectedParameters = method.Parameters.ToList();
            }

            var argumentResolveResults = arguments.Select(arg => arg.ResolveResult).ToList();

            ResolveResult rr = new CSharpInvocationResolveResult(target.ResolveResult, method, argumentResolveResults, isExpandedForm: isExpandedForm);

            if (callOpCode == OpCode.NewObj)
            {
                if (settings.AnonymousTypes && method.DeclaringType.IsAnonymousType())
                {
                    var argumentExpressions            = arguments.SelectArray(arg => arg.Expression);
                    AnonymousTypeCreateExpression atce = new AnonymousTypeCreateExpression();
                    if (CanInferAnonymousTypePropertyNamesFromArguments(argumentExpressions, expectedParameters))
                    {
                        atce.Initializers.AddRange(argumentExpressions);
                    }
                    else
                    {
                        for (int i = 0; i < argumentExpressions.Length; i++)
                        {
                            atce.Initializers.Add(
                                new NamedExpression {
                                Name       = expectedParameters[i].Name,
                                Expression = arguments[i].ConvertTo(expectedParameters[i].Type, expressionBuilder)
                            });
                        }
                    }
                    return(atce
                           .WithRR(rr));
                }
                else
                {
                    if (IsUnambiguousCall(expectedTargetDetails, method, target, Empty <IType> .Array, arguments) != OverloadResolutionErrors.None)
                    {
                        for (int i = 0; i < arguments.Count; i++)
                        {
                            if (settings.AnonymousTypes && expectedParameters[i].Type.ContainsAnonymousType())
                            {
                                if (arguments[i].Expression is LambdaExpression lambda)
                                {
                                    ModifyReturnTypeOfLambda(lambda);
                                }
                            }
                            else
                            {
                                arguments[i] = arguments[i].ConvertTo(expectedParameters[i].Type, expressionBuilder);
                            }
                        }
                    }
                    return(new ObjectCreateExpression(expressionBuilder.ConvertType(method.DeclaringType), arguments.SelectArray(arg => arg.Expression))
                           .WithRR(rr));
                }
            }
            else
            {
                int allowedParamCount = (method.ReturnType.IsKnownType(KnownTypeCode.Void) ? 1 : 0);
                if (method.IsAccessor && (method.AccessorOwner.SymbolKind == SymbolKind.Indexer || expectedParameters.Count == allowedParamCount))
                {
                    return(HandleAccessorCall(expectedTargetDetails, method, target, arguments.ToList()));
                }
                else if (method.Name == "Invoke" && method.DeclaringType.Kind == TypeKind.Delegate)
                {
                    return(new InvocationExpression(target, arguments.Select(arg => arg.Expression)).WithRR(rr));
                }
                else if (IsDelegateEqualityComparison(method, arguments))
                {
                    return(HandleDelegateEqualityComparison(method, arguments)
                           .WithRR(rr));
                }
                else if (method.IsOperator && method.Name == "op_Implicit" && arguments.Count == 1)
                {
                    return(HandleImplicitConversion(method, arguments[0]));
                }
                else
                {
                    bool    requireTypeArguments = false;
                    bool    targetCasted         = false;
                    bool    argumentsCasted      = false;
                    IType[] typeArguments        = Empty <IType> .Array;

                    OverloadResolutionErrors errors;
                    while ((errors = IsUnambiguousCall(expectedTargetDetails, method, target, typeArguments, arguments)) != OverloadResolutionErrors.None)
                    {
                        switch (errors)
                        {
                        case OverloadResolutionErrors.TypeInferenceFailed:
                        case OverloadResolutionErrors.WrongNumberOfTypeArguments:
                            if (requireTypeArguments)
                            {
                                goto default;
                            }
                            requireTypeArguments = true;
                            typeArguments        = method.TypeArguments.ToArray();
                            continue;

                        default:
                            if (!argumentsCasted)
                            {
                                argumentsCasted = true;
                                for (int i = 0; i < arguments.Count; i++)
                                {
                                    if (settings.AnonymousTypes && expectedParameters[i].Type.ContainsAnonymousType())
                                    {
                                        if (arguments[i].Expression is LambdaExpression lambda)
                                        {
                                            ModifyReturnTypeOfLambda(lambda);
                                        }
                                    }
                                    else
                                    {
                                        arguments[i] = arguments[i].ConvertTo(expectedParameters[i].Type, expressionBuilder);
                                    }
                                }
                            }
                            else if (!targetCasted)
                            {
                                targetCasted = true;
                                target       = target.ConvertTo(method.DeclaringType, expressionBuilder);
                            }
                            else if (!requireTypeArguments)
                            {
                                requireTypeArguments = true;
                                typeArguments        = method.TypeArguments.ToArray();
                            }
                            else
                            {
                                break;
                            }
                            continue;
                        }
                        break;
                    }

                    Expression targetExpr = target.Expression;
                    string     methodName = method.Name;
                    // HACK : convert this.Dispose() to ((IDisposable)this).Dispose(), if Dispose is an explicitly implemented interface method.
                    if (method.IsExplicitInterfaceImplementation && targetExpr is ThisReferenceExpression)
                    {
                        targetExpr = new CastExpression(expressionBuilder.ConvertType(method.ImplementedInterfaceMembers[0].DeclaringType), targetExpr);
                        methodName = method.ImplementedInterfaceMembers[0].Name;
                    }
                    var mre = new MemberReferenceExpression(targetExpr, methodName);
                    if (requireTypeArguments && (!settings.AnonymousTypes || !method.TypeArguments.Any(a => a.ContainsAnonymousType())))
                    {
                        mre.TypeArguments.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));
                    }
                    var argumentExpressions = arguments.Select(arg => arg.Expression);
                    return(new InvocationExpression(mre, argumentExpressions).WithRR(rr));
                }
            }
        }
Esempio n. 8
0
        public void SetupInput(string input)
        {
            _i = _j = _current = 0;
            _chunks = new List<string>();
            _input = input.Replace("\r\n", "\n");
            _inputLength = _input.Length;

            // Split the input into chunks,
            // Either delimited by /\n\n/ or
            // delmited by '\n}' (see rationale above),
            // depending on the level of optimization.

            if (Optimization == 0)
                _chunks.Add(_input);
            else
            {
                var chunkParts = new List<StringBuilder> { new StringBuilder() };
                var chunkPart = chunkParts.Last();
                var skip = new Regex(@"\G[^\""'{}/\\`]+");
                var comment = new Regex(@"\G\/\*(?:[^*\n]|\*+[^\/\n]|\*?(\n))*\*+\/");
                var level = 0;
                var lastBlock = 0;
                var lastQuote = 0;
                char? inString = null;

                for (int i = 0; i < _inputLength; i++)
                {
                    var match = skip.Match(_input, i);
                    if(match.Success)
                    {
                        chunkPart.Append(match.Value);
                        i += match.Length;

                        if (i == _inputLength)
                            break;
                    }

                    if(i < _inputLength - 1 && _input[i] == '/')
                    {
                        var cc = _input[i + 1];
                        if(cc == '/' || cc=='*')
                        {
                            match = comment.Match(_input, i);
                            if (match.Success)
                            {
                                i += match.Length;
                                chunkPart.Append(match.Value);

                                if (i == _inputLength)
                                    break;
                            }
                        }
                    }

                    var c = _input[i];

                    if (c == '"' || c == '\'' || c == '`')
                    {
                        if (inString == null)
                        {
                            inString = c;
                            lastQuote = i;
                        }
                        else
                            inString = inString == c ? null : inString;
                    }
                    else if (inString != null && c == '\\' && i < _inputLength - 1)
                    {
                        chunkPart.Append(_input, i, 2);
                        i++;
                        continue;
                    }
                    else if (inString == null && c == '{')
                    {
                        level++;
                        lastBlock = i;
                    }
                    else if (inString == null && c == '}')
                    {
                        level--;

                        if (level < 0)
                            throw new ParsingException("Unexpected '}'", i);

                        chunkPart.Append(c);
                        chunkPart = new StringBuilder();
                        chunkParts.Add(chunkPart);
                        continue;
                    }

                    chunkPart.Append(c);
                }

                if(inString != null)
                    throw new ParsingException(string.Format("Missing closing quote ({0})", inString), lastQuote);

                if(level > 0)
                    throw new ParsingException("Missing closing '}'", lastBlock);

                _chunks = chunkParts.SelectList(p => p.ToString());

                _input = _chunks.JoinStrings("");

                _inputLength = _input.Length;
            }

            Advance(0); // skip any whitespace characters at the start.
        }
Esempio n. 9
0
        public ExpressionWithResolveResult Build(OpCode callOpCode, IMethod method, IReadOnlyList <ILInstruction> callArguments,
                                                 IType constrainedTo = null)
        {
            // Used for Call, CallVirt and NewObj
            var expectedTargetDetails = new ExpectedTargetDetails {
                CallOpCode = callOpCode
            };
            TranslatedExpression target;

            if (callOpCode == OpCode.NewObj)
            {
                target = default(TranslatedExpression);                 // no target
            }
            else
            {
                target = expressionBuilder.TranslateTarget(
                    callArguments.FirstOrDefault(),
                    nonVirtualInvocation: callOpCode == OpCode.Call,
                    memberStatic: method.IsStatic,
                    memberDeclaringType: constrainedTo ?? method.DeclaringType);
                if (constrainedTo == null &&
                    target.Expression is CastExpression cast &&
                    target.ResolveResult is ConversionResolveResult conversion &&
                    target.Type.IsKnownType(KnownTypeCode.Object) &&
                    conversion.Conversion.IsBoxingConversion)
                {
                    // boxing conversion on call target?
                    // let's see if we can make that implicit:
                    target = target.UnwrapChild(cast.Expression);
                    // we'll need to make sure the boxing effect is preserved
                    expectedTargetDetails.NeedsBoxingConversion = true;
                }
            }

            int firstParamIndex = (method.IsStatic || callOpCode == OpCode.NewObj) ? 0 : 1;

            // Translate arguments to the expected parameter types
            var arguments = new List <TranslatedExpression>(method.Parameters.Count);

            Debug.Assert(callArguments.Count == firstParamIndex + method.Parameters.Count);
            var  expectedParameters = method.Parameters.ToList();
            bool isExpandedForm     = false;

            for (int i = 0; i < method.Parameters.Count; i++)
            {
                var parameter = expectedParameters[i];
                var arg       = expressionBuilder.Translate(callArguments[firstParamIndex + i], parameter.Type);
                if (parameter.IsParams && i + 1 == method.Parameters.Count)
                {
                    // Parameter is marked params
                    // If the argument is an array creation, inline all elements into the call and add missing default values.
                    // Otherwise handle it normally.
                    if (arg.ResolveResult is ArrayCreateResolveResult acrr &&
                        acrr.SizeArguments.Count == 1 &&
                        acrr.SizeArguments[0].IsCompileTimeConstant &&
                        acrr.SizeArguments[0].ConstantValue is int length)
                    {
                        var expandedParameters = expectedParameters.Take(expectedParameters.Count - 1).ToList();
                        var expandedArguments  = new List <TranslatedExpression>(arguments);
                        if (length > 0)
                        {
                            var arrayElements = ((ArrayCreateExpression)arg.Expression).Initializer.Elements.ToArray();
                            var elementType   = ((ArrayType)acrr.Type).ElementType;
                            for (int j = 0; j < length; j++)
                            {
                                expandedParameters.Add(new DefaultParameter(elementType, parameter.Name + j));
                                if (j < arrayElements.Length)
                                {
                                    expandedArguments.Add(new TranslatedExpression(arrayElements[j]));
                                }
                                else
                                {
                                    expandedArguments.Add(expressionBuilder.GetDefaultValueExpression(elementType).WithoutILInstruction());
                                }
                            }
                        }
                        if (IsUnambiguousCall(expectedTargetDetails, method, target.ResolveResult, Empty <IType> .Array, expandedArguments, out _) == OverloadResolutionErrors.None)
                        {
                            isExpandedForm     = true;
                            expectedParameters = expandedParameters;
                            arguments          = expandedArguments.SelectList(a => new TranslatedExpression(a.Expression.Detach()));
                            continue;
                        }
                    }
                }

                arguments.Add(arg.ConvertTo(parameter.Type, expressionBuilder, allowImplicitConversion: true));

                if (parameter.IsOut && arguments[i].Expression is DirectionExpression dirExpr && arguments[i].ResolveResult is ByReferenceResolveResult brrr)
                {
                    dirExpr.FieldDirection = FieldDirection.Out;
                    dirExpr.RemoveAnnotations <ByReferenceResolveResult>();
                    if (brrr.ElementResult == null)
                    {
                        brrr = new ByReferenceResolveResult(brrr.ElementType, isOut: true);
                    }
                    else
                    {
                        brrr = new ByReferenceResolveResult(brrr.ElementResult, isOut: true);
                    }
                    dirExpr.AddAnnotation(brrr);
                    arguments[i] = new TranslatedExpression(dirExpr);
                }
            }

            if (method is VarArgInstanceMethod)
            {
                int regularParameterCount = ((VarArgInstanceMethod)method).RegularParameterCount;
                var argListArg            = new UndocumentedExpression();
                argListArg.UndocumentedExpressionType = UndocumentedExpressionType.ArgList;
                int paramIndex = regularParameterCount;
                var builder    = expressionBuilder;
                argListArg.Arguments.AddRange(arguments.Skip(regularParameterCount).Select(arg => arg.ConvertTo(expectedParameters[paramIndex++].Type, builder).Expression));
                var argListRR = new ResolveResult(SpecialType.ArgList);
                arguments = arguments.Take(regularParameterCount)
                            .Concat(new[] { argListArg.WithoutILInstruction().WithRR(argListRR) }).ToList();
                method             = (IMethod)method.MemberDefinition;
                expectedParameters = method.Parameters.ToList();
            }

            var argumentResolveResults = arguments.Select(arg => arg.ResolveResult).ToList();

            if (callOpCode == OpCode.NewObj)
            {
                ResolveResult rr = new CSharpInvocationResolveResult(target.ResolveResult, method, argumentResolveResults, isExpandedForm: isExpandedForm);
                if (settings.AnonymousTypes && method.DeclaringType.IsAnonymousType())
                {
                    var argumentExpressions            = arguments.SelectArray(arg => arg.Expression);
                    AnonymousTypeCreateExpression atce = new AnonymousTypeCreateExpression();
                    if (CanInferAnonymousTypePropertyNamesFromArguments(argumentExpressions, expectedParameters))
                    {
                        atce.Initializers.AddRange(argumentExpressions);
                    }
                    else
                    {
                        for (int i = 0; i < argumentExpressions.Length; i++)
                        {
                            atce.Initializers.Add(
                                new NamedExpression {
                                Name       = expectedParameters[i].Name,
                                Expression = arguments[i].ConvertTo(expectedParameters[i].Type, expressionBuilder)
                            });
                        }
                    }
                    return(atce
                           .WithRR(rr));
                }
                else
                {
                    if (IsUnambiguousCall(expectedTargetDetails, method, null, Empty <IType> .Array, arguments, out _) != OverloadResolutionErrors.None)
                    {
                        for (int i = 0; i < arguments.Count; i++)
                        {
                            if (settings.AnonymousTypes && expectedParameters[i].Type.ContainsAnonymousType())
                            {
                                if (arguments[i].Expression is LambdaExpression lambda)
                                {
                                    ModifyReturnTypeOfLambda(lambda);
                                }
                            }
                            else
                            {
                                arguments[i] = arguments[i].ConvertTo(expectedParameters[i].Type, expressionBuilder);
                            }
                        }
                    }
                    return(new ObjectCreateExpression(expressionBuilder.ConvertType(method.DeclaringType), arguments.SelectArray(arg => arg.Expression))
                           .WithRR(rr));
                }
            }
            else
            {
                int allowedParamCount = (method.ReturnType.IsKnownType(KnownTypeCode.Void) ? 1 : 0);
                if (method.IsAccessor && (method.AccessorOwner.SymbolKind == SymbolKind.Indexer || expectedParameters.Count == allowedParamCount))
                {
                    return(HandleAccessorCall(expectedTargetDetails, method, target, arguments.ToList()));
                }
                else if (method.Name == "Invoke" && method.DeclaringType.Kind == TypeKind.Delegate && !IsNullConditional(target))
                {
                    return(new InvocationExpression(target, arguments.Select(arg => arg.Expression))
                           .WithRR(new CSharpInvocationResolveResult(target.ResolveResult, method, argumentResolveResults, isExpandedForm: isExpandedForm)));
                }
                else if (IsDelegateEqualityComparison(method, arguments))
                {
                    return(HandleDelegateEqualityComparison(method, arguments)
                           .WithRR(new CSharpInvocationResolveResult(target.ResolveResult, method, argumentResolveResults, isExpandedForm: isExpandedForm)));
                }
                else if (method.IsOperator && method.Name == "op_Implicit" && arguments.Count == 1)
                {
                    return(HandleImplicitConversion(method, arguments[0]));
                }
                else
                {
                    bool requireTypeArguments = false;
                    bool requireTarget;
                    if (expressionBuilder.HidesVariableWithName(method.Name))
                    {
                        requireTarget = true;
                    }
                    else
                    {
                        if (method.IsStatic)
                        {
                            requireTarget = !expressionBuilder.IsCurrentOrContainingType(method.DeclaringTypeDefinition) || method.Name == ".cctor";
                        }
                        else if (method.Name == ".ctor")
                        {
                            requireTarget = true;                             // always use target for base/this-ctor-call, the constructor initializer pattern depends on this
                        }
                        else if (target.Expression is BaseReferenceExpression)
                        {
                            requireTarget = (callOpCode != OpCode.CallVirt && method.IsVirtual);
                        }
                        else
                        {
                            requireTarget = !(target.Expression is ThisReferenceExpression);
                        }
                    }
                    bool    targetCasted        = false;
                    bool    argumentsCasted     = false;
                    IType[] typeArguments       = Empty <IType> .Array;
                    var     targetResolveResult = requireTarget ? target.ResolveResult : null;
                    IParameterizedMember     foundMethod;
                    OverloadResolutionErrors errors;
                    while ((errors = IsUnambiguousCall(expectedTargetDetails, method, targetResolveResult, typeArguments, arguments, out foundMethod)) != OverloadResolutionErrors.None)
                    {
                        switch (errors)
                        {
                        case OverloadResolutionErrors.TypeInferenceFailed:
                        case OverloadResolutionErrors.WrongNumberOfTypeArguments:
                            if (requireTypeArguments)
                            {
                                goto default;
                            }
                            requireTypeArguments = true;
                            typeArguments        = method.TypeArguments.ToArray();
                            continue;

                        default:
                            // TODO : implement some more intelligent algorithm that decides which of these fixes (cast args, add target, cast target, add type args)
                            // is best in this case. Additionally we should not cast all arguments at once, but step-by-step try to add only a minimal number of casts.
                            if (!argumentsCasted)
                            {
                                argumentsCasted = true;
                                for (int i = 0; i < arguments.Count; i++)
                                {
                                    if (settings.AnonymousTypes && expectedParameters[i].Type.ContainsAnonymousType())
                                    {
                                        if (arguments[i].Expression is LambdaExpression lambda)
                                        {
                                            ModifyReturnTypeOfLambda(lambda);
                                        }
                                    }
                                    else
                                    {
                                        arguments[i] = arguments[i].ConvertTo(expectedParameters[i].Type, expressionBuilder);
                                    }
                                }
                            }
                            else if (!requireTarget)
                            {
                                requireTarget       = true;
                                targetResolveResult = target.ResolveResult;
                            }
                            else if (!targetCasted)
                            {
                                targetCasted        = true;
                                target              = target.ConvertTo(method.DeclaringType, expressionBuilder);
                                targetResolveResult = target.ResolveResult;
                            }
                            else if (!requireTypeArguments)
                            {
                                requireTypeArguments = true;
                                typeArguments        = method.TypeArguments.ToArray();
                            }
                            else
                            {
                                break;
                            }
                            continue;
                        }
                        // We've given up.
                        foundMethod = method;
                        break;
                    }
                    // Note: after this loop, 'method' and 'foundMethod' may differ,
                    // but as far as allowed by IsAppropriateCallTarget().

                    Expression targetExpr;
                    string     methodName = method.Name;
                    AstNodeCollection <AstType> typeArgumentList;
                    if (requireTarget)
                    {
                        targetExpr       = new MemberReferenceExpression(target.Expression, methodName);
                        typeArgumentList = ((MemberReferenceExpression)targetExpr).TypeArguments;

                        // HACK : convert this.Dispose() to ((IDisposable)this).Dispose(), if Dispose is an explicitly implemented interface method.
                        if (method.IsExplicitInterfaceImplementation && target.Expression is ThisReferenceExpression)
                        {
                            var castExpression = new CastExpression(expressionBuilder.ConvertType(method.ImplementedInterfaceMembers[0].DeclaringType), target.Expression);
                            methodName       = method.ImplementedInterfaceMembers[0].Name;
                            targetExpr       = new MemberReferenceExpression(castExpression, methodName);
                            typeArgumentList = ((MemberReferenceExpression)targetExpr).TypeArguments;
                        }
                    }
                    else
                    {
                        targetExpr       = new IdentifierExpression(methodName);
                        typeArgumentList = ((IdentifierExpression)targetExpr).TypeArguments;
                    }

                    if (requireTypeArguments && (!settings.AnonymousTypes || !method.TypeArguments.Any(a => a.ContainsAnonymousType())))
                    {
                        typeArgumentList.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType));
                    }
                    var argumentExpressions = arguments.Select(arg => arg.Expression);
                    return(new InvocationExpression(targetExpr, argumentExpressions)
                           .WithRR(new CSharpInvocationResolveResult(target.ResolveResult, foundMethod, argumentResolveResults, isExpandedForm: isExpandedForm)));
                }
            }
        }