private void _combineArguments(PValue[] args, out PValue[] nonArguments,
            out PValue[] effectiveArguments)
        {
            System.Diagnostics.Debug.Assert(args.All(value => value != null),
                "Actual (CLI) null references passed to " +
                    GetType().Name + ".IndirectCall");

            var argc = args.Length;
            var countExcessArguments = System.Math.Max(
                argc - _computeCountOpenArgumentsMapped(argc), 0);
            var nonArgumentPrefix = NonArgumentPrefix;
            var mappingLength = _mappings.Count;
            var countEffectiveArguments =
                System.Math.Max(mappingLength + countExcessArguments - nonArgumentPrefix, 0);

            nonArguments = new PValue[nonArgumentPrefix];
            effectiveArguments = new PValue[countEffectiveArguments];
            System.Diagnostics.Debug.Assert(effectiveArguments.Length + nonArgumentPrefix >=
                mappingLength);

            //Apply mapping
            var openArgumentUsed = new bool[argc];
            var absoluteIndex = 0;
            for (; absoluteIndex < mappingLength; absoluteIndex++)
            {
                var mapping = _mappings.Array[_mappings.Offset + absoluteIndex];
                System.Diagnostics.Debug.Assert(mapping != 0, "Mapping contains zero");

                int relativeIndex;
                var argumentList = _determineArgumentList(
                    out relativeIndex, nonArgumentPrefix, absoluteIndex, nonArguments,
                    effectiveArguments);

                if (0 <= mapping)
                {
                    var index = mapping - 1;
                    //maps closed arguments   
                    argumentList[relativeIndex] = _closedArguments[index];
                }
                else
                {
                    var index = (-mapping) - 1;
                    //maps open argument
                    if (index < argc)
                    {
                        argumentList[relativeIndex] = args[index];
                        openArgumentUsed[index] = true;
                    }
                    else
                    {
                        argumentList[relativeIndex] = PType.Null;
                    }
                }
            }

            //Add excess arguments
            for (var i = 0; i < openArgumentUsed.Length; i++)
            {
                if (openArgumentUsed[i])
                    continue;

                int relativeIndex;
                var argumentList = _determineArgumentList(out relativeIndex, nonArgumentPrefix,
                    absoluteIndex++, nonArguments,
                    effectiveArguments);
                argumentList[relativeIndex] = args[i];
            }

            System.Diagnostics.Debug.Assert(nonArguments.All(x => !ReferenceEquals(x, null)),
                "non-argument left unassigned");
            System.Diagnostics.Debug.Assert(effectiveArguments.All(x => !ReferenceEquals(x, null)),
                "effective argument left unassigned");
        }