void AddAspAttributeValueCompletionData(CompletionDataList list, XName tagName, XName attName, string id)
        {
            Debug.Assert(tagName.IsValid && tagName.HasPrefix);
            Debug.Assert(attName.IsValid && !attName.HasPrefix);

            INamedTypeSymbol controlClass = refman.GetControlType(tagName.Prefix, tagName.Name);

            if (controlClass == null)
            {
                return;
            }

            //find the codebehind class
            INamedTypeSymbol codeBehindClass;

            GetCodeBehind(out codeBehindClass);

            //if it's an event, suggest compatible methods
            if (codeBehindClass != null && attName.Name.StartsWith("On", StringComparison.Ordinal))
            {
                string eventName = attName.Name.Substring(2);

                foreach (IEventSymbol ev in controlClass.GetAccessibleMembersInThisAndBaseTypes <IEventSymbol> (controlClass))
                {
                    if (ev.Name == eventName)
                    {
                        var domMethod = BindingService.MDDomToCodeDomMethod(ev);
                        if (domMethod == null)
                        {
                            return;
                        }

                        foreach (IMethodSymbol meth
                                 in BindingService.GetCompatibleMethodsInClass(codeBehindClass, ev))
                        {
                            list.Add(meth.Name, "md-method",
                                     GettextCatalog.GetString("A compatible method in the CodeBehind class"));
                        }

                        string suggestedIdentifier = ev.Name;
                        if (id != null)
                        {
                            suggestedIdentifier = id + "_" + suggestedIdentifier;
                        }
                        else
                        {
                            suggestedIdentifier = tagName.Name + "_" + suggestedIdentifier;
                        }

                        domMethod.Name = BindingService.GenerateIdentifierUniqueInClass
                                             (codeBehindClass, suggestedIdentifier);
                        domMethod.Attributes = (domMethod.Attributes & ~System.CodeDom.MemberAttributes.AccessMask)
                                               | System.CodeDom.MemberAttributes.Family;

                        list.Add(
                            new SuggestedHandlerCompletionData(project, domMethod, codeBehindClass,
                                                               CodeBehind.GetNonDesignerClassLocation(codeBehindClass))
                            );
                        return;
                    }
                }
            }

            //if it's a property and is an enum or bool, suggest valid values
            foreach (IPropertySymbol prop in GetAllMembers <IPropertySymbol> (controlClass))
            {
                if (prop.Name != attName.Name)
                {
                    continue;
                }

                //boolean completion
                if (prop.GetReturnType().Equals(refman.Compilation.GetTypeByMetadataName("System.Boolean")))
                {
                    AddBooleanCompletionData(list);
                    return;
                }
                //color completion
                if (prop.GetReturnType().Equals(refman.Compilation.GetTypeByMetadataName("System.Drawing.Color")))
                {
                    var conv = new System.Drawing.ColorConverter();
                    foreach (System.Drawing.Color c in conv.GetStandardValues(null))
                    {
                        if (c.IsSystemColor)
                        {
                            continue;
                        }
                        string hexcol = string.Format("#{0:x2}{1:x2}{2:x2}", c.R, c.G, c.B);
                        list.Add(c.Name, hexcol);
                    }
                    return;
                }

                //enum completion
                var retCls = prop.GetReturnType() as INamedTypeSymbol;
                if (retCls != null && retCls.TypeKind == TypeKind.Enum)
                {
                    foreach (var enumVal in GetAllMembers <IFieldSymbol> (retCls))
                    {
                        if (enumVal.DeclaredAccessibility == Accessibility.Public && enumVal.IsStatic)
                        {
                            list.Add(enumVal.Name, "md-literal", Ambience.GetSummaryMarkup(enumVal));
                        }
                    }
                    return;
                }
            }
        }