/// <summary>
        /// Writes job output objects and propagates streams.
        /// Moves refilling objects from output to the queue.
        /// </summary>
        /// <remarks>
        /// v1.4.2 Only errors are propagated, other streams are written to the host.
        /// </remarks>
        void WriteResults(Job job, ICollection<PSObject> output)
        {
            // process output
            if (output != null && output.Count > 0)
            {
                if (Refill)
                {
                    foreach (var it in output)
                    {
                        if (it != null)
                        {
                            var reference = it.BaseObject as PSReference;
                            if (reference == null)
                                WriteObject(it);
                            else
                                Enqueue(new PSObject(reference.Value));
                        }
                    }
                }
                else
                {
                    foreach (var it in output)
                        WriteObject(it);
                }
            }

            // process streams
            var streams = job.Streams;

            // v1.4.2 Even with the shared host errors must be propagated explicitly.
            if (streams.Error.Count > 0)
            {
                foreach (var record in streams.Error)
                    WriteError(record);
            }

            // v1.4.2 Debug, progress, verbose, and warning messages are written to the host.
            // But streams are still populated, so we clear them on writing results.
            // NB: It is possible to log these streams in addition.
            streams.ClearStreams();
        }
        /// <summary>
        /// Gets the next part of input items and feeds them to a ready job.
        /// If forced waits for a ready job.
        /// </summary>
        void Feed(bool force)
        {
            // try to make more jobs ready and more input available on Refill
            Take();

            // no input? check this after taking, Refill adds input on taking
            if (_queue.Count == 0)
                return;

            // all busy?
            if (_Count - _work.Count == 0)
            {
                // no ready jobs, done if not forced
                if (!force)
                    return;

                // wait for jobs and make them ready
                Wait();
                Take();
            }

            // split the queue equally between all potential jobs
            int load = _queue.Count / _Count;
            if (load * _Count < _queue.Count)
                ++load;

            // check limits
            if (load < MinLoad)
                load = MinLoad;
            else if (load > MaxLoad)
                load = MaxLoad;

            lock (_syncObject)
            {
                int nReadyJobs = _Count - _work.Count;
                if (xStop || nReadyJobs == 0)
                    return;

                do
                {
                    // limit load by the queue
                    if (load > _queue.Count)
                    {
                        load = _queue.Count;

                        // if load is less than minimum and not forced then exit
                        if (load < MinLoad && !force)
                            return;
                    }

                    // next job node
                    LinkedListNode<Job> node = _done.First;
                    if (node == null)
                    {
                        // v1.4.2 Runspaces use the same host as the cmdlet.
                        var job = new Job(RunspaceFactory.CreateRunspace(Host, _iss));
                        node = new LinkedListNode<Job>(job);
                        _work.AddLast(node);
                        WriteResults(job, job.InvokeBegin(_Begin, _Script));
                    }
                    else
                    {
                        _done.RemoveFirst();
                        _work.AddLast(node);
                    }

                    if (xStop)
                        return;

                    // feed the job
                    ++_infoPartCount;
                    node.Value.BeginInvoke(_queue, load);

                    // show feed info
                    if (_verbose)
                        WriteVerbose(string.Format(null, "Split-Pipeline: Jobs = {0}; Load = {1}; Queue = {2}", _work.Count, load, _queue.Count));
                }
                while (!xStop && --nReadyJobs > 0 && _queue.Count > 0);
            }
        }