/// <summary>
        /// Returns additional required ObjC import directives.
        /// </summary>
        /// <param name="facet"></param>
        /// <returns></returns>
        public List <string> ObjCImportDirectives(CodeFacet facet, bool filter = true)
        {
            List <string> imports = new List <string>();

            if (!Config.GenerateFacetBinding(facet))
            {
                return(imports);
            }

            // objC type
            // note that a constructor has no return type
            string objCType  = facet.ObjCFacet.Type;
            string importStr = null;

            if (!string.IsNullOrEmpty(objCType))
            {
                // we only need to import types defined in the current assembly.
                // other types will be imported via their own assembly's header
                if (AssemblyFacet.DefinesFacetType(facet.Type))
                {
                    // if the type is an enum
                    if (facet.IsEnum)
                    {
                        objCType  = facet.ObjCFacet.Type;
                        importStr = $"#import \"{objCType}.h\"";
                        imports.Add(importStr);
                    }
                }
            }

            // forward declare objC facet types for all children
            List <CodeFacet> children = facet.Children();

            foreach (CodeFacet child in children)
            {
                imports.AddRange(ObjCImportDirectives(child, false));
            }

            // remove duplicates
            imports = imports.Distinct().ToList();
            imports.Sort();

            // the filter ensures that the import list doesn't include
            // the header that the import directives will be inserted into
            if (filter && importStr != null)
            {
                imports.Remove(importStr);
            }

            return(imports);
        }
        /// <summary>
        /// Returns all ObjC import directives required to fully derive an ObjC class from its subclass and its adopted protocols.
        /// These directives constitute the minimum required to define a class in an ObjC interface header file.
        /// </summary>
        /// <param name="facet">Facet</param>
        /// <returns>List of ObjC import directives.</returns>
        public List <string> ObjCDerivationImportDirectives(CodeFacet facet)
        {
            List <string> imports = new List <string>();

            // iterate over the sub facets required to derive the native representation
            List <CodeFacet> derivation = facet.Derivation();

            foreach (CodeFacet cursor in derivation)
            {
                string objCType = null;

                // Managed interfaces don't derive from a base type but from other interfaces (see GetInterfaces)
                // https://msdn.microsoft.com/en-us/library/system.type.basetype(v=vs.110).aspx
                // However, our native implementation of the managed interface is a class of System.Object.
                if (cursor.GetType() == typeof(InterfaceFacet))
                {
                    if (AssemblyFacet.DefinesFacetType("System.Object"))
                    {
                        objCType = "System_Object";
                        imports.Add($"#import \"{objCType}.h\"");
                    }
                }

                // for all interfaces we require to import a protocol
                if (cursor.GetType() == typeof(ImplementedInterfaceFacet) || cursor.GetType() == typeof(InterfaceFacet))
                {
                    if (!AssemblyFacet.DefinesFacetType(cursor.Type))
                    {
                        continue;
                    }

                    // if this interface type is not required then just skip it.
                    // this means that some of the interface methods etc may be represented
                    // and others may not depending on the type exclusion settings
                    if (!Config.GenerateFacetBinding(cursor))
                    {
                        continue;
                    }

                    objCType = cursor.ObjCFacet.Type;
                    imports.Add($"#import \"{objCType}_Protocol.h\"");
                }

                // use base type
                else
                {
                    string baseType = cursor.BaseType;

                    // System.Object has no base type
                    if (baseType == null)
                    {
                        continue;
                    }

                    // Derived import directives will only be required for types
                    // defined in the target assembly. If this is not the case
                    // then the required import will have to be defined elsewhere,
                    // most likely in a framework header.
                    if (!AssemblyFacet.DefinesFacetType(baseType))
                    {
                        continue;
                    }

                    // if we are not generating bindings for the given type then
                    // a header file won't be available
                    string importPrefix = "";
                    string importSuffix = "";
                    if (!Config.GenerateTypeBinding(baseType))
                    {
                        importPrefix = "//";
                        importSuffix = " // class base defaults to System.Object";
                    }

                    objCType = cursor.ObjCFacet.BaseType;
                    imports.Add($"{importPrefix}#import \"{objCType}.h\"{importSuffix}");
                }
            }

            // return a distinct list to remove duplicates
            imports = imports.Distinct().ToList();
            imports.Sort();
            return(imports);
        }