/// <summary>
        /// Set the pair information using only either the entity or the type
        /// </summary>
        /// <param name="entityTypeStr">the entity or type string</param>
        /// <param name="predefineType">predefinedtype string</param>
        public void SetValueWithPair(string entityTypeStr, string predefineType = null)
        {
            int  typeLen = 4;
            bool isType  = entityTypeStr.Substring(entityTypeStr.Length - 4, 4).Equals("Type", StringComparison.CurrentCultureIgnoreCase);

            if (!isType)
            {
                if (entityTypeStr.Equals("IfcDoorStyle", StringComparison.InvariantCultureIgnoreCase) ||
                    entityTypeStr.Equals("IfcWindowStyle", StringComparison.InvariantCultureIgnoreCase))
                {
                    isType  = true;
                    typeLen = 5;
                }
            }

            if (isType)
            {
                // Get the instance
                string instName          = entityTypeStr.Substring(0, entityTypeStr.Length - typeLen);
                IfcSchemaEntityNode node = IfcSchemaEntityTree.Find(instName);
                if (node != null && !node.isAbstract)
                {
                    IFCEntityType instType = IFCEntityType.UnKnown;
                    if (IFCEntityType.TryParse(instName, true, out instType))
                    {
                        m_ExportInstance = instType;
                    }
                }
                else
                {
                    // If not found, try non-abstract supertype derived from the type
                    node = IfcSchemaEntityTree.FindNonAbsInstanceSuperType(instName);
                    if (node != null)
                    {
                        IFCEntityType instType = IFCEntityType.UnKnown;
                        if (IFCEntityType.TryParse(node.Name, true, out instType))
                        {
                            m_ExportInstance = instType;
                        }
                    }
                }

                // set the type
                IFCEntityType entityType = ElementFilteringUtil.GetValidIFCEntityType(entityTypeStr);
                if (entityType != IFCEntityType.UnKnown)
                {
                    m_ExportType = entityType;
                }
                else
                {
                    node = IfcSchemaEntityTree.FindNonAbsInstanceSuperType(entityTypeStr);
                    if (node != null)
                    {
                        IFCEntityType instType = IFCEntityType.UnKnown;
                        if (IFCEntityType.TryParse(node.Name, true, out instType))
                        {
                            m_ExportType = instType;
                        }
                    }
                }
            }
            else
            {
                // set the instance
                IFCEntityType instType = ElementFilteringUtil.GetValidIFCEntityType(entityTypeStr);
                if (instType != IFCEntityType.UnKnown)
                {
                    m_ExportInstance = instType;
                }
                else
                {
                    // If not found, try non-abstract supertype derived from the type
                    IfcSchemaEntityNode node = IfcSchemaEntityTree.FindNonAbsInstanceSuperType(entityTypeStr);
                    if (node != null)
                    {
                        instType = IFCEntityType.UnKnown;
                        if (IFCEntityType.TryParse(node.Name, true, out instType))
                        {
                            m_ExportInstance = instType;
                        }
                    }
                }

                // set the type pair
                string typeName = entityTypeStr;
                if (ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4 &&
                    (entityTypeStr.Equals("IfcDoor", StringComparison.InvariantCultureIgnoreCase) ||
                     entityTypeStr.Equals("IfcWindow", StringComparison.InvariantCultureIgnoreCase)))
                {
                    typeName += "Style";
                }
                else
                {
                    typeName += "Type";
                }

                IFCEntityType entityType = ElementFilteringUtil.GetValidIFCEntityType(typeName);
                if (entityType != IFCEntityType.UnKnown)
                {
                    m_ExportType = entityType;
                }
                else
                {
                    // If the type name is not found, likely it does not have the pair at this level, needs to get the supertype of the instance to get the type pair
                    IList <IfcSchemaEntityNode> instNodes = IfcSchemaEntityTree.FindAllSuperTypes(entityTypeStr, "IfcProduct", "IfcGroup");
                    foreach (IfcSchemaEntityNode instNode in instNodes)
                    {
                        typeName = instNode.Name + "Type";
                        IfcSchemaEntityNode node = IfcSchemaEntityTree.Find(typeName);
                        if (node == null)
                        {
                            node = IfcSchemaEntityTree.FindNonAbsInstanceSuperType(typeName);
                        }

                        if (node != null && !node.isAbstract)
                        {
                            instType = IFCEntityType.UnKnown;
                            if (IFCEntityType.TryParse(node.Name, true, out instType))
                            {
                                m_ExportType = instType;
                                break;
                            }
                        }
                    }
                }
            }

            ValidatedPredefinedType = predefineType;
        }
        private void button_Go_Click(object sender, RoutedEventArgs e)
        {
            if (listBox_schemaList.SelectedItems.Count == 0)
            {
                return;
            }

            DirectoryInfo dInfo = new DirectoryInfo(textBox_folderLocation.Text);

            if (dInfo == null)
            {
                return;
            }

            if (aggregateEntities == null)
            {
                aggregateEntities = new SortedSet <string>();
            }
            aggregateEntities.Clear();

            if (!Directory.Exists(textBox_outputFolder.Text))
            {
                textBox_outputFolder.Text = "";
                return;
            }

            logF = new StreamWriter(System.IO.Path.Combine(outputFolder, "entityList.log"));

            IList <IFCEntityAndPsetList> fxEntityNPsetList = new List <IFCEntityAndPsetList>();

            string jsonFile = outputFolder + @"\IFCEntityAndPsetDefs.json";

            if (File.Exists(jsonFile))
            {
                File.Delete(jsonFile);
            }
            FileStream fs = File.Create(jsonFile);
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List <IFCEntityAndPsetList>));

            foreach (string fileName in listBox_schemaList.SelectedItems)
            {
                FileInfo f = dInfo.GetFiles(fileName).First();
                processSchema(f);

                ProcessPsetDefinition procPdef = new ProcessPsetDefinition(logF);

                string schemaName = f.Name.Replace(".xsd", "");
                IDictionary <string, IfcSchemaEntityNode> entDict = IfcSchemaEntityTree.GetEntityDictFor(f.Name);
                IFCEntityAndPsetList schemaEntities = new IFCEntityAndPsetList();
                schemaEntities.Version     = schemaName;
                schemaEntities.EntityList  = new HashSet <IFCEntityInfo>();
                schemaEntities.PsetDefList = new HashSet <IFCPropertySetDef>();

                DirectoryInfo[] psdFolders      = new DirectoryInfo(System.IO.Path.Combine(textBox_folderLocation.Text, schemaName)).GetDirectories("psd", SearchOption.AllDirectories);
                DirectoryInfo[] underpsdFolders = psdFolders[0].GetDirectories();
                if (underpsdFolders.Count() > 0)
                {
                    foreach (DirectoryInfo subDir in psdFolders[0].GetDirectories())
                    {
                        procPdef.ProcessSchemaPsetDef(schemaName, subDir);
                    }
                }
                else
                {
                    procPdef.ProcessSchemaPsetDef(schemaName, psdFolders[0]);
                }

                //Collect information on applicable Psets for Entity
                IDictionary <string, HashSet <string> > entPsetDict = new Dictionary <string, HashSet <string> >();
                foreach (KeyValuePair <string, IList <VersionSpecificPropertyDef> > pdefEntry in procPdef.allPDefDict)
                {
                    foreach (VersionSpecificPropertyDef vPdef in pdefEntry.Value)
                    {
                        //if (vPdef.IfcVersion.Equals(schemaName, StringComparison.InvariantCultureIgnoreCase))
                        {
                            IFCPropertySetDef psetDef = new IFCPropertySetDef();
                            psetDef.PsetName = vPdef.PropertySetDef.Name;
                            IList <string> props = new List <string>();
                            foreach (PropertySet.PsetProperty property in vPdef.PropertySetDef.properties)
                            {
                                props.Add(property.Name);
                            }
                            psetDef.Properties = props;
                            schemaEntities.PsetDefList.Add(psetDef);

                            // TODO: to check the appl classes either a type or not and check whether the pair (type or without) exists in entDict, if there is add
                            foreach (string applEntity in vPdef.PropertySetDef.ApplicableClasses)
                            {
                                if (entPsetDict.ContainsKey(applEntity))
                                {
                                    entPsetDict[applEntity].Add(vPdef.PropertySetDef.Name);
                                }
                                else
                                {
                                    entPsetDict.Add(applEntity, new HashSet <string>()
                                    {
                                        vPdef.PropertySetDef.Name
                                    });
                                }

                                // The Pset will be valid for both the Instance and the Type. Check for that here and add if found
                                string entOrTypePair;
                                if (applEntity.Length > 4 && applEntity.EndsWith("Type"))
                                {
                                    entOrTypePair = applEntity.Substring(0, applEntity.Length - 4);
                                }
                                else
                                {
                                    entOrTypePair = applEntity + "Type";
                                }

                                if (aggregateEntities.Contains(entOrTypePair))
                                {
                                    if (entPsetDict.ContainsKey(entOrTypePair))
                                    {
                                        entPsetDict[entOrTypePair].Add(vPdef.PropertySetDef.Name);
                                    }
                                    else
                                    {
                                        entPsetDict.Add(entOrTypePair, new HashSet <string>()
                                        {
                                            vPdef.PropertySetDef.Name
                                        });
                                    }
                                }
                            }
                        }
                    }
                }

                // For every entity of the schema, collect the list of PredefinedType (obtained from the xsd), and collect all applicable
                //  Pset Definitions collected above
                foreach (KeyValuePair <string, IfcSchemaEntityNode> ent in entDict)
                {
                    IFCEntityInfo entInfo = new IFCEntityInfo();

                    // The abstract entity type is not going to be listed here as they can never be created
                    if (ent.Value.isAbstract)
                    {
                        continue;
                    }

                    // Collect only the IfcProducts or IfcGroup
                    if (!ent.Value.IsSubTypeOf("IfcProduct") && !ent.Value.IsSubTypeOf("IfcGroup") && !ent.Value.IsSubTypeOf("IfcTypeProduct"))
                    {
                        continue;
                    }

                    entInfo.Entity = ent.Key;
                    if (!string.IsNullOrEmpty(ent.Value.PredefinedType))
                    {
                        if (IfcSchemaEntityTree.PredefinedTypeEnumDict.ContainsKey(ent.Value.PredefinedType))
                        {
                            entInfo.PredefinedType = IfcSchemaEntityTree.PredefinedTypeEnumDict[ent.Value.PredefinedType];
                        }
                    }

                    // Get Pset list that is applicable to this entity type
                    if (entPsetDict.ContainsKey(entInfo.Entity))
                    {
                        entInfo.PropertySets = entPsetDict[entInfo.Entity].ToList();
                    }
                    // Collect Pset that is applicable to the supertype of this entity
                    IList <IfcSchemaEntityNode> supertypeList = IfcSchemaEntityTree.FindAllSuperTypes(entInfo.Entity,
                                                                                                      "IfcProduct", "IfcTypeProduct", "IfcGroup");
                    if (supertypeList != null && supertypeList.Count > 0)
                    {
                        foreach (IfcSchemaEntityNode superType in supertypeList)
                        {
                            if (entPsetDict.ContainsKey(superType.Name))
                            {
                                if (entInfo.PropertySets == null)
                                {
                                    entInfo.PropertySets = new List <string>();
                                }

                                foreach (string pset in entPsetDict[superType.Name])
                                {
                                    entInfo.PropertySets.Add(pset);
                                }
                            }
                        }
                    }

                    schemaEntities.EntityList.Add(entInfo);
                }
                fxEntityNPsetList.Add(schemaEntities);
            }
            ser.WriteObject(fs, fxEntityNPsetList);
            fs.Close();

            if (aggregateEntities.Count > 0)
            {
                string entityList;
                entityList = "using System;"
                             + "\r\nusing System.Collections.Generic;"
                             + "\r\nusing System.Linq;"
                             + "\r\nusing System.Text;"
                             + "\r\n"
                             + "\r\nnamespace Revit.IFC.Common.Enums"
                             + "\r\n{"
                             + "\r\n   /// <summary>"
                             + "\r\n   /// IFC entity types. Combining IFC2x3 and IFC4 (Add2) entities."
                             + "\r\n   /// List of Entities for IFC2x is found in IFC2xEntityType.cs"
                             + "\r\n   /// List of Entities for IFC4 is found in IFC4EntityType.cs"
                             + "\r\n   /// </summary>"
                             + "\r\n   public enum IFCEntityType"
                             + "\r\n   {";

                foreach (string ent in aggregateEntities)
                {
                    entityList += "\r\n      /// <summary>"
                                  + "\r\n      /// IFC Entity " + ent + " enumeration"
                                  + "\r\n      /// </summary>"
                                  + "\r\n      " + ent + ",\n";
                }
                entityList += "\r\n      Unknown,"
                              + "\r\n      DontExport"
                              + "\r\n   }"
                              + "\r\n}";
                System.IO.File.WriteAllText(outputFolder + @"\IFCEntityType.cs", entityList);
            }

            foreach (IFCEntityAndPsetList fxEntityNPset in fxEntityNPsetList)
            {
                string entityList;
                entityList = "using System;"
                             + "\r\nusing System.Collections.Generic;"
                             + "\r\nusing System.Linq;"
                             + "\r\nusing System.Text;"
                             + "\r\n"
                             + "\r\nnamespace Revit.IFC.Common.Enums." + fxEntityNPset.Version
                             + "\r\n{"
                             + "\r\n   /// <summary>"
                             + "\r\n   /// List of Entities for " + fxEntityNPset.Version
                             + "\r\n   /// </summary>"
                             + "\r\n   public enum EntityType"
                             + "\r\n   {";

                foreach (IFCEntityInfo entInfo in fxEntityNPset.EntityList)
                {
                    entityList += "\r\n      /// <summary>"
                                  + "\r\n      /// IFC Entity " + entInfo.Entity + " enumeration"
                                  + "\r\n      /// </summary>"
                                  + "\r\n      " + entInfo.Entity + ",\r\n";
                }
                entityList += "\r\n      Unknown,"
                              + "\r\n      DontExport"
                              + "\r\n   }"
                              + "\r\n}";
                System.IO.File.WriteAllText(outputFolder + @"\" + fxEntityNPset.Version + "EntityType.cs", entityList);
            }

            // Only allows test when only one schema is selected
            if (listBox_schemaList.SelectedItems.Count == 1)
            {
                button_subtypeTest.IsEnabled    = true;
                button_supertypeTest.IsEnabled  = true;
                button_ExportInfoPair.IsEnabled = true;
            }
            else
            {
                button_subtypeTest.IsEnabled    = false;
                button_supertypeTest.IsEnabled  = false;
                button_ExportInfoPair.IsEnabled = false;
            }

            if (logF != null)
            {
                logF.Close();
            }
        }