private async Task PerformAnalysis(String path, Rectangle rectangle)
        {
            UShortArrayAsImage image = null;

            double[] pcaComponents = null;
            int      tasksComplete = 0;

            UpdateStatus(path, startingImageStatusStr);
            List <Task> tasks = new List <Task>()
            {
                new Task(() =>
                {
                    var file = db.FileStorage.FindById($"images/{path}");
                    var ms   = new MemoryStream();
                    file.CopyTo(ms);
                    ms.Seek(0, 0);
                    image = DicomFile.Open(ms).GetUshortImageInfo();

                    UpdateStatus(path, loadedImageStatusStr);
                }),
                new Task(() =>
                {
                    image = Normalization.GetNormalizedImage(image, rectangle,
                                                             int.Parse(Configuration.Get("sizeImageToAnalyze")));
                    db.FileStorage.Upload($"images/{path}-cropped", $"{path}-cropped",
                                          image.GetPngAsMemoryStream());

                    UpdateStatus(path, croppedImageStatusStr);
                }),
                new Task(() =>
                {
                    image = Contrast.ApplyHistogramEqualization(image);

                    db.FileStorage.Upload($"images/{path}-croppedContrast", $"{path}-croppedContrast",
                                          image.GetPngAsMemoryStream());

                    UpdateStatus(path, contrastImageStatusStr);
                }),
                new Task(() =>
                {
                    //PCA
                    PCA pca = PCA.LoadModelFromFile(Configuration.Get("PcaModelLocation"));

                    if (!int.TryParse(Configuration.Get("componentsToUse"), out int components))
                    {
                        components = pca.Eigenvalues.Length;
                    }
                    pcaComponents = pca.GetComponentsFromImage(image, components);
                    UpdateStatus(path, pcaImageStatusStr);
                }),
                new Task(() =>
                {
                    //SVM
                    SVMProblem svmProblem = new SVMProblem();

                    // add all the components to an SVMNode[]
                    SVMNode[] nodes = new SVMNode[pcaComponents.Length];
                    for (int i = 0; i < pcaComponents.Length; i++)
                    {
                        nodes[i] = new SVMNode(i + 1, pcaComponents[i]);
                    }

                    svmProblem.Add(nodes, 0);

                    svmProblem = svmProblem.Normalize(SVMNormType.L2);

                    SVMModel svmModel = SVM.LoadModel(Configuration.Get("ModelLocation"));

                    double[] results = svmProblem.PredictProbability(svmModel, out var probabilities);

                    var analysis              = db.GetCollection <Analysis>("analysis");
                    Analysis currentAnalysis  = analysis.FindOne(x => x.Id.ToString().Equals(path));
                    currentAnalysis.Certainty = results[0] == 0 ? probabilities[0][1] * 100 : probabilities[0][0] * 100;
                    currentAnalysis.Diagnosis = results[0] == 0
                        ? DdsmImage.Pathologies.Benign
                        : DdsmImage.Pathologies
                                                .Malignant;
                    analysis.Update(currentAnalysis);


                    UpdateStatus(path, svmImageStatusStr);
                })
            };

            foreach (Task task in tasks)
            {
                task.Start();
                await task;

                // lets set percentage done:
                var      analysis        = db.GetCollection <Analysis>("analysis");
                Analysis currentAnalysis = analysis.FindOne(x => x.Id.ToString().Equals(path));
                currentAnalysis.PercentageDone = (++tasksComplete * 100) / tasks.Count;
                analysis.Update(currentAnalysis);
            }

            UpdateStatus(path, doneStatusStr);
        }