internal override void Complete()
        {
            try
            {
                if (_exitWasCalled)
                {
                    return;
                }

                // process any items that may still be in the input pipeline
                if (_scriptBlock.HasProcessBlock && IsPipelineInputExpected())
                {
                    DoProcessRecordWithInput();
                }

                if (_scriptBlock.HasEndBlock)
                {
                    var endBlock = _runOptimizedCode ? _scriptBlock.EndBlock : _scriptBlock.UnoptimizedEndBlock;

                    if (this.CommandRuntime.InputPipe.ExternalReader == null)
                    {
                        if (IsPipelineInputExpected())
                        {
                            // read any items that may still be in the input pipe
                            while (Read())
                            {
                                _input.Add(Command.CurrentPipelineObject);
                            }
                        }

                        // run with accumulated input
                        RunClause(endBlock, AutomationNull.Value, _input);
                    }
                    else
                    {
                        // run with asynchronously updated $input enumerator
                        RunClause(endBlock, AutomationNull.Value, this.CommandRuntime.InputPipe.ExternalReader.GetReadEnumerator());
                    }
                }
            }
            finally
            {
                if (!_scriptBlock.HasCleanBlock)
                {
                    ScriptBlock.LogScriptBlockEnd(_scriptBlock, Context.CurrentRunspace.InstanceId);
                }
            }
        }
        protected override void CleanResource()
        {
            if (_scriptBlock.HasCleanBlock && _anyClauseExecuted)
            {
                // The 'Clean' block doesn't write to pipeline.
                Pipe oldOutputPipe = _functionContext._outputPipe;
                _functionContext._outputPipe = new Pipe {
                    NullPipe = true
                };

                try
                {
                    RunClause(
                        clause: _runOptimizedCode?_scriptBlock.CleanBlock: _scriptBlock.UnoptimizedCleanBlock,
                        dollarUnderbar: AutomationNull.Value,
                        inputToProcess: AutomationNull.Value);
                }
                finally
                {
                    _functionContext._outputPipe = oldOutputPipe;
                    ScriptBlock.LogScriptBlockEnd(_scriptBlock, Context.CurrentRunspace.InstanceId);
                }
            }
        }