The subsequence importer.
Inheritance: IDisposable
        public ActionResult Index(long matterId)
        {
            return Action(() =>
            {
                string matterName;
                Subsequence[] sequenceSubsequences;
                using (var db = new LibiadaWebEntities())
                {
                    long parentSequenceId = db.DnaSequence.Single(d => d.MatterId == matterId).Id;
                    DnaSequence parentSequence = db.DnaSequence.Single(c => c.Id == parentSequenceId);

                    var features = NcbiHelper.GetFeatures(parentSequence.RemoteId);
                    using (var subsequenceImporter = new SubsequenceImporter(features, parentSequenceId))
                    {
                        subsequenceImporter.CreateSubsequences();
                    }

                    matterName = db.Matter.Single(m => m.Id == matterId).Name;
                    sequenceSubsequences = db.Subsequence.Where(s => s.SequenceId == parentSequenceId)
                                                         .Include(s => s.Position)
                                                         .Include(s => s.Feature)
                                                         .Include(s => s.SequenceAttribute)
                                                         .ToArray();
                }

                return new Dictionary<string, object>
                                     {
                                         { "matterName", matterName },
                                         { "genes", sequenceSubsequences }
                                     };
            });
        }
        public ActionResult Index(long[] matterIds)
        {
            return Action(() =>
                {
                    string[] matterNames;
                    string[] results = new string[matterIds.Length];
                    string[] statuses = new string[matterIds.Length];
                    using (var db = new LibiadaWebEntities())
                    {
                        matterNames = db.Matter.Where(m => matterIds.Contains(m.Id)).OrderBy(m => m.Id).Select(m => m.Name).ToArray();
                        var parentSequences = db.DnaSequence.Where(c => matterIds.Contains(c.MatterId)).OrderBy(c => c.MatterId);
                        long[] parentSequenceIds = parentSequences.Select(c => c.Id).ToArray();
                        string[] parentRemoteIds = parentSequences.Select(c => c.RemoteId).ToArray();
                        var features = NcbiHelper.GetFeatures(parentRemoteIds);

                        for (int i = 0; i < matterIds.Length; i++)
                        {
                            try
                            {
                                var parentSequenceId = parentSequenceIds[i];
                                using (var subsequenceImporter = new SubsequenceImporter(features[i], parentSequenceId))
                                {
                                    subsequenceImporter.CreateSubsequences();
                                }

                                var nonCodingCount = db.Subsequence.Count(s => s.SequenceId == parentSequenceId && s.FeatureId == Aliases.Feature.NonCodingSequence);
                                var featuresCount = db.Subsequence.Count(s => s.SequenceId == parentSequenceId && s.FeatureId != Aliases.Feature.NonCodingSequence);

                                statuses[i] = "Success";
                                results[i] = "Successfully imported " + featuresCount + " features and " + nonCodingCount + " non coding subsequences";
                            }
                            catch (Exception exception)
                            {
                                statuses[i] = "Error";
                                results[i] = exception.Message;
                                if (exception.InnerException != null)
                                {
                                    results[i] += " " + exception.InnerException.Message;
                                }
                            }
                        }
                    }

                    return new Dictionary<string, object>
                           {
                               { "matterNames", matterNames },
                               { "results", results },
                               { "status", statuses }
                           };
                });
        }
        public ActionResult Index(string[] accessions, bool importGenes)
        {
            return Action(() =>
            {
                var matterNames = new string[accessions.Length];
                var savedMatterNames = new string[accessions.Length];
                var results = new string[accessions.Length];
                var statuses = new string[accessions.Length];

                using (var db = new LibiadaWebEntities())
                {
                    var existingAccessions = db.DnaSequence.Select(d => d.RemoteId).Distinct().ToArray();
                    var dnaSequenceRepository = new DnaSequenceRepository(db);
                    var bioSequences = NcbiHelper.GetGenBankSequences(accessions);

                    for (int i = 0; i < accessions.Length; i++)
                    {
                        string accession = accessions[i];
                        matterNames[i] = accession;
                        if (existingAccessions.Contains(accession) || existingAccessions.Contains(accession + ".1"))
                        {
                            results[i] = "Sequence already exists";
                            statuses[i] = "Exist";
                            continue;
                        }

                        try
                        {
                            var metadata = NcbiHelper.GetMetadata(bioSequences[i]);
                            if (existingAccessions.Contains(metadata.Version.CompoundAccession))
                            {
                                results[i] = "Sequence already exists";
                                statuses[i] = "Exist";
                                continue;
                            }

                            savedMatterNames[i] = NcbiHelper.ExtractSequenceName(metadata) + " | " + metadata.Version.CompoundAccession;
                            matterNames[i] = "Common name=" + metadata.Source.CommonName +
                                             ", Species=" + metadata.Source.Organism.Species +
                                             ", Definition=" + metadata.Definition +
                                             ", Saved matter name=" + savedMatterNames[i];

                            var matter = new Matter
                                             {
                                                 Name = savedMatterNames[i],
                                                 Nature = Nature.Genetic,
                                                 Group = GroupRepository.ExtractSequenceGroup(savedMatterNames[i]),
                                                 SequenceType = SequenceTypeRepsitory.ExtractSequenceGroup(savedMatterNames[i])
                                             };

                            var sequence = new CommonSequence
                                               {
                                                   Matter = matter,
                                                   NotationId = Aliases.Notation.Nucleotide,
                                                   RemoteDbId = Aliases.RemoteDb.RemoteDbNcbi,
                                                   RemoteId = metadata.Version.CompoundAccession
                                               };

                            dnaSequenceRepository.Create(sequence, bioSequences[i], metadata.Definition.ToLower().Contains("partial"));
                            if (importGenes)
                            {
                                try
                                {
                                    using (var subsequenceImporter = new SubsequenceImporter(metadata.Features.All, sequence.Id))
                                    {
                                        subsequenceImporter.CreateSubsequences();
                                    }

                                    var nonCodingCount = db.Subsequence.Count(s => s.SequenceId == sequence.Id && s.FeatureId == Aliases.Feature.NonCodingSequence);
                                    var featuresCount = db.Subsequence.Count(s => s.SequenceId == sequence.Id && s.FeatureId != Aliases.Feature.NonCodingSequence);

                                    statuses[i] = "Success";
                                    results[i] = "Successfully imported  sequence and " + featuresCount + " features and " + nonCodingCount + " non coding subsequences";
                                }
                                catch (Exception exception)
                                {
                                    results[i] = "successfully imported sequence but failed to import genes: " + exception.Message;
                                    statuses[i] = "Error";

                                    if (exception.InnerException != null)
                                    {
                                        results[i] += " " + exception.InnerException.Message;
                                    }
                                }
                            }
                            else
                            {
                                results[i] = "successfully imported sequence";
                                statuses[i] = "Success";
                            }
                        }
                        catch (Exception exception)
                        {
                            results[i] = "Error:" + exception.Message + (exception.InnerException == null ? string.Empty : exception.InnerException.Message);
                            statuses[i] = "Error";
                        }
                    }

                    // removing matters for whitch adding of sequence failed
                    var orphanMatters = db.Matter.Include(m => m.Sequence).Where(m => savedMatterNames.Contains(m.Name) && m.Sequence.Count == 0).ToArray();

                    if (orphanMatters.Length > 0)
                    {
                        db.Matter.RemoveRange(orphanMatters);
                        db.SaveChanges();
                    }
                }

                return new Dictionary<string, object>
                           {
                               { "matterNames", matterNames },
                               { "results", results },
                               { "status", statuses }
                           };
            });
        }