/// <summary>
        /// Do a rich invocation of the scriptblock
        /// </summary>
        /// <param name="UseLocalScope">Whether a new scope should be created for this</param>
        /// <param name="DollerUnder">The value to make available as $_</param>
        /// <param name="Input">The value to make available to $input</param>
        /// <param name="ScriptThis">The value to make available as $this</param>
        /// <param name="ImportContext">Whether to first import the scriptblock into the current Context.</param>
        /// <param name="ImportGlobal">When importing the ScriptBlock, import it into the global Context instead.</param>
        /// <param name="Args">The value to make available as $args</param>
        /// <returns>Whatever output this scriptblock generates</returns>
        public System.Collections.ObjectModel.Collection <PSObject> InvokeEx(bool UseLocalScope, object DollerUnder, object Input, object ScriptThis, bool ImportContext, bool ImportGlobal, params object[] Args)
        {
            ScriptBlock tempScriptBlock = ScriptBlock;

            if (ImportContext)
            {
                tempScriptBlock = ScriptBlock.Clone().Import(ImportGlobal);
            }
            object result = tempScriptBlock.DoInvokeReturnAsIs(UseLocalScope, 2, DollerUnder, Input, ScriptThis, Args);

            if (result == null)
            {
                return(null);
            }
            if (result.GetType() == typeof(PSObject))
            {
                return new System.Collections.ObjectModel.Collection <PSObject>()
                       {
                           result as PSObject
                       }
            }
            ;
            return((System.Collections.ObjectModel.Collection <PSObject>)result);
        }
        /// <summary>
        /// Returns the correct results, either by executing the scriptblock or consulting the cache
        /// </summary>
        /// <returns></returns>
        public string[] Invoke()
        {
            if (!ShouldExecute)
            {
                return(LastResult);
            }

            List <string> results = new List <string>();

            CallStackFrame callerFrame = null;
            InvocationInfo info        = null;

            try
            {
                object CurrentCommandProcessor = UtilityHost.GetPrivateProperty("CurrentCommandProcessor", UtilityHost.GetExecutionContextFromTLS());
                object CommandObject           = UtilityHost.GetPrivateProperty("Command", CurrentCommandProcessor);
                info = UtilityHost.GetPublicProperty("MyInvocation", CommandObject) as InvocationInfo;
            }
            catch (Exception e)
            {
                if (PSFCore.PSFCoreHost.DebugMode)
                {
                    PSFCore.PSFCoreHost.WriteDebug(String.Format("Script Container {0} | Error accessing Current Command Processor", Name), e);
                }
            }

            if (info == null)
            {
                IEnumerable <CallStackFrame> _callStack = UtilityHost.Callstack;

                object errorItem = null;
                try
                {
                    if (_callStack.Count() > 0)
                    {
                        callerFrame = _callStack.Where(frame => frame.InvocationInfo != null && frame.InvocationInfo.MyCommand != null).First();
                    }
                }
                catch (Exception e) { errorItem = e; }
                if (PSFCore.PSFCoreHost.DebugMode)
                {
                    PSFCore.PSFCoreHost.WriteDebug(String.Format("Script Container {0} | Callframe selected", Name), callerFrame);
                    PSFCore.PSFCoreHost.WriteDebug(String.Format("Script Container {0} | Script Callstack", Name), new Message.CallStack(UtilityHost.Callstack));
                    if (errorItem != null)
                    {
                        PSFCore.PSFCoreHost.WriteDebug(String.Format("Script Container {0} | Error when selecting Callframe", Name), errorItem);
                    }
                }
            }
            if (info == null && callerFrame != null)
            {
                info = callerFrame.InvocationInfo;
            }

            object[] arguments = null;
            if (info != null)
            {
                arguments = new object[] { info.MyCommand.Name, "", "", null, info.BoundParameters }
            }
            ;
            else
            {
                arguments = new object[] { "<ScriptBlock>", "", "", null, new Dictionary <string, object>(StringComparer.InvariantCultureIgnoreCase) }
            };

            ScriptBlock tempScriptBlock = ScriptBlock;

            if (Global)
            {
                tempScriptBlock = ScriptBlock.Clone().ToGlobal();
            }

            foreach (PSObject item in tempScriptBlock.Invoke(arguments))
            {
                results.Add((string)item.Properties["CompletionText"].Value);
            }

            return(results.ToArray());
        }
    }