static void UploadDirectoryToProject(OneSky.Project project, DirectoryInfo directory, string fileExtension)
    {
        foreach (var file in Directory.GetFiles(directory.FullName, fileExtension, SearchOption.AllDirectories))
        {
            DirectoryInfo parentDirectory = Directory.GetParent(file);
            string localeName = parentDirectory.Name;
            string currentFile = file;

            using (var fileStream = File.OpenRead(currentFile))
            {
                // Read the BOM
                var bom = new byte[3];
                fileStream.Read(bom, 0, 3);

                //We want to ignore the utf8 BOM
                if (bom[0] != 0xef || bom[1] != 0xbb || bom[2] != 0xbf)
                {
                    fileStream.Position = 0;
                }

                Console.WriteLine("Uploading: " + currentFile + " Locale: " + localeName);
                var uploadedFile = project.Upload(Path.GetFileName(currentFile), fileStream, new CultureInfo(OneSky.LocaleCodeHelper.ConvertFromLocaleCode(localeName))).Result;

                if (uploadedFile == null)
                {
                    Console.WriteLine("[FAILED] Uploading: " + currentFile + " Locale: " + localeName);
                }
                else
                {
                    Console.WriteLine("[SUCCESS] Uploading: " + currentFile + " Locale: " + localeName);
                }
            }
        }
    }
    static void UploadDirectoryToProject(OneSky.Project project, DirectoryInfo directory, string fileExtension)
    {
        DirectoryInfo[] cultureDirectories = directory.GetDirectories("*", SearchOption.TopDirectoryOnly);

        // Upload, synchronously, the base culture POs.
        DirectoryInfo nativeCultureDirectory = Array.Find(cultureDirectories, d => { return string.Equals(d.Name, project.BaseCultureName, StringComparison.InvariantCultureIgnoreCase); });
        if (nativeCultureDirectory != null)
        {
            string[] files = Directory.GetFiles(nativeCultureDirectory.FullName, fileExtension, SearchOption.AllDirectories);
            UploadFilesToProjectForLocale(project, files, nativeCultureDirectory.Name);
        }

        // Upload all other POs asynchronously.
        foreach (var foreignCultureDirectory in Array.FindAll(cultureDirectories, d => { return d != nativeCultureDirectory; }))
        {
            string[] files = Directory.GetFiles(foreignCultureDirectory.FullName, fileExtension, SearchOption.AllDirectories);
            UploadFilesToProjectForLocale(project, files, foreignCultureDirectory.Name);
        }
    }
	private void UploadFileToOneSky(OneSky.Project OneSkyProject, FileInfo FileToUpload, string Culture)
	{
		using (var FileStream = FileToUpload.OpenRead())
		{
			// Read the BOM
			var UTF8BOM = new byte[3];
			FileStream.Read(UTF8BOM, 0, 3);

			// We want to ignore the utf8 BOM
			if (UTF8BOM[0] != 0xef || UTF8BOM[1] != 0xbb || UTF8BOM[2] != 0xbf)
			{
				FileStream.Position = 0;
			}

			var OneSkyFileName = GetOneSkyFilename(Path.GetFileName(FileToUpload.FullName));

			Console.WriteLine("Uploading: '{0}' as '{1}' ({2})", FileToUpload.FullName, OneSkyFileName, Culture);

			var UploadedFile = UploadOneSkyTranslationWithRetry(OneSkyProject, OneSkyFileName, Culture, FileStream);

			if (UploadedFile == null)
			{
				Console.WriteLine("[FAILED] Uploading: '{0}' ({1})", FileToUpload.FullName, Culture);
			}
			else
			{
				Console.WriteLine("[SUCCESS] Uploading: '{0}' ({1})", FileToUpload.FullName, Culture);
			}
		}
	}
    static void UploadFilesToProjectForLocale(OneSky.Project project, string[] files, string localeName)
    {
        foreach (var currentFile in files)
        {
            using (var fileStream = File.OpenRead(currentFile))
            {
                // Read the BOM
                var bom = new byte[3];
                fileStream.Read(bom, 0, 3);

                //We want to ignore the utf8 BOM
                if (bom[0] != 0xef || bom[1] != 0xbb || bom[2] != 0xbf)
                {
                    fileStream.Position = 0;
                }

                Console.WriteLine("Uploading: " + currentFile + " Locale: " + localeName);
                var uploadedFile = project.Upload(Path.GetFileName(currentFile), fileStream, localeName).Result;
                
                if (uploadedFile == null)
                {
                    Console.WriteLine("[FAILED] Uploading: " + currentFile + " Locale: " + localeName);
                }
                else
                {
                    Console.WriteLine("[SUCCESS] Uploading: " + currentFile + " Locale: " + localeName);                    
                }
            }
        }
    }
	private UploadedFile UploadOneSkyTranslationWithRetry(OneSky.Project OneSkyProject, string OneSkyFileName, string Culture, FileStream FileStream)
	{
		const int MAX_COUNT = 3;

		long StartingFilePos = FileStream.Position;
		int Count = 0;
		for (;;)
		{
			try
			{
				return OneSkyProject.Upload(OneSkyFileName, FileStream, Culture).Result;
			}
			catch (Exception)
			{
				if (++Count < MAX_COUNT)
				{
					FileStream.Position = StartingFilePos;
					Console.WriteLine("UploadOneSkyTranslation attempt {0}/{1} failed. Retrying...", Count, MAX_COUNT);
					continue;
				}

				Console.WriteLine("UploadOneSkyTranslation attempt {0}/{1} failed.", Count, MAX_COUNT);
				break;
			}
		}

		return null;
	}