/*
 * ObjectOps.cs --
 *
 * Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: $
 */

using System;

#if DATA
using System.Data;
#endif

using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using Eagle._Attributes;
using Eagle._Components.Public;
using Eagle._Constants;
using Eagle._Containers.Private;
using Eagle._Containers.Public;
using Eagle._Interfaces.Public;

namespace Eagle._Components.Private
{
    [ObjectId("21953933-d364-453c-b848-01e348a8f8ac")]
    internal static class ObjectOps
    {
        #region Private Constants
        #region Object Creation
        private static readonly bool DefaultCreate = false;
        private static readonly bool DefaultNoCreate = true;
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Object Disposal
        private static readonly bool DefaultDispose = true;
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Default Reflection-Related Flags
        private static readonly MemberTypes DefaultMemberTypes =
            MemberTypes.Field | MemberTypes.Method | MemberTypes.Property;

        ///////////////////////////////////////////////////////////////////////

        private static readonly BindingFlags DefaultBindingFlags =
            BindingFlags.Instance | BindingFlags.Static |
            BindingFlags.Public | BindingFlags.FlattenHierarchy;
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Default Pattern-Related Flags
        private static readonly MatchMode DefaultMatchMode = MatchMode.None;
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Default Marshal-Related Flags
        private static readonly LoadType DefaultLoadType = LoadType.Default;

        ///////////////////////////////////////////////////////////////////////

        private static readonly MarshalFlags DefaultMarshalFlags =
            MarshalFlags.Default;

        ///////////////////////////////////////////////////////////////////////

        private static readonly ByRefArgumentFlags DefaultByRefArgumentFlags =
            ByRefArgumentFlags.None;

        ///////////////////////////////////////////////////////////////////////

        private static readonly ObjectFlags DefaultObjectFlags =
            ObjectFlags.Default;

        ///////////////////////////////////////////////////////////////////////

        private static readonly ObjectOptionType DefaultObjectOptionType =
            ObjectOptionType.Default;
        #endregion
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Private Data
        #region Type Conversion
        //
        // NOTE: *WARNING* Changes to this assembly name are considered
        //        to be a "breaking change".
        //
        private static readonly string systemSimpleName =
            AssemblyOps.GetFullName(typeof(object)); /* mscorlib */

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: *WARNING* Changes to this list are considered to be a
        //       "breaking change".
        //
        private static readonly string[] systemNamespaces = {
            /* System */
            typeof(object).Namespace
        };

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: *WARNING* Changes to this assembly name are considered
        //        to be a "breaking change".
        //
        private static readonly string assemblySimpleName =
            GlobalState.GetAssemblyFullName(); /* Eagle */

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: *WARNING* Changes to this list are considered to be a
        //       "breaking change".
        //
        private static readonly string[] assemblyNamespaces = {
            /* Eagle._Attributes */
            // typeof(AssemblyDateTimeAttribute).Namespace,

            /* Eagle._Components.Public */
            typeof(Engine).Namespace,

            /* Eagle._Containers.Public */
            typeof(ArgumentList).Namespace,

            /* Eagle._Encodings */
            // typeof(_Encodings.OneByteEncoding).Namespace,

            /* Eagle._Interfaces.Public */
            // typeof(IClientData).Namespace,
        };
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region System Defaults
        #region GC Settings
        //
        // NOTE: The default behavior is to run garbage collection after
        //       removing a managed object from the interpreter; however,
        //       that may have negative performance implications.
        //
        private static bool DefaultSynchronous = true;
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Option Flags
        //
        // NOTE: Any changes to these default option flag values will be
        //       library-wide.
        //
        private static OptionFlags AliasOptionFlags = OptionFlags.None;
        private static OptionFlags CreateOptionFlags = OptionFlags.None;
        private static OptionFlags NoCreateOptionFlags = OptionFlags.None;
        private static OptionFlags NoDisposeOptionFlags = OptionFlags.None;
        private static OptionFlags SynchronousOptionFlags = OptionFlags.None;
        private static OptionFlags TraceOptionFlags = OptionFlags.None;
        private static OptionFlags VerboseOptionFlags = OptionFlags.None;
        private static OptionFlags ArrayAsLinkOptionFlags = OptionFlags.None;
        private static OptionFlags ArrayAsValueOptionFlags = OptionFlags.None;
        #endregion
        #endregion
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Default Settings Support Methods
        public static bool GetDefaultSynchronous()
        {
            return DefaultSynchronous;
        }

        ///////////////////////////////////////////////////////////////////////

        public static BindingFlags GetDefaultBindingFlags()
        {
            return DefaultBindingFlags;
        }

        ///////////////////////////////////////////////////////////////////////

        public static ObjectFlags GetDefaultObjectFlags()
        {
            return DefaultObjectFlags;
        }

        ///////////////////////////////////////////////////////////////////////

