internal bool Process()
            {
                RestoreStreamData();

                bool isactor = false;
                ZScriptClassStructure _pstruct = this;

                while (_pstruct != null)
                {
                    if (_pstruct.ClassName.ToLowerInvariant() == "actor")
                    {
                        isactor = true;
                        break;
                    }

                    if (_pstruct.ParentName != null)
                    {
                        string _pname = _pstruct.ParentName.ToLowerInvariant();
                        Parser.allclasses.TryGetValue(_pname, out _pstruct);
                    }
                    else
                    {
                        _pstruct = null;
                    }
                }

                string log_inherits = ((ParentName != null) ? "inherits " + ParentName : "");

                if (ReplacementName != null)
                {
                    log_inherits += ((log_inherits.Length > 0) ? ", " : "") + "replaces " + ReplacementName;
                }
                if (log_inherits.Length > 0)
                {
                    log_inherits = " (" + log_inherits + ")";
                }

                if (isactor)
                {
                    Actor = new ZScriptActorStructure(Parser, Region, ClassName, ReplacementName, ParentName);
                    if (Parser.HasError)
                    {
                        Actor = null;
                        return(false);
                    }

                    // check actor replacement.
                    Parser.archivedactors[Actor.ClassName.ToLowerInvariant()]     = Actor;
                    Parser.realarchivedactors[Actor.ClassName.ToLowerInvariant()] = Actor;
                    if (Actor.CheckActorSupported())
                    {
                        Parser.actors[Actor.ClassName.ToLowerInvariant()] = Actor;
                    }

                    // Replace an actor?
                    if (Actor.ReplacesClass != null)
                    {
                        if (Parser.GetArchivedActorByName(Actor.ReplacesClass, false) != null)
                        {
                            Parser.archivedactors[Actor.ReplacesClass.ToLowerInvariant()] = Actor;
                        }
                        else
                        {
                            Parser.LogWarning("Unable to find \"" + Actor.ReplacesClass + "\" class to replace, while parsing \"" + Actor.ClassName + "\"");
                        }

                        if (Actor.CheckActorSupported() && Parser.GetActorByName(Actor.ReplacesClass) != null)
                        {
                            Parser.actors[Actor.ReplacesClass.ToLowerInvariant()] = Actor;
                        }
                    }

                    //mxd. Add to current text resource
                    if (!Parser.scriptresources[TextResourcePath].Entries.Contains(Actor.ClassName))
                    {
                        Parser.scriptresources[TextResourcePath].Entries.Add(Actor.ClassName);
                    }
                }

                //Parser.LogWarning(string.Format("Parsed {0}class {1}{2}", isactor?"actor ":"", ClassName, log_inherits));

                return(true);
            }
        internal bool ParseClassOrStruct(bool isstruct, bool extend, DecorateCategoryInfo region)
        {
            // 'class' keyword is already parsed
            tokenizer.SkipWhitespace();
            ZScriptToken tok_classname = tokenizer.ExpectToken(ZScriptTokenType.Identifier);

            if (tok_classname == null || !tok_classname.IsValid)
            {
                ReportError("Expected class name, got " + ((Object)tok_classname ?? "<null>").ToString());
                return(false);
            }

            // name [replaces name] [: name] [native]
            ZScriptToken tok_replacename = null;
            ZScriptToken tok_parentname  = null;
            ZScriptToken tok_native      = null;
            ZScriptToken tok_scope       = null;
            ZScriptToken tok_version     = null;

            string[] class_scope_modifiers = new string[] { "clearscope", "ui", "play" };
            while (true)
            {
                tokenizer.SkipWhitespace();
                ZScriptToken token = tokenizer.ReadToken();

                if (token == null)
                {
                    ReportError("Expected a token");
                    return(false);
                }

                if (token.Type == ZScriptTokenType.Identifier)
                {
                    if (token.Value.ToLowerInvariant() == "replaces")
                    {
                        if (tok_native != null)
                        {
                            ReportError("Cannot have replacement after native");
                            return(false);
                        }

                        if (tok_replacename != null)
                        {
                            ReportError("Cannot have two replacements per class");
                            return(false);
                        }

                        tokenizer.SkipWhitespace();
                        tok_replacename = tokenizer.ExpectToken(ZScriptTokenType.Identifier);
                        if (tok_replacename == null || !tok_replacename.IsValid)
                        {
                            ReportError("Expected replacement class name, got " + ((Object)tok_replacename ?? "<null>").ToString());
                            return(false);
                        }
                    }
                    else if (token.Value.ToLowerInvariant() == "native")
                    {
                        if (tok_native != null)
                        {
                            ReportError("Cannot have two native keywords");
                            return(false);
                        }

                        tok_native = token;
                    }
                    else if (Array.IndexOf(class_scope_modifiers, token.Value.ToLowerInvariant()) >= 0)
                    {
                        if (tok_scope != null)
                        {
                            ReportError("Cannot have two scope qualifiers");
                            return(false);
                        }

                        tok_scope = token;
                    }
                    else if (token.Value.ToLowerInvariant() == "version")
                    {
                        if (tok_version != null)
                        {
                            ReportError("Cannot have two versions");
                            return(false);
                        }

                        // read in the version.
                        tokenizer.SkipWhitespace();
                        token = tokenizer.ExpectToken(ZScriptTokenType.OpenParen);
                        if (token == null || !token.IsValid)
                        {
                            ReportError("Expected (, got " + ((Object)token ?? "<null>").ToString());
                            return(false);
                        }

                        tokenizer.SkipWhitespace();
                        token = tokenizer.ExpectToken(ZScriptTokenType.String);
                        if (token == null || !token.IsValid)
                        {
                            ReportError("Expected version, got " + ((Object)token ?? "<null>").ToString());
                            return(false);
                        }

                        tok_version = token;
                        tokenizer.SkipWhitespace();
                        token = tokenizer.ExpectToken(ZScriptTokenType.CloseParen);
                        if (token == null || !token.IsValid)
                        {
                            ReportError("Expected ), got " + ((Object)token ?? "<null>").ToString());
                            return(false);
                        }
                    }
                    else
                    {
                        ReportError("Unexpected token " + ((Object)token ?? "<null>").ToString());
                    }
                }
                else if (token.Type == ZScriptTokenType.Colon)
                {
                    if (tok_parentname != null)
                    {
                        ReportError("Cannot have two parent classes");
                        return(false);
                    }

                    if (tok_replacename != null || tok_native != null)
                    {
                        ReportError("Cannot have parent class after replacement class or native keyword");
                        return(false);
                    }

                    tokenizer.SkipWhitespace();
                    tok_parentname = tokenizer.ExpectToken(ZScriptTokenType.Identifier);
                    if (tok_parentname == null || !tok_parentname.IsValid)
                    {
                        ReportError("Expected replacement class name, got " + ((Object)tok_parentname ?? "<null>").ToString());
                        return(false);
                    }
                }
                else if (token.Type == ZScriptTokenType.OpenCurly)
                {
                    datastream.Position--;
                    break;
                }
            }

            // do nothing else atm, except remember the position to put it into the class parsing code
            tokenizer.SkipWhitespace();
            long cpos = datastream.Position;

            //List<ZScriptToken> classblocktokens = ParseBlock(false);
            //if (classblocktokens == null) return false;
            if (!SkipBlock())
            {
                return(false);
            }

            string log_inherits = ((tok_parentname != null) ? "inherits " + tok_parentname.Value : "");

            if (tok_replacename != null)
            {
                log_inherits += ((log_inherits.Length > 0) ? ", " : "") + "replaces " + tok_replacename.Value;
            }
            if (extend)
            {
                log_inherits += ((log_inherits.Length > 0) ? ", " : "") + "extends";
            }
            if (log_inherits.Length > 0)
            {
                log_inherits = " (" + log_inherits + ")";
            }

            // now if we are a class, and we inherit actor, parse this entry as an actor. don't process extensions.
            if (!isstruct && !extend)
            {
                ZScriptClassStructure cls = new ZScriptClassStructure(this, tok_classname.Value, (tok_replacename != null) ? tok_replacename.Value : null, (tok_parentname != null) ? tok_parentname.Value : null, region);
                cls.Position = cpos;
                string clskey = cls.ClassName.ToLowerInvariant();
                if (allclasses.ContainsKey(clskey))
                {
                    ReportError("Class " + cls.ClassName + " is double-defined");
                    return(false);
                }

                allclasses.Add(cls.ClassName.ToLowerInvariant(), cls);
                allclasseslist.Add(cls);
            }

            //LogWarning(string.Format("Parsed {0} {1}{2}", (isstruct ? "struct" : "class"), tok_classname.Value, log_inherits));

            return(true);
        }