private void endGroupAction(ParserState currentState, ParserState previousState)
        {
            switch (currentState.rds)
            {
            case DestinationState.Header:
                emitHeaderGroup(_headerGroupBuffer.ToString());
                _headerGroupBuffer = new StringBuilder();
                break;

            default:
                List <AttributeValue> changes = new List <AttributeValue>();

                foreach (CharacterAttributeType attrType in CharacterAttributeType.Values)
                {
                    int currentVal  = currentState.CharacterAttributes.Get(attrType);
                    int previousVal = previousState.CharacterAttributes.Get(attrType);
                    if (previousVal != currentVal)
                    {
                        AttributeKeyword attrKeyword = Keyword.findAttributeKeyword(attrType);
                        if (attrKeyword != null)
                        {
                            changes.Add(new AttributeValue(attrKeyword.getKeyword(), true, previousVal));
                        }
                    }
                }

                if (_handler != null && changes.Count > 0)
                {
                    _handler.onCharacterAttributeChange(changes);
                }
                break;
            }
        }
        private void translateKeyword(String keyword, int param, bool hasParam)
        {
            if (Keyword.KEYWORDS.ContainsKey(keyword))
            {
                Keyword kwd = Keyword.KEYWORDS[keyword];
                switch (kwd.getKeywordType())
                {
                case KeywordType.Character:
                    parseChar(((CharacterKeyword)kwd).getOutputChar());
                    break;

                case KeywordType.Destination:
                    _parserState.rds = ((DestinationKeyword)kwd).getDestinationState();
                    if (_parserState.rds == DestinationState.Header)
                    {
                        _headerGroupBuffer = new StringBuilder(keyword);
                    }
                    break;

                case KeywordType.Attribute:
                    AttributeKeyword attrKwd = (AttributeKeyword)kwd;

                    if (hasParam)
                    {
                        _parserState.CharacterAttributes.set(attrKwd.getAttributeType(), param);
                    }
                    else
                    {
                        _parserState.CharacterAttributes.set(attrKwd.getAttributeType(), attrKwd.getDefaultValue());
                    }

                    AttributeValue val = new AttributeValue(attrKwd.getKeyword(), hasParam, param);
                    if (_handler != null)
                    {
                        List <AttributeValue> values = new List <AttributeValue>();
                        values.Add(val);
                        _handler.onCharacterAttributeChange(values);
                    }
                    break;

                case KeywordType.Special:
                    char[] output = ((SpecialKeyword)kwd).process(param, this);
                    foreach (char ch in output)
                    {
                        parseChar(ch);
                    }
                    break;

                default:
                    break;
                }
            }
            else
            {
                if (_parserState.rds == DestinationState.Header)
                {
                    _headerGroupBuffer.Append("\\").Append(keyword);
                    if (hasParam)
                    {
                        _headerGroupBuffer.Append(param);
                    }
                }
                else
                {
                    if (_handler != null)
                    {
                        _handler.onKeyword(keyword, hasParam, param);
                    }
                }
            }
        }