        public static ObjectOptionType GetDefaultObjectOptionType()
        {
            return DefaultObjectOptionType;
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Type Support Methods
        public static IClientData GetClientData(
            object @object
            )
        {
            IIdentifier identifier = @object as IIdentifier;

            if (identifier != null)
                return identifier.ClientData;
            else
                return null;
        }

        ///////////////////////////////////////////////////////////////////////

        public static ReturnCode AddSystemObjectNamespaces(
            ref StringDictionary namespaces,
            ref Result error
            )
        {
            if (namespaces == null)
                namespaces = new StringDictionary();

            if (systemNamespaces == null)
            {
                error = "system namespaces not available";
                return ReturnCode.Error;
            }

            foreach (string systemNamespace in systemNamespaces)
                if (!namespaces.ContainsKey(systemNamespace))
                    namespaces.Add(systemNamespace, systemSimpleName);

            return ReturnCode.Ok;
        }

        ///////////////////////////////////////////////////////////////////////

        public static ReturnCode AddAssemblyObjectNamespaces(
            ref StringDictionary namespaces,
            ref Result error
            )
        {
            if (namespaces == null)
                namespaces = new StringDictionary();

            if (assemblyNamespaces == null)
            {
                error = "assembly namespaces not available";
                return ReturnCode.Error;
            }

            foreach (string assemblyNamespace in assemblyNamespaces)
                if (!namespaces.ContainsKey(assemblyNamespace))
                    namespaces.Add(assemblyNamespace, assemblySimpleName);

            return ReturnCode.Ok;
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Garbage Collection Support Methods
        private static bool ShouldGC()
        {
            //
            // NOTE: If this environment variable is set, the Eagle library
            //       will never manually call into the GC to have it collect
            //       garbage; otherwise, manual calls into the GC will be
            //       enabled at certain strategic points in the code where
            //       it makes sense.
            //
            if (CommonOps.Environment.GetVariable(EnvVars.NeverGC) != null)
            {
                return false;
            }

            return true;
        }

        ///////////////////////////////////////////////////////////////////////

        private static bool ShouldWaitForGC()
        {
            //
            // NOTE: If this environment variable is set, always wait for
            //       the GC to finish the pending finalizers; otherwise,
            //       we will only wait if this is the default application
            //       domain to prevent a subtle deadlock that can seemingly
            //       occur in applications that contain a user-interface
            //       that may be running in an isolated application domain
            //       (see below).  Otherwise, if the "opposite" environment
            //       variable is set, never wait for the GC to finish the
            //       pending finalizers.
            //
            if (CommonOps.Environment.GetVariable(
                    EnvVars.AlwaysWaitForGC) != null)
            {
                return true;
            }
            else if (CommonOps.Environment.GetVariable(
                    EnvVars.NeverWaitForGC) != null)
            {
                return false;
            }
            else
            {
                //
                // BUGBUG: Only wait for pending finalizers in the default
                //         application domain (due to potential deadlocks?).
                //         This seems to be related to the cross-AppDomain
                //         marshalling in .NET wanting to obtain a lock on
                //         the GC from two threads at the same time, which
                //         results in a deadlock.  This issue was observed
                //         in a WPF application loaded into an isolated
                //         application domain; therefore, this issue may be
                //         limited to applications that contain some kind
                //         of user-interface thread.
                //
                if (AppDomainOps.IsDefault())
                    return true;
            }

            return false;
        }

        ///////////////////////////////////////////////////////////////////////

        private static void CollectGarbage(
            int generation,
            GCCollectionMode collectionMode
            ) /* throw */
        {
            if (generation == -1)
                GC.Collect();
            else
                GC.Collect(generation, collectionMode);
        }

        ///////////////////////////////////////////////////////////////////////

        public static void CollectGarbage() /* throw */
        {
            CollectGarbage(null, null);
        }

        ///////////////////////////////////////////////////////////////////////

        public static void CollectGarbage(
            bool? force,
            bool? wait
            ) /* throw */
        {
            CollectGarbage(-1, GCCollectionMode.Default, force, wait);
        }

        ///////////////////////////////////////////////////////////////////////

        private static void CollectGarbage(
            int generation,
            GCCollectionMode collectionMode,
            bool? force,
            bool? wait
            ) /* throw */
        {
            //
            // NOTE: If the force parameter is null, that means we should
            //       attempt to automatically detect whether or not we
            //       should actually collect any garbage.
            //
            bool reallyCollect = (force == null) ? ShouldGC() : (bool)force;

            if (!reallyCollect)
                return;

            //
            // NOTE: If the wait parameter is null, that means we should
            //       attempt to automatically detect whether or not we
            //       should wait for the pending finalizers to finish.
            //
            bool reallyWait = (wait == null) ? ShouldWaitForGC() : (bool)wait;

            CollectGarbage(generation, collectionMode);

            if (reallyWait)
            {
                GC.WaitForPendingFinalizers();
                CollectGarbage(generation, collectionMode);
            }
        }

        ///////////////////////////////////////////////////////////////////////

#if SHELL
        public static void GetTotalMemory(
            bool collect,
            ref long beforeBytes,
            ref long afterBytes
            )
        {
            beforeBytes = GC.GetTotalMemory(false);

            if (collect)
                afterBytes = GC.GetTotalMemory(true);
        }
#endif
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Object Option Support Methods
        #region Object Option Translation Methods
        public static ObjectOptionType GetOptionType(
            bool raw,
            bool all
            )
        {
            if (all)
                return ObjectOptionType.InvokeAll;

            if (raw)
                return ObjectOptionType.InvokeRaw;

            return ObjectOptionType.Invoke;
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for use with the MarshalOps.FixupReturnValue and
        //       MarshalOps.FixupByRefArguments methods.
        //
        public static OptionDictionary GetInvokeOptions(
            ObjectOptionType objectOptionType
            )
        {
            //
            // NOTE: Enforce the logical union of alias option types here,
            //       via all return paths.  In this case, if more than one
            //       invoke option type is specified, the return value will
            //       be null.
            //
            objectOptionType = objectOptionType &
                ObjectOptionType.InvokeOptionMask;

            if ((objectOptionType == ObjectOptionType.Invoke) ||
                (objectOptionType == ObjectOptionType.InvokeRaw) ||
                (objectOptionType == ObjectOptionType.InvokeAll))
            {
                return GetObjectOptions(objectOptionType);
            }

            return null;
        }

        ///////////////////////////////////////////////////////////////////////

        public static ObjectOptionType GetByRefOptionType(
            ObjectOptionType objectOptionType,
            ByRefArgumentFlags byRefArgumentFlags
            )
        {
            //
            // NOTE: Enforce the logical union of alias option types here,
            //       via all return paths.
            //
            if (FlagOps.HasFlags(
                    byRefArgumentFlags, ByRefArgumentFlags.AliasAll, true))
            {
                return (objectOptionType &
                    ~ObjectOptionType.InvokeOptionMask) |
                    ObjectOptionType.InvokeAll;
            }
            else if (FlagOps.HasFlags(
                    byRefArgumentFlags, ByRefArgumentFlags.AliasRaw, true))
            {
                return (objectOptionType &
                    ~ObjectOptionType.InvokeOptionMask) |
                    ObjectOptionType.InvokeRaw;
            }

            return (objectOptionType &
                ~ObjectOptionType.InvokeOptionMask) | ObjectOptionType.Invoke;
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Object Option "Factory" Methods
        //
        // NOTE: This is for the [object alias] sub-command.
        //
        public static OptionDictionary GetAliasOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasraw", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasall", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasreference", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-stricttype", null),
                new Option(null, VerboseOptionFlags, Index.Invalid,
                    Index.Invalid, "-verbose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is primarily for the [library call] sub-command.
        //
        public static OptionDictionary GetCallOptions()
        {
            //
            // NOTE: These options are used by both the InvokeDelegate method
            //       (below) and the code for the [library call] command.
            //       Normally, this method would simply call into a static
            //       method exported from the _Commands.Library class; however,
            //       that class is only available when the library has been
            //       compiled with native code enabled; therefore, we define
            //       the actual options here and both the _Commands.Library
            //       class and the InvokeDelegate method can simply call us.
            //
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-objectname", null),
                new Option(null, OptionFlags.MustHaveTypeValue, Index.Invalid,
                    Index.Invalid, "-type", null),
                new Option(typeof(ByRefArgumentFlags),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-argumentflags",
                    new Variant(DefaultByRefArgumentFlags)),
                new Option(typeof(MarshalFlags),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-marshalflags",
                    new Variant(DefaultMarshalFlags)),
                new Option(null, CreateOptionFlags, Index.Invalid,
                    Index.Invalid, "-create", null),
                new Option(null, NoDisposeOptionFlags, Index.Invalid,
                    Index.Invalid, "-nodispose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noinvoke", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noargs", null),
                new Option(null, OptionFlags.MustHaveIntegerValue,
                    Index.Invalid, Index.Invalid, "-limit", null),
                new Option(null, OptionFlags.MustHaveIntegerValue,
                    Index.Invalid, Index.Invalid, "-index", null),
                new Option(null, AliasOptionFlags, Index.Invalid,
                    Index.Invalid, "-alias", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasraw", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasall", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasreference", null),
#if NATIVE && TCL
                new Option(null, OptionFlags.MustHaveTclInterpreterValue,
                    Index.Invalid, Index.Invalid, "-tcl", null),
#else
                new Option(null, OptionFlags.MustHaveValue |
                    OptionFlags.Unsupported, Index.Invalid,
                    Index.Invalid, "-tcl", null),
#endif
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noforcedelete", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-tostring", null),
                new Option(null, ArrayAsValueOptionFlags, Index.Invalid,
                    Index.Invalid, "-arrayasvalue", null),
                new Option(null, ArrayAsLinkOptionFlags, Index.Invalid,
                    Index.Invalid, "-arrayaslink", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-default", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-strictmember", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-strictargs", null),
                new Option(null, VerboseOptionFlags, Index.Invalid,
                    Index.Invalid, "-verbose", null),
                new Option(null, TraceOptionFlags, Index.Invalid,
                    Index.Invalid, "-trace", null),
                new Option(typeof(BindingFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-flags",
                    new Variant(DefaultBindingFlags)),
                new Option(typeof(BindingFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-bindingflags",
                    new Variant(DefaultBindingFlags)),
                new Option(typeof(ObjectFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-objectflags",
                    new Variant(DefaultObjectFlags)),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [library certificate] and
        //       [object certificate] sub-commands.
        //
        public static OptionDictionary GetCertificateOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-chain", null),
                new Option(typeof(X509VerificationFlags),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-verificationflags",
                    new Variant(CertificateOps.DefaultVerificationFlags)),
                new Option(typeof(X509RevocationMode),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-revocationmode",
                    new Variant(CertificateOps.DefaultRevocationMode)),
                new Option(typeof(X509RevocationFlag),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-revocationflag",
                    new Variant(CertificateOps.DefaultRevocationFlag)),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object cleanup] sub-command.
        //
        public static OptionDictionary GetCleanupOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, SynchronousOptionFlags, Index.Invalid,
                    Index.Invalid, "-synchronous", null),
                new Option(null, NoDisposeOptionFlags, Index.Invalid,
                    Index.Invalid, "-nodispose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nocomplain", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object create] sub-command.
        //
        public static OptionDictionary GetCreateOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-objectname", null),
                new Option(null, OptionFlags.MustHaveTypeValue,
                    Index.Invalid, Index.Invalid, "-type", null),
                new Option(null, OptionFlags.MustHaveTypeListValue,
                    Index.Invalid, Index.Invalid, "-parametertypes", null),
                new Option(null, TraceOptionFlags, Index.Invalid,
                    Index.Invalid, "-trace", null),
                new Option(typeof(ByRefArgumentFlags),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-argumentflags",
                    new Variant(DefaultByRefArgumentFlags)),
                new Option(typeof(MarshalFlags),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-marshalflags",
                    new Variant(DefaultMarshalFlags)),
                new Option(null, NoCreateOptionFlags, Index.Invalid,
                    Index.Invalid, "-nocreate", null),
                new Option(null, NoDisposeOptionFlags, Index.Invalid,
                    Index.Invalid, "-nodispose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noinvoke", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noargs", null),
                new Option(null, OptionFlags.MustHaveIntegerValue,
                    Index.Invalid, Index.Invalid, "-limit", null),
                new Option(null, OptionFlags.MustHaveIntegerValue,
                    Index.Invalid, Index.Invalid, "-index", null),
                new Option(null, AliasOptionFlags, Index.Invalid,
                    Index.Invalid, "-alias", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasraw", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasall", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasreference", null),
#if NATIVE && TCL
                new Option(null, OptionFlags.MustHaveTclInterpreterValue,
                    Index.Invalid, Index.Invalid, "-tcl", null),
#else
                new Option(null, OptionFlags.MustHaveValue |
                    OptionFlags.Unsupported, Index.Invalid,
                    Index.Invalid, "-tcl", null),
#endif
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noforcedelete", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-tostring", null),
                new Option(null, ArrayAsValueOptionFlags, Index.Invalid,
                    Index.Invalid, "-arrayasvalue", null),
                new Option(null, ArrayAsLinkOptionFlags, Index.Invalid,
                    Index.Invalid, "-arrayaslink", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-stricttype", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-strictmember", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-strictargs", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-default", null),
                new Option(null, VerboseOptionFlags, Index.Invalid,
                    Index.Invalid, "-verbose", null),
                new Option(typeof(BindingFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-flags",
                    new Variant(DefaultBindingFlags)),
                new Option(typeof(BindingFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-bindingflags",
                    new Variant(DefaultBindingFlags)),
                new Option(typeof(ObjectFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-objectflags",
                    new Variant(DefaultObjectFlags)),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object declare] sub-command.
        //
        public static OptionDictionary GetDeclareOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-stricttype", null),
                new Option(null, VerboseOptionFlags, Index.Invalid,
                    Index.Invalid, "-verbose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-declarenonpublic", null),
                new Option(null, OptionFlags.MustHaveMatchModeValue,
                    Index.Invalid, Index.Invalid, "-declaremode",
                    new Variant(DefaultMatchMode)),
                new Option(null, OptionFlags.MustHaveValue,
                    Index.Invalid, Index.Invalid, "-declarepattern", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-declarenocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

#if CALLBACK_QUEUE
        //
        // NOTE: This is for the [callback dequeue] sub-command.
        //
        public static OptionDictionary GetDequeueOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-objectname", null),
                new Option(null, OptionFlags.MustHaveTypeValue, Index.Invalid,
                    Index.Invalid, "-type", null),
                new Option(null, CreateOptionFlags, Index.Invalid,
                    Index.Invalid, "-create", null),
                new Option(null, NoDisposeOptionFlags, Index.Invalid,
                    Index.Invalid, "-nodispose", null),
                new Option(null, AliasOptionFlags, Index.Invalid,
                    Index.Invalid, "-alias", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasraw", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasall", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasreference", null),
#if NATIVE && TCL
                new Option(null, OptionFlags.MustHaveTclInterpreterValue,
                    Index.Invalid, Index.Invalid, "-tcl", null),
#else
                new Option(null, OptionFlags.MustHaveValue |
                    OptionFlags.Unsupported, Index.Invalid,
                    Index.Invalid, "-tcl", null),
#endif
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noforcedelete", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-tostring", null),
                new Option(typeof(ObjectFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-objectflags",
                    new Variant(DefaultObjectFlags)),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }
#endif

        ///////////////////////////////////////////////////////////////////////

#if XML && SERIALIZATION
        //
        // NOTE: This is for the [xml deserialize] sub-command.
        //
        public static OptionDictionary GetDeserializeOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-objectname", null),
                new Option(null, OptionFlags.MustHaveTypeValue, Index.Invalid,
                    Index.Invalid, "-type", null),
                new Option(null, NoCreateOptionFlags, Index.Invalid,
                    Index.Invalid, "-nocreate", null),
                new Option(null, NoDisposeOptionFlags, Index.Invalid,
                    Index.Invalid, "-nodispose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-tostring", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-stricttype", null),
                new Option(null, VerboseOptionFlags, Index.Invalid,
                    Index.Invalid, "-verbose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nocase", null),
                new Option(null, AliasOptionFlags, Index.Invalid,
                    Index.Invalid, "-alias", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasraw", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasall", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasreference", null),
#if NATIVE && TCL
                new Option(null, OptionFlags.MustHaveTclInterpreterValue,
                    Index.Invalid, Index.Invalid, "-tcl", null),
#else
                new Option(null, OptionFlags.MustHaveValue |
                    OptionFlags.Unsupported, Index.Invalid,
                    Index.Invalid, "-tcl", null),
#endif
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noforcedelete", null),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-encoding", null),
                new Option(typeof(ObjectFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-objectflags",
                    new Variant(DefaultObjectFlags)),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }
#endif

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object dispose] command.
        //
        public static OptionDictionary GetDisposeOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, SynchronousOptionFlags, Index.Invalid,
                    Index.Invalid, "-synchronous", null),
                new Option(null, NoDisposeOptionFlags, Index.Invalid,
                    Index.Invalid, "-nodispose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nocomplain", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

#if PREVIOUS_RESULT
        //
        // NOTE: This is for the [debug exception] command.
        //
        public static OptionDictionary GetExceptionOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-objectname", null),
                new Option(null, OptionFlags.MustHaveTypeValue, Index.Invalid,
                    Index.Invalid, "-type", null),
                new Option(null, NoCreateOptionFlags, Index.Invalid,
                    Index.Invalid, "-nocreate", null),
                new Option(null, NoDisposeOptionFlags, Index.Invalid,
                    Index.Invalid, "-nodispose", null),
                new Option(null, AliasOptionFlags, Index.Invalid,
                    Index.Invalid, "-alias", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasraw", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasall", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasreference", null),
#if NATIVE && TCL
                new Option(null, OptionFlags.MustHaveTclInterpreterValue,
                    Index.Invalid, Index.Invalid, "-tcl", null),
#else
                new Option(null, OptionFlags.MustHaveValue |
                    OptionFlags.Unsupported, Index.Invalid,
                    Index.Invalid, "-tcl", null),
#endif
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noforcedelete", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-tostring", null),
                new Option(typeof(ObjectFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-objectflags",
                    new Variant(DefaultObjectFlags)),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }
#endif

        ///////////////////////////////////////////////////////////////////////

#if DATA
        //
        // NOTE: This is for the [sql execute] sub-command.
        //
        public static OptionDictionary GetExecuteOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-verbatim", null),
                new Option(typeof(DateTimeBehavior),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-datetimebehavior",
                    new Variant(DateTimeBehavior.Default)),
                new Option(typeof(ValueFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-valueflags",
                    new Variant(ValueFlags.AnyNonCharacter)),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-valueformat", null),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-datetimeformat", null),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-transaction", null),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-rowsvar", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-time", null),
                new Option(null, OptionFlags.MustHaveBooleanValue,
                    Index.Invalid, Index.Invalid, "-nested", null),
                new Option(null, OptionFlags.MustHaveBooleanValue,
                    Index.Invalid, Index.Invalid, "-allownull", null),
                new Option(null, OptionFlags.MustHaveBooleanValue,
                    Index.Invalid, Index.Invalid, "-pairs", null),
                new Option(null, OptionFlags.MustHaveBooleanValue,
                    Index.Invalid, Index.Invalid, "-names", null),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-timevar", null),
                new Option(null, OptionFlags.MustHaveIntegerValue,
                    Index.Invalid, Index.Invalid, "-timeout", null),
                new Option(null, OptionFlags.MustHaveIntegerValue,
                    Index.Invalid, Index.Invalid, "-limit", null),
                new Option(typeof(CommandType), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-commandtype", null),
                new Option(typeof(DbResultFormat),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-format", null),
                new Option(typeof(DbExecuteType),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-execute", null),
                new Option(typeof(CommandBehavior),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-behavior",
                    new Variant(CommandBehavior.Default)),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-objectname", null),
                new Option(null, OptionFlags.MustHaveTypeValue, Index.Invalid,
                    Index.Invalid, "-objecttype", null),
                new Option(typeof(ObjectFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-objectflags",
                    new Variant(DefaultObjectFlags)),
                new Option(null, NoCreateOptionFlags, Index.Invalid,
                    Index.Invalid, "-nocreate", null),
                new Option(null, NoDisposeOptionFlags, Index.Invalid,
                    Index.Invalid, "-nodispose", null),
                new Option(null, AliasOptionFlags, Index.Invalid,
                    Index.Invalid, "-alias", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasraw", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasall", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasreference", null),
#if NATIVE && TCL
                new Option(null, OptionFlags.MustHaveTclInterpreterValue,
                    Index.Invalid, Index.Invalid, "-tcl", null),
#else
                new Option(null, OptionFlags.MustHaveValue |
                    OptionFlags.Unsupported, Index.Invalid,
                    Index.Invalid, "-tcl", null),
#endif
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noforcedelete", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-tostring", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }
#endif

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for use with the MarshalOps.FixupReturnValue and/or
        //       Utility.FixupReturnValue methods.
        //
        public static OptionDictionary GetFixupReturnValueOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-objectname", null),
                new Option(null, OptionFlags.MustHaveTypeValue |
                    OptionFlags.Unsafe, Index.Invalid, Index.Invalid,
                    "-returntype", null),
                new Option(null, CreateOptionFlags, Index.Invalid,
                    Index.Invalid, "-create", null),
                new Option(null, NoDisposeOptionFlags | OptionFlags.Unsafe,
                    Index.Invalid, Index.Invalid, "-nodispose", null),
                new Option(null, AliasOptionFlags, Index.Invalid,
                    Index.Invalid, "-alias", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasraw", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasall", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasreference", null),
#if NATIVE && TCL
                new Option(null, OptionFlags.MustHaveTclInterpreterValue |
                    OptionFlags.Unsafe, Index.Invalid, Index.Invalid,
                    "-tcl", null),
#else
                new Option(null, OptionFlags.MustHaveValue |
                    OptionFlags.Unsafe | OptionFlags.Unsupported,
                    Index.Invalid, Index.Invalid, "-tcl", null),
#endif
                new Option(null, OptionFlags.Unsafe, Index.Invalid,
                    Index.Invalid, "-noforcedelete", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-tostring", null),
                new Option(typeof(ObjectFlags), OptionFlags.MustHaveEnumValue |
                    OptionFlags.Unsafe, Index.Invalid, Index.Invalid,
                    "-objectflags", new Variant(DefaultObjectFlags)),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object foreach] sub-command.
        //
        public static OptionDictionary GetForEachOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-objectname", null),
                new Option(null, OptionFlags.MustHaveTypeValue, Index.Invalid,
                    Index.Invalid, "-type", null),
                new Option(null, OptionFlags.MustHaveBooleanValue,
                    Index.Invalid, Index.Invalid, "-collect", null),
                new Option(null, NoCreateOptionFlags, Index.Invalid,
                    Index.Invalid, "-nocreate", null),
                new Option(null, NoDisposeOptionFlags, Index.Invalid,
                    Index.Invalid, "-nodispose", null),
                new Option(null, AliasOptionFlags, Index.Invalid,
                    Index.Invalid, "-alias", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasraw", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasall", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasreference", null),
#if NATIVE && TCL
                new Option(null, OptionFlags.MustHaveTclInterpreterValue,
                    Index.Invalid, Index.Invalid, "-tcl", null),
#else
                new Option(null, OptionFlags.MustHaveValue |
                    OptionFlags.Unsupported, Index.Invalid,
                    Index.Invalid, "-tcl", null),
#endif
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noforcedelete", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-tostring", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nocase", null),
                new Option(typeof(ObjectFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-objectflags",
                    new Variant(DefaultObjectFlags)),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object get] sub-command.
        //
        public static OptionDictionary GetGetOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-objectname", null),
                new Option(null, OptionFlags.MustHaveTypeValue, Index.Invalid,
                    Index.Invalid, "-type", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-stricttype", null),
                new Option(null, VerboseOptionFlags, Index.Invalid,
                    Index.Invalid, "-verbose", null),
                new Option(null, NoCreateOptionFlags, Index.Invalid,
                    Index.Invalid, "-nocreate", null),
                new Option(null, NoDisposeOptionFlags, Index.Invalid,
                    Index.Invalid, "-nodispose", null),
                new Option(null, AliasOptionFlags, Index.Invalid,
                    Index.Invalid, "-alias", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasraw", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasall", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasreference", null),
#if NATIVE && TCL
                new Option(null, OptionFlags.MustHaveTclInterpreterValue,
                    Index.Invalid, Index.Invalid, "-tcl", null),
#else
                new Option(null, OptionFlags.MustHaveValue |
                    OptionFlags.Unsupported, Index.Invalid,
                    Index.Invalid, "-tcl", null),
#endif
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noforcedelete", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-tostring", null),
                new Option(typeof(ObjectFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-objectflags",
                    new Variant(DefaultObjectFlags)),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object import] sub-command.
        //
        public static OptionDictionary GetImportOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-system", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-assembly", null),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-container", null),
                new Option(null, OptionFlags.MustHaveMatchModeValue,
                    Index.Invalid, Index.Invalid, "-importmode",
                    new Variant(DefaultMatchMode)),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-importpattern", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-importnocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object invoke] sub-command.
        //
        public static OptionDictionary GetInvokeOptions()
        {
            //
            // NOTE: The reason this is defined here is because it must be
            //       used anywhere that can create an alias that refers to
            //       this command (i.e. an "object alias").  Currently, this
            //       includes the [library] command, the [debug] command,
            //       and the custom event handling mechanism as well as the
            //       [object] command itself, specifically the "load",
            //       "create", and "invoke" sub-commands.
            //
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-objectname", null),
                new Option(null, OptionFlags.MustHaveTypeValue |
                    OptionFlags.Unsafe, Index.Invalid, Index.Invalid,
                    "-type", null),
                new Option(null, OptionFlags.MustHaveTypeValue |
                    OptionFlags.Unsafe, Index.Invalid, Index.Invalid,
                    "-returntype", null),
                new Option(null, OptionFlags.MustHaveTypeListValue,
                    Index.Invalid, Index.Invalid, "-parametertypes", null),
                new Option(null, TraceOptionFlags | OptionFlags.Unsafe,
                    Index.Invalid, Index.Invalid, "-trace", null),
                new Option(typeof(ByRefArgumentFlags),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-argumentflags",
                    new Variant(DefaultByRefArgumentFlags)),
                new Option(typeof(MarshalFlags),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-marshalflags",
                    new Variant(DefaultMarshalFlags)),
                new Option(null, CreateOptionFlags, Index.Invalid,
                    Index.Invalid, "-create", null),
                new Option(null, NoDisposeOptionFlags | OptionFlags.Unsafe,
                    Index.Invalid, Index.Invalid, "-nodispose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noinvoke", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noargs", null),
                new Option(null, OptionFlags.MustHaveIntegerValue,
                    Index.Invalid, Index.Invalid, "-limit", null),
                new Option(null, OptionFlags.MustHaveIntegerValue,
                    Index.Invalid, Index.Invalid, "-index", null),
                new Option(null, AliasOptionFlags, Index.Invalid,
                    Index.Invalid, "-alias", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasraw", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasall", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasreference", null),
                new Option(null, OptionFlags.Ignored, Index.Invalid,
                    Index.Invalid, "-invoke", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-invokeraw", null),
                new Option(null, OptionFlags.Ignored, Index.Invalid,
                    Index.Invalid, "-keepresults", null),
                new Option(null, OptionFlags.Ignored, Index.Invalid,
                    Index.Invalid, "-nocomplain", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-invokeall", null),
#if NATIVE && TCL
                new Option(null, OptionFlags.MustHaveTclInterpreterValue |
                    OptionFlags.Unsafe, Index.Invalid, Index.Invalid,
                    "-tcl", null),
#else
                new Option(null, OptionFlags.MustHaveValue |
                    OptionFlags.Unsafe | OptionFlags.Unsupported,
                    Index.Invalid, Index.Invalid, "-tcl", null),
#endif
                new Option(null, OptionFlags.Unsafe, Index.Invalid,
                    Index.Invalid, "-noforcedelete", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-tostring", null),
                new Option(null, ArrayAsValueOptionFlags, Index.Invalid,
                    Index.Invalid, "-arrayasvalue", null),
                new Option(null, ArrayAsLinkOptionFlags, Index.Invalid,
                    Index.Invalid, "-arrayaslink", null),
                /* FIXME: Unsafe? */
                new Option(null, VerboseOptionFlags | OptionFlags.Unsafe,
                    Index.Invalid,Index.Invalid, "-verbose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-default", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nonestedobject", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nonestedmember", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-stricttype", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-strictmember", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-strictargs", null),
                new Option(typeof(MemberTypes), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-membertypes",
                    new Variant(DefaultMemberTypes)),
                new Option(typeof(BindingFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-flags",
                    new Variant(DefaultBindingFlags)),
                new Option(typeof(BindingFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-bindingflags",
                    new Variant(DefaultBindingFlags)),
                new Option(typeof(ObjectFlags), OptionFlags.MustHaveEnumValue |
                    OptionFlags.Unsafe, Index.Invalid, Index.Invalid,
                    "-objectflags", new Variant(DefaultObjectFlags)),
                new Option(null, OptionFlags.Unsafe, Index.Invalid,
                    Index.Invalid, "-identity", null),
                new Option(null, OptionFlags.Unsafe, Index.Invalid,
                    Index.Invalid, "-typeidentity", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object invokeall] sub-command.
        //
        public static OptionDictionary GetInvokeAllOptions()
        {
            OptionDictionary options = GetInvokeOptions();

            options["-invoke"].Flags &= ~OptionFlags.Ignored;
            options["-invokeraw"].Flags &= ~OptionFlags.Ignored;
            options["-invokeall"].Flags |= OptionFlags.Ignored;

            options["-keepresults"].Flags &= ~OptionFlags.Ignored;
            options["-nocomplain"].Flags &= ~OptionFlags.Ignored;

            return options;
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object invokeraw] sub-command.
        //
        public static OptionDictionary GetInvokeRawOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-objectname", null),
                new Option(null, OptionFlags.MustHaveTypeValue |
                    OptionFlags.Unsafe, Index.Invalid, Index.Invalid,
                    "-type", null),
                new Option(null, OptionFlags.MustHaveTypeValue |
                    OptionFlags.Unsafe, Index.Invalid, Index.Invalid,
                    "-returntype", null),
                new Option(null, OptionFlags.MustHaveTypeListValue,
                    Index.Invalid, Index.Invalid, "-parametertypes", null),
                new Option(null, TraceOptionFlags | OptionFlags.Unsafe,
                    Index.Invalid, Index.Invalid, "-trace", null),
                new Option(typeof(ByRefArgumentFlags),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-argumentflags",
                    new Variant(DefaultByRefArgumentFlags)),
                new Option(typeof(MarshalFlags),
                    OptionFlags.MustHaveEnumValue, Index.Invalid,
                    Index.Invalid, "-marshalflags",
                    new Variant(DefaultMarshalFlags)),
                new Option(null, CreateOptionFlags, Index.Invalid,
                    Index.Invalid, "-create", null),
                new Option(null, NoDisposeOptionFlags | OptionFlags.Unsafe,
                    Index.Invalid, Index.Invalid, "-nodispose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noinvoke", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noargs", null),
                new Option(null, AliasOptionFlags, Index.Invalid,
                    Index.Invalid, "-alias", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasraw", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasall", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasreference", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-invoke", null),
                new Option(null, OptionFlags.Ignored, Index.Invalid,
                    Index.Invalid, "-invokeraw", null),
                new Option(null, OptionFlags.Ignored, Index.Invalid,
                    Index.Invalid, "-keepresults", null),
                new Option(null, OptionFlags.Ignored, Index.Invalid,
                    Index.Invalid, "-nocomplain", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-invokeall", null),
#if NATIVE && TCL
                new Option(null, OptionFlags.MustHaveTclInterpreterValue |
                    OptionFlags.Unsafe, Index.Invalid, Index.Invalid,
                    "-tcl", null),
#else
                new Option(null, OptionFlags.MustHaveValue |
                    OptionFlags.Unsafe | OptionFlags.Unsupported,
                    Index.Invalid, Index.Invalid, "-tcl", null),
#endif
                new Option(null, OptionFlags.Unsafe, Index.Invalid,
                    Index.Invalid, "-noforcedelete", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-tostring", null),
                new Option(null, ArrayAsValueOptionFlags, Index.Invalid,
                    Index.Invalid, "-arrayasvalue", null),
                new Option(null, ArrayAsLinkOptionFlags, Index.Invalid,
                    Index.Invalid, "-arrayaslink", null),
                /* FIXME: Unsafe? */
                new Option(null, VerboseOptionFlags | OptionFlags.Unsafe,
                    Index.Invalid,Index.Invalid, "-verbose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-default", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nonestedobject", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-stricttype", null),
                new Option(typeof(BindingFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-flags",
                    new Variant(DefaultBindingFlags)),
                new Option(typeof(BindingFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-bindingflags",
                    new Variant(DefaultBindingFlags)),
                new Option(typeof(ObjectFlags), OptionFlags.MustHaveEnumValue |
                    OptionFlags.Unsafe, Index.Invalid, Index.Invalid,
                    "-objectflags", new Variant(DefaultObjectFlags)),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object load] sub-command.
        //
        public static OptionDictionary GetLoadOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.MustHaveRelativeNamespaceValue,
                    Index.Invalid, Index.Invalid, "-namespace", null),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-objectname", null),
                new Option(null, OptionFlags.MustHaveTypeValue, Index.Invalid,
                    Index.Invalid, "-type", null),
                new Option(null, CreateOptionFlags, Index.Invalid,
                    Index.Invalid, "-create", null),
                new Option(null, NoDisposeOptionFlags, Index.Invalid,
                    Index.Invalid, "-nodispose", null),
                new Option(null, AliasOptionFlags, Index.Invalid,
                    Index.Invalid, "-alias", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasraw", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasall", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasreference", null),
#if NATIVE && TCL
                new Option(null, OptionFlags.MustHaveTclInterpreterValue,
                    Index.Invalid, Index.Invalid, "-tcl", null),
#else
                new Option(null, OptionFlags.MustHaveValue |
                    OptionFlags.Unsupported, Index.Invalid,
                    Index.Invalid, "-tcl", null),
#endif
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noforcedelete", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-tostring", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-import", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-importnonpublic", null),
                new Option(null, OptionFlags.MustHaveMatchModeValue,
                    Index.Invalid, Index.Invalid, "-importmode",
                    new Variant(DefaultMatchMode)),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-importpattern", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-importnocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-declare", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-declarenonpublic", null),
                new Option(null, OptionFlags.MustHaveMatchModeValue,
                    Index.Invalid, Index.Invalid, "-declaremode",
                    new Variant(DefaultMatchMode)),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-declarepattern", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-declarenocase", null),
                new Option(typeof(LoadType), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-loadtype",
                    new Variant(DefaultLoadType)),
                new Option(typeof(ObjectFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-objectflags",
                    new Variant(DefaultObjectFlags | ObjectFlags.Assembly)),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object members] sub-command.
        //
        public static OptionDictionary GetMembersOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.MustHaveMatchModeValue,
                    Index.Invalid, Index.Invalid, "-mode",
                    new Variant(DefaultMatchMode)),
                new Option(null, OptionFlags.MustHaveTypeValue, Index.Invalid,
                    Index.Invalid, "-type", null),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-pattern", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-attributes", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-stricttype", null),
                new Option(null, VerboseOptionFlags, Index.Invalid,
                    Index.Invalid, "-verbose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-signatures", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-qualified", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-matchnameonly", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nameonly", null),
                new Option(typeof(MemberTypes), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-membertypes",
                    new Variant(DefaultMemberTypes)),
                new Option(typeof(BindingFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-flags",
                    new Variant(DefaultBindingFlags)),
                new Option(typeof(BindingFlags), OptionFlags.MustHaveEnumValue,
                    Index.Invalid, Index.Invalid, "-bindingflags",
                    new Variant(DefaultBindingFlags)),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object search] sub-command.
        //
        public static OptionDictionary GetSearchOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noshowname", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nonamespace", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noassembly", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-noexception", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-fullname", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-stricttype", null),
                new Option(null, VerboseOptionFlags, Index.Invalid,
                    Index.Invalid, "-verbose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

#if XML && SERIALIZATION
        //
        // NOTE: This is for the [xml serialize] sub-command.
        //
        public static OptionDictionary GetSerializeOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-stricttype", null),
                new Option(null, VerboseOptionFlags, Index.Invalid,
                    Index.Invalid, "-verbose", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-nocase", null),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-encoding", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }
#endif

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object type] and [object untype]
        //       sub-commands.
        //
        public static OptionDictionary GetTypeOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.MustHaveMatchModeValue,
                    Index.Invalid, Index.Invalid, "-typemode",
                    new Variant(DefaultMatchMode)),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-typepattern", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-typenocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object unaliasnamespace] sub-command.
        //
        public static OptionDictionary GetUnaliasNamespaceOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-bycontainer", null),
                new Option(null, OptionFlags.MustHaveMatchModeValue,
                    Index.Invalid, Index.Invalid, "-aliasmode",
                    new Variant(DefaultMatchMode)),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-aliaspattern", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-aliasnocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object undeclare] sub-command.
        //
        public static OptionDictionary GetUndeclareOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-bycontainer", null),
                new Option(null, OptionFlags.MustHaveMatchModeValue,
                    Index.Invalid, Index.Invalid, "-declaremode",
                    new Variant(DefaultMatchMode)),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-declarepattern", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-declarenocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        //
        // NOTE: This is for the [object unimport] sub-command.
        //
        public static OptionDictionary GetUnimportOptions()
        {
            return new OptionDictionary(
                new Option[] {
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-bycontainer", null),
                new Option(null, OptionFlags.MustHaveMatchModeValue,
                    Index.Invalid, Index.Invalid, "-importmode",
                    new Variant(DefaultMatchMode)),
                new Option(null, OptionFlags.MustHaveValue, Index.Invalid,
                    Index.Invalid, "-importpattern", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, "-importnocase", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                    Index.Invalid, Option.EndOfOptions, null)
            });
        }

        ///////////////////////////////////////////////////////////////////////

        public static OptionDictionary GetObjectOptions(
            ObjectOptionType objectOptionType
            )
        {
            switch (objectOptionType)
            {
                case ObjectOptionType.Alias:             // [object alias]
                    return GetAliasOptions();            //
                case ObjectOptionType.Call:              // [library call]
                    return GetCallOptions();             //
                case ObjectOptionType.Certificate:       // [object certificate]
                    return GetCertificateOptions();      //
                case ObjectOptionType.Cleanup:           // [object cleanup]
                    return GetCleanupOptions();          //
                case ObjectOptionType.Create:            // [object create]
                    return GetCreateOptions();           //
                case ObjectOptionType.Declare:           // [object declare]
                    return GetDeclareOptions();          //
#if CALLBACK_QUEUE                                       //
                case ObjectOptionType.Dequeue:           // [callback dequeue]
                    return GetDequeueOptions();          //
#endif                                                   //
#if XML && SERIALIZATION                                 //
                case ObjectOptionType.Deserialize:       // [xml deserialize]
                    return GetDeserializeOptions();      //
#endif                                                   //
                case ObjectOptionType.Dispose:           // [object dispose]
                    return GetDisposeOptions();          //
#if PREVIOUS_RESULT                                      //
                case ObjectOptionType.Exception:         // [debug exception]
                    return GetExceptionOptions();        //
#endif                                                   //
#if DATA                                                 //
                case ObjectOptionType.Execute:           // [sql execute]
                    return GetExecuteOptions();          //
#endif                                                   //
                case ObjectOptionType.FixupReturnValue:  // MarshalOps
                    return GetFixupReturnValueOptions(); //
                case ObjectOptionType.ForEach:           // [object foreach]
                    return GetForEachOptions();          //
                case ObjectOptionType.Get:               // [object get]
                    return GetGetOptions();              //
                case ObjectOptionType.Import:            // [object import]
                    return GetImportOptions();           //
                case ObjectOptionType.Invoke:            // [object invoke]
                    return GetInvokeOptions();           //
                case ObjectOptionType.InvokeAll:         // [object invokeall]
                    return GetInvokeAllOptions();        //
                case ObjectOptionType.InvokeRaw:         // [object invokeraw]
                    return GetInvokeRawOptions();        //
                case ObjectOptionType.Load:              // [object load]
                    return GetLoadOptions();             //
                case ObjectOptionType.Members:           // [object members]
                    return GetMembersOptions();          //
                case ObjectOptionType.Search:            // [object search]
                    return GetSearchOptions();           //
#if XML && SERIALIZATION                                 //
                case ObjectOptionType.Serialize:         // [xml serialize]
                    return GetSerializeOptions();        //
#endif                                                   //
                case ObjectOptionType.Type:              // [object type]
                    return GetTypeOptions();             //
                case ObjectOptionType.UnaliasNamespace:  // [object unaliasnamespace]
                    return GetUnaliasNamespaceOptions(); //
                case ObjectOptionType.Undeclare:         // [object undeclare]
                    return GetUndeclareOptions();        //
                case ObjectOptionType.Unimport:          // [object unimport]
                    return GetUnimportOptions();         //
                case ObjectOptionType.Untype:            // [object untype]
                    return GetTypeOptions();             //
            }

            return null;
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Object Option Processing Methods
        public static void ProcessFindMethodsAndFixupArgumentsOptions(
            Interpreter interpreter,
            OptionDictionary options,
            BindingFlags? defaultBindingFlags,
            MarshalFlags? defaultMarshalFlags,
            ByRefArgumentFlags? defaultByRefArgumentFlags,
            out BindingFlags bindingFlags,
            out MarshalFlags marshalFlags,
            out ByRefArgumentFlags byRefArgumentFlags,
            out int limit,
            out int index,
            out bool strictMember,
            out bool strictArgs,
            out bool invoke,
            out bool noArgs,
            out bool arrayAsValue,
            out bool arrayAsLink,
            out bool trace
            )
        {
            TypeList parameterTypes;
            MemberTypes memberTypes;
            bool strictType;
            bool identity;
            bool typeIdentity;
            bool noNestedObject;
            bool noNestedMember;
            bool noCase;

            ProcessFindMethodsAndFixupArgumentsOptions(
                interpreter, options, null, defaultBindingFlags,
                defaultMarshalFlags, defaultByRefArgumentFlags,
                out parameterTypes, out memberTypes, out bindingFlags,
                out marshalFlags, out byRefArgumentFlags, out limit,
                out index, out strictType, out strictMember, out strictArgs,
                out identity, out typeIdentity, out noNestedObject,
                out noNestedMember, out noCase, out invoke, out noArgs,
                out arrayAsValue, out arrayAsLink, out trace);
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessFindMethodsAndFixupArgumentsOptions(
            Interpreter interpreter,
            OptionDictionary options,
            BindingFlags? defaultBindingFlags,
            MarshalFlags? defaultMarshalFlags,
            ByRefArgumentFlags? defaultByRefArgumentFlags,
            out TypeList parameterTypes,
            out BindingFlags bindingFlags,
            out MarshalFlags marshalFlags,
            out ByRefArgumentFlags byRefArgumentFlags,
            out int limit,
            out int index,
            out bool strictType,
            out bool strictMember,
            out bool strictArgs,
            out bool noCase,
            out bool invoke,
            out bool noArgs,
            out bool arrayAsValue,
            out bool arrayAsLink,
            out bool trace
            )
        {
            MemberTypes memberTypes;
            bool identity;
            bool typeIdentity;
            bool noNestedObject;
            bool noNestedMember;

            ProcessFindMethodsAndFixupArgumentsOptions(
                interpreter, options, null, defaultBindingFlags,
                defaultMarshalFlags, defaultByRefArgumentFlags,
                out parameterTypes, out memberTypes, out bindingFlags,
                out marshalFlags, out byRefArgumentFlags, out limit,
                out index, out strictType, out strictMember, out strictArgs,
                out identity, out typeIdentity, out noNestedObject,
                out noNestedMember, out noCase, out invoke, out noArgs,
                out arrayAsValue, out arrayAsLink, out trace);
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessFindMethodsAndFixupArgumentsOptions(
            Interpreter interpreter,
            OptionDictionary options,
            MemberTypes? defaultMemberTypes,
            BindingFlags? defaultBindingFlags,
            MarshalFlags? defaultMarshalFlags,
            ByRefArgumentFlags? defaultByRefArgumentFlags,
            out TypeList parameterTypes,
            out MemberTypes memberTypes,
            out BindingFlags bindingFlags,
            out MarshalFlags marshalFlags,
            out ByRefArgumentFlags byRefArgumentFlags,
            out int limit,
            out int index,
            out bool strictType,
            out bool strictMember,
            out bool strictArgs,
            out bool identity,
            out bool typeIdentity,
            out bool noNestedObject,
            out bool noNestedMember,
            out bool noCase,
            out bool invoke,
            out bool noArgs,
            out bool arrayAsValue,
            out bool arrayAsLink,
            out bool trace
            )
        {
            bool verbose;

            ProcessFindMethodsAndFixupArgumentsOptions(
                interpreter, options, defaultMemberTypes, defaultBindingFlags,
                defaultMarshalFlags, defaultByRefArgumentFlags,
                out parameterTypes, out memberTypes, out bindingFlags,
                out marshalFlags, out byRefArgumentFlags, out limit, out index,
                out verbose, out strictType, out strictMember, out strictArgs,
                out identity, out typeIdentity, out noNestedObject,
                out noNestedMember, out noCase, out invoke, out noArgs,
                out arrayAsValue, out arrayAsLink, out trace);
        }

        ///////////////////////////////////////////////////////////////////////

        private static void ProcessFindMethodsAndFixupArgumentsOptions(
            Interpreter interpreter,
            OptionDictionary options,
            MemberTypes? defaultMemberTypes,
            BindingFlags? defaultBindingFlags,
            MarshalFlags? defaultMarshalFlags,
            ByRefArgumentFlags? defaultByRefArgumentFlags,
            out TypeList parameterTypes,
            out MemberTypes memberTypes,
            out BindingFlags bindingFlags,
            out MarshalFlags marshalFlags,
            out ByRefArgumentFlags byRefArgumentFlags,
            out int limit,
            out int index,
            out bool verbose,
            out bool strictType,
            out bool strictMember,
            out bool strictArgs,
            out bool identity,
            out bool typeIdentity,
            out bool noNestedObject,
            out bool noNestedMember,
            out bool noCase,
            out bool invoke,
            out bool noArgs,
            out bool arrayAsValue,
            out bool arrayAsLink,
            out bool trace
            )
        {
            Variant value = null;

            ///////////////////////////////////////////////////////////////////

            verbose = false;

            if ((options != null) && options.CheckPresent("-verbose"))
                verbose = true;

            ///////////////////////////////////////////////////////////////////

            strictType = false;

            if ((options != null) && options.CheckPresent("-stricttype"))
                strictType = true;

            ///////////////////////////////////////////////////////////////////

            strictMember = false;

            if ((options != null) && options.CheckPresent("-strictmember"))
                strictMember = true;

            ///////////////////////////////////////////////////////////////////

            strictArgs = false;

            if ((options != null) && options.CheckPresent("-strictargs"))
                strictArgs = true;

            ///////////////////////////////////////////////////////////////////

            identity = false;

            if ((options != null) && options.CheckPresent("-identity"))
                identity = true;

            ///////////////////////////////////////////////////////////////////

            typeIdentity = false;

            if ((options != null) && options.CheckPresent("-typeidentity"))
                typeIdentity = true;

            ///////////////////////////////////////////////////////////////////

            noNestedObject = false;

            if ((options != null) && options.CheckPresent("-nonestedobject"))
                noNestedObject = true;

            ///////////////////////////////////////////////////////////////////

            noNestedMember = false;

            if ((options != null) && options.CheckPresent("-nonestedmember"))
                noNestedMember = true;

            ///////////////////////////////////////////////////////////////////

            //
            // NOTE: Now check for and use the -nocase value.  It is also
            //       important to note here that a specifying the binding
            //       flags does not override this setting.
            //
            noCase = false;

            if ((options != null) && options.CheckPresent("-nocase"))
                noCase = true;

            ///////////////////////////////////////////////////////////////////

            invoke = true;

            if ((options != null) && options.CheckPresent("-noinvoke"))
                invoke = false;

            ///////////////////////////////////////////////////////////////////

            noArgs = false;

            if ((options != null) && options.CheckPresent("-noargs"))
                noArgs = true;

            ///////////////////////////////////////////////////////////////////

            arrayAsValue = false;

            if ((options != null) && options.CheckPresent("-arrayasvalue"))
                arrayAsValue = true;

            ///////////////////////////////////////////////////////////////////

            arrayAsLink = false;

            if ((options != null) && options.CheckPresent("-arrayaslink"))
                arrayAsLink = true;

            ///////////////////////////////////////////////////////////////////

            trace = false;

            if ((options != null) && options.CheckPresent("-trace"))
                trace = true;

            ///////////////////////////////////////////////////////////////////

            ProcessReflectionOptions(
                options, defaultMemberTypes, defaultBindingFlags,
                out memberTypes, out bindingFlags);

            //
            // NOTE: Now check for and use the -nocase value.  It is also
            //       important to note here that a specifying the binding
            //       flags does not override this setting.
            //
            if (noCase)
                bindingFlags |= BindingFlags.IgnoreCase;

            //
            // NOTE: Now check for and use the -identity and -typeidentity
            //       values.  It is also important to note here that a
            //       specifying the binding flags does not override this
            //       setting.
            //
            if (identity || typeIdentity)
            {
                //
                // NOTE: These flags are needed because of the precise
                //       signature of the "MarshalOps.Identity" method.
                //
                bindingFlags |= MarshalOps.PublicStaticMethodBindingFlags;
            }

            ///////////////////////////////////////////////////////////////////

            //
            // NOTE: For "safe" interpreters, prevent the use of "unsafe"
            //       member types and binding flags (e.g. NonPublic, etc).
            //
            if ((interpreter != null) && interpreter.IsSafe())
            {
                memberTypes &= ~MarshalOps.UnsafeObjectMemberTypes;
                bindingFlags &= ~MarshalOps.UnsafeObjectBindingFlags;
            }

            ///////////////////////////////////////////////////////////////////

            marshalFlags = (defaultMarshalFlags != null) ?
                (MarshalFlags)defaultMarshalFlags : DefaultMarshalFlags;

            if (options != null)
            {
                if (options.CheckPresent("-marshalflags", ref value))
                    marshalFlags = (MarshalFlags)value.Value;

                if (options.CheckPresent("-default"))
                    marshalFlags |= MarshalFlags.DefaultValue;
            }

            if (verbose)
                marshalFlags |= MarshalFlags.Verbose;

            if (arrayAsValue)
                marshalFlags |= MarshalFlags.SkipNullSetupValue;

            ///////////////////////////////////////////////////////////////////

            byRefArgumentFlags = (defaultByRefArgumentFlags != null) ?
                (ByRefArgumentFlags)defaultByRefArgumentFlags :
                DefaultByRefArgumentFlags;

            if ((options != null) &&
                options.CheckPresent("-argumentflags", ref value))
            {
                byRefArgumentFlags = (ByRefArgumentFlags)value.Value;
            }

            ///////////////////////////////////////////////////////////////////

            parameterTypes = null;

            if ((options != null) &&
                options.CheckPresent("-parametertypes", ref value))
            {
                parameterTypes = (TypeList)value.Value;
            }

            ///////////////////////////////////////////////////////////////////

            limit = invoke ? 1 : 0;

            if ((options != null) && options.CheckPresent("-limit", ref value))
                limit = (int)value.Value;

            ///////////////////////////////////////////////////////////////////

            index = Index.Invalid;

            if ((options != null) && options.CheckPresent("-index", ref value))
                index = (int)value.Value;
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessFixupReturnValueOptions(
            OptionDictionary options,
            ObjectFlags? defaultObjectFlags,
            out ObjectFlags objectFlags,
            out string objectName,
            out string interpName,
            out bool alias,
            out bool aliasRaw,
            out bool aliasAll,
            out bool aliasReference
            )
        {
            Type returnType;
            bool create;
            bool dispose;
            bool toString;

            ProcessFixupReturnValueOptions(
                options, defaultObjectFlags, out returnType, out objectFlags,
                out objectName, out interpName, out create, out dispose,
                out alias, out aliasRaw, out aliasAll, out aliasReference,
                out toString);
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessFixupReturnValueOptions(
            OptionDictionary options,
            ObjectFlags? defaultObjectFlags,
            out Type returnType,
            out ObjectFlags objectFlags,
            out string objectName,
            out string interpName,
            out bool create,
            out bool dispose,
            out bool alias,
            out bool aliasRaw,
            out bool aliasAll,
            out bool aliasReference,
            out bool toString
            )
        {
            Variant value = null;

            ///////////////////////////////////////////////////////////////////

            returnType = null;

            if (options != null)
            {
                if (options.Has("-objecttype"))
                {
                    //
                    // NOTE: For example, [sql execute]...
                    //
                    if (options.CheckPresent("-objecttype", ref value))
                        returnType = (Type)value.Value;
                }
                else if (options.Has("-returntype"))
                {
                    //
                    // NOTE: For example, [object invoke]...
                    //
                    if (options.CheckPresent("-returntype", ref value))
                        returnType = (Type)value.Value;
                }
                else
                {
                    //
                    // NOTE: For example, [callback dequeue],
                    //       InvokeDelegate()...
                    //
                    if (options.CheckPresent("-type", ref value))
                        returnType = (Type)value.Value;
                }
            }

            ///////////////////////////////////////////////////////////////////

            objectFlags = (defaultObjectFlags != null) ?
                (ObjectFlags)defaultObjectFlags : DefaultObjectFlags;

            if (options != null)
            {
                if (options.CheckPresent("-objectflags", ref value))
                    objectFlags = (ObjectFlags)value.Value;

                if (options.CheckPresent("-noforcedelete"))
                    objectFlags &= ~ObjectFlags.ForceDelete;
            }

            ///////////////////////////////////////////////////////////////////

            objectName = null;

            if ((options != null) &&
                options.CheckPresent("-objectname", ref value))
            {
                objectName = value.ToString();
            }

            ///////////////////////////////////////////////////////////////////

            interpName = null;

#if NATIVE && TCL
            if ((options != null) && options.CheckPresent("-tcl", ref value))
                interpName = value.ToString();
#endif

            ///////////////////////////////////////////////////////////////////

            if (options != null)
            {
                if (options.Has("-nocreate"))
                {
                    create = DefaultNoCreate;

                    if (options.CheckPresent("-nocreate"))
                        create = false;
                }
                else
                {
                    create = DefaultCreate;

                    if (options.CheckPresent("-create"))
                        create = true;
                }
            }
            else
            {
                create = DefaultCreate;
            }

            ///////////////////////////////////////////////////////////////////

            dispose = true;

            if ((options != null) && options.CheckPresent("-nodispose"))
                dispose = false;

            ///////////////////////////////////////////////////////////////////

            alias = false;

            if ((options != null) && options.CheckPresent("-alias"))
                alias = true;

            ///////////////////////////////////////////////////////////////////

            aliasRaw = false;

            if ((options != null) && options.CheckPresent("-aliasraw"))
                aliasRaw = true;

            ///////////////////////////////////////////////////////////////////

            aliasAll = false;

            if ((options != null) && options.CheckPresent("-aliasall"))
                aliasAll = true;

            ///////////////////////////////////////////////////////////////////

            aliasReference = false;

            if ((options != null) && options.CheckPresent("-aliasreference"))
                aliasReference = true;

            ///////////////////////////////////////////////////////////////////

            toString = false;

            if ((options != null) && options.CheckPresent("-tostring"))
                toString = true;
        }

        ///////////////////////////////////////////////////////////////////////

        private static void ProcessGetTypeOptions(
            OptionDictionary options,
            out bool verbose,
            out bool strictType
            )
        {
            bool noCase;

            ProcessGetTypeOptions(
                options, out verbose, out strictType, out noCase);
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessGetTypeOptions(
            OptionDictionary options,
            out bool verbose,
            out bool strictType,
            out bool noCase
            )
        {
            verbose = false;

            if ((options != null) && options.CheckPresent("-verbose"))
                verbose = true;

            ///////////////////////////////////////////////////////////////////

            strictType = false;

            if ((options != null) && options.CheckPresent("-stricttype"))
                strictType = true;

            ///////////////////////////////////////////////////////////////////

            noCase = false;

            if ((options != null) && options.CheckPresent("-nocase"))
                noCase = true;
        }

        ///////////////////////////////////////////////////////////////////////

        private static void ProcessMarshalOptions(
            OptionDictionary options,
            MemberTypes? defaultMemberTypes,
            BindingFlags? defaultBindingFlags,
            MarshalFlags? defaultMarshalFlags,
            ByRefArgumentFlags? defaultByRefArgumentFlags,
            out Type type,
            out TypeList parameterTypes,
            out MemberTypes memberTypes,
            out BindingFlags bindingFlags,
            out MarshalFlags marshalFlags,
            out ByRefArgumentFlags byRefArgumentFlags,
            out bool verbose,
            out bool strictType,
            out bool strictArgs,
            out bool noNestedObject,
            out bool noCase,
            out bool invoke,
            out bool noArgs,
            out bool arrayAsValue,
            out bool arrayAsLink,
            out bool trace
            )
        {
            Variant value = null;

            ///////////////////////////////////////////////////////////////////

            verbose = false;

            if ((options != null) && options.CheckPresent("-verbose"))
                verbose = true;

            ///////////////////////////////////////////////////////////////////

            strictType = false;

            if ((options != null) && options.CheckPresent("-stricttype"))
                strictType = true;

            ///////////////////////////////////////////////////////////////////

            strictArgs = false;

            if ((options != null) && options.CheckPresent("-strictargs"))
                strictArgs = true;

            ///////////////////////////////////////////////////////////////////

            noNestedObject = false;

            if ((options != null) && options.CheckPresent("-nonestedobject"))
                noNestedObject = true;

            ///////////////////////////////////////////////////////////////////

            noCase = false;

            if ((options != null) && options.CheckPresent("-nocase"))
                noCase = true;

            ///////////////////////////////////////////////////////////////////

            invoke = true;

            if ((options != null) && options.CheckPresent("-noinvoke"))
                invoke = false;

            ///////////////////////////////////////////////////////////////////

            noArgs = false;

            if ((options != null) && options.CheckPresent("-noargs"))
                noArgs = true;

            ///////////////////////////////////////////////////////////////////

            arrayAsValue = false;

            if ((options != null) && options.CheckPresent("-arrayasvalue"))
                arrayAsValue = true;

            ///////////////////////////////////////////////////////////////////

            arrayAsLink = false;

            if ((options != null) && options.CheckPresent("-arrayaslink"))
                arrayAsLink = true;

            ///////////////////////////////////////////////////////////////////

            trace = false;

            if ((options != null) && options.CheckPresent("-trace"))
                trace = true;

            ///////////////////////////////////////////////////////////////////

            ProcessReflectionOptions(
                options, defaultMemberTypes, defaultBindingFlags,
                out memberTypes, out bindingFlags);

            //
            // NOTE: Now check for and use the -nocase value.  It is also
            //       important to note here that a specifying the binding
            //       flags does not override this setting.
            //
            if (noCase)
                bindingFlags |= BindingFlags.IgnoreCase;

            ///////////////////////////////////////////////////////////////////

            byRefArgumentFlags = (defaultByRefArgumentFlags != null) ?
                (ByRefArgumentFlags)defaultByRefArgumentFlags :
                DefaultByRefArgumentFlags;

            if ((options != null) &&
                options.CheckPresent("-argumentflags", ref value))
            {
                byRefArgumentFlags = (ByRefArgumentFlags)value.Value;
            }

            ///////////////////////////////////////////////////////////////////

            marshalFlags = (defaultMarshalFlags != null) ?
                (MarshalFlags)defaultMarshalFlags : DefaultMarshalFlags;

            if (options != null)
            {
                if (options.CheckPresent("-marshalflags", ref value))
                    marshalFlags = (MarshalFlags)value.Value;

                if (options.CheckPresent("-default"))
                    marshalFlags |= MarshalFlags.DefaultValue;
            }

            if (verbose)
                marshalFlags |= MarshalFlags.Verbose;

            if (arrayAsValue)
                marshalFlags |= MarshalFlags.SkipNullSetupValue;

            ///////////////////////////////////////////////////////////////////

            type = null;

            if ((options != null) && options.CheckPresent("-type", ref value))
                type = (Type)value.Value;

            ///////////////////////////////////////////////////////////////////

            parameterTypes = null;

            if ((options != null) &&
                options.CheckPresent("-parametertypes", ref value))
            {
                parameterTypes = (TypeList)value.Value;
            }
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessObjectAliasOptions(
            OptionDictionary options,
            out bool verbose,
            out bool strictType,
            out bool noCase,
            out bool aliasRaw,
            out bool aliasAll,
            out bool aliasReference
            )
        {
            ProcessGetTypeOptions(
                options, out verbose, out strictType, out noCase);

            ///////////////////////////////////////////////////////////////////

            aliasRaw = false;

            if ((options != null) && options.CheckPresent("-aliasraw"))
                aliasRaw = true;

            ///////////////////////////////////////////////////////////////////

            aliasAll = false;

            if ((options != null) && options.CheckPresent("-aliasall"))
                aliasAll = true;

            ///////////////////////////////////////////////////////////////////

            aliasReference = false;

            if ((options != null) && options.CheckPresent("-aliasreference"))
                aliasReference = true;
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessObjectCertificateOptions(
            OptionDictionary options,
            X509VerificationFlags? defaultX509VerificationFlags,
            X509RevocationMode? defaultX509RevocationMode,
            X509RevocationFlag? defaultX509RevocationFlag,
            out X509VerificationFlags x509VerificationFlags,
            out X509RevocationMode x509RevocationMode,
            out X509RevocationFlag x509RevocationFlag,
            out bool chain
            )
        {
            Variant value = null;

            ///////////////////////////////////////////////////////////////////

            x509VerificationFlags = (defaultX509VerificationFlags != null) ?
                (X509VerificationFlags)defaultX509VerificationFlags :
                CertificateOps.DefaultVerificationFlags;

            if ((options != null) &&
                options.CheckPresent("-verificationflags", ref value))
            {
                x509VerificationFlags = (X509VerificationFlags)value.Value;
            }

            ///////////////////////////////////////////////////////////////////

            x509RevocationMode = (defaultX509RevocationMode != null) ?
                (X509RevocationMode)defaultX509RevocationMode :
                CertificateOps.DefaultRevocationMode;

            if ((options != null) &&
                options.CheckPresent("-revocationmode", ref value))
            {
                x509RevocationMode = (X509RevocationMode)value.Value;
            }

            ///////////////////////////////////////////////////////////////////

            x509RevocationFlag = (defaultX509RevocationFlag != null) ?
                (X509RevocationFlag)defaultX509RevocationFlag :
                CertificateOps.DefaultRevocationFlag;

            if ((options != null) &&
                options.CheckPresent("-revocationflag", ref value))
            {
                x509RevocationFlag = (X509RevocationFlag)value.Value;
            }

            ///////////////////////////////////////////////////////////////////

            chain = false;

            if ((options != null) && options.CheckPresent("-chain"))
                chain = true;
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessObjectDeclareOptions(
            OptionDictionary options,
            MatchMode? defaultMatchMode,
            out MatchMode matchMode,
            out string pattern,
            out bool verbose,
            out bool strictType,
            out bool nonPublic,
            out bool noCase
            )
        {
            ProcessGetTypeOptions(options, out verbose, out strictType);

            ///////////////////////////////////////////////////////////////////

            ProcessPatternMatchingOptions(
                options, "-declaremode", "-declarepattern", "-declarenocase",
                defaultMatchMode, out matchMode, out pattern, out noCase);

            ///////////////////////////////////////////////////////////////////

            nonPublic = false;

            if ((options != null) && options.CheckPresent("-declarenonpublic"))
                nonPublic = true;
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessObjectImportOptions(
            OptionDictionary options,
            MatchMode? defaultMatchMode,
            out MatchMode matchMode,
            out string container,
            out string pattern,
            out bool assembly,
            out bool system,
            out bool noCase
            )
        {
            bool nonPublic;

            ProcessObjectImportOptions(
                options, defaultMatchMode, out matchMode, out container,
                out pattern, out assembly, out system, out nonPublic,
                out noCase);
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessObjectImportOptions(
            OptionDictionary options,
            MatchMode? defaultMatchMode,
            out MatchMode matchMode,
            out string container,
            out string pattern,
            out bool assembly,
            out bool system,
            out bool nonPublic,
            out bool noCase
            )
        {
            Variant value = null;

            ///////////////////////////////////////////////////////////////////

            ProcessPatternMatchingOptions(
                options, "-importmode", "-importpattern", "-importnocase",
                defaultMatchMode, out matchMode, out pattern, out noCase);

            ///////////////////////////////////////////////////////////////////

            container = null;

            if ((options != null) &&
                options.CheckPresent("-container", ref value))
            {
                container = value.ToString();
            }

            ///////////////////////////////////////////////////////////////////

            nonPublic = false;

            if ((options != null) && options.CheckPresent("-importnonpublic"))
                nonPublic = true;

            ///////////////////////////////////////////////////////////////////

            assembly = false;

            if ((options != null) && options.CheckPresent("-assembly"))
                assembly = true;

            ///////////////////////////////////////////////////////////////////

            system = false;

            if ((options != null) && options.CheckPresent("-system"))
                system = true;
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessObjectInvokeRawOptions(
            OptionDictionary options,
            BindingFlags? defaultBindingFlags,
            MarshalFlags? defaultMarshalFlags,
            ByRefArgumentFlags? defaultByRefArgumentFlags,
            out Type type,
            out TypeList parameterTypes,
            out BindingFlags bindingFlags,
            out MarshalFlags marshalFlags,
            out ByRefArgumentFlags byRefArgumentFlags,
            out bool strictType,
            out bool strictArgs,
            out bool noNestedObject,
            out bool noCase,
            out bool invoke,
            out bool noArgs,
            out bool arrayAsValue,
            out bool arrayAsLink,
            out bool trace
            )
        {
            MemberTypes memberTypes;
            bool verbose;

            ProcessMarshalOptions(
                options, null, defaultBindingFlags, defaultMarshalFlags,
                defaultByRefArgumentFlags, out type, out parameterTypes,
                out memberTypes, out bindingFlags, out marshalFlags,
                out byRefArgumentFlags, out verbose, out strictType,
                out strictArgs, out noNestedObject, out noCase, out invoke,
                out noArgs, out arrayAsValue, out arrayAsLink, out trace);
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessObjectLoadOptions(
            OptionDictionary options,
            LoadType? defaultLoadType,
            MatchMode? defaultMatchMode,
            out INamespace @namespace,
            out LoadType loadType,
            out MatchMode declareMatchMode,
            out MatchMode importMatchMode,
            out string declarePattern,
            out string importPattern,
            out bool declare,
            out bool import,
            out bool declareNonPublic,
            out bool declareNoCase,
            out bool importNonPublic,
            out bool importNoCase
            )
        {
            Variant value = null;

            ///////////////////////////////////////////////////////////////////

            ProcessPatternMatchingOptions(
                options, "-declaremode", "-declarepattern", "-declarenocase",
                defaultMatchMode, out declareMatchMode, out declarePattern,
                out declareNoCase);

            ///////////////////////////////////////////////////////////////////

            ProcessPatternMatchingOptions(
                options, "-importmode", "-importpattern", "-importnocase",
                defaultMatchMode, out importMatchMode, out importPattern,
                out importNoCase);

            ///////////////////////////////////////////////////////////////////

            @namespace = null;

            if ((options != null) &&
                options.CheckPresent("-namespace", ref value))
            {
                @namespace = (INamespace)value.Value;
            }

            ///////////////////////////////////////////////////////////////////

            loadType = (defaultLoadType != null) ?
                (LoadType)defaultLoadType : DefaultLoadType;

            if ((options != null) &&
                options.CheckPresent("-loadtype", ref value))
            {
                loadType = (LoadType)value.Value;
            }

            ///////////////////////////////////////////////////////////////////

            declare = false;

            if ((options != null) && options.CheckPresent("-declare"))
                declare = true;

            ///////////////////////////////////////////////////////////////////

            import = false;

            if ((options != null) && options.CheckPresent("-import"))
                import = true;

            ///////////////////////////////////////////////////////////////////

            declareNonPublic = false;

            if ((options != null) && options.CheckPresent("-declarenonpublic"))
                declareNonPublic = true;

            ///////////////////////////////////////////////////////////////////

            importNonPublic = false;

            if ((options != null) && options.CheckPresent("-importnonpublic"))
                importNonPublic = true;
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessObjectMembersOptions(
            OptionDictionary options,
            MemberTypes? defaultMemberTypes,
            BindingFlags? defaultBindingFlags,
            MatchMode? defaultMatchMode,
            out MemberTypes memberTypes,
            out BindingFlags bindingFlags,
            out MatchMode matchMode,
            out string pattern,
            out bool verbose,
            out bool strictType,
            out bool noCase,
            out bool attributes,
            out bool matchNameOnly,
            out bool nameOnly,
            out bool signatures,
            out bool qualified
            )
        {
            ProcessGetTypeOptions(
                options, out verbose, out strictType, out noCase);

            ///////////////////////////////////////////////////////////////////

            ProcessReflectionOptions(
                options, defaultMemberTypes, defaultBindingFlags,
                out memberTypes, out bindingFlags);

            ///////////////////////////////////////////////////////////////////

            ProcessPatternMatchingOptions(
                options, "-mode", "-pattern", defaultMatchMode,
                out matchMode, out pattern);

            ///////////////////////////////////////////////////////////////////

            attributes = false;

            if ((options != null) && options.CheckPresent("-attributes"))
                attributes = true;

            ///////////////////////////////////////////////////////////////////

            matchNameOnly = false;

            if ((options != null) && options.CheckPresent("-matchnameonly"))
                matchNameOnly = true;

            ///////////////////////////////////////////////////////////////////

            nameOnly = false;

            if ((options != null) && options.CheckPresent("-nameonly"))
                nameOnly = true;

            ///////////////////////////////////////////////////////////////////

            signatures = false;

            if ((options != null) && options.CheckPresent("-signatures"))
                signatures = true;

            ///////////////////////////////////////////////////////////////////

            qualified = false;

            if ((options != null) && options.CheckPresent("-qualified"))
                qualified = true;
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessObjectTypeOptions(
            OptionDictionary options,
            MatchMode? defaultMatchMode,
            out MatchMode matchMode,
            out string pattern,
            out bool noCase
            )
        {
            ProcessPatternMatchingOptions(
                options, "-typemode", "-typepattern", "-typenocase",
                defaultMatchMode, out matchMode, out pattern, out noCase);
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessObjectUnaliasNamespaceOptions(
            OptionDictionary options,
            MatchMode? defaultMatchMode,
            out MatchMode matchMode,
            out string pattern,
            out bool noCase,
            out bool values
            )
        {
            ProcessPatternMatchingOptions(
                options, "-aliasmode", "-aliaspattern", "-aliasnocase",
                defaultMatchMode, out matchMode, out pattern, out noCase);

            ///////////////////////////////////////////////////////////////////

            values = false;

            if ((options != null) && options.CheckPresent("-bycontainer"))
                values = true;
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessObjectUndeclareOptions(
            OptionDictionary options,
            MatchMode? defaultMatchMode,
            out MatchMode matchMode,
            out string pattern,
            out bool noCase,
            out bool values
            )
        {
            ProcessPatternMatchingOptions(
                options, "-declaremode", "-declarepattern", "-declarenocase",
                defaultMatchMode, out matchMode, out pattern, out noCase);

            ///////////////////////////////////////////////////////////////////

            values = false;

            if ((options != null) && options.CheckPresent("-bycontainer"))
                values = true;
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessObjectUnimportOptions(
            OptionDictionary options,
            MatchMode? defaultMatchMode,
            out MatchMode matchMode,
            out string pattern,
            out bool noCase,
            out bool values
            )
        {
            ProcessPatternMatchingOptions(
                options, "-importmode", "-importpattern", "-importnocase",
                defaultMatchMode, out matchMode, out pattern, out noCase);

            ///////////////////////////////////////////////////////////////////

            values = false;

            if ((options != null) && options.CheckPresent("-bycontainer"))
                values = true;
        }

        ///////////////////////////////////////////////////////////////////////

        public static void ProcessObjectUntypeOptions(
            OptionDictionary options,
            MatchMode? defaultMatchMode,
            out MatchMode matchMode,
            out string pattern,
            out bool noCase
            )
        {
            ProcessPatternMatchingOptions(
                options, "-typemode", "-typepattern", "-typenocase",
                defaultMatchMode, out matchMode, out pattern, out noCase);
        }

        ///////////////////////////////////////////////////////////////////////

        private static void ProcessPatternMatchingOptions(
            OptionDictionary options,
            string matchModeOptionName,
            string patternOptionName,
            MatchMode? defaultMatchMode,
            out MatchMode matchMode,
            out string pattern
            )
        {
            bool noCase;

            ProcessPatternMatchingOptions(
                options, matchModeOptionName, patternOptionName, null,
                defaultMatchMode, out matchMode, out pattern, out noCase);
        }

        ///////////////////////////////////////////////////////////////////////

        private static void ProcessPatternMatchingOptions(
            OptionDictionary options,
            string matchModeOptionName,
            string patternOptionName,
            string noCaseOptionName,
            MatchMode? defaultMatchMode,
            out MatchMode matchMode,
            out string pattern,
            out bool noCase
            )
        {
            Variant value = null;

            ///////////////////////////////////////////////////////////////////

            matchMode = (defaultMatchMode != null) ?
                (MatchMode)defaultMatchMode : DefaultMatchMode;

            if ((options != null) &&
                (matchModeOptionName != null) &&
                options.CheckPresent(matchModeOptionName, ref value))
            {
                matchMode = (MatchMode)value.Value;
            }

            ///////////////////////////////////////////////////////////////////

            pattern = null;

            if ((options != null) &&
                (patternOptionName != null) &&
                options.CheckPresent(patternOptionName, ref value))
            {
                pattern = value.ToString();
            }

            ///////////////////////////////////////////////////////////////////

            noCase = false;

            if ((options != null) &&
                (noCaseOptionName != null) &&
                options.CheckPresent(noCaseOptionName))
            {
                noCase = true;
            }
        }

        ///////////////////////////////////////////////////////////////////////

        private static void ProcessReflectionOptions(
            OptionDictionary options,
            MemberTypes? defaultMemberTypes,
            BindingFlags? defaultBindingFlags,
            out MemberTypes memberTypes,
            out BindingFlags bindingFlags
            )
        {
            Variant value = null;

            ///////////////////////////////////////////////////////////////////

            memberTypes = (defaultMemberTypes != null) ?
                (MemberTypes)defaultMemberTypes : DefaultMemberTypes;

            if ((options != null) &&
                options.CheckPresent("-membertypes", ref value))
            {
                memberTypes = (MemberTypes)value.Value;
            }

            ///////////////////////////////////////////////////////////////////

            bindingFlags = (defaultBindingFlags != null) ?
                (BindingFlags)defaultBindingFlags : DefaultBindingFlags;

            //
            // TODO: Is this a really bad option name?
            //
            bool hadFlags = (options != null) &&
                options.CheckPresent("-flags", ref value);

            if (hadFlags)
                bindingFlags = (BindingFlags)value.Value;

            if ((options != null) &&
                options.CheckPresent("-bindingflags", ref value))
            {
                if (hadFlags)
                    bindingFlags |= (BindingFlags)value.Value;
                else
                    bindingFlags = (BindingFlags)value.Value;
            }
        }
        #endregion
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Object Invocation Support Methods
        public static ReturnCode InvokeDelegate(
            Interpreter interpreter,
            Delegate @delegate,
            ArgumentList arguments,
            ref Result result
            )
        {
            ///////////////////////////////////////////////////////////////////
            //                       ARGUMENT VALIDATION
            ///////////////////////////////////////////////////////////////////

            if (interpreter == null)
            {
                result = "invalid interpreter";
                return ReturnCode.Error;
            }

            if (@delegate == null)
            {
                result = "invalid delegate";
                return ReturnCode.Error;
            }

            if (arguments == null)
            {
                result = "invalid arguments";
                return ReturnCode.Error;
            }

            ///////////////////////////////////////////////////////////////////
            //                        OPTION PROCESSING
            ///////////////////////////////////////////////////////////////////

            ReturnCode code = ReturnCode.Ok;
            OptionDictionary options = GetCallOptions();
            int argumentIndex = Index.Invalid;

            if (arguments.Count > 1)
            {
                code = interpreter.GetOptions(
                    options, arguments, 0, 1, Index.Invalid, true,
                    ref argumentIndex, ref result);

                if (code != ReturnCode.Ok)
                    return code;
            }

            ///////////////////////////////////////////////////////////////////

            BindingFlags bindingFlags;
            MarshalFlags marshalFlags;
            ByRefArgumentFlags byRefArgumentFlags;
            int limit;
            int index;
            bool strictMember;
            bool strictArgs;
            bool invoke;
            bool noArgs;
            bool arrayAsValue;
            bool arrayAsLink;
            bool trace;

            ProcessFindMethodsAndFixupArgumentsOptions(
                interpreter, options, null, null, null, out bindingFlags,
                out marshalFlags, out byRefArgumentFlags, out limit,
                out index, out strictMember, out strictArgs, out invoke,
                out noArgs, out arrayAsValue, out arrayAsLink, out trace);

            ///////////////////////////////////////////////////////////////////

            Type returnType;
            ObjectFlags objectFlags;
            string objectName;
            string interpName;
            bool create;
            bool dispose;
            bool alias;
            bool aliasRaw;
            bool aliasAll;
            bool aliasReference;
            bool toString;

            ProcessFixupReturnValueOptions(
                options, null, out returnType, out objectFlags,
                out objectName, out interpName, out create, out dispose,
                out alias, out aliasRaw, out aliasAll, out aliasReference,
                out toString);

            ///////////////////////////////////////////////////////////////////
            //                    METHOD ARGUMENT BUILDING
            ///////////////////////////////////////////////////////////////////

            object[] args = null;
            int argumentCount = 0;

            if ((argumentIndex != Index.Invalid) &&
                (argumentIndex < arguments.Count))
            {
                //
                // NOTE: How many arguments were supplied?
                //
                argumentCount = (arguments.Count - argumentIndex);

                //
                // NOTE: Create and populate the array of arguments for the
                //       invocation.
                //
                args = new object[argumentCount];

                for (int index2 = argumentIndex; index2 < arguments.Count;
                        index2++)
                {
                    /* need String, not Argument */
                    args[index2 - argumentIndex] = arguments[index2].String;
                }
            }
            else if (invoke || !noArgs)
            {
                //
                // FIXME: When no arguments are specified, we actually need an
                //        array of zero arguments for the parameter to argument
                //        matching code to work correctly.
                //
                args = new object[0];
            }

            //
            // HACK: We want to use the existing marshalling code; therefore,
            //       we pre-bake some of the required arguments here (i.e. we
            //       KNOW what method we are going to call, however we want
            //       magical bi-directional type coercion, etc).
            //
            object delegateTarget = @delegate.Target;
            MethodInfo delegateMethodInfo = @delegate.Method;

            if (delegateMethodInfo == null)
            {
                result = "cannot invoke delegate, no method";
                return ReturnCode.Error;
            }

            string newObjectName = (delegateTarget != null) ?
                delegateTarget.GetType().FullName : null;

            string newMemberName = delegateMethodInfo.Name;
            MethodInfo[] methodInfo = new MethodInfo[] { delegateMethodInfo };

            if (methodInfo == null) // NOTE: Redundant [for now].
            {
                result = String.Format(
                    "delegate \"{0}\" has no methods matching \"{1}\"",
                    newObjectName, bindingFlags);

                return ReturnCode.Error;
            }

            ///////////////////////////////////////////////////////////////////
            //                    METHOD ARGUMENT CONVERSION
            ///////////////////////////////////////////////////////////////////

            IntList methodIndexList = null;
            ObjectArrayList argsList = null;
            ArgumentInfoList argumentInfoList = null;
            ResultList errors = null;

            //
            // NOTE: Attempt to convert the argument strings to something
            //       potentially more meaningful and find the corresponding
            //       method.
            //
            code = MarshalOps.FindMethodsAndFixupArguments(
                interpreter, interpreter.Binder, interpreter.CultureInfo,
                @delegate.GetType(), newObjectName, newObjectName,
                newMemberName, newMemberName, MemberTypes.Method,
                bindingFlags, methodInfo, null, args, limit, marshalFlags,
                ref methodIndexList, ref argsList, ref argumentInfoList,
                ref errors);

            if (code != ReturnCode.Ok)
            {
                result = errors;
                return code;
            }

            ///////////////////////////////////////////////////////////////////
            //                   METHOD OVERLOAD VALIDATION
            ///////////////////////////////////////////////////////////////////

            if ((methodIndexList == null) || (methodIndexList.Count == 0) ||
                (argsList == null) || (argsList.Count == 0))
            {
                result = String.Format(
                    "method \"{0}\" of delegate \"{1}\" not found",
                    newMemberName, newObjectName);

                return ReturnCode.Error;
            }

            if ((index != Index.Invalid) &&
                ((index < 0) || (index >= methodIndexList.Count) ||
                (index >= argsList.Count)))
            {
                result = String.Format(
                    "method \"{0}\" of delegate \"{1}\" not found, " +
                    "invalid method index {2}, must be {3}",
                    newMemberName, newObjectName, index,
                    FormatOps.BetweenOrExact(0, methodIndexList.Count - 1));

                return ReturnCode.Error;
            }

            //
            // NOTE: Figure out which type of options are needed for created
            //       aliases.
            //
            ObjectOptionType objectOptionType = ObjectOptionType.Delegate |
                ObjectOps.GetOptionType(aliasRaw, aliasAll);

            //
            // NOTE: Are we actually going to invoke the method or are we simply
            //       returning the list of matching method overloads?  For this
            //       method, the list of method overloads should always have
            //       exactly one result (i.e. it is somewhat redundant; however,
            //       it is designed to match the semantics of [object invoke]).
            //
            if (invoke)
            {
                ///////////////////////////////////////////////////////////////
                //                  METHOD OVERLOAD SELECTION
                ///////////////////////////////////////////////////////////////

                if (strictMember && (methodIndexList.Count != 1))
                {
                    result = String.Format(
                        "matched {0} method overloads of \"{1}\" on delegate " +
                        "\"{2}\", need exactly 1", methodIndexList.Count,
                        newMemberName, newObjectName);

                    return ReturnCode.Error;
                }

                //
                // FIXME: Select the first method that matches.  More
                //        sophisticated logic may need to be added here later.
                //
                int methodIndex = (index != Index.Invalid) ?
                    methodIndexList[index] : methodIndexList[0];

                if (methodIndex == Index.Invalid)
                {
                    result = String.Format(
                        "method \"{0}\" of delegate \"{1}\" not found",
                        newMemberName, newObjectName);

                    return ReturnCode.Error;
                }

                ///////////////////////////////////////////////////////////////
                //               METHOD ARGUMENT ARRAY SELECTION
                ///////////////////////////////////////////////////////////////

                //
                // NOTE: Get the arguments we are going to use to perform
                //       the actual method call.
                //
                args = (index != Index.Invalid) ? argsList[index] : argsList[0];

                ///////////////////////////////////////////////////////////////
                //                       METHOD TRACING
                ///////////////////////////////////////////////////////////////

                if (trace)
                    TraceOps.DebugTrace(String.Format(
                        "{0}: InvokeDelegate: " +
                        "methodIndex = {1}, delegate = {2}, args = {3}{4}",
                        GlobalState.GetCurrentThreadId(), methodIndex,
                        FormatOps.WrapOrNull(@delegate),
                        FormatOps.WrapOrNull(new StringList(args)),
                        Environment.NewLine), typeof(ObjectOps).Name);

                ///////////////////////////////////////////////////////////////
                //                      METHOD INVOCATION
                ///////////////////////////////////////////////////////////////

                object returnValue = null;

                code = Engine.ExecuteDelegate(
                    @delegate, args, ref returnValue, ref result);

                ///////////////////////////////////////////////////////////////
                //                   BYREF ARGUMENT HANDLING
                ///////////////////////////////////////////////////////////////

                if ((code == ReturnCode.Ok) && (argumentInfoList != null))
                {
                    code = MarshalOps.FixupByRefArguments(
                        interpreter, interpreter.Binder,
                        interpreter.CultureInfo, argumentInfoList, objectFlags,
                        GetInvokeOptions(objectOptionType), objectOptionType,
                        interpName, args, byRefArgumentFlags, strictArgs,
                        create, dispose, alias, aliasReference, toString,
                        arrayAsValue, arrayAsLink, ref result);
                }

                ///////////////////////////////////////////////////////////////
                //                    RETURN VALUE HANDLING
                ///////////////////////////////////////////////////////////////

                if (code == ReturnCode.Ok)
                {
                    code = MarshalOps.FixupReturnValue(
                        interpreter, interpreter.Binder,
                        interpreter.CultureInfo, returnType, objectFlags,
                        GetInvokeOptions(objectOptionType), objectOptionType,
                        objectName, interpName, returnValue, create, dispose,
                        alias, aliasReference, toString, ref result);
                }
            }
            else
            {
                MethodInfoList methodInfoList = new MethodInfoList();

                if (index != Index.Invalid)
                {
                    methodInfoList.Add(methodInfo[methodIndexList[index]]);
                }
                else
                {
                    foreach (int methodIndex in methodIndexList)
                        methodInfoList.Add(methodInfo[methodIndex]);
                }

                code = MarshalOps.FixupReturnValue(
                    interpreter, interpreter.Binder,
                    interpreter.CultureInfo, returnType, objectFlags,
                    GetInvokeOptions(objectOptionType), objectOptionType,
                    objectName, interpName, methodInfoList, create, dispose,
                    alias, aliasReference, toString, ref result);
            }

            return code;
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Object Disposal Support Methods
        public static ReturnCode TryDispose(
            object @object,  /* in */
            ref Result error /* out */
            )
        {
            return TryDispose(@object, DefaultDispose, ref error);
        }

        ///////////////////////////////////////////////////////////////////////

        public static ReturnCode TryDispose(
            object @object,  /* in */
            bool dispose,    /* in */
            ref Result error /* out */
            )
        {
            Exception exception = null;

            return TryDispose(
                @object, ref dispose, ref error, ref exception);
        }

        ///////////////////////////////////////////////////////////////////////

        public static ReturnCode TryDispose(
            object @object,   /* in */
            ref bool dispose, /* out */
            ref Result error  /* out */
            )
        {
            Exception exception = null;

            return TryDispose(
                @object, ref dispose, ref error, ref exception);
        }

        ///////////////////////////////////////////////////////////////////////

        public static ReturnCode TryDispose(
            object @object,         /* in */
            ref bool dispose,       /* out */
            ref Result error,       /* out */
            ref Exception exception /* out */
            )
        {
            if (@object != null)
            {
                try
                {
                    IDisposable disposable = @object as IDisposable;

                    if (disposable != null)
                    {
                        try
                        {
                            disposable.Dispose(); /* throw */
                            dispose = true; /* disposed */

                            return ReturnCode.Ok; /* success */
                        }
                        catch (Exception e)
                        {
                            //
                            // NOTE: The object threw an exception during its
                            //       disposal.  This is technically allowed;
                            //       however, it is typically discouraged.
                            //       Save the information and report it to our
                            //       caller.
                            //
                            error = e;
                            exception = e;

                            return ReturnCode.Error; /* failure */
                        }
                        finally
                        {
                            disposable = null;
                        }
                    }
                    else
                    {
                        //
                        // NOTE: Object does not implement IDisposable.
                        //
                        dispose = false; /* not disposable */

                        return ReturnCode.Ok; /* success */
                    }
                }
                finally
                {
                    @object = null;
                }
            }
            else
            {
                //
                // NOTE: Object is not valid.
                //
                dispose = false; /* invalid object */

                return ReturnCode.Ok;
            }
        }
        #endregion
    }
}
