// Returns the list of properties this element definition defines for an element with the given set of pseudo-classes.
void ElementDefinition::GetDefinedProperties(PropertyNameList& property_names, const PseudoClassList& pseudo_classes) const
{
	for (PropertyMap::const_iterator i = properties.GetProperties().begin(); i != properties.GetProperties().end(); ++i)
		property_names.insert((*i).first);

	for (PseudoClassPropertyDictionary::const_iterator i = pseudo_class_properties.begin(); i != pseudo_class_properties.end(); ++i)
	{
		// If this property is already in the default dictionary, don't bother checking for it here.
		if (property_names.find((*i).first) != property_names.end())
			continue;

		const PseudoClassPropertyList& property_list = (*i).second;

		// Search through all the pseudo-class combinations that have a definition for this property; if the calling
		// element matches at least one of them, then add it to the list.
		bool property_defined = false;
		for (size_t j = 0; j < property_list.size(); ++j)
		{
			if (IsPseudoClassRuleApplicable(property_list[j].first, pseudo_classes))
			{
				property_defined = true;
				break;
			}
		}

		if (property_defined)
			property_names.insert((*i).first);
	}
}
// Sets a single property as dirty.
void ElementStyle::DirtyProperty(const String& property)
{
	PropertyNameList properties;
	properties.insert(String(property));

	DirtyProperties(properties);
}
// Returns the list of properties this element definition has explicit definitions for involving the given
// pseudo-class.
void ElementDefinition::GetDefinedProperties(PropertyNameList& property_names, const PseudoClassList& pseudo_classes, const String& pseudo_class) const
{
	for (PseudoClassPropertyDictionary::const_iterator i = pseudo_class_properties.begin(); i != pseudo_class_properties.end(); ++i)
	{
		// If this property has already been found, don't bother checking for it again.
		if (property_names.find((*i).first) != property_names.end())
			continue;

		const PseudoClassPropertyList& property_list = (*i).second;

		bool property_defined = false;
		for (size_t j = 0; j < property_list.size(); ++j)
		{
			bool rule_valid = true;
			bool found_toggled_pseudo_class = false;

			const StringList& rule_pseudo_classes = property_list[j].first;
			for (size_t j = 0; j < rule_pseudo_classes.size(); ++j)
			{
				if (rule_pseudo_classes[j] == pseudo_class)
				{
					found_toggled_pseudo_class = true;
					continue;
				}

				if (pseudo_classes.find(rule_pseudo_classes[j]) == pseudo_classes.end())
				{			
					rule_valid = false;
					break;
				}
			}

			if (rule_valid &&
				found_toggled_pseudo_class)
			{
				property_defined = true;
				break;
			}
		}

		if (property_defined)
			property_names.insert((*i).first);
	}
}