/// <summary>
        /// Runs one step of the pipeline using propertyBag as the pipeline input
        /// Saves last outputed object
        /// Saves whether the pipeline returned 0 or 1 object
        /// throws exception if pipeline outputed more than 1 object
        /// <param name="propertyBag">The property bag to run the powershell script's pipeline on</param>
        public void StepPipeline(
            IFsrmPropertyBag propertyBag
            )
        {
            ResetRuleResults();

            m_waitHandleIndex lockIndex;
            bool readAValue    = false;
            bool tooManyValues = false;

            m_ruleNoApply = false;

            // insert the property bag into the pipeline after adding the GetStream Method
            PSObject psPropertyBag = new PSObject(propertyBag);

            psPropertyBag.Methods.Add(new PSCodeMethod("GetStream", m_getStreamMethodInfo));
            m_propertyBagWriter.InsertData(psPropertyBag);

            // wait for either the pipeline to close or
            // for another property to be requested from the enumerator
            // If for input a in the script value 1 is emitted, it must be emitted before value b is requested
            // Handle multiple values being emitted but fail the current property bag if it happens
            do
            {
                lockIndex = (m_waitHandleIndex)WaitHandle.WaitAny(m_powershellPaused);

                //pipeline terminated unexpectedly save message and restart it
                if (m_pipeLine.Output.EndOfPipeline)
                {
                    string message;

                    if (m_pipeLine.PipelineStateInfo.State == PipelineState.Failed)
                    {
                        message = string.Format(CultureInfo.InvariantCulture,
                                                "Powershell Classifier terminated abruptly due to failuer while processing file [{0}] in rule [{1}] - failure details: [{2}]",
                                                propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                                                m_ruleName,
                                                m_pipeLine.PipelineStateInfo.Reason.Message);
                    }
                    else
                    {
                        message = string.Format(CultureInfo.InvariantCulture,
                                                "Powershell Classifier exited abruptly without failures while processing file [{0}] in rule [{1}].",
                                                propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                                                m_ruleName);
                    }

                    propertyBag.AddMessage(message);
                    CreateAndBeginPipeline();
                    throw new COMException(message, m_pipeLine.PipelineStateInfo.Reason);
                }

                // if we haven't read a value pop one off and save it
                if (m_pipeLine.Output.Count >= 1 && !readAValue)
                {
                    readAValue      = true;
                    m_propertyValue = m_pipeLine.Output.Read();
                }

                // if we have read a value and there are values in the pipeline, then
                // set the tooManyValues flag and eat everythign in the pipeline
                while (m_pipeLine.Output.Count > 0 && readAValue)
                {
                    // if the m_propertyValue currently points to the first value ouput for the pipeline
                    // the add a message for it, other wise output messages for duplicate values after popping them off
                    if (!tooManyValues)
                    {
                        string message1 = string.Format(CultureInfo.InvariantCulture,
                                                        "Powershell Classifier returned too many values while processing file [{0}] in rule [{1}] - returned object of type [{2}], and value [{3}]",
                                                        propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                                                        m_ruleName,
                                                        m_propertyValue.BaseObject.GetType().ToString(),
                                                        m_propertyValue.BaseObject.ToString());
                        propertyBag.AddMessage(message1);
                    }

                    // cleanup pipeline
                    m_propertyValue = m_pipeLine.Output.Read();

                    // ouput message for current object
                    string message2 = string.Format(CultureInfo.InvariantCulture,
                                                    "Powershell Classifier returned too many values while processing file [{0}] in rule [{1}] - returned object of type [{2}], and value [{3}]",
                                                    propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                                                    m_ruleName,
                                                    m_propertyValue.BaseObject.GetType().ToString(),
                                                    m_propertyValue.BaseObject.ToString());
                    propertyBag.AddMessage(message2);

                    tooManyValues = true;
                }
            } while (lockIndex != m_waitHandleIndex.Enumerator && m_pipeLine.Output.IsOpen);

            // if script didn't output any values for this property bag record it
            if (!readAValue)
            {
                m_ruleNoApply = true;
            }

            // if output too many values finish failing this property
            if (tooManyValues)
            {
                //already added messages for reason why we are failing
                string message3 = string.Format(CultureInfo.InvariantCulture,
                                                "Powershell Classifier returned too many values while processing file [{0}] in rule [{1}]",
                                                propertyBag.VolumeName + propertyBag.RelativePath + "\\" + propertyBag.Name,
                                                m_ruleName);
                throw new COMException(message3, HRESULTS.PS_CLS_E_TOO_MANY_VALUES);
            }

            // if there were errors in the pipeline pop them all off and then fail current property bag
            if (m_pipeLine.Error.Count > 0)
            {
                Exception firstError = null;
                while (m_pipeLine.Error.Count > 0)
                {
                    Exception exception = (Exception)m_pipeLine.Error.Read();
                    if (firstError == null)
                    {
                        firstError = exception;
                    }
                    // add message to pipeline
                    propertyBag.AddMessage(exception.Message);
                }

                throw (Exception)firstError;
            }
        }