StyleProperty& LexerConf::GetProperty(int propertyId)
{
    StyleProperty::Map_t::iterator iter = m_properties.find(propertyId);
    if(iter == m_properties.end()) {
        static StyleProperty NullProperty;
        NullProperty.SetId(STYLE_PROPERTY_NULL_ID);
        return NullProperty;
    }
    return iter->second;
}
void LexerConf::FromXml(wxXmlNode* element)
{
    if(element) {
        m_flags = 0;
        m_name = element->GetPropVal(wxT("Name"), wxEmptyString);
        m_name.MakeLower();

        m_lexerId = XmlUtils::ReadLong(element, wxT("Id"), 0);
        m_themeName = XmlUtils::ReadString(element, "Theme", "Default");
        EnableFlag(kIsActive, XmlUtils::ReadBool(element, "IsActive", false));
        EnableFlag(kUseCustomTextSelectionFgColour,
                   XmlUtils::ReadBool(element, "UseCustomTextSelFgColour", false));
        EnableFlag(kStyleInPP,
                   element->GetPropVal(wxT("StylingWithinPreProcessor"), wxT("yes")) == wxT("yes") ? true : false);

        // load key words
        wxXmlNode* node = NULL;
        for(int i = 0; i < 10; ++i) {
            wxString tagName = "KeyWords";
            tagName << i;
            node = XmlUtils::FindFirstByTagName(element, tagName);
            if(node) {
                wxString content = node->GetNodeContent();
                content.Replace("\r", "");
                content.Replace("\n", " ");
                content.Replace("\\", " ");
                m_keyWords[i] = content;
            }
        }

        // load extensions
        node = XmlUtils::FindFirstByTagName(element, wxT("Extensions"));
        if(node) {
            m_extension = node->GetNodeContent();
            // Make sure that CMake includes the CMakeLists.txt file
            if(m_lexerId == wxSTC_LEX_CMAKE) {
                if(!m_extension.Contains("CMakeLists.txt")) {
                    m_extension = "*.cmake;*.CMAKE;*CMakeLists.txt";
                }
            }
        }

        // Hack: add RawString property to the lexers if not exist
        // By default, we use the settings defined for the wxSTC_C_STRING
        // property
        bool isCxxLexer = (m_lexerId == wxSTC_LEX_CPP);
        bool hasRawString = false;

        // Keey NULL property
        StyleProperty stringProp;
        stringProp.SetId(STYLE_PROPERTY_NULL_ID);

        // load properties
        // Search for <properties>
        node = XmlUtils::FindFirstByTagName(element, wxT("Properties"));
        if(node) {
            // We found the element, read the attributes
            wxXmlNode* prop = node->GetChildren();
            while(prop) {
                if(prop->GetName() == wxT("Property")) {
                    // Read the font attributes
                    wxString Name = XmlUtils::ReadString(prop, wxT("Name"), wxT("DEFAULT"));
                    wxString bold = XmlUtils::ReadString(prop, wxT("Bold"), wxT("no"));
                    wxString italic = XmlUtils::ReadString(prop, wxT("Italic"), wxT("no"));
                    wxString eolFill = XmlUtils::ReadString(prop, wxT("EolFilled"), wxT("no"));
                    wxString underline = XmlUtils::ReadString(prop, wxT("Underline"), wxT("no"));
                    wxString strikeout = XmlUtils::ReadString(prop, wxT("Strikeout"), wxT("no"));
                    wxString face = XmlUtils::ReadString(prop, wxT("Face"), wxT("Courier"));
                    wxString colour = XmlUtils::ReadString(prop, wxT("Colour"), wxT("black"));
                    wxString bgcolour = XmlUtils::ReadString(prop, wxT("BgColour"), wxT("white"));
                    long fontSize = XmlUtils::ReadLong(prop, wxT("Size"), 10);
                    long propId = XmlUtils::ReadLong(prop, wxT("Id"), 0);
                    long alpha = XmlUtils::ReadLong(prop, wxT("Alpha"), 50);

                    // Mainly for upgrade purposes: check if already read
                    // the StringRaw propery
                    if(isCxxLexer && !hasRawString && propId == wxSTC_C_STRINGRAW) {
                        hasRawString = true;
                    }
                    StyleProperty property = StyleProperty(propId,
                                                           colour,
                                                           bgcolour,
                                                           fontSize,
                                                           Name,
                                                           face,
                                                           StringTolBool(bold),
                                                           StringTolBool(italic),
                                                           StringTolBool(underline),
                                                           StringTolBool(eolFill),
                                                           alpha);
                    if(isCxxLexer && propId == wxSTC_C_STRING) {
                        stringProp = property;
                    }
                    m_properties.insert(std::make_pair(propId, property));
                }
                prop = prop->GetNext();
            }

            // If we don't have the raw string style property,
            // copy the string property and add it
            if(isCxxLexer && !hasRawString && !stringProp.IsNull()) {
                stringProp.SetId(wxSTC_C_STRINGRAW);
                stringProp.SetName("Raw String");
                m_properties.insert(std::make_pair(wxSTC_C_STRINGRAW, stringProp));
            }
        }
    }
}