public override object GetValue(RubyContext /*!*/ context, RubyScope scope)
        {
            switch (_id)
            {
            // regular expressions:
            case GlobalVariableId.MatchData:
                return((scope != null) ? scope.GetInnerMostClosureScope().CurrentMatch : null);

            case GlobalVariableId.MatchLastGroup:
                return((scope != null) ? scope.GetInnerMostClosureScope().GetCurrentMatchLastGroup() : null);

            case GlobalVariableId.MatchPrefix:
                // TODO:
                throw new NotImplementedException();

            case GlobalVariableId.MatchSuffix:
                // TODO:
                throw new NotImplementedException();

            case GlobalVariableId.EntireMatch:
                return((scope != null) ? scope.GetInnerMostClosureScope().GetCurrentMatchGroup(0) : null);


            // exceptions:
            case GlobalVariableId.CurrentException:
                return(context.CurrentException);

            case GlobalVariableId.CurrentExceptionBacktrace:
                return(context.GetCurrentExceptionBacktrace());


            // input:
            case GlobalVariableId.InputContent:
                return(context.InputProvider.Singleton);

            case GlobalVariableId.InputFileName:
                return(context.InputProvider.CurrentFileName);

            case GlobalVariableId.LastInputLine:
                return((scope != null) ? scope.GetInnerMostClosureScope().LastInputLine : null);

            case GlobalVariableId.LastInputLineNumber:
                return(context.InputProvider.LastInputLineNumber);

            case GlobalVariableId.CommandLineArguments:
                return(context.InputProvider.CommandLineArguments);


            // output:
            case GlobalVariableId.OutputStream:
                return(context.StandardOutput);

            case GlobalVariableId.ErrorOutputStream:
                return(context.StandardErrorOutput);

            case GlobalVariableId.InputStream:
                return(context.StandardInput);


            // separators:
            case GlobalVariableId.InputSeparator:
                return(context.InputSeparator);

            case GlobalVariableId.OutputSeparator:
                return(context.OutputSeparator);

            case GlobalVariableId.StringSeparator:
                return(context.StringSeparator);

            case GlobalVariableId.ItemSeparator:
                return(context.ItemSeparator);


            // loader:
            case GlobalVariableId.LoadPath:
                return(context.Loader.LoadPaths);

            case GlobalVariableId.LoadedFiles:
                return(context.Loader.LoadedFiles);


            // misc:
            case GlobalVariableId.SafeLevel:
                return(context.CurrentSafeLevel);

            case GlobalVariableId.Verbose:
                return(context.Verbose);

            case GlobalVariableId.KCode:
                // TODO: Ruby 1.9 reports a warning:
                string name = context.GetKCodeName();
                return((name != null) ? MutableString.Create(name) : null);

            case GlobalVariableId.ChildProcessExitStatus:
                return(context.ChildProcessExitStatus);

            default:
                throw Assert.Unreachable;
            }
        }
        public override object GetValue(RubyContext/*!*/ context, RubyScope scope) {
            switch (_id) {
                
                // regular expressions:
                case GlobalVariableId.MatchData:
                    return (scope != null) ? scope.GetInnerMostClosureScope().CurrentMatch : null;

                case GlobalVariableId.MatchLastGroup:
                    return (scope != null) ? scope.GetInnerMostClosureScope().GetCurrentMatchLastGroup() : null;

                case GlobalVariableId.MatchPrefix:
                    // TODO:
                    throw new NotImplementedException();

                case GlobalVariableId.MatchSuffix:
                    // TODO:
                    throw new NotImplementedException();

                case GlobalVariableId.EntireMatch:
                    return (scope != null) ? scope.GetInnerMostClosureScope().GetCurrentMatchGroup(0) : null;


                // exceptions:
                case GlobalVariableId.CurrentException:
                    return context.CurrentException;

                case GlobalVariableId.CurrentExceptionBacktrace:
                    return context.GetCurrentExceptionBacktrace();


                // input:
                case GlobalVariableId.InputContent:
                    return context.InputProvider.Singleton;

                case GlobalVariableId.InputFileName:
                    return context.InputProvider.CurrentFileName;

                case GlobalVariableId.LastInputLine:
                    return (scope != null) ? scope.GetInnerMostClosureScope().LastInputLine : null;

                case GlobalVariableId.LastInputLineNumber:
                    return context.InputProvider.LastInputLineNumber;

                case GlobalVariableId.CommandLineArguments:
                    return context.InputProvider.CommandLineArguments;


                // output:
                case GlobalVariableId.OutputStream:
                    return context.StandardOutput;

                case GlobalVariableId.ErrorOutputStream:
                    return context.StandardErrorOutput;

                case GlobalVariableId.InputStream:
                    return context.StandardInput;


                // separators:
                case GlobalVariableId.InputSeparator:
                    return context.InputSeparator;

                case GlobalVariableId.OutputSeparator:
                    return context.OutputSeparator;

                case GlobalVariableId.StringSeparator:
                    return context.StringSeparator;

                case GlobalVariableId.ItemSeparator:
                    return context.ItemSeparator;

                
                // loader:
                case GlobalVariableId.LoadPath:
                    return context.Loader.LoadPaths;

                case GlobalVariableId.LoadedFiles:
                    return context.Loader.LoadedFiles;


                // misc:
                case GlobalVariableId.SafeLevel:
                    return context.CurrentSafeLevel;

                case GlobalVariableId.Verbose:
                    return context.Verbose;

                case GlobalVariableId.KCode:
                    // TODO: Ruby 1.9 reports a warning:
                    string name = context.GetKCodeName();
                    return (name != null) ? MutableString.Create(name) : null;

                case GlobalVariableId.ChildProcessExitStatus:
                    return context.ChildProcessExitStatus;

                default:
                    throw Assert.Unreachable;
            }
        }