private static void GenerateSourceFile(GeneratorExecutionContext context, string interfaceFullTypeName)
        {
            INamedTypeSymbol?interfaceSymbol = context.Compilation.GetTypeByMetadataName(interfaceFullTypeName);

            if (interfaceSymbol == null)
            {
                return;
            }

            if (!TryGetTypeNamesFromInterface(interfaceFullTypeName, out string interfaceNamespace, out string controlTypeName))
            {
                return;
            }

            if (interfaceFullTypeName == "Microcharts.IChart")
            {
                // For now, hack the IChart case
                GenerateChartSourceFile(context);
                return;
            }

            string baseTypeName        = GetBaseInterface(interfaceSymbol).Name;
            string controlBaseTypeName = baseTypeName == "IStandardControl" ? "StandardControl" : baseTypeName.Substring(1);

            StringBuilder sourceCode = new StringBuilder();

            sourceCode.Append($@"// This file was generated

using Microsoft.StandardUI.Media;
using Microsoft.StandardUI.Wpf.Media;
using Microsoft.StandardUI.Wpf;

namespace {interfaceNamespace}.Wpf
{{
    public class {controlTypeName} : {controlBaseTypeName}, {interfaceFullTypeName}
    {{
        public {controlTypeName}()
        {{
            InitImplementation(new {interfaceNamespace}.{controlTypeName}Implementation<{interfaceFullTypeName}>(this));
        }}");

            ImportedControlGenerator.GenerateProperties(interfaceSymbol, controlTypeName, sourceCode);

            sourceCode.Append($@"
    }}
}}");

            // Create the file
            context.AddSource(controlTypeName, sourceCode.ToString());
        }
        /// <summary>
        /// Appends the source code to implement the properties on <paramref name="interfaceSymbol"/> to <paramref name="sourceCode"/>.
        /// </summary>
        /// <example>
        /// public Brush? Fill
        /// {
        ///     get => (Brush?)GetValue(FillProperty);
        ///     set => SetValue(FillProperty, value);
        /// }
        ///
        /// IBrush IRadialGauge.Fill
        /// {
        ///     get => Fill;
        ///     set => Fill = (Brush?)value;
        /// }
        /// </example>
        /// <param name="interfaceSymbol">The interface whose properties should be implemented.</param>
        /// <param name="controlTypeName">The name of the control class that is implementing the interface.</param>
        /// <param name="sourceCode">The StringBuilder to which the source code should be written.</param>
        private static void GenerateProperties(INamedTypeSymbol interfaceSymbol, string controlTypeName, StringBuilder sourceCode)
        {
            foreach (IPropertySymbol propertySymbol in interfaceSymbol.GetMembers().Where(member => member.Kind == SymbolKind.Property))
            {
                string propertyName = propertySymbol.Name;
                string explicitInterfacePropertyType = propertySymbol.Type.Name;
                string publicPropertyType            = ImportedControlGenerator.IsStandardUIInterface(propertySymbol.Type) ? explicitInterfacePropertyType.Substring(1) : explicitInterfacePropertyType;

                // The dependency property
                sourceCode.Append($@"

        public static readonly System.Windows.DependencyProperty {propertyName}Property = PropertyUtils.Register(nameof({propertyName}), typeof({publicPropertyType}), typeof({controlTypeName}), null);
");

                // The public property implementation
                sourceCode.Append($@"
        public {publicPropertyType}? {propertyName}
        {{
            get => ({publicPropertyType}?)GetValue({propertyName}Property);");

                if (propertySymbol.SetMethod != null)
                {
                    sourceCode.Append($@"
            set => SetValue({propertyName}Property, value);");
                }

                sourceCode.Append($@"
        }}
");

                // The explicit property implementation
                sourceCode.Append($@"
        {explicitInterfacePropertyType} {propertySymbol.ContainingType.Name}.{propertyName}
        {{
            get => {propertyName};");

                if (propertySymbol.SetMethod != null)
                {
                    sourceCode.Append($@"
            set => { propertyName} = ({publicPropertyType}?)value;");
                }

                sourceCode.Append($@"
        }}");
            }
        }
        public void Execute(GeneratorExecutionContext context)
        {
            SyntaxReceiver rx = (SyntaxReceiver)context.SyntaxContextReceiver !;

            HashSet <string> generatedInterfaces = new HashSet <string>();

            foreach (string interfaceFullTypeName in rx.InterfacesToGenerate)
            {
                INamedTypeSymbol?interfaceSymbol = context.Compilation.GetTypeByMetadataName(interfaceFullTypeName);
                if (interfaceSymbol == null)
                {
                    continue;
                }

                if (generatedInterfaces.Contains(interfaceFullTypeName))
                {
                    continue;
                }

                ImportedControlGenerator.GenerateSourceFile(context, interfaceFullTypeName);
                generatedInterfaces.Add(interfaceFullTypeName);

                // Generate any ancestor types
                INamedTypeSymbol?ancestorType = GetBaseInterface(interfaceSymbol);
                while (ancestorType != null)
                {
                    var symbolDisplayFormat = new SymbolDisplayFormat(
                        typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces);
                    string ancestorFullTypeName = ancestorType.ToDisplayString(symbolDisplayFormat);

                    if (ancestorFullTypeName == "Microsoft.StandardUI.Controls.IStandardControl" || generatedInterfaces.Contains(ancestorFullTypeName))
                    {
                        break;
                    }

                    ImportedControlGenerator.GenerateSourceFile(context, ancestorFullTypeName);
                    generatedInterfaces.Add(ancestorFullTypeName);

                    ancestorType = GetBaseInterface(ancestorType);
                }
            }
        }