public static async Task <SpriteDocument> FromFile(string fileName)
        {
            string root   = ProjectHelpers.GetProjectFolder(fileName);
            string folder = Path.GetDirectoryName(root);

            if (folder == null || root == null)
            {
                return(null);
            }

            XDocument doc = null;

            string contents = await FileHelpers.ReadAllTextRetry(fileName);

            try
            {
                doc = XDocument.Parse(contents);
            }
            catch (XmlException)
            {
                return(null);
            }

            XElement element = null;

            IEnumerable <string> imageFiles = ProjectHelpers.GetBundleConstituentFiles(doc.Descendants("file").Select(s => s.Value), root, folder, fileName);

            SpriteDocument sprite = new SpriteDocument(fileName, imageFiles.ToArray());

            element = doc.Descendants("optimize").FirstOrDefault();

            if (element != null)
            {
                sprite.Optimize = element.Value.Equals("true", StringComparison.OrdinalIgnoreCase);
            }

            element = doc.Descendants("orientation").FirstOrDefault();

            if (element != null)
            {
                sprite.IsVertical = element.Value.Equals("vertical", StringComparison.OrdinalIgnoreCase);
            }

            element = doc.Descendants("runOnBuild").FirstOrDefault();

            if (element != null)
            {
                sprite.RunOnBuild = element.Value.Equals("true", StringComparison.OrdinalIgnoreCase);
            }

            element = doc.Descendants("outputType").FirstOrDefault();

            if (element != null)
            {
                sprite.FileExtension = element.Value;
            }

            element = doc.Descendants("fullPathForIdentifierName").FirstOrDefault();

            if (element != null)
            {
                sprite.UseFullPathForIdentifierName = element.Value.Equals("true", StringComparison.OrdinalIgnoreCase);
            }

            element = doc.Descendants("outputDirectory").FirstOrDefault();

            if (element != null)
            {
                sprite.OutputDirectory = element.Value;
            }

            element = doc.Descendants("useAbsoluteUrl").FirstOrDefault();

            if (element != null)
            {
                sprite.UseAbsoluteUrl = element.Value.Equals("true", StringComparison.OrdinalIgnoreCase);
            }

            element = doc.Descendants("outputDirectoryForCss").FirstOrDefault();

            if (element != null)
            {
                sprite.CssOutputDirectory = element.Value;
            }

            element = doc.Descendants("outputDirectoryForLess").FirstOrDefault();

            if (element != null)
            {
                sprite.LessOutputDirectory = element.Value;
            }

            element = doc.Descendants("outputDirectoryForScss").FirstOrDefault();

            if (element != null)
            {
                sprite.ScssOutputDirectory = element.Value;
            }

            return(sprite);
        }