public static TypeDefinitionProjection RemoveProjection(TypeDefinition type)
        {
            if (!type.IsWindowsRuntimeProjection)
            {
                return(null);
            }

            TypeDefinitionProjection projection = type.WindowsRuntimeProjection;

            type.WindowsRuntimeProjection = null;

            type.Attributes = projection.Attributes;
            type.Name       = projection.Name;

            if (projection.Treatment == TypeDefinitionTreatment.RedirectImplementedMethods)
            {
                foreach (MethodDefinition method in projection.RedirectedMethods)
                {
                    type.Methods.Remove(method);
                }

                foreach (KeyValuePair <InterfaceImplementation, InterfaceImplementation> redirectedInterfacePair in projection.RedirectedInterfaces)
                {
                    foreach (MethodDefinition method in type.Methods)
                    {
                        foreach (MethodReference @override in method.Overrides)
                        {
                            if (TypeReferenceEqualityComparer.AreEqual(@override.DeclaringType, redirectedInterfacePair.Value.InterfaceType))
                            {
                                @override.DeclaringType = redirectedInterfacePair.Key.InterfaceType;
                            }
                        }
                    }

                    foreach (CustomAttribute customAttribute in redirectedInterfacePair.Value.CustomAttributes)
                    {
                        redirectedInterfacePair.Key.CustomAttributes.Add(customAttribute);
                    }

                    redirectedInterfacePair.Value.CustomAttributes.Clear();
                    type.Interfaces.Remove(redirectedInterfacePair.Value);
                }
            }

            return(projection);
        }
        public static void ApplyProjection(TypeDefinition type, TypeDefinitionProjection projection)
        {
            if (projection == null)
            {
                return;
            }

            TypeDefinitionTreatment treatment = projection.Treatment;

            switch (treatment & TypeDefinitionTreatment.KindMask)
            {
            case TypeDefinitionTreatment.NormalType:
                type.Attributes |= TypeAttributes.WindowsRuntime | TypeAttributes.Import;
                break;

            case TypeDefinitionTreatment.NormalAttribute:
                type.Attributes |= TypeAttributes.WindowsRuntime | TypeAttributes.Sealed;
                break;

            case TypeDefinitionTreatment.UnmangleWindowsRuntimeName:
                type.Attributes = type.Attributes & ~TypeAttributes.SpecialName | TypeAttributes.Public;
                type.Name       = type.Name.Substring("<CLR>".Length);
                break;

            case TypeDefinitionTreatment.PrefixWindowsRuntimeName:
                type.Attributes = type.Attributes & ~TypeAttributes.Public | TypeAttributes.Import;
                type.Name       = "<WinRT>" + type.Name;
                break;

            case TypeDefinitionTreatment.RedirectToClrType:
                type.Attributes = type.Attributes & ~TypeAttributes.Public | TypeAttributes.Import;
                break;

            case TypeDefinitionTreatment.RedirectToClrAttribute:
                type.Attributes = type.Attributes & ~TypeAttributes.Public;
                break;

            case TypeDefinitionTreatment.RedirectImplementedMethods:
            {
                type.Attributes |= TypeAttributes.WindowsRuntime | TypeAttributes.Import;

                foreach (KeyValuePair <InterfaceImplementation, InterfaceImplementation> redirectedInterfacePair in projection.RedirectedInterfaces)
                {
                    type.Interfaces.Add(redirectedInterfacePair.Value);

                    foreach (CustomAttribute customAttribute in redirectedInterfacePair.Key.CustomAttributes)
                    {
                        redirectedInterfacePair.Value.CustomAttributes.Add(customAttribute);
                    }

                    redirectedInterfacePair.Key.CustomAttributes.Clear();

                    foreach (MethodDefinition method in type.Methods)
                    {
                        foreach (MethodReference @override in method.Overrides)
                        {
                            if (TypeReferenceEqualityComparer.AreEqual(@override.DeclaringType, redirectedInterfacePair.Key.InterfaceType))
                            {
                                @override.DeclaringType = redirectedInterfacePair.Value.InterfaceType;
                            }
                        }
                    }
                }

                foreach (MethodDefinition method in projection.RedirectedMethods)
                {
                    type.Methods.Add(method);
                }
            }
            break;
            }

            if ((treatment & TypeDefinitionTreatment.Abstract) != 0)
            {
                type.Attributes |= TypeAttributes.Abstract;
            }

            if ((treatment & TypeDefinitionTreatment.Internal) != 0)
            {
                type.Attributes &= ~TypeAttributes.Public;
            }

            type.WindowsRuntimeProjection = projection;
        }