public VMFStructure(String type, StreamReader reader)
        {
            if (stTypeDict.ContainsKey(type))
            {
                Type = stTypeDict[type];
            }
            else
            {
                Type = VMFStructureType.Unknown;
            }

            Properties = new List <KeyValuePair <String, VMFValue> >();
            Structures = new List <VMFStructure>();

            myIDIndex = -1;

            String line;

            while (!reader.EndOfStream && (line = reader.ReadLine().Trim()) != "}")
            {
                if (line == "{" || line.Length == 0)
                {
                    continue;
                }

                if (line[0] == '"')
                {
                    String[] pair = line.Trim('"').Split(new String[] { "\" \"" }, StringSplitOptions.None);
                    if (pair.Length != 2)
                    {
                        continue;
                    }

                    KeyValuePair <String, VMFValue> keyVal;

                    if (Type == VMFStructureType.Normals || Type == VMFStructureType.Offsets || Type == VMFStructureType.Offset_Normals)
                    {
                        keyVal = new KeyValuePair <string, VMFValue>(pair[0], new VMFVector3ArrayValue()
                        {
                            String = pair[1]
                        });
                    }
                    else
                    {
                        keyVal = new KeyValuePair <string, VMFValue>(pair[0], VMFValue.Parse(pair[1]));
                    }

                    if (keyVal.Key == "id" && keyVal.Value is VMFNumberValue)
                    {
                        myIDIndex = Properties.Count;
                    }

                    Properties.Add(keyVal);
                }
                else
                {
                    Structures.Add(new VMFStructure(line, reader));
                }
            }
        }
        private VMFStructure(VMFStructure clone, int idOffset, int nodeOffset, TargetNameFixupStyle fixupStyle, String targetName,
                             List <KeyValuePair <String, String> > replacements, List <KeyValuePair <String, String> > matReplacements)
        {
            Type = clone.Type;

            Properties = new List <KeyValuePair <string, VMFValue> >();
            Structures = new List <VMFStructure>();

            myIDIndex = clone.myIDIndex;

            Dictionary <String, TransformType> entDict = stDefaultEntDict;

            if (Type == VMFStructureType.Entity)
            {
                String className = clone["classname"].String;
                if (className != null && stEntitiesDict.ContainsKey(className))
                {
                    entDict = stEntitiesDict[className];
                }
            }

            foreach (KeyValuePair <String, VMFValue> keyVal in clone.Properties)
            {
                String str   = keyVal.Value.String;
                bool   fixup = true;
                if (replacements != null && str.Contains("$"))
                {
                    fixup = false;
                    foreach (KeyValuePair <String, String> repKeyVal in replacements)
                    {
                        str = str.Replace(repKeyVal.Key, repKeyVal.Value);
                    }
                }

                KeyValuePair <String, VMFValue> kvClone;

                if (keyVal.Value is VMFVector3ArrayValue)
                {
                    kvClone = new KeyValuePair <string, VMFValue>(keyVal.Key, new VMFVector3ArrayValue()
                    {
                        String = str
                    });
                }
                else
                {
                    kvClone = new KeyValuePair <string, VMFValue>(keyVal.Key, VMFValue.Parse(str));
                }

                if (Type == VMFStructureType.Connections)
                {
                    if (fixupStyle != TargetNameFixupStyle.None && targetName != null)
                    {
                        String[] split = kvClone.Value.String.Split(',');
                        split[0] = FixupName(split[0], fixupStyle, targetName);
                        if (stInputsDict.ContainsKey(split[1]))
                        {
                            switch (stInputsDict[split[1]])
                            {
                            case TransformType.EntityName:
                                split[2] = FixupName(split[2], fixupStyle, targetName);
                                break;
                                // add more later
                            }
                        }
                        kvClone.Value.String = String.Join(",", split);
                    }
                }
                else
                {
                    if (Type == VMFStructureType.Side && matReplacements != null && kvClone.Key == "material")
                    {
                        var material = kvClone.Value.String;
                        foreach (KeyValuePair <String, String> repKeyVal in matReplacements)
                        {
                            if (material == repKeyVal.Key)
                            {
                                ((VMFStringValue)kvClone.Value).String = repKeyVal.Value;
                                break;
                            }
                        }
                    }
                    else if (kvClone.Key == "groupid")
                    {
                        ((VMFNumberValue)kvClone.Value).Value += idOffset;
                    }
                    else if (kvClone.Key == "nodeid")
                    {
                        ((VMFNumberValue)kvClone.Value).Value += nodeOffset;
                    }
                    else if (Type == VMFStructureType.Entity)
                    {
                        TransformType trans = entDict.ContainsKey(kvClone.Key) ? entDict[kvClone.Key] : TransformType.None;

                        if (trans == TransformType.Identifier)
                        {
                            kvClone.Value.OffsetIdentifiers(idOffset);
                        }
                        else if (fixup && (kvClone.Key == "targetname" || trans == TransformType.EntityName) && fixupStyle != TargetNameFixupStyle.None && targetName != null)
                        {
                            kvClone = new KeyValuePair <string, VMFValue>(kvClone.Key, new VMFStringValue {
                                String = FixupName(kvClone.Value.String, fixupStyle, targetName)
                            });
                        }
                    }
                }

                Properties.Add(kvClone);
            }

            foreach (VMFStructure structure in clone.Structures)
            {
                Structures.Add(new VMFStructure(structure, idOffset, nodeOffset, fixupStyle, targetName, replacements, matReplacements));
            }

            ID += idOffset;
        }