private ControlPropertyMetadata GetPropertyMetadata(IPropertySymbol property)
        {
            var attribute = property.GetAttributes().FirstOrDefault(a => CheckType(a.AttributeClass, typeof(MarkupOptionsAttribute)));
            
            var metadata = new ControlPropertyMetadata()
            {
                Type = property.Type,
                IsTemplate = CheckType((INamedTypeSymbol)property.Type, typeof(ITemplate)) || property.Type.AllInterfaces.Any(i => CheckType(i, typeof(ITemplate))),
                AllowHtmlContent = property.Type.AllInterfaces.Any(i => CheckType(i, typeof(IControlWithHtmlAttributes)))
            };

            if (attribute != null)
            {
                metadata.Name = attribute.NamedArguments.Where(a => a.Key == "Name").Select(a => a.Value.Value as string).FirstOrDefault() ?? property.Name;
                metadata.AllowBinding = attribute.NamedArguments.Where(a => a.Key == "AllowBinding").Select(a => a.Value.Value as bool?).FirstOrDefault() ?? true;
                metadata.AllowHardCodedValue = attribute.NamedArguments.Where(a => a.Key == "AllowHardCodedValue").Select(a => a.Value.Value as bool?).FirstOrDefault() ?? true;

                var mappingMode = (MappingMode)(attribute.NamedArguments.Where(a => a.Key == "MappingMode").Select(a => a.Value.Value as int?).FirstOrDefault() ?? 0);
                if (mappingMode == MappingMode.InnerElement)
                {
                    metadata.IsElement = true;
                }
                else if (mappingMode == MappingMode.Exclude)
                {
                    return null;
                }
            }
            else
            {
                metadata.Name = property.Name;
                metadata.AllowBinding = true;
                metadata.AllowHardCodedValue = true;
            }
            
            if (metadata.IsTemplate)
            {
                metadata.IsElement = true;
            }

            return metadata;
        }
        internal void GetElementContext(List<string> tagNameHierarchy, out ControlMetadata currentControl, out ControlPropertyMetadata currentProperty)
        {
            currentProperty = null;
            currentControl = null;

            for (int i = 0; i < tagNameHierarchy.Count; i++)
            {
                currentProperty = null;
                currentControl = null;

                var tagName = tagNameHierarchy[i];
                if (metadata.ContainsKey(tagName))
                {
                    // we have found a control
                    currentControl = metadata[tagName];

                    // the next element in the hierarchy might be a property
                    if (i + 1 < tagNameHierarchy.Count)
                    {
                        currentProperty = currentControl.Properties.FirstOrDefault(p => p.Name == tagNameHierarchy[i + 1] && p.IsElement);
                        if (currentProperty != null)
                        {
                            i++;
                        }
                    }
                }
                else
                {
                    // HTML or unknown element
                    currentControl = htmlGenericControlMetadata;
                }
            }
        }