/// <summary>
        /// Sets the ExceptionEnhanced switch of the associated ExceptionStopOptionPolicy object
        /// on or off. 
        /// </summary>
        /// <param name="behavior">DebuggerBehaviors.stop turns ON ExceptionEnhanced switch of the associated 
        /// ExceptionStopOptionPolicy object, and DebuggerBehaviors.ignore turns the switch OFF. The command 
        /// DebuggerBehaviors.log is not supported.</param>
        /// <param name="arguments">Must be null.</param>
        public override void SetBehavior(DebuggerBehavior behavior, string arguments)
        {
            if (arguments != null)
            {
                throw new MDbgShellException("This event type does not accept arguments.");
            }
            switch (behavior)
            {
                case DebuggerBehavior.Stop:
                    m_esop.ExceptionEnhancedOn = true;
                    break;
                case DebuggerBehavior.Ignore:
                    m_esop.ExceptionEnhancedOn = false;
                    break;
                case DebuggerBehavior.Log:
                    throw new MDbgShellException("ExceptionEnhanced can only be switched on and off, using the catch and ignore commands.");
            }

            // To preserve legacy behavior, if m_esop contains no MDbgExceptionPolicyItem objects
            // describing debugger behaviors for specific exception types, and the default behavior
            // is not log, then the command "catch ee" will set the default behavior of m_esop
            // to stop, and "ignore ee" will set it to ignore.

            if ((m_esop.ItemsCount() == 0) &&
                (behavior == DebuggerBehavior.Stop || behavior == DebuggerBehavior.Ignore) &&
                (m_esop.Default != DebuggerBehavior.Log))
            {
                m_esop.SetBehavior(behavior, null);
            }
        }
 /// <summary>
 /// Default constructor. Sets the default behavior to DebuggerBehaviors.ignore.
 /// </summary>
 /// <param name="acronym">The acronym associated with this stop option policy.</param>
 /// <param name="fullName">The full name of the callback event, for printing.</param>
 public SimpleStopOptionPolicy(string acronym, string fullName)
 {
     Acronym = acronym;
     m_behavior = DebuggerBehavior.Ignore;
     m_fullName = fullName;
 }
 /// <summary>
 /// Sets the debugger behavior for this stop option policy.
 /// </summary>
 /// <param name="behavior">Debugger behavior - stop, log, or ignore.</param>
 /// <param name="arguments">Other arguments.</param>
 public abstract void SetBehavior(DebuggerBehavior behavior, string arguments);
        /// <summary>
        /// Modifies the exception settings, given an exception type and corresponding debugger behavior.
        /// </summary>
        /// <param name="behavior">stop, log, or ignore</param>
        /// <param name="arguments">A type of exception, or a regular expression.</param>
        public override void SetBehavior(DebuggerBehavior behavior, string arguments)
        {
            ExceptionStopOptionPolicyItem exceptionItem;
            string regex;
            int existingItemIndex = -1;
            bool redundantEntry = false;
            bool regexSubset = false;

            if (arguments == null)
            {
                // If no exception types are specified, then all existing settings are cleared and the
                // behavior becomes the default behavior for all exceptions.
                m_items.Clear();
                m_default = behavior;
                if (behavior == DebuggerBehavior.Ignore)
                {
                    // To preserve legacy behavior, ignoring all exceptions also turns the exception
                    // enhanced switch off.
                    m_exceptionEnhancedOn = false;
                }
            }
            else
            {
                // The arguments string can contain multiple exception types and regular expressions,
                // so the arguments are split into a string array. For example, if the arguments string
                // is "System.Exception System.A*", it is split into {"System.Exception", "System.A*"}.
                // The behavior for all of these arguments is then set to the given behavior. 
                string[] exceptionTypes = arguments.Split();
                string exceptionType;
                foreach (string type in exceptionTypes)
                {
                    exceptionType = type.Trim();
                    if (MDbgUtil.IsRegex(exceptionType))
                    {
                        // Input is a regular expression. Go through the existing exception items
                        // and check if any of them match the input regular expression. If they do,
                        // remove them, because the input regular expression is added after them
                        // and has precedence. For example, if input is "System.*" and an exception
                        // item already exists for "System.Exception", we remove the System.Exception
                        // item.
                        for (int i = 0; i < m_items.Count; i++)
                        {
                            exceptionItem = m_items[i];
                            regex = MDbgUtil.ConvertSimpleExpToRegExp(exceptionType);
                            if (Regex.IsMatch(exceptionItem.ExceptionType, regex))
                            {
                                m_items.Remove(exceptionItem);
                                i--;
                            }
                        }
                    }
                    else
                    {
                        // Input is not a regular expression. Check if m_items already contains
                        // an entry for this exception type.
                        foreach (ExceptionStopOptionPolicyItem item in m_items)
                        {
                            if (item.ExceptionType == type)
                            {
                                existingItemIndex = m_items.IndexOf(item);
                                break;
                            }
                        }
                    }

                    // Check if input is redundant. An input is redundant if it does not change the existing
                    // behavior. There are two cases in which an input is redundant:
                    //
                    // - An exception item already exists that is a regular expression accepting the
                    // input exception type, and specifying the same debugger behavior. For example,
                    // if a "log System.*" exception item already exists, an input of "log System.Exception" 
                    // if redundant. However, an input of "ignore System.Exception" is NOT redundant,
                    // because it is added after the "log System.*" item and has precedence over it.
                    // 
                    // - The input behavior is the same as the default behavior. For example, if the 
                    // default behavior is ignore, an input of "ignore System.Exception" is redundant,
                    // UNLESS the input matches some existing exception item regular expression (as in
                    // the example above).

                    for (int i = m_items.Count - 1; i >= 0; i--)
                    {
                        exceptionItem = m_items[i];
                        if (m_items.IndexOf(exceptionItem) == existingItemIndex)
                        {
                            break;
                        }
                        if (MDbgUtil.IsRegex(exceptionItem.ExceptionType))
                        {
                            regex = MDbgUtil.ConvertSimpleExpToRegExp(exceptionItem.ExceptionType);
                            if (Regex.IsMatch(type, regex))
                            {
                                regexSubset = true;
                                if (behavior == exceptionItem.Behavior)
                                {
                                    redundantEntry = true;
                                }
                                break;
                            }
                        }
                    }
                    if (!regexSubset)
                    {
                        if (behavior == m_default)
                        {
                            redundantEntry = true;
                        }
                    }

                    // If the input modifies some existing exception item existing entry and the behavior 
                    // is redundant, remove the existing item. If no matching item exists and the input
                    // is redundant, do nothing.
                    if (existingItemIndex != -1)
                    {
                        if (redundantEntry)
                        {
                            m_items.RemoveAt(existingItemIndex);
                        }
                        else
                        {
                            m_items[existingItemIndex].Behavior = behavior;
                        }
                    }
                    else
                    {
                        if (!redundantEntry)
                        {
                            m_items.Add(new ExceptionStopOptionPolicyItem(type, behavior));
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Default constructor. Sets the default behavior to ignore all exceptions, and sets
 /// the ExceptionEnhanced switch to false.
 /// </summary>
 public ExceptionStopOptionPolicy()
 {
     m_items = new List<ExceptionStopOptionPolicyItem>();
     m_default = DebuggerBehavior.Ignore;
     Acronym = "ex";
 }
 /// <summary>
 /// Sets the debugger behavior for this stop option policy.
 /// </summary>
 /// <param name="behavior">stop, log, or ignore</param>
 /// <param name="arguments">Must be null.</param>
 public override void SetBehavior(DebuggerBehavior behavior, string arguments)
 {
     if (arguments != null)
     {
         throw new MDbgShellException("This event type does not accept arguments.");
     }
     m_behavior = behavior;
 }