/// <summary>
        /// Parses an entityDef into an EntityDef object
        /// </summary>
        /// <param name="entityDefText">text containing the entityDef</param>
        /// <param name="currentLineNumber">current line number reference in the file</param>
        /// <returns>an EntityDef object containing the parsed data from the entityDef</reurns>
        internal EntityDef ParseEntityDef(string entityDefText, ref int currentLineNumber)
        {
            EntityDef             entityDef        = new EntityDef();
            List <EntityProperty> entityProperties = new List <EntityProperty>();

            // Split the entity definition into lines
            string[] entityDefTextLines = entityDefText.Split('\n');
            currentLineNumber -= entityDefTextLines.Length - 1;

            for (int i = 0; i < entityDefTextLines.Length; i++)
            {
                if (i > 0)
                {
                    currentLineNumber++;
                }

                entityDefTextLines[i] = entityDefTextLines[i].Trim();

                // The entityDef declaration is in the first line and contains its name
                if (i == 0)
                {
                    string[] entityDefParts = entityDefTextLines[i].Split(' ');

                    if (!entityDefParts[0].Equals("entityDef") && !entityDefParts[0].Equals("entityDef{"))
                    {
                        Errors.Add(string.Format("Line {0}: unknown type '{1}'", currentLineNumber, entityDefParts[0]));
                        return(null);
                    }

                    // The bracket could be next to the entityDef name so we have to check that
                    if (entityDefParts.Length == 1)
                    {
                        Errors.Add(string.Format("Line {0}: missing entityDef name", currentLineNumber));
                        return(null);
                    }
                    else if (entityDefParts.Length == 2)
                    {
                        if (entityDefParts[1].Equals("{"))
                        {
                            Errors.Add(string.Format("Line {0}: missing entityDef name", currentLineNumber));
                            return(null);
                        }
                        else if (entityDefParts[1][entityDefParts[1].Length - 1] != '{')
                        {
                            Errors.Add(string.Format("Line {0}: missing '{{'", currentLineNumber));
                            return(null);
                        }
                        else if (!IsValidEntityDefName(entityDefParts[1].Remove(entityDefParts[1].Length - 1, 1)))
                        {
                            Errors.Add(string.Format("Line {0}: invalid entityDef name '{1}'",
                                                     currentLineNumber, entityDefParts[1].Remove(entityDefParts[1].Length - 1, 1)));

                            return(null);
                        }
                        else
                        {
                            entityDef.Name = entityDefParts[1].Remove(entityDefParts[1].Length - 1, 1);
                        }
                    }
                    else if (entityDefParts.Length == 3)
                    {
                        if (!entityDefParts[2].Equals("{"))
                        {
                            Errors.Add(string.Format("Line {0}: missing '{{'", currentLineNumber));
                            return(null);
                        }
                        else if (!IsValidEntityDefName(entityDefParts[1]))
                        {
                            Errors.Add(string.Format("Line {0}: invalid entityDef name '{1}'", currentLineNumber, entityDefParts[1]));
                            return(null);
                        }
                        else
                        {
                            entityDef.Name = entityDefParts[1];
                        }
                    }
                    else
                    {
                        Errors.Add(string.Format("Line {0}: expected entityDef declaration not found", currentLineNumber, entityDefTextLines[i]));
                        return(null);
                    }

                    continue;
                }

                // Everything inside the entityDef must be a property of some kind
                EntityProperty entityProperty = null;

                // We will get all the text of the property and pass it to the property parser
                string[] propertyText = entityDefTextLines[i].Split('=');

                if (propertyText.Length != 2)
                {
                    if (entityDefTextLines[i].Equals("{") || entityDefTextLines[i].Equals("}"))
                    {
                        continue;
                    }
                    else
                    {
                        Errors.Add(string.Format("Line {0}: unexpected '{1}'", currentLineNumber, entityDefTextLines[i]));
                        continue;
                    }
                }

                propertyText[0] = propertyText[0].TrimEnd();
                propertyText[1] = propertyText[1].Trim();

                // First we need to determine which kind of property this is to get all it's text
                // This is probably a "single-line" property, so we can just pass the whole line to the property parser
                if (propertyText[1][propertyText[1].Length - 1] != '{')
                {
                    try
                    {
                        entityProperty = ParseEntityProperty(entityDefTextLines[i], ref currentLineNumber);
                    }
                    catch (FormatException)
                    {
                        throw;
                    }
                }
                else
                {
                    // Check if the "Important" flag is present
                    if (propertyText[1].Length > 1 && propertyText[1][0] == '!')
                    {
                        entityProperty.Important = true;
                    }

                    // This is either an object or an array, so we'll just get the whole block
                    // to pass it to the property parser
                    StringBuilder currentPropertyText = new StringBuilder();
                    int           openingBracketCount = 1;
                    int           closingBracketCount = 0;

                    currentPropertyText.Append(entityDefTextLines[i]).Append("\n");
                    currentLineNumber++;

                    // Get everything until the block is closed
                    for (int j = i + 1; j < entityDefTextLines.Length; j++, currentLineNumber++, i = j)
                    {
                        if (string.IsNullOrEmpty(entityDefTextLines[j]))
                        {
                            continue;
                        }

                        if (entityDefTextLines[j][entityDefTextLines[j].Length - 1] == '{')
                        {
                            openingBracketCount++;
                            currentPropertyText.Append(entityDefTextLines[j]).Append("\n");
                            continue;
                        }

                        if (entityDefTextLines[j][entityDefTextLines[j].Length - 1] == '}')
                        {
                            closingBracketCount++;
                        }

                        if (openingBracketCount == closingBracketCount)
                        {
                            currentPropertyText.Append(entityDefTextLines[j]);
                            break;
                        }

                        currentPropertyText.Append(entityDefTextLines[j]).Append("\n");
                    }

                    entityProperty = ParseEntityProperty(currentPropertyText.ToString(), ref currentLineNumber);
                    currentPropertyText.Clear();
                }

                if (entityProperty != null)
                {
                    entityProperties.Add(entityProperty);
                }
            }

            entityDef.Properties = entityProperties;
            return(entityDef);
        }
        /// <summary>
        /// Parses an entity
        /// </summary>
        /// <param name="entityText">text block containing the entity</param>
        /// <param name="currentLineNumber">current line number reference in the file</param>
        /// <returns>an Entity object with the parsed data from the entity</returns>
        internal Entity ParseEntity(string entityText, ref int currentLineNumber)
        {
            // Split the entity definition into lines
            string[] entityTextLines = entityText.Split('\n');
            currentLineNumber -= entityTextLines.Length - 1;

            Entity    entity    = new Entity();
            EntityDef entityDef = null;

            for (int i = 0; i < entityTextLines.Length; i++)
            {
                entityTextLines[i] = entityTextLines[i].Trim();

                if (i > 0)
                {
                    currentLineNumber++;
                }

                // Parse the layers
                if (entityTextLines[i].Equals("layers {") || entityTextLines[i].Equals("layers{"))
                {
                    i++;
                    entity.Layers = new List <EntityPropertyStringValue>();

                    while (!entityTextLines[i].Trim().Equals("}"))
                    {
                        try
                        {
                            var layer = (EntityPropertyStringValue)ParseEntityPropertyValue(entityTextLines[i++].Trim(), ref currentLineNumber);

                            if (layer != null)
                            {
                                entity.Layers.Add(layer);
                            }

                            currentLineNumber++;
                        }
                        catch (FormatException)
                        {
                            throw;
                        }
                    }

                    // Closing bracket
                    currentLineNumber++;
                }
                else if (entityTextLines[i].Contains("originalName"))
                {
                    // Look for "originalName" and "instanceId" properties
                    string[] originalNameParts = entityTextLines[i].Split('=');

                    if (originalNameParts.Length != 2)
                    {
                        Errors.Add(string.Format("Line {0}: bad property declaration '{1}'", currentLineNumber, entityTextLines[i]));
                        continue;
                    }

                    if (entityTextLines[i][entityTextLines[i].Length - 1] != ';')
                    {
                        Errors.Add(string.Format("Line {0}: missing ';'", currentLineNumber));
                        continue;
                    }

                    entity.OriginalName = (EntityPropertyStringValue)ParseEntityPropertyValue(originalNameParts[1].Remove(originalNameParts[1].Length - 1, 1).Trim(), ref currentLineNumber);
                }
                else if (entityTextLines[i].Contains("instanceId"))
                {
                    string[] instanceIdParts = entityTextLines[i].Split('=');

                    if (instanceIdParts.Length != 2)
                    {
                        Errors.Add(string.Format("Line {0}: bad property declaration '{1}'", currentLineNumber, entityTextLines[1]));
                        continue;
                    }

                    if (entityTextLines[i][entityTextLines[i].Length - 1] != ';')
                    {
                        Errors.Add(string.Format("Line {0}: missing ';'", currentLineNumber));
                        continue;
                    }

                    entity.InstanceId = (EntityPropertyLongValue)ParseEntityPropertyValue(instanceIdParts[1].Remove(instanceIdParts[1].Length - 1, 1).Trim(), ref currentLineNumber);
                }
                else if (entityTextLines[i].Contains("entityDef"))
                {
                    // Get the entityDef block and parse it
                    if (entityTextLines[i][entityTextLines[i].Length - 1] != '{')
                    {
                        Errors.Add(string.Format("Line {0}: missing '{{'", currentLineNumber));
                        continue;
                    }

                    StringBuilder entityDefText       = new StringBuilder();
                    int           openingBracketCount = 1;
                    int           closingBracketCount = 0;

                    // Append the first entityDef line, which opens the block
                    entityDefText.Append(entityTextLines[i]).Append("\n");

                    // Get everything until the block is closed
                    for (int j = i + 1; j < entityTextLines.Length; j++, currentLineNumber++, i = j)
                    {
                        if (string.IsNullOrEmpty(entityTextLines[j]))
                        {
                            continue;
                        }

                        if (entityTextLines[j][entityTextLines[j].Length - 1] == '{')
                        {
                            openingBracketCount++;
                            entityDefText.Append(entityTextLines[j]).Append("\n");
                            continue;
                        }

                        if (entityTextLines[j][entityTextLines[j].Length - 1] == '}')
                        {
                            closingBracketCount++;
                        }

                        if (openingBracketCount == closingBracketCount)
                        {
                            entityDefText.Append(entityTextLines[j]);
                            currentLineNumber++;
                            break;
                        }

                        entityDefText.Append(entityTextLines[j]).Append("\n");
                    }

                    entityDef = ParseEntityDef(entityDefText.ToString(), ref currentLineNumber);
                    entityDefText.Clear();
                }
                else if (!entityTextLines[i].Equals("entity{") && !entityTextLines[i].Equals("entity {") &&
                         !entityTextLines[i].Equals("{") && !entityTextLines[i].Equals("}"))
                {
                    Errors.Add(string.Format("Line {0}: unexpected '{1}' inside entity definition", currentLineNumber, entityTextLines[i]));
                    continue;
                }
            }

            entity.EntityDef = entityDef;
            return(entity);
        }