public static bool ConnectToStorage(CloudMediaContext context, CredentialsEntry credentials)
 {
     try
     {
         CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(context.DefaultStorageAccount.Name, credentials.StorageKey), credentials.ReturnStorageSuffix(), true);
         CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
         return true;
     }
     catch (Exception e)
     {
         MessageBox.Show(string.Format("There is a problem when connecting to the Azure storage account.\r\nIs the storage key correct ?\r\n{0}", e.Message), "Storage Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
         return false;
     }
 }
        private async void ProcessExportAssetToAnotherAMSAccount(CredentialsEntry DestinationCredentialsEntry, string DestinationStorageAccount, Dictionary<string, string> storagekeys, List<IAsset> SourceAssets, string TargetAssetName, int index, bool DeleteSourceAssets = false, bool CopyDynEnc = false, bool ReWriteLAURL = false, bool CloneAssetFilters = false)
        {
            // If upload in the queue, let's wait our turn
            DoGridTransferWaitIfNeeded(index);

            CloudMediaContext DestinationContext = Program.ConnectAndGetNewContext(DestinationCredentialsEntry);
            IAsset TargetAsset = DestinationContext.Assets.Create(TargetAssetName, DestinationStorageAccount, AssetCreationOptions.None);

            // let's backup the primary file from the first asset to set it to the copied/merged asset
            var ismAssetFile = SourceAssets.FirstOrDefault().AssetFiles.ToList().Where(f => f.IsPrimary).ToArray();

            bool ErrorCopyAsset = false;

            TextBoxLogWriteLine("Starting the asset copy process.");

            // let's get cloudblobcontainer for target
            CloudStorageAccount DestinationCloudStorageAccount =
                (DestinationStorageAccount == null) ?
                new CloudStorageAccount(new StorageCredentials(DestinationContext.DefaultStorageAccount.Name, storagekeys[DestinationContext.DefaultStorageAccount.Name]), DestinationCredentialsEntry.ReturnStorageSuffix(), true) :
                new CloudStorageAccount(new StorageCredentials(DestinationStorageAccount, storagekeys[DestinationStorageAccount]), DestinationCredentialsEntry.ReturnStorageSuffix(), true);

            var DestinationCloudBlobClient = DestinationCloudStorageAccount.CreateCloudBlobClient();
            IAccessPolicy writePolicy = DestinationContext.AccessPolicies.Create("writepolicy", TimeSpan.FromDays(1), AccessPermissions.Write);
            ILocator DestinationLocator = DestinationContext.Locators.CreateLocator(LocatorType.Sas, TargetAsset, writePolicy);

            // Get the asset container URI and copy blobs from mediaContainer to assetContainer.
            Uri targetUri = new Uri(DestinationLocator.Path);
            CloudBlobContainer DestinationCloudBlobContainer = DestinationCloudBlobClient.GetContainerReference(targetUri.Segments[1]);

            foreach (IAsset SourceAsset in SourceAssets) // there are several assets only if user wants to do a copy with merge
            {
                if (storagekeys.ContainsKey(SourceAsset.StorageAccountName))
                {
                    // let's get cloudblobcontainer for source
                    CloudStorageAccount SourceCloudStorageAccount = new CloudStorageAccount(new StorageCredentials(SourceAsset.StorageAccountName, storagekeys[SourceAsset.StorageAccountName]), _credentials.ReturnStorageSuffix(), true);
                    var SourceCloudBlobClient = SourceCloudStorageAccount.CreateCloudBlobClient();
                    IAccessPolicy readpolicy = _context.AccessPolicies.Create("readpolicy", TimeSpan.FromDays(1), AccessPermissions.Read);
                    ILocator SourceLocator = _context.Locators.CreateLocator(LocatorType.Sas, SourceAsset, readpolicy);

                    // Get the asset container URI and copy blobs from mediaContainer to assetContainer.
                    Uri sourceUri = new Uri(SourceLocator.Path);
                    CloudBlobContainer SourceCloudBlobContainer = SourceCloudBlobClient.GetContainerReference(sourceUri.Segments[1]);

                    ErrorCopyAsset = false;
                    CloudBlockBlob sourceCloudBlockBlob, destinationCloudBlockBlob;
                    long Length = 0;
                    long BytesCopied = 0;
                    double percentComplete = 0;

                    //calculate size
                    foreach (IAssetFile file in SourceAsset.AssetFiles)
                    {
                        Length += file.ContentFileSize;
                    }
                    if (Length == 0) Length = 1; // as this could happen with Live archive and create a divide error

                    // do the copy
                    int nbblob = 0;


                    // foreach (IAssetFile file in SourceAsset.AssetFiles) 
                    // For LIve archive, the folder for chiks are returnbed as files. So we detect this case and don't try to copy the folders as asset files
                    IEnumerable<IAssetFile> assetFilesToCopy = SourceAsset.AssetFiles.ToList();
                    if (
                        assetFilesToCopy.Where(af => af.Name.Contains(".")).Count() == 2
                        && assetFilesToCopy.Where(af => af.Name.ToUpper().EndsWith(".ISMC")).Count() == 1
                        && assetFilesToCopy.Where(af => af.Name.ToUpper().EndsWith(".ISM")).Count() == 1
                        ) // only 2 files with extensions, and these files are ISMC and ISM
                    {
                        assetFilesToCopy = SourceAsset.AssetFiles.ToList().Where(af => !af.Name.StartsWith("audio_") && !af.Name.StartsWith("video_") && !af.Name.StartsWith("scte35_"));
                        var assetFilesLiveFolders = SourceAsset.AssetFiles.ToList().Where(af => af.Name.StartsWith("audio_") || af.Name.StartsWith("video_") || af.Name.StartsWith("scte35_"));

                        foreach (IAssetFile sourcefolder in assetFilesLiveFolders)
                        {
                            var folder = TargetAsset.AssetFiles.Create(sourcefolder.Name);
                            folder.ContentFileSize = sourcefolder.ContentFileSize;
                            folder.MimeType = sourcefolder.MimeType;
                            folder.Update();
                        }
                    }
                    foreach (IAssetFile file in assetFilesToCopy)
                    {
                        if (file.IsEncrypted)
                        {
                            TextBoxLogWriteLine("   Cannot copy file '{0}' because it is encrypted.", file.Name, true);
                        }
                        else
                        {
                            bool ErrorCopyAssetFile = false;
                            nbblob++;

                            try
                            {
                                sourceCloudBlockBlob = SourceCloudBlobContainer.GetBlockBlobReference(file.Name);
                                // TO DO: chek if this is a folder or a file
                                sourceCloudBlockBlob.FetchAttributes();

                                if (sourceCloudBlockBlob.Properties.Length > 0)
                                {
                                    if (!TargetAsset.AssetFiles.ToList().Any(f => f.Name == file.Name))  // file does not exist in the target asset
                                    {
                                        IAssetFile destinationAssetFile = TargetAsset.AssetFiles.Create(file.Name);
                                        destinationCloudBlockBlob = DestinationCloudBlobContainer.GetBlockBlobReference(destinationAssetFile.Name);

                                        try
                                        {
                                            destinationCloudBlockBlob.DeleteIfExists();
                                        }
                                        catch
                                        {
                                            // exception if Blob does not exist, which is fine
                                        }
                                        destinationCloudBlockBlob.StartCopy(file.GetSasUri());

                                        CloudBlockBlob blob;
                                        blob = (CloudBlockBlob)DestinationCloudBlobContainer.GetBlobReferenceFromServer(file.Name);

                                        while (blob.CopyState.Status == CopyStatus.Pending)
                                        {
                                            Task.Delay(TimeSpan.FromSeconds(0.5d)).Wait();
                                            blob.FetchAttributes();
                                            percentComplete = (Convert.ToDouble(nbblob) / Convert.ToDouble(SourceAsset.AssetFiles.Count())) * 100d * (long)(BytesCopied + blob.CopyState.BytesCopied) / Length;
                                            DoGridTransferUpdateProgressText(string.Format("File '{0}'", file.Name), (int)percentComplete, index);
                                        }

                                        if (blob.CopyState.Status == CopyStatus.Failed)
                                        {
                                            DoGridTransferDeclareError(index, blob.CopyState.StatusDescription);
                                            ErrorCopyAssetFile = true;
                                            ErrorCopyAsset = true;
                                            break;
                                        }

                                        destinationCloudBlockBlob.FetchAttributes();
                                        destinationAssetFile.ContentFileSize = sourceCloudBlockBlob.Properties.Length;
                                        destinationAssetFile.Update();

                                        if (sourceCloudBlockBlob.Properties.Length != destinationCloudBlockBlob.Properties.Length)
                                        {
                                            DoGridTransferDeclareError(index, "Error during blob copy.");
                                            ErrorCopyAssetFile = true;
                                            ErrorCopyAsset = true;
                                            break;
                                        }

                                        BytesCopied += sourceCloudBlockBlob.Properties.Length;
                                        percentComplete = (long)100 * (long)BytesCopied / (long)Length;
                                    }
                                    else // file already exists.Can occur with merge function
                                    {
                                        TextBoxLogWriteLine("Failed to copy file '{0} as file already exists in the destination asset.", file.Name, true);
                                        ErrorCopyAssetFile = true;
                                    }

                                }
                            }
                            catch (Exception ex)
                            {
                                TextBoxLogWriteLine("Failed to copy file '{0}'", file.Name, true);
                                DoGridTransferDeclareError(index, ex);
                                ErrorCopyAsset = true;
                                ErrorCopyAssetFile = true;
                            }
                            if (!ErrorCopyAssetFile) TextBoxLogWriteLine("File '{0}' copied.", file.Name);
                        }

                    }

                    if (!ErrorCopyAsset) // let's do the copy of additional fragblob if there are
                    {
                        List<CloudBlobDirectory> ListDirectories = new List<CloudBlobDirectory>();
                        // do the copy
                        nbblob = 0;
                        DoGridTransferUpdateProgressText(string.Format("fragblobs", SourceAsset.Name, DestinationCredentialsEntry.AccountName), 0, index);
                        try
                        {
                            var mediablobs = SourceCloudBlobContainer.ListBlobs();
                            if (mediablobs.ToList().Any(b => b.GetType() == typeof(CloudBlobDirectory))) // there are fragblobs
                            {
                                List<Task> mylistresults = new List<Task>();

                                foreach (var blob in mediablobs)
                                {
                                    if (blob.GetType() == typeof(CloudBlobDirectory))
                                    {
                                        CloudBlobDirectory blobdir = (CloudBlobDirectory)blob;
                                        ListDirectories.Add(blobdir);
                                        TextBoxLogWriteLine("Fragblobs detected (live archive) '{0}'.", blobdir.Prefix);
                                    }
                                    else if (blob.GetType() == typeof(CloudBlockBlob))
                                    {
                                        // we must copy the file.ismc too
                                        var blockblob = (CloudBlockBlob)blob;
                                        if (blockblob.Name.EndsWith(".ismc") && !SourceAsset.AssetFiles.ToList().Any(f => f.Name == blockblob.Name)) // if there is a .ismc in the blov and not in the asset files, then we need to copy it
                                        {
                                            CloudBlockBlob targetBlob = DestinationCloudBlobContainer.GetBlockBlobReference(blockblob.Name);
                                            // copy using src blob as SAS
                                            mylistresults.Add(targetBlob.StartCopyAsync(new Uri(blockblob.Uri.AbsoluteUri + SourceLocator.ContentAccessComponent)));
                                        }
                                    }
                                }
                                // let's launch the copy of fragblobs
                                double ind = 0;
                                foreach (var dir in ListDirectories)
                                {
                                    TextBoxLogWriteLine("Copying fragblobs directory '{0}'....", dir.Prefix);

                                    mylistresults.AddRange(AssetInfo.CopyBlobDirectory(dir, DestinationCloudBlobContainer, SourceLocator.ContentAccessComponent));//blobToken));
                                    if (mylistresults.Count > 0)
                                    {
                                        while (!mylistresults.All(r => r.IsCompleted))
                                        {
                                            Task.Delay(TimeSpan.FromSeconds(3d)).Wait();
                                            percentComplete = 100d * (ind + Convert.ToDouble(mylistresults.Where(c => c.IsCompleted).Count()) / Convert.ToDouble(mylistresults.Count)) / Convert.ToDouble(ListDirectories.Count);
                                            DoGridTransferUpdateProgressText(string.Format("fragblobs directory '{0}' ({1}/{2})", dir.Prefix, mylistresults.Where(r => r.IsCompleted).Count(), mylistresults.Count), (int)percentComplete, index);
                                        }
                                    }
                                    ind++;
                                    mylistresults.Clear();
                                }

                            }
                        }
                        catch (Exception ex)
                        {
                            TextBoxLogWriteLine("Failed to copy live fragblobs", true);
                            TextBoxLogWriteLine(ex);
                            DoGridTransferDeclareError(index, ex);
                            ErrorCopyAsset = true;
                        }
                    }

                    SourceLocator.Delete();
                    readpolicy.Delete();
                }
                else
                {
                    TextBoxLogWriteLine("Error storage key not found for asset '{0}'.", SourceAsset.Name, true);
                    ErrorCopyAsset = true;
                }
            }

            // let's set the primary file
            if (ismAssetFile.Count() > 0)
            {
                AssetInfo.SetFileAsPrimary(TargetAsset, ismAssetFile.FirstOrDefault().Name);
            }
            else
            {
                AssetInfo.SetISMFileAsPrimary(TargetAsset);
            }


            // Copy Dynamic Encryption
            if (CopyDynEnc && !ErrorCopyAsset)
            {
                TextBoxLogWriteLine("Dynamic encryption settings copy...");
                try
                {
                    await DynamicEncryption.CopyDynamicEncryption(SourceAssets.FirstOrDefault(), TargetAsset, ReWriteLAURL);
                    TextBoxLogWriteLine("Dynamic encryption settings copied.");

                }
                catch (Exception ex)
                {
                    TextBoxLogWriteLine("Error when copying Dynamic encryption", true);
                    TextBoxLogWriteLine(ex);
                }
            }

            // Copy filters
            if (CloneAssetFilters && !ErrorCopyAsset && SourceAssets.FirstOrDefault().AssetFilters.Count() > 0)
            {
                try
                {
                    TextBoxLogWriteLine("Copying filter(s) to cloned asset '{0}'", SourceAssets.FirstOrDefault().Name);

                    foreach (var filter in SourceAssets.FirstOrDefault().AssetFilters)
                    {
                        TargetAsset.AssetFilters.Create(filter.Name, filter.PresentationTimeRange, filter.Tracks);
                        TextBoxLogWriteLine(string.Format("Cloned filter {0} created.", filter.Name));
                    }
                }
                catch (Exception ex)
                {
                    // Add useful information to the exception
                    TextBoxLogWriteLine("There is a problem when copying filter(s) to the asset '{0}'.", TargetAsset.Name, true);
                    TextBoxLogWriteLine(ex);
                }
            }

            DestinationLocator.Delete();
            writePolicy.Delete();

            if (!ErrorCopyAsset)
            {
                if (DeleteSourceAssets) SourceAssets.ForEach(a => a.Delete());
                TextBoxLogWriteLine("Asset copy completed. The new asset in '{0}' has the Id :", DestinationCredentialsEntry.AccountName);
                TextBoxLogWriteLine(TargetAsset.Id);
                DoGridTransferDeclareCompleted(index, DestinationCloudBlobContainer.Uri.AbsoluteUri);
            }
            DoRefreshGridAssetV(false);
        }