/// <summary>
 /// Detects which expressions in a <see cref="Grammar"/> are left-adjacent.
 /// </summary>
 /// <param name="grammar">The <see cref="Grammar"/> to inspect.</param>
 /// <returns>A <see cref="ILookup{Rule, Expression}"/> containing the left-adjacent rules.</returns>
 public static ILookup<Rule, Expression> Detect(Grammar grammar)
 {
     var leftAdjacent = new Dictionary<Rule, List<Expression>>();
     var zeroWidth = ZeroWidthEvaluator.Evaluate(grammar);
     new LeftRecursionExpressionTreeWalker(zeroWidth, leftAdjacent).WalkGrammar(grammar);
     return leftAdjacent.SelectMany(i => i.Value, (i, v) => new { i.Key, Value = v }).ToLookup(i => i.Key, i => i.Value);
 }
        public void Run(BuildTarget target, 
			NodeData node, 
			ConnectionPointData inputPoint,
			ConnectionData connectionToOutput, 
			Dictionary<string, List<Asset>> inputGroupAssets, 
			List<string> alreadyCached, 
			Action<ConnectionData, Dictionary<string, List<Asset>>, List<string>> Output)
        {
            var incomingAssets = inputGroupAssets.SelectMany(v => v.Value).ToList();

            var modifier = ModifierUtility.CreateModifier(node, target);
            UnityEngine.Assertions.Assert.IsNotNull(modifier);
            bool isAnyAssetModified = false;

            foreach(var asset in incomingAssets) {
                var loadedAsset = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(asset.importFrom);
                if(modifier.IsModified(loadedAsset)) {
                    modifier.Modify(loadedAsset);
                    isAnyAssetModified = true;
                }
            }

            if(isAnyAssetModified) {
                // apply asset setting changes to AssetDatabase.
                AssetDatabase.Refresh();
            }

            // Modifier does not add, filter or change structure of group, so just pass given group of assets
            Output(connectionToOutput, inputGroupAssets, null);
        }
Example #3
0
 private static IEnumerable<dynamic> LetterValuePairs(
 Dictionary<int, IList<string>> old)
 {
     return old.SelectMany(
       kvp => kvp.Value.Select(
     letter => new {Letter = letter.ToLower(), Value = kvp.Key}));
 }
        public TagConverter(ISettingsProvider settingsProvider)
        {
            using (var reader = new StreamReader(settingsProvider.Get<string>(SettingsKeys.TagMappingFile)))
            {
                normalizedTags = reader
                    .ReadAllLines()
                    .Where(x => !string.IsNullOrWhiteSpace(x))
                    .Select(ParseTagDescription)
                    .ToDictionary(x => x.Name, x => x.RawTags);

                rawTagsMapping = normalizedTags
                    .SelectMany(normalizedTag => normalizedTag.Value.Select(rawTag => new { Normalized = normalizedTag.Key, Raw = rawTag }))
                    .ToDictionary(x => x.Raw, x => x.Normalized);
            }

            using (var reader = new StreamReader(settingsProvider.Get<string>(SettingsKeys.CorrectionsFile)))
            {
                correctionsByProblemUrl = reader
                    .ReadAllLines()
                    .Where(x => !string.IsNullOrWhiteSpace(x))
                    .SelectMany(ParseCorrections)
                    .GroupBy(x => x.ProblemUrl)
                    .ToDictionary(x => x.Key, x => x.ToArray());
            }
        }
Example #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FakeDataQueue"/> class to randomly emit data for each symbol
 /// </summary>
 public FakeDataQueue()
 {
     _ticks = new ConcurrentQueue<BaseData>();
     _symbols = new Dictionary<SecurityType, List<string>>();
     _timer = new Timer
     {
         AutoReset = true,
         Enabled = true
     };
     _timer.Elapsed += (sender, args) =>
     {
         _timer.Interval = _random.Next(15, 2500); // around each second
         foreach (var symbol in _symbols.SelectMany(x => x.Value))
         {
             // 50/50 repeating chance of emitting each symbol
             while (_random.NextDouble() > 0.75)
             {
                 _ticks.Enqueue(new Tick
                 {
                     Time = DateTime.Now,
                     Symbol = symbol,
                     Value = 10 + (decimal) Math.Abs(Math.Sin(DateTime.Now.TimeOfDay.TotalMinutes)),
                     TickType = TickType.Trade,
                     Quantity = _random.Next(10, (int) _timer.Interval)
                 });
             }
         }
     };
 }
        public void Given_30_New_Feeds_GetLatest_Returns_Feeds_In_Correct_Order()
        {
            var urlFeeds = new Dictionary<string, IEnumerable<Item>>
            {
                { "http://atom1", BuildFeeds(5) },
                { "http://atom2", BuildFeeds(10) },
                { "http://atom3", BuildFeeds(15) }
            };
            var minDate = urlFeeds.SelectMany(kv => kv.Value).Select(f => f.Published).Min();
            var maxDate = urlFeeds.SelectMany(kv => kv.Value).Select(f => f.Published).Max();
            var rssAggregator = BuildRssAggregator(urlFeeds);

            var feeds = rssAggregator.GetLatest(DateTime.MinValue).ToList();

            Assert.AreEqual(minDate, feeds.First().Published);
            Assert.AreEqual(maxDate, feeds.Last().Published);
        }
        public void Given_30_New_Tweets_GetLatest_Returns_Tweets_In_Correct_Order()
        {
            var queryTweets = new Dictionary<string, IEnumerable<Item>>
            {
                { "#hashtag", BuildTweets(5) },
                { "@user", BuildTweets(10) },
                { "text", BuildTweets(15) }
            };
            var minDate = queryTweets.SelectMany(kv => kv.Value).Select(f => f.Published).Min();
            var maxDate = queryTweets.SelectMany(kv => kv.Value).Select(f => f.Published).Max();
            var twitterAggregator = BuildTwitterAggregator(queryTweets);

            var tweets = twitterAggregator.GetLatest(DateTime.MinValue).ToList();

            Assert.AreEqual(minDate, tweets.First().Published);
            Assert.AreEqual(maxDate, tweets.Last().Published);
        }
 private string[] GetDistinctFieldCodes(Dictionary<TemplateModel, List<FieldCodeSummaryModel>> analysisData)
 {
     var distinctFieldCodes = new List<string>();
     foreach (var fieldCodeSummary in analysisData.SelectMany(i => i.Value.Where(fc => !distinctFieldCodes.Contains(fc.ColumnName))))
     {
         distinctFieldCodes.Add(fieldCodeSummary.ColumnName);
     }
     return distinctFieldCodes.OrderBy(fc => fc).ToArray();
 }
Example #9
0
        public IEnumerable<BlogPost> GetItems(int feedCount = 20, int pagenum = 0)
        {
            string json = File.ReadAllText("feeddata.json");
            var metadataEntries = json.FromJson<MetaData[]>();

            var syndicationFeeds = new Dictionary<string, SyndicationFeed>();

            foreach (var metadata in metadataEntries)
            {
                var reader = XmlReader.Create(metadata.FeedUrl);
                var feed = SyndicationFeed.Load(reader);

                reader.Close();
                if (feed != null)
                {
                    syndicationFeeds.Add(metadata.Id, feed);
                }
            }

            var data = syndicationFeeds
                .SelectMany(pair => pair.Value.Items, (pair, item) => new { Id = pair.Key, Item = item })
                .Where(x => x.Item.Categories.Any(y => y.Name.ToLower() == "nancy" || y.Name.ToLower() == "nancyfx"))
                .Select(x =>
                {
                    var rssauthor = x.Item.Authors.FirstOrDefault();
                    var metaauthor = metadataEntries.FirstOrDefault(y => y.Id == x.Id);
                    var authorname = string.Empty;
                    var authoremail = string.Empty;

                    if (metaauthor != null)
                    {
                        authorname = rssauthor == null ? metaauthor.Author : rssauthor.Name;
                        authoremail = rssauthor == null ? metaauthor.AuthorEmail : rssauthor.Email;
                    }

                    var link = x.Item.Links.FirstOrDefault();
                    var locallink = link == null ? string.Empty : link.Uri.PathAndQuery;
                    var originallink = link == null ? string.Empty : link.Uri.AbsoluteUri;

                    return new BlogPost
                    {
                        Title = x.Item.Title.Text,
                        Summary = x.Item.Summary.Text,
                        Author = authorname,
                        AuthorEmail = authoremail,
                        Localink = locallink,
                        OriginalLink = originallink
                    };

                })
                .Skip(feedCount * pagenum)
                .Take(feedCount)
                .OrderByDescending(x => x.PublishedDate)
                ;

            return data;
        }
Example #10
0
        public List<Fork> Search(Dictionary<SportType, Dictionary<GameInfo, List<Game>>> games)
        {
            if (games == null)
            {
                throw new ArgumentNullException(nameof(games));
            }

            return games.SelectMany(pair => this.GetForks(pair.Key, pair.Value)).ToList();
        }
Example #11
0
        public Job(string name, string rowScope, Dictionary<string, List<Column>> capturePathToColumns, TextWriter textWriter)
        {
            _rowScope = rowScope;
            _capturePathToColumn = capturePathToColumns;

            Name = name;
            List<string> columnNames = capturePathToColumns.SelectMany(x => x.Value.Select(y => y.Name)).ToList();
            Writer = new Writer(columnNames, textWriter);
        }
Example #12
0
        public FakeNewsServer(Dictionary<int, int[]> channelsByAccount)
        {
            var endDate = DateTime.Now.AddHours(-1);
            var startDate = endDate.AddDays(-40);

            this.channelsByAccount = channelsByAccount;
            var channels = channelsByAccount.SelectMany(ca => ca.Value).Distinct();
            newsByChannel = channels.ToDictionary(c => c,
                                                  c => NewsMaker.MakeSomeNews(c, startDate, endDate, 1,
                                                                              random.Next(100) < 50
                                                                                  ? random.Next(1, 10)
                                                                                  : random.Next(2, 1440)));
        }
Example #13
0
 public static byte[] GetPJL(Dictionary<string, string> jobattribs, Dictionary<string, string> pjlsettings, string language)
 {
     return Encoding.ASCII.GetBytes(
         "\x1B%-12345X".ToArray()
         .Concat("@PJL JOB MODE=PRINTER\r\n")
         .Concat(jobattribs == null ? new char[] { } : jobattribs.SelectMany(kvp => "@PJL SET JOBATTR=\"@".ToArray().Concat(kvp.Key).Concat("=").Concat(kvp.Value).Concat("\"\r\n")))
         .Concat(pjlsettings == null ? new char[] { } : pjlsettings.SelectMany(kvp => "@PJL SET ".ToArray().Concat(kvp.Key).Concat("=").Concat(kvp.Value).Concat("\r\n")))
         .Concat("@PJL ENTER LANGUAGE=")
         .Concat(language)
         .Concat("\r\n")
         .ToArray()
     );
 }
        public void TestDetectionEngine()
        {
            Dictionary<string, IList<ISoundSignalReader>> learningWordSignals = new Dictionary<string, IList<ISoundSignalReader>>();
            Dictionary<string, IList<ISoundSignalReader>> testWordSignals = new Dictionary<string, IList<ISoundSignalReader>>();

            var learningDirectories = Directory.GetDirectories("Sounds\\Learning");
            var testDirectories = Directory.GetDirectories("Sounds\\test");

            foreach (var directory in learningDirectories.Where(item => !item.Contains("catalog")))
            {
                var word = new DirectoryInfo(directory).Name;
                learningWordSignals.Add(word, new List<ISoundSignalReader>());
                var wavFiles = Directory.GetFiles(directory).Select(item => new FileInfo(item)).Where(fItem => fItem.Extension.Contains("wav"));
                foreach (var file in wavFiles)
                {
                    learningWordSignals[word].Add(new WavSoundSignalReader(file.FullName));
                }
            }

            foreach (var directory in testDirectories)
            {
                var word = new DirectoryInfo(directory).Name;
                testWordSignals.Add(word, new List<ISoundSignalReader>());
                var wavFiles = Directory.GetFiles(directory).Select(item => new FileInfo(item)).Where(fItem => fItem.Extension.Contains("wav"));
                foreach (var file in wavFiles)
                {
                    testWordSignals[word].Add(new WavSoundSignalReader(file.FullName));
                }
            }

            var catalogSignals = new List<ISoundSignalReader>();
            catalogSignals.AddRange(learningWordSignals.SelectMany(item => item.Value));

            var codeBook = CodeBookFactory.FromWaves(catalogSignals, EngineParameters.Default);

            var recognitionEngine = new DetectionEngine(codeBook);
            var result = recognitionEngine.Train(learningWordSignals);

            foreach (var word in testWordSignals)
            {
                foreach (var signal in word.Value)
                {
                    string name;
                    var value = recognitionEngine.Recognize(signal, out name);
                    Assert.AreEqual(word.Key, name);

                }
            }
        }
        /// <summary>
        /// Process the content of Claim files and change to structure we want for Result file
        /// </summary>
        /// <param name="rows">content of claim file</param>
        /// <returns></returns>
        public ProcessClaimFileResult Process(Dictionary<string, Dictionary<int, List<BaseClaimRowMetaData>>> rows)
        {
            if (!rows.Any())
            {
                //We can throw Exception here too, depend on our policies
                return new ProcessClaimFileResult{Exception = new ProcessFileRowNotFoundException() };
            }

            var originYears = rows.SelectMany(r => r.Value.Select(v => v.Key)).Distinct().OrderBy(o => o).ToArray();
            _earliestOriginYear = originYears.First();
            _lastDevelopmentYear = originYears.Last();
            _numberOfDevelopment = _lastDevelopmentYear - _earliestOriginYear + 1;

            var accumulatedTriangle = CalculateAccumulatedTriangle(rows);

            return new ProcessClaimFileResult { EarliestOriginYear = _earliestOriginYear, NumberOfDevelopment = _numberOfDevelopment, AccumulatedTriangle = accumulatedTriangle };
        }
Example #16
0
        protected IEnumerable<BsaFolder> BuildBsaLayout(Dictionary<string, IList<FileRecord>> folderDict, IList<string> fileNames)
        {
            var pathedFiles = folderDict
                .SelectMany(kvp =>
                    kvp.Value.Select(record => new { path = kvp.Key, record }))
                .Zip(fileNames, (a, fn) => new { a.path, fn, a.record });

            var fileLookup = pathedFiles.ToLookup(a => a.path, a => new { a.fn, a.record });
            return
                from g in fileLookup
                let bsaFiles =
                    g.Select(a =>
                        new BsaFile(
                            g.Key,
                            a.fn,
                            Settings,
                            a.record,
                            (off, len) => _mmf.ToReader(a.record.offset + off, len)))
                select new BsaFolder(g.Key, bsaFiles);
        }
Example #17
0
 private GameResult GetResults(TagInfo tag, PlayersRepo playersRepo, Dictionary<string, PlayerAnswers> playerAnswers)
 {
     IDictionary<string, int> wordStats = playerAnswers.SelectMany(ans => ans.Value.Answers).CountStatistics(word => word);
     return
         new GameResult
             {
                 Results = playerAnswers.Keys.Select(
                     k => new PlayerResult
                          	{
                          		Player = playersRepo.Find(k),
                                 WordsScores =
                          			playerAnswers[k].Answers.Select(ans => Tuple.Create(ans, wordStats[ans])).ToArray(),
                                 Score = playerAnswers[k].Answers.Sum(ans => wordStats[ans])
                          	}
                     ).OrderByDescending(p => p.Score).ToArray(),
                 Tag = tag,
                 WordsScores =
                     wordStats.OrderByDescending(kv => kv.Value).Select(kv => Tuple.Create(kv.Key, kv.Value)).ToArray()
             };
 }
        private static void Main()
        {
            var configsList = new List<string>
            {
                "Name: Link, Level: 1, Hp: 20",
                "Name: Zelda, Level: 1, Hp: 20 ",
                "Name: Zelda, Hp: 30",
                "Name: Mario, Hp: 30"
            };
            var gamesDic = new Dictionary<string, Dictionary<string,string>>();

            foreach (var configs in configsList)
            {
                UpdateDictionary(configs, gamesDic);
            }

            foreach (var kvp in gamesDic.SelectMany(games => games.Value))
            {
                Console.WriteLine($"{kvp.Key}:{kvp.Value}");
            }

              Console.ReadKey();
        }
Example #19
0
 public PivotedRows GroupAndTotal(TickCounter tickCounter, PivotedRows pivotedRows)
 {
     IDictionary<IList<Tuple<PropertyPath, PivotKey, object>>, List<GroupedRow>> allReportRows
         = new Dictionary<IList<Tuple<PropertyPath, PivotKey, object>>, List<GroupedRow>>();
     var groupColumns = ViewInfo.DisplayColumns
         .Where(col => TotalOperation.GroupBy == col.ColumnSpec.TotalOperation)
         .Select(col => col.ColumnDescriptor)
         .ToArray();
     var pivotOnColumns = ViewInfo.DisplayColumns
         .Where(col => TotalOperation.PivotKey == col.ColumnSpec.TotalOperation)
         .Select(col => col.ColumnDescriptor)
         .ToArray();
     var allInnerPivotKeys = new HashSet<PivotKey>();
     var allPivotKeys = new Dictionary<PivotKey, PivotKey>();
     foreach (var rowItem in pivotedRows.RowItems)
     {
         allInnerPivotKeys.UnionWith(rowItem.PivotKeys);
         IList<Tuple<PropertyPath, PivotKey, object>> groupKey = new List<Tuple<PropertyPath, PivotKey, object>>();
         foreach (var column in groupColumns)
         {
             var pivotColumn = GetPivotColumn(column);
             if (null == pivotColumn)
             {
                 groupKey.Add(new Tuple<PropertyPath, PivotKey, object>(column.PropertyPath, null,
                     column.GetPropertyValue(rowItem, null)));
             }
             else
             {
                 foreach (var pivotKey in GetPivotKeys(pivotColumn.PropertyPath, new []{rowItem}))
                 {
                     if (!pivotKey.Contains(pivotColumn.PropertyPath))
                     {
                         continue;
                     }
                     groupKey.Add(new Tuple<PropertyPath, PivotKey, object>(column.PropertyPath, pivotKey, column.GetPropertyValue(rowItem, pivotKey)));
                 }
             }
         }
         groupKey = ImmutableList.ValueOf(groupKey);
         var pivotOnKeyValues = new List<KeyValuePair<PropertyPath, object>>();
         foreach (var column in pivotOnColumns)
         {
             var pivotColumn = GetPivotColumn(column);
             if (null == pivotColumn)
             {
                 pivotOnKeyValues.Add(new KeyValuePair<PropertyPath, object>(column.PropertyPath,
                     column.GetPropertyValue(rowItem, null)));
             }
             else
             {
                 Trace.TraceWarning("Unable to pivot on column {0} because it is already pivoted.", pivotColumn.PropertyPath); // Not L10N
             }
         }
         var pivotOnKey = PivotKey.GetPivotKey(allPivotKeys, pivotOnKeyValues);
         List<GroupedRow> rowGroups;
         if (!allReportRows.TryGetValue(groupKey, out rowGroups))
         {
             rowGroups = new List<GroupedRow>();
             allReportRows.Add(groupKey, rowGroups);
         }
         var rowGroup = rowGroups.FirstOrDefault(rg => !rg.ContainsKey(pivotOnKey));
         if (null == rowGroup)
         {
             rowGroup = new GroupedRow();
             rowGroups.Add(rowGroup);
         }
         rowGroup.AddInnerRow(pivotOnKey, rowItem);
     }
     var outerPivotKeys = allPivotKeys.Keys.Where(key=>key.Length == pivotOnColumns.Length).ToArray();
     var pivotKeyComparer = PivotKey.GetComparer(ViewInfo.DataSchema);
     Array.Sort(outerPivotKeys, pivotKeyComparer);
     var innerPivotKeys = allInnerPivotKeys.ToArray();
     Array.Sort(innerPivotKeys, pivotKeyComparer);
     var reportItemProperties = new List<PropertyDescriptor>();
     var propertyNames = new HashSet<string>();
     foreach (var displayColumn in ViewInfo.DisplayColumns)
     {
         if (displayColumn.ColumnSpec.Hidden)
         {
             continue;
         }
         var totalOperation = displayColumn.ColumnSpec.TotalOperation;
         if (TotalOperation.GroupBy == totalOperation)
         {
             var pivotColumn = GetPivotColumn(displayColumn.ColumnDescriptor);
             if (null == pivotColumn)
             {
                 string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath);
                 reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, displayColumn, null));
             }
             else
             {
                 foreach (var innerPivotKey in innerPivotKeys)
                 {
                     string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath);
                     reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, displayColumn, innerPivotKey));
                 }
             }
         }
     }
     foreach (var outerPivotKey in outerPivotKeys)
     {
         foreach (var displayColumn in ViewInfo.DisplayColumns)
         {
             if (displayColumn.ColumnSpec.Hidden)
             {
                 continue;
             }
             if (TotalOperation.PivotValue == displayColumn.ColumnSpec.TotalOperation || TotalOperation.PivotKey == displayColumn.ColumnSpec.TotalOperation)
             {
                 var pivotColumn = GetPivotColumn(displayColumn.ColumnDescriptor);
                 if (null == pivotColumn)
                 {
                     string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath);
                     reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, outerPivotKey, displayColumn, null));
                 }
                 else
                 {
                     foreach (var innerPivotKey in allInnerPivotKeys)
                     {
                         string propertyName = MakeUniqueName(propertyNames, displayColumn.PropertyPath);
                         reportItemProperties.Add(new GroupedPropertyDescriptor(propertyName, outerPivotKey, displayColumn, innerPivotKey));
                     }
                 }
             }
         }
     }
     return new PivotedRows(allReportRows.SelectMany(entry=>entry.Value.Select(
         reportRow=>new RowItem(reportRow))), 
         new PropertyDescriptorCollection(reportItemProperties.ToArray()));
 }
Example #20
0
        public override void Weave(
            TypeDefinition typeDef,
            AssemblyDefinition assemblyDefinition,
            MapDefinition mapDefinition,
            Dictionary<string, List<MapDefinition>> assemblyMapDefinitions,
            Dictionary<string, AssemblyDefinition> assemblyDefinitions) {
            var boolTypeDef = typeDef.Module.Import(typeof(bool));
            foreach (var columnDef in
                mapDefinition.ColumnDefinitions.Where(
                    c => c.Relationship == RelationshipType.ManyToOne || c.Relationship == RelationshipType.OneToOne)) {
                // remember the property may be defined on a parent class
                var propDef = this.GetProperty(typeDef, columnDef.Name);

                // add a field with DbType and DbName 
                TypeReference fkTypeReference;
                var fkPkType = columnDef.DbType.GetCLRType();
                if (fkPkType.IsValueType) {
                    fkTypeReference = typeDef.Module.Import(typeof(Nullable<>).MakeGenericType(fkPkType));
                }
                else {
                    fkTypeReference = typeDef.Module.Import(fkPkType);
                }

                var fkField = new FieldDefinition(columnDef.DbName, FieldAttributes.Public, fkTypeReference);
                if (propDef.DeclaringType.Fields.Any(f => f.Name == columnDef.DbName)) {
                    continue; // already done something here!
                }

                this.MakeNotDebuggerBrowsable(typeDef.Module, fkField);
                propDef.DeclaringType.Fields.Add(fkField);

                // override the set method to set to null
                propDef.SetMethod.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Initobj, fkTypeReference));
                propDef.SetMethod.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Ldflda, fkField));
                propDef.SetMethod.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Ldarg_0));

                // override the get method to access this field if null and create a new instance
                // TODO solve for non auto properties
                if (!propDef.GetMethod.Body.Variables.Any()) {
                    // Release code is different to debug code!
                    propDef.GetMethod.Body.Variables.Add(new VariableDefinition(propDef.PropertyType));
                }

                propDef.GetMethod.Body.Variables.Add(new VariableDefinition(propDef.PropertyType));
                propDef.GetMethod.Body.Variables.Add(new VariableDefinition(boolTypeDef));
                propDef.GetMethod.Body.InitLocals = true;
                //propDef.GetMethod.Body.Instructions.Clear();

                var backingField = this.GetBackingField(propDef);
                var il = propDef.GetMethod.Body.Instructions;
                var lastInstr = il[0];
                var index = 0;

                // first bit does the null/hasValue checks on the backing fields
                il.Insert(index++, Instruction.Create(OpCodes.Ldarg_0));
                il.Insert(index++, Instruction.Create(OpCodes.Ldfld, backingField));

                il.Insert(index++, Instruction.Create(OpCodes.Brtrue, lastInstr));

                if (fkPkType.IsValueType) {
                    il.Insert(index++, Instruction.Create(OpCodes.Ldarg_0));
                    il.Insert(index++, Instruction.Create(OpCodes.Ldflda, fkField));
                    il.Insert(
                        index++,
                        Instruction.Create(
                            OpCodes.Call,
                            MakeGeneric(
                                typeDef.Module.Import(fkTypeReference.Resolve().GetMethods().Single(m => m.Name == "get_HasValue")),
                                typeDef.Module.Import(fkPkType))));
                }
                else {
                    il.Insert(index++, Instruction.Create(OpCodes.Ldarg_0));
                    il.Insert(index++, Instruction.Create(OpCodes.Ldfld, fkField));
                }

                il.Insert(index++, Instruction.Create(OpCodes.Brfalse, lastInstr));

                // if we have a pk but no ref we create a new instance with the primary key set
                il.Insert(index++, Instruction.Create(OpCodes.Ldarg_0));
                il.Insert(
                    index++,
                    Instruction.Create(OpCodes.Newobj, typeDef.Module.Import(propDef.PropertyType.Resolve().GetConstructors().First())));
                il.Insert(index++, Instruction.Create(OpCodes.Stloc_0));
                il.Insert(index++, Instruction.Create(OpCodes.Ldloc_0));
                il.Insert(index++, Instruction.Create(OpCodes.Ldarg_0));

                if (fkPkType.IsValueType) {
                    il.Insert(index++, Instruction.Create(OpCodes.Ldflda, fkField));
                    il.Insert(
                        index++,
                        Instruction.Create(
                            OpCodes.Call,
                            typeDef.Module.Import(
                                MakeGeneric(
                                    fkField.FieldType.Resolve().GetMethods().Single(m => m.Name == "get_Value"),
                                    typeDef.Module.Import(fkPkType)))));
                    var fkMapDef = assemblyMapDefinitions.SelectMany(am => am.Value).First(m => m.TypeFullName == columnDef.TypeFullName);
                    var assemblyDef = assemblyDefinitions.Single(ad => ad.Value.FullName == fkMapDef.AssemblyFullName).Value;
                    var fkMapTypeRef = GetTypeDefFromFullName(columnDef.TypeFullName, assemblyDef);
                    il.Insert(
                        index++,
                        Instruction.Create(
                            OpCodes.Callvirt,
                            typeDef.Module.Import(
                                this.GetProperty(fkMapTypeRef, fkMapDef.ColumnDefinitions.Single(cd => cd.IsPrimaryKey).Name).SetMethod)));
                }
                else {
                    il.Insert(index++, Instruction.Create(OpCodes.Ldfld, fkField));
                    var fkMapDef = assemblyMapDefinitions.SelectMany(am => am.Value).First(m => m.TypeFullName == columnDef.TypeFullName);
                    var assemblyDef = assemblyDefinitions.Single(ad => ad.Value.FullName == fkMapDef.AssemblyFullName).Value;
                    var fkMapTypeRef = GetTypeDefFromFullName(columnDef.TypeFullName, assemblyDef);
                    il.Insert(
                        index++,
                        Instruction.Create(
                            OpCodes.Callvirt,
                            typeDef.Module.Import(
                                this.GetProperty(fkMapTypeRef, fkMapDef.ColumnDefinitions.Single(cd => cd.IsPrimaryKey).Name).SetMethod)));
                }

                il.Insert(index++, Instruction.Create(OpCodes.Ldloc_0));
                il.Insert(index, Instruction.Create(OpCodes.Stfld, backingField));
            }
        }
Example #21
0
 /// <summary>
 /// Find all ranges of the specified strings.
 /// </summary>
 /// <param name="words">Must be a dictionary of strings (keys) to search for and
 /// whether these strings represent whole words (true or false value).</param>
 /// <returns></returns>
 private IEnumerable<int[]> FindWordRanges(Dictionary<string, bool> words)
     => words.SelectMany(word => FindWordRanges(word.Key, word.Value));
        private void Train()
        {
            Dictionary<string, IList<ISoundSignalReader>> learningWordSignals = new Dictionary<string, IList<ISoundSignalReader>>();

            List<string> learningDirectories = new List<string>();
            foreach (var folder in ConfigurationSettings.LearningsFolders)
            {
                learningDirectories.AddRange(Directory.GetDirectories(folder));
            }

            foreach (var directory in learningDirectories.Where(item => !item.Contains("catalog")))
            {
                var word = new DirectoryInfo(directory).Name;
                learningWordSignals.Add(word, new List<ISoundSignalReader>());
                var wavFiles = Directory.GetFiles(directory).Select(item => new FileInfo(item)).Where(fItem => fItem.Extension.Contains("wav"));
                foreach (var file in wavFiles)
                {
                    learningWordSignals[word].Add(new WavSoundSignalReader(file.FullName));
                }
            }

            var catalogSignals = new List<ISoundSignalReader>();
            catalogSignals.AddRange(learningWordSignals.SelectMany(item => item.Value));

            var codeBook = CodeBookFactory.FromWaves(catalogSignals, EngineParameters.Default);

            var recognitionEngine = new DetectionEngine(codeBook);
            var result = recognitionEngine.Train(learningWordSignals);
            //result.Hmm.Save("HMModels.dat");
            _models = result.Models;
            _codebook = result.Catalog;

            result.Save("SavedData", "model");
        }
Example #23
0
        public List<Tuple<GrainId, string, int>> GetGrainStatistics()
        {
            var counts = new Dictionary<string, Dictionary<GrainId, int>>();
            lock (activations)
            {
                foreach (var activation in activations)
                {
                    ActivationData data = activation.Value;
                    if (data == null || data.GrainInstance == null) continue;

                    // TODO: generic type expansion
                    var grainTypeName = TypeUtils.GetFullName(data.GrainInstanceType);
                    
                    Dictionary<GrainId, int> grains;
                    int n;
                    if (!counts.TryGetValue(grainTypeName, out grains))
                    {
                        counts.Add(grainTypeName, new Dictionary<GrainId, int> { { data.Grain, 1 } });
                    }
                    else if (!grains.TryGetValue(data.Grain, out n))
                        grains[data.Grain] = 1;
                    else
                        grains[data.Grain] = n + 1;
                }
            }
            return counts
                .SelectMany(p => p.Value.Select(p2 => Tuple.Create(p2.Key, p.Key, p2.Value)))
                .ToList();
        }
        private IEnumerable<DrugExposure> PrepareDrugExposures(IEnumerable<DrugExposure> drugExposures, Dictionary<long, VisitOccurrence> visitOccurrences)
        {
            var rxDrugs = new Dictionary<Guid, List<DrugExposure>>();
              var medicalDrugs = new Dictionary<Guid, List<DrugExposure>>();
              foreach (var drugExposure in drugExposures)
              {
             if (drugExposure.TypeConceptId == 38000175 || drugExposure.TypeConceptId == 38000176)
             {
                if (!rxDrugs.ContainsKey(drugExposure.SourceRecordGuid))
                   rxDrugs.Add(drugExposure.SourceRecordGuid, new List<DrugExposure>());

                rxDrugs[drugExposure.SourceRecordGuid].Add(drugExposure);
                continue;
             }

             if (!medicalDrugs.ContainsKey(drugExposure.SourceRecordGuid))
                medicalDrugs.Add(drugExposure.SourceRecordGuid, new List<DrugExposure>());

             medicalDrugs[drugExposure.SourceRecordGuid].Add(drugExposure);
              }

              foreach (var sourceRecordGuid in medicalDrugs.Keys)
              {
             //TypeConceptId == 0, ndc
             var ndcExists = medicalDrugs[sourceRecordGuid].Any(d => d.TypeConceptId == 0);

             foreach (var drugExposure in medicalDrugs[sourceRecordGuid])
             {
                //TypeConceptId == 4, proc_cd
                if (drugExposure.TypeConceptId == 4 && ndcExists)
                   continue;

                var visitOccurrence = GetVisitOccurrence(drugExposure);
                if (visitOccurrence == null)
                   continue;

                drugExposure.VisitOccurrenceId = visitOccurrence.Id;
                drugExposure.TypeConceptId = visitOccurrence.ConceptId == 9201 ? 38000180 : 38000179;

                yield return drugExposure;
             }
              }

              foreach (var similarDrugs in rxDrugs.SelectMany(drugs => drugs.Value.GroupBy(d => d.SourceValue.Length >= 9 ? d.SourceValue.Substring(0, 9) : d.SourceValue)))
              {
             if (similarDrugs.Count(d => d.ConceptId > 0) > 0)
             {
                yield return similarDrugs.Where(d => d.ConceptId > 0).OrderBy(d => d.SourceValue.Length).Last();
                continue;
             }

             yield return similarDrugs.OrderBy(d => d.SourceValue.Length).Last();
              }
        }
        public void NonSatisfiedImports()
        {
            var lockKey = new DatasetLockKey();
            var datasetLock = new Mock<ITrackDatasetLocks>();
            {
                datasetLock.Setup(d => d.LockForReading())
                    .Returns(lockKey)
                    .Verifiable();
                datasetLock.Setup(d => d.RemoveReadLock(It.IsAny<DatasetLockKey>()))
                    .Callback<DatasetLockKey>(key => Assert.AreSame(lockKey, key))
                    .Verifiable();
            }

            var groups = new Dictionary<GroupCompositionId, IEnumerable<GroupImportDefinition>>
                {
                    {
                        new GroupCompositionId(),
                        new List<GroupImportDefinition>
                            {
                                GroupImportDefinition.CreateDefinition(
                                    "a",
                                    new GroupRegistrationId("a"),
                                    null,
                                    Enumerable.Empty<ImportRegistrationId>()),
                                GroupImportDefinition.CreateDefinition(
                                    "b",
                                    new GroupRegistrationId("a"),
                                    null,
                                    Enumerable.Empty<ImportRegistrationId>()),
                            }
                    },
                    {
                        new GroupCompositionId(),
                        new List<GroupImportDefinition>
                            {
                                GroupImportDefinition.CreateDefinition(
                                    "c",
                                    new GroupRegistrationId("c"),
                                    null,
                                    Enumerable.Empty<ImportRegistrationId>()),
                                GroupImportDefinition.CreateDefinition(
                                    "d",
                                    new GroupRegistrationId("c"),
                                    null,
                                    Enumerable.Empty<ImportRegistrationId>()),
                            }
                    },
                };
            var storage = new Mock<IStoreGroupsAndConnections>();
            {
                storage.Setup(s => s.Groups())
                    .Returns(groups.Keys);
                storage.Setup(s => s.UnsatisfiedImports(It.IsAny<GroupCompositionId>()))
                    .Returns<GroupCompositionId>(id => groups[id]);
            }

            var commands = new CompositionCommands(datasetLock.Object, storage.Object);
            var task = commands.NonSatisfiedImports(false);
            var results = task.Result;
            Assert.That(
                results,
                Is.EquivalentTo(
                    groups.SelectMany(p => p.Value.Select(v => new Tuple<GroupCompositionId, GroupImportDefinition>(p.Key, v)))));

            datasetLock.Verify(d => d.LockForReading(), Times.Once());
            datasetLock.Verify(d => d.RemoveReadLock(It.IsAny<DatasetLockKey>()), Times.Once());
        }
        static void Main(string[] args)
        {
            var assemblyDictionary = new Dictionary<int, Assembly>()
            {
                { 1, Assembly.GetAssembly(typeof(Certification.Chapter1.Objective1_1.Threads.Listing_1_1)) },
                { 2 , Assembly.GetAssembly(typeof(Certification.Chapter2.Objective2_1.Listing_2_1)) },
                { 3, Assembly.GetAssembly(typeof(Chapter3.Objective1.Listing_3_6)) }
            };

            var typeDictionary = new Dictionary<int, IEnumerable<Type>>();
            foreach (var kvp in assemblyDictionary)
            {
                typeDictionary.Add(kvp.Key, kvp.Value.GetTypes()
                      .Where(type => type != typeof(IRunnable) && typeof(IRunnable).IsAssignableFrom(type)));
            }

            while (true)
            {
                Console.WriteLine("Enter the listing number:");
                var input = Console.ReadLine();

                bool isListing = Regex.IsMatch(input, listingRegExp);
                bool isChapter = Regex.IsMatch(input, chapterRegExp);

                if (isChapter)
                {
                    IEnumerable<Type> listings;
                    var chapterNumber = int.Parse(input);

                    if (typeDictionary.TryGetValue(chapterNumber, out listings))
                    {
                        Console.WriteLine("Available listing are:");
                        var listingNames = listings.Select(l => l.Name.Replace(typePrefix, string.Empty).Replace("_", "."));

                        foreach (var listing in listings.OrderBy(l => GetListingNumber(l)))
                        {
                            var displayName = listing.Name.Replace(typePrefix, string.Empty).Replace("_", ".");
                            var listingAttribute = (ListingAttribute)Attribute.GetCustomAttribute(listing, typeof(ListingAttribute));

                            if (listingAttribute != null)
                            {
                                displayName += " - " + listingAttribute.Description;
                            }

                            Console.WriteLine(displayName);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Chapter " + input + " is unknown.");
                    }
                }
                else if (isListing)
                {
                    input = input.Replace('.', '_');

                    var type = typeDictionary.SelectMany(kvp => kvp.Value).FirstOrDefault(t => t.Name == typePrefix + input);

                    if (type == null)
                    {
                        Console.WriteLine("Unknown listing {0}", typePrefix + input);
                    }
                    else
                    {
                        var runnable = (IRunnable)(type.GetConstructor(new Type[0]).Invoke(new object[0]));
                        var listingAttribute = (ListingAttribute)Attribute.GetCustomAttribute(type, typeof(ListingAttribute));

                        if (listingAttribute != null)
                        {
                            Console.WriteLine("Running listing \"" + listingAttribute.Description + "\"");
                            Console.WriteLine();
                        }
                        runnable.Run();
                        Console.WriteLine("_______________________________________________________");
                    }
                }
                else if (input == "0" || input == String.Empty)
                {
                    Console.WriteLine("Bye bye pov' type");
                    Thread.Sleep(500);
                    return;
                }
            }
        }
Example #27
0
 public void PostTraceReconciliation(Dictionary<Guid, List<ISerializable>> orphanedSerializables)
 {
     Assert.AreEqual(orphanedSerializables.SelectMany(kvp=>kvp.Value).Count(), ExpectedOrphanCount);
 }
Example #28
0
        private void ImplementITrackedEntityForTypeDefinition(TypeDefinition typeDef, MapDefinition mapDefinition, bool notInInheritance, Dictionary<string, AssemblyDefinition> assemblyDefinitions, Dictionary<string, List<MapDefinition>> assemblyMapDefinitions) {
            if (typeDef.Methods.Any(m => m.Name == "GetDirtyProperties")) {
                return; // type already woven
            }

            if (!this.ImplementsInterface(typeDef, typeof(ITrackedEntity))) {
                this.AddInterfaceToNonObjectAncestor(typeDef, typeof(ITrackedEntity));
            }

            // some common type definitions
            var boolTypeDef = typeDef.Module.Import(typeof(bool));
            var voidTypeDef = typeDef.Module.Import(typeof(void));
            var stringTypeDef = typeDef.Module.Import(typeof(string));
            var listStringTypeDef = typeDef.Module.Import(typeof(List<>)).MakeGenericInstanceType(stringTypeDef);
            var objectTypeDef = typeDef.Module.Import(typeof(object));

            // some column names
            const string isTrackingName = "__isTracking";

            // add isTracking field if base class
            if (this.IsBaseClass(typeDef)) {
                var _isTrackingField = new FieldDefinition(isTrackingName, FieldAttributes.Family, boolTypeDef);
                this.MakeNotDebuggerBrowsable(typeDef.Module, _isTrackingField);
                typeDef.Fields.Add(_isTrackingField);
            }

            // fields for tracking state of properties on this class only
            var nonPkCols = mapDefinition.ColumnDefinitions.Where(c => !c.IsPrimaryKey && c.Relationship != RelationshipType.OneToMany).ToList();
            foreach (var columnDefinition in nonPkCols) {
                if (this.HasPropertyInInheritanceChain(typeDef, columnDefinition.Name)) {
                    var propertyDefinition = this.GetProperty(typeDef, columnDefinition.Name);
                    if (propertyDefinition.DeclaringType.FullName == typeDef.FullName) {
                        var dirtyField = new FieldDefinition(
                            string.Format("__{0}_IsDirty", columnDefinition.Name),
                            FieldAttributes.Family,
                            boolTypeDef);
                        this.MakeNotDebuggerBrowsable(typeDef.Module, dirtyField);
                        typeDef.Fields.Add(dirtyField);

                        // handle other maps, strings, valuetype, valuetype?
                        var oldValuePropType = propertyDefinition.PropertyType;
                        if (columnDefinition.Relationship == RelationshipType.None && propertyDefinition.PropertyType.IsValueType
                            && propertyDefinition.PropertyType.Name != "Nullable`1") {
                            oldValuePropType = typeDef.Module.Import(typeof(Nullable<>)).MakeGenericInstanceType(oldValuePropType);
                            // use nullable value types
                        }

                        var oldValueField = new FieldDefinition(
                            string.Format("__{0}_OldValue", columnDefinition.Name),
                            FieldAttributes.Family,
                            oldValuePropType);
                        this.MakeNotDebuggerBrowsable(typeDef.Module, oldValueField);
                        typeDef.Fields.Add(oldValueField);
                    }
                }
            }

            // insert the instructions in to the setter
            var isTrackingField = this.GetField(typeDef, isTrackingName);
            foreach (var columnDefinition in nonPkCols) {
                if (this.HasPropertyInInheritanceChain(typeDef, columnDefinition.Name)) {
                    var propertyDefinition = this.GetProperty(typeDef, columnDefinition.Name);
                    if (propertyDefinition.DeclaringType.FullName == typeDef.FullName) {
                        var backingField = this.GetBackingField(propertyDefinition);
                        var setter = propertyDefinition.SetMethod;
                        setter.Body.Variables.Add(new VariableDefinition(boolTypeDef)); // we need a local bool
                        setter.Body.InitLocals = true;
                        var setIl = setter.Body.Instructions;
                        var setIntructions = new List<Instruction>();
                        setIntructions.Add(Instruction.Create(OpCodes.Nop));
                        setIntructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                        setIntructions.Add(Instruction.Create(OpCodes.Ldfld, isTrackingField));
                        setIntructions.Add(Instruction.Create(OpCodes.Ldc_I4_0));
                        setIntructions.Add(Instruction.Create(OpCodes.Ceq));
                        setIntructions.Add(Instruction.Create(OpCodes.Stloc_0));
                        setIntructions.Add(Instruction.Create(OpCodes.Ldloc_0));
                        var endNopInstr = Instruction.Create(OpCodes.Nop);
                        var endLdArgInstr = setIl.First();
                        setIntructions.Add(Instruction.Create(OpCodes.Brtrue, endLdArgInstr));
                        setIntructions.Add(Instruction.Create(OpCodes.Nop));
                        setIntructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                        setIntructions.Add(
                            Instruction.Create(
                                OpCodes.Ldfld,
                                typeDef.Fields.Single(f => f.Name == string.Format("__{0}_IsDirty", columnDefinition.Name))));
                        setIntructions.Add(Instruction.Create(OpCodes.Stloc_0));
                        setIntructions.Add(Instruction.Create(OpCodes.Ldloc_0));
                        setIntructions.Add(Instruction.Create(OpCodes.Brtrue, endNopInstr));
                        setIntructions.Add(Instruction.Create(OpCodes.Nop));
                        setIntructions.Add(Instruction.Create(OpCodes.Ldarg_0));

                        if (propertyDefinition.PropertyType.IsValueType) {
                            var isEnum = propertyDefinition.PropertyType.Resolve().IsEnum;
                            if (isEnum) {
                                setIntructions.Add(Instruction.Create(OpCodes.Ldfld, backingField));
                                setIntructions.Add(Instruction.Create(OpCodes.Box, propertyDefinition.PropertyType));
                            }
                            else {
                                setIntructions.Add(Instruction.Create(OpCodes.Ldflda, backingField));
                            }

                            setIntructions.Add(Instruction.Create(OpCodes.Ldarg_1));
                            if (isEnum) {
                                setIntructions.Add(Instruction.Create(OpCodes.Box, propertyDefinition.PropertyType));
                                setIntructions.Add(
                                    Instruction.Create(
                                        OpCodes.Callvirt,
                                        typeDef.Module.Import(
                                            objectTypeDef.Resolve()
                                                         .GetMethods()
                                                         .Single(
                                                             m =>
                                                             m.Name == "Equals" && m.Parameters.Count == 1
                                                             && m.Parameters.First().ParameterType.Name.ToLowerInvariant() == "object"))));
                            }
                            else if (propertyDefinition.PropertyType.Name == "Nullable`1") {
                                setIntructions.Add(Instruction.Create(OpCodes.Box, backingField.FieldType));
                                setIntructions.Add(Instruction.Create(OpCodes.Constrained, backingField.FieldType));
                                setIntructions.Add(
                                    Instruction.Create(
                                        OpCodes.Callvirt,
                                        typeDef.Module.Import(
                                            objectTypeDef.Resolve()
                                                         .GetMethods()
                                                         .Single(
                                                             m =>
                                                             m.Name == "Equals" && m.Parameters.Count == 1
                                                             && m.Parameters.First().ParameterType.Name.ToLowerInvariant() == "object"))));
                            }
                            else {
                                setIntructions.Add(
                                    Instruction.Create(
                                        OpCodes.Call,
                                        typeDef.Module.Import(
                                            propertyDefinition.PropertyType.Resolve()
                                                              .Methods.Single(
                                                                  m =>
                                                                  m.Name == "Equals" && m.Parameters.Count == 1
                                                                  && m.Parameters.First().ParameterType.Name.ToLowerInvariant() != "object"))));
                            }

                            setIntructions.Add(Instruction.Create(OpCodes.Stloc_0));
                            setIntructions.Add(Instruction.Create(OpCodes.Ldloc_0));
                            setIntructions.Add(Instruction.Create(OpCodes.Brtrue, endNopInstr));
                        }
                        else {
                            var fkPkType = columnDefinition.DbType.GetCLRType();
                            TypeReference fkTypeReference;
                            if (fkPkType.IsValueType) {
                                fkTypeReference = typeDef.Module.Import(typeof(Nullable<>).MakeGenericType(fkPkType));
                            }
                            else {
                                fkTypeReference = typeDef.Module.Import(fkPkType);
                            }

                            setIntructions.Add(Instruction.Create(OpCodes.Ldfld, backingField));
                            var hmmInstr = Instruction.Create(OpCodes.Ldc_I4_0);
                            var hmmInstr2 = Instruction.Create(OpCodes.Ldc_I4_1);

                            if (propertyDefinition.PropertyType.Name.ToLowerInvariant() == "string") {
                                var orInstr = Instruction.Create(OpCodes.Ldarg_0);
                                setIntructions.Add(Instruction.Create(OpCodes.Brtrue, orInstr));
                                setIntructions.Add(Instruction.Create(OpCodes.Ldarg_1));
                                setIntructions.Add(Instruction.Create(OpCodes.Brtrue, hmmInstr));
                                setIntructions.Add(orInstr);
                            }
                            else {
                                var orInstr = Instruction.Create(OpCodes.Ldarg_1);
                                var orInstr2 = Instruction.Create(OpCodes.Ldarg_0);
                                setIntructions.Add(Instruction.Create(OpCodes.Brtrue, orInstr));
                                setIntructions.Add(Instruction.Create(OpCodes.Ldarg_1));
                                setIntructions.Add(Instruction.Create(OpCodes.Brtrue, hmmInstr));
                                setIntructions.Add(orInstr);
                                setIntructions.Add(Instruction.Create(OpCodes.Brtrue, orInstr2));
                                setIntructions.Add(Instruction.Create(OpCodes.Ldarg_0));

                                if (fkPkType.IsValueType) {
                                    // need to call HasValue
                                    setIntructions.Add(Instruction.Create(OpCodes.Ldflda, typeDef.Fields.Single(f => f.Name == columnDefinition.DbName)));
                                    setIntructions.Add(Instruction.Create(
                                        OpCodes.Call,
                                        MakeGeneric(
                                            typeDef.Module.Import(fkTypeReference.Resolve().GetMethods().Single(m => m.Name == "get_HasValue")),
                                            typeDef.Module.Import(fkPkType))));
                                    setIntructions.Add(Instruction.Create(OpCodes.Brtrue, hmmInstr));
                                }
                                else {
                                    // check for null
                                    setIntructions.Add(Instruction.Create(OpCodes.Ldfld, typeDef.Fields.Single(f => f.Name == columnDefinition.DbName)));
                                    setIntructions.Add(Instruction.Create(OpCodes.Brtrue, hmmInstr));
                                }

                                setIntructions.Add(orInstr2);
                            }

                            setIntructions.Add(Instruction.Create(OpCodes.Ldfld, backingField));
                            setIntructions.Add(Instruction.Create(OpCodes.Brfalse, hmmInstr2));
                            setIntructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                            setIntructions.Add(Instruction.Create(OpCodes.Ldfld, backingField));
                            setIntructions.Add(Instruction.Create(OpCodes.Ldarg_1));
                            if (propertyDefinition.PropertyType.Name.ToLowerInvariant() == "string") {
                                setIntructions.Add(
                                    Instruction.Create(
                                        OpCodes.Callvirt,
                                        typeDef.Module.Import(
                                            propertyDefinition.PropertyType.Resolve()
                                                              .GetMethods()
                                                              .Single(
                                                                  m =>
                                                                  m.Name == "Equals" && m.Parameters.Count == 1
                                                                  && m.Parameters.First().ParameterType.Name.ToLowerInvariant() == "string"))));
                            }
                            else {
                                setIntructions.Add(
                                    Instruction.Create(
                                        OpCodes.Callvirt,
                                        typeDef.Module.Import(
                                            objectTypeDef.Resolve()
                                                         .GetMethods()
                                                         .Single(
                                                             m =>
                                                             m.Name == "Equals" && m.Parameters.Count == 1
                                                             && m.Parameters.First().ParameterType.Name.ToLowerInvariant() == "object"))));
                            }

                            var nopInstr = Instruction.Create(OpCodes.Nop);
                            setIntructions.Add(Instruction.Create(OpCodes.Br, nopInstr));
                            setIntructions.Add(hmmInstr2);
                            setIntructions.Add(nopInstr);
                            var nopInstr2 = Instruction.Create(OpCodes.Nop);
                            setIntructions.Add(Instruction.Create(OpCodes.Br, nopInstr2));
                            setIntructions.Add(hmmInstr);
                            setIntructions.Add(nopInstr2);
                            setIntructions.Add(Instruction.Create(OpCodes.Stloc_0));
                            setIntructions.Add(Instruction.Create(OpCodes.Ldloc_0));
                            setIntructions.Add(Instruction.Create(OpCodes.Brtrue, endNopInstr));
                            setIntructions.Add(Instruction.Create(OpCodes.Nop));
                        }

                        // it's now dirty
                        setIntructions.Add(Instruction.Create(OpCodes.Nop));

                        var topOfSetIsDirtyInstr = Instruction.Create(OpCodes.Ldarg_0);
                        if (columnDefinition.Relationship == RelationshipType.ManyToOne || columnDefinition.Relationship == RelationshipType.OneToOne) {
                            // we need to check whether the foreign key backing field has a value
                            var setToBackingFieldInstr = Instruction.Create(OpCodes.Ldarg_0);
                            setIntructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                            setIntructions.Add(Instruction.Create(OpCodes.Ldfld, backingField));
                            setIntructions.Add(Instruction.Create(OpCodes.Brtrue, setToBackingFieldInstr));
                            var fkPkType = columnDefinition.DbType.GetCLRType();
                            TypeReference fkTypeReference;
                            if (fkPkType.IsValueType) {
                                fkTypeReference = typeDef.Module.Import(typeof(Nullable<>).MakeGenericType(fkPkType));
                            }
                            else {
                                fkTypeReference = typeDef.Module.Import(fkPkType);
                            }

                            var fkField = typeDef.Fields.Single(f => f.Name == columnDefinition.DbName);
                            setIntructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                            if (fkPkType.IsValueType) {
                                // need to call HasValue
                                setIntructions.Add(Instruction.Create(OpCodes.Ldflda, fkField));
                                setIntructions.Add(Instruction.Create(
                                    OpCodes.Call,
                                    MakeGeneric(
                                        typeDef.Module.Import(fkTypeReference.Resolve().GetMethods().Single(m => m.Name == "get_HasValue")),
                                        typeDef.Module.Import(fkPkType))));
                                setIntructions.Add(Instruction.Create(OpCodes.Brfalse, setToBackingFieldInstr));
                            }
                            else {
                                // check for null
                                setIntructions.Add(Instruction.Create(OpCodes.Ldfld, fkField));
                                setIntructions.Add(Instruction.Create(OpCodes.Brfalse, setToBackingFieldInstr));
                            }

                            // need to add a variable to hold the new obj
                            var fkGeneratedVariableDef = new VariableDefinition(propertyDefinition.PropertyType);
                            propertyDefinition.SetMethod.Body.Variables.Add(fkGeneratedVariableDef);

                            // if we get here then we have an FK value but null in this backing field so we need to create a new instance of the FK and set that as the old value
                            setIntructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                            setIntructions.Add(Instruction.Create(OpCodes.Newobj, typeDef.Module.Import(propertyDefinition.PropertyType.Resolve().GetConstructors().First())));
                            setIntructions.Add(Instruction.Create(OpCodes.Stloc, fkGeneratedVariableDef));
                            setIntructions.Add(Instruction.Create(OpCodes.Ldloc, fkGeneratedVariableDef));
                            setIntructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                            if (fkPkType.IsValueType) {
                                setIntructions.Add(Instruction.Create(OpCodes.Ldflda, typeDef.Fields.Single(f => f.Name == columnDefinition.DbName)));
                                setIntructions.Add(Instruction.Create(
                                        OpCodes.Call,
                                        typeDef.Module.Import(
                                            MakeGeneric(
                                                fkField.FieldType.Resolve().GetMethods().Single(m => m.Name == "get_Value"),
                                                typeDef.Module.Import(fkPkType)))));
                                var fkMapDef = assemblyMapDefinitions.SelectMany(am => am.Value).First(m => m.TypeFullName == columnDefinition.TypeFullName);
                                var assemblyDef = assemblyDefinitions.Single(ad => ad.Value.FullName == fkMapDef.AssemblyFullName).Value;
                                var fkMapTypeRef = GetTypeDefFromFullName(columnDefinition.TypeFullName, assemblyDef);
                                setIntructions.Add(
                                    Instruction.Create(
                                        OpCodes.Callvirt,
                                        typeDef.Module.Import(
                                            this.GetProperty(fkMapTypeRef, fkMapDef.ColumnDefinitions.Single(cd => cd.IsPrimaryKey).Name).SetMethod)));
                            }
                            else {
                                setIntructions.Add(Instruction.Create(OpCodes.Ldfld, fkField));
                                var fkMapDef = assemblyMapDefinitions.SelectMany(am => am.Value).First(m => m.TypeFullName == columnDefinition.TypeFullName);
                                var assemblyDef = assemblyDefinitions.Single(ad => ad.Value.FullName == fkMapDef.AssemblyFullName).Value;
                                var fkMapTypeRef = GetTypeDefFromFullName(columnDefinition.TypeFullName, assemblyDef);
                                setIntructions.Add(Instruction.Create(
                                        OpCodes.Callvirt,
                                        typeDef.Module.Import(
                                            this.GetProperty(fkMapTypeRef, fkMapDef.ColumnDefinitions.Single(cd => cd.IsPrimaryKey).Name).SetMethod)));
                            }

                            setIntructions.Add(Instruction.Create(OpCodes.Ldloc, fkGeneratedVariableDef));
                            setIntructions.Add(Instruction.Create(OpCodes.Stfld, typeDef.Fields.Single(f => f.Name == string.Format("__{0}_OldValue", columnDefinition.Name))));
                            setIntructions.Add(Instruction.Create(OpCodes.Br, topOfSetIsDirtyInstr));

                            // set using backing field
                            setIntructions.Add(setToBackingFieldInstr);
                            setIntructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                            setIntructions.Add(Instruction.Create(OpCodes.Ldfld, backingField));
                            setIntructions.Add(
                                Instruction.Create(
                                    OpCodes.Stfld,
                                    typeDef.Fields.Single(f => f.Name == string.Format("__{0}_OldValue", columnDefinition.Name))));
                        }
                        else { 
                            setIntructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                            setIntructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                            setIntructions.Add(Instruction.Create(OpCodes.Ldfld, backingField));
                            if (columnDefinition.Relationship == RelationshipType.None && propertyDefinition.PropertyType.IsValueType
                                && propertyDefinition.PropertyType.Name != "Nullable`1") {
                                setIntructions.Add(
                                    Instruction.Create(
                                        OpCodes.Newobj,
                                        MakeGeneric(
                                            typeDef.Module.Import(
                                                typeDef.Fields.Single(f => f.Name == string.Format("__{0}_OldValue", columnDefinition.Name))
                                                       .FieldType.Resolve()
                                                       .GetConstructors()
                                                       .First()),
                                            propertyDefinition.PropertyType)));
                            }

                            setIntructions.Add(
                                Instruction.Create(
                                    OpCodes.Stfld,
                                    typeDef.Fields.Single(f => f.Name == string.Format("__{0}_OldValue", columnDefinition.Name))));
                        }

                        setIntructions.Add(topOfSetIsDirtyInstr);
                        setIntructions.Add(Instruction.Create(OpCodes.Ldc_I4_1));
                        setIntructions.Add(
                            Instruction.Create(
                                OpCodes.Stfld,
                                typeDef.Fields.Single(f => f.Name == string.Format("__{0}_IsDirty", columnDefinition.Name))));
                        setIntructions.Add(Instruction.Create(OpCodes.Nop));
                        setIntructions.Add(endNopInstr);
                        setIntructions.Reverse();
                        foreach (var instruction in setIntructions) {
                            setIl.Insert(0, instruction);
                        }
                    }
                }
            }

            // implement the ITrackedEntity methods
            // EnableTracking
            if (this.IsBaseClass(typeDef)) {
                var enableTracking = new MethodDefinition(
                    "EnableTracking",
                    MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual
                    | MethodAttributes.Final,
                    voidTypeDef);
                enableTracking.Body.Instructions.Add(Instruction.Create(OpCodes.Nop));
                enableTracking.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                enableTracking.Body.Instructions.Add(Instruction.Create(OpCodes.Ldc_I4_1));
                enableTracking.Body.Instructions.Add(Instruction.Create(OpCodes.Stfld, typeDef.Fields.Single(f => f.Name == isTrackingName)));
                enableTracking.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
                typeDef.Methods.Add(enableTracking);
            }

            // DisableTracking
            var disableTrackingMethodAttrs = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual;
            if (notInInheritance) {
                disableTrackingMethodAttrs = disableTrackingMethodAttrs | MethodAttributes.NewSlot | MethodAttributes.Final;
            }
            var disableTracking = new MethodDefinition("DisableTracking", disableTrackingMethodAttrs, voidTypeDef);
            var disableInstructions = disableTracking.Body.Instructions;
            disableInstructions.Add(Instruction.Create(OpCodes.Nop));
            disableInstructions.Add(Instruction.Create(OpCodes.Ldarg_0));
            disableInstructions.Add(Instruction.Create(OpCodes.Ldc_I4_0));
            disableInstructions.Add(Instruction.Create(OpCodes.Stfld, isTrackingField));
            foreach (var col in nonPkCols) {
                if (this.HasPropertyInInheritanceChain(typeDef, col.Name)) {
                    var propDef = this.GetProperty(typeDef, col.Name);

                    // reset isdirty
                    disableInstructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                    disableInstructions.Add(Instruction.Create(OpCodes.Ldc_I4_0));
                    disableInstructions.Add(Instruction.Create(OpCodes.Stfld, this.GetField(typeDef, string.Format("__{0}_IsDirty", col.Name))));

                    // reset oldvalue
                    disableInstructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                    var oldValueField = this.GetField(typeDef, string.Format("__{0}_OldValue", col.Name));
                    if (propDef.PropertyType.IsValueType) {
                        disableInstructions.Add(Instruction.Create(OpCodes.Ldflda, oldValueField));
                        disableInstructions.Add(Instruction.Create(OpCodes.Initobj, oldValueField.FieldType));
                    }
                    else {
                        disableInstructions.Add(Instruction.Create(OpCodes.Ldnull));
                        disableInstructions.Add(Instruction.Create(OpCodes.Stfld, oldValueField));
                    }
                }
            }

            disableInstructions.Add(Instruction.Create(OpCodes.Ret));
            typeDef.Methods.Add(disableTracking);

            // IsTrackingEnabled
            if (this.IsBaseClass(typeDef)) {
                var isTrackingEnabled = new MethodDefinition(
                    "IsTrackingEnabled",
                    MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual
                    | MethodAttributes.Final,
                    boolTypeDef);
                isTrackingEnabled.Body.Instructions.Add(Instruction.Create(OpCodes.Nop));
                isTrackingEnabled.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                isTrackingEnabled.Body.Instructions.Add(Instruction.Create(OpCodes.Ldfld, typeDef.Fields.Single(f => f.Name == isTrackingName)));
                isTrackingEnabled.Body.Instructions.Add(Instruction.Create(OpCodes.Stloc_0));
                var loadInstr = Instruction.Create(OpCodes.Ldloc_0);
                isTrackingEnabled.Body.Instructions.Add(Instruction.Create(OpCodes.Br, loadInstr));
                isTrackingEnabled.Body.Instructions.Add(loadInstr);
                isTrackingEnabled.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
                isTrackingEnabled.Body.InitLocals = true;
                isTrackingEnabled.Body.Variables.Add(new VariableDefinition(boolTypeDef));
                typeDef.Methods.Add(isTrackingEnabled);
            }

            // GetDirtyProperties
            var getDirtyPropertiesMethodAttrs = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual;
            if (notInInheritance) {
                getDirtyPropertiesMethodAttrs = getDirtyPropertiesMethodAttrs | MethodAttributes.NewSlot | MethodAttributes.Final;
            }
            var getDirtyProperties = new MethodDefinition(
                "GetDirtyProperties",
                getDirtyPropertiesMethodAttrs,
                typeDef.Module.Import(typeof(IEnumerable<>)).MakeGenericInstanceType(stringTypeDef));
            getDirtyProperties.Body.Variables.Add(new VariableDefinition("dirtyProps", listStringTypeDef));
            getDirtyProperties.Body.Variables.Add(
                new VariableDefinition(typeDef.Module.Import(typeof(IEnumerable<>)).MakeGenericInstanceType(stringTypeDef)));
            getDirtyProperties.Body.Variables.Add(new VariableDefinition(boolTypeDef));
            getDirtyProperties.Body.InitLocals = true;
            var instructions = getDirtyProperties.Body.Instructions;
            instructions.Add(Instruction.Create(OpCodes.Nop));
            var listStringContruictor =
                MakeGeneric(
                    typeDef.Module.Import(listStringTypeDef.Resolve().GetConstructors().First(c => !c.HasParameters && !c.IsStatic && c.IsPublic)),
                    stringTypeDef);
            instructions.Add(Instruction.Create(OpCodes.Newobj, listStringContruictor));
            instructions.Add(Instruction.Create(OpCodes.Stloc_0));

            var breakToInstruction = Instruction.Create(nonPkCols.Count == 1 ? OpCodes.Ldloc_0 : OpCodes.Ldarg_0);
            var addMethod = typeDef.Module.Import(listStringTypeDef.Resolve().Methods.Single(m => m.Name == "Add"));
            addMethod = MakeGeneric(addMethod, stringTypeDef);
            var visibleCols = nonPkCols.Where(c => this.HasPropertyInInheritanceChain(typeDef, c.Name)).ToList();
            for (var i = 0; i < visibleCols.Count; i++) {
                if (i == 0) {
                    instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                }

                instructions.Add(
                    Instruction.Create(OpCodes.Ldfld, this.GetField(typeDef, string.Format("__{0}_IsDirty", visibleCols.ElementAt(i).Name))));
                instructions.Add(Instruction.Create(OpCodes.Ldc_I4_0));
                instructions.Add(Instruction.Create(OpCodes.Ceq));
                instructions.Add(Instruction.Create(OpCodes.Stloc_2));
                instructions.Add(Instruction.Create(OpCodes.Ldloc_2));
                instructions.Add(Instruction.Create(OpCodes.Brtrue, breakToInstruction));
                instructions.Add(Instruction.Create(OpCodes.Nop));
                instructions.Add(Instruction.Create(OpCodes.Ldloc_0));
                instructions.Add(Instruction.Create(OpCodes.Ldstr, visibleCols.ElementAt(i).Name));
                instructions.Add(Instruction.Create(OpCodes.Callvirt, addMethod));
                instructions.Add(Instruction.Create(OpCodes.Nop));
                instructions.Add(Instruction.Create(OpCodes.Nop));
                instructions.Add(breakToInstruction);
                breakToInstruction = Instruction.Create(i == visibleCols.Count - 2 ? OpCodes.Ldloc_0 : OpCodes.Ldarg_0);
            }

            instructions.Add(Instruction.Create(OpCodes.Stloc_1));
            var retInstr = Instruction.Create(OpCodes.Ldloc_1);
            instructions.Add(Instruction.Create(OpCodes.Br, retInstr));
            instructions.Add(retInstr);
            instructions.Add(Instruction.Create(OpCodes.Ret));
            typeDef.Methods.Add(getDirtyProperties);

            // GetOldValue
            var getOldValueMethodAttrs = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual;
            if (notInInheritance) {
                getOldValueMethodAttrs = getOldValueMethodAttrs | MethodAttributes.NewSlot | MethodAttributes.Final;
            }

            var getOldValue = new MethodDefinition("GetOldValue", getOldValueMethodAttrs, objectTypeDef);
            getOldValue.Parameters.Add(new ParameterDefinition("propertyName", ParameterAttributes.None, stringTypeDef));
            getOldValue.Body.Variables.Add(new VariableDefinition(objectTypeDef));
            getOldValue.Body.Variables.Add(new VariableDefinition(stringTypeDef));
            getOldValue.Body.Variables.Add(new VariableDefinition(boolTypeDef));
            getOldValue.Body.InitLocals = true;
            var getBodyInstructions = getOldValue.Body.Instructions;
            getBodyInstructions.Add(Instruction.Create(OpCodes.Nop));
            getBodyInstructions.Add(Instruction.Create(OpCodes.Ldarg_1));
            getBodyInstructions.Add(Instruction.Create(OpCodes.Stloc_1));
            getBodyInstructions.Add(Instruction.Create(OpCodes.Ldloc_1));

            var throwExceptionTarget = Instruction.Create(OpCodes.Ldstr, "propertyName");
            var returnTarget = Instruction.Create(OpCodes.Ldloc_0);
            getBodyInstructions.Add(Instruction.Create(OpCodes.Brfalse, throwExceptionTarget));

            var switchInstructions = new List<Instruction>();
            var opEqualityRef = typeDef.Module.Import(typeof(string).GetMethods().Single(m => m.Name == "op_Equality"));
            for (var i = 0; i < visibleCols.Count; i++) {
                // generate the switch bit
                getBodyInstructions.Add(Instruction.Create(OpCodes.Ldloc_1));
                getBodyInstructions.Add(Instruction.Create(OpCodes.Ldstr, visibleCols.ElementAt(i).Name));
                getBodyInstructions.Add(Instruction.Create(OpCodes.Call, opEqualityRef));

                // generate the if bit
                var targetInstr = Instruction.Create(OpCodes.Ldarg_0);
                getBodyInstructions.Add(Instruction.Create(OpCodes.Brtrue, targetInstr));
                switchInstructions.Add(targetInstr);
                switchInstructions.Add(
                    Instruction.Create(OpCodes.Ldfld, this.GetField(typeDef, String.Format("__{0}_IsDirty", visibleCols.ElementAt(i).Name))));
                switchInstructions.Add(Instruction.Create(OpCodes.Ldc_I4_0));
                switchInstructions.Add(Instruction.Create(OpCodes.Ceq));
                switchInstructions.Add(Instruction.Create(OpCodes.Stloc_2));
                switchInstructions.Add(Instruction.Create(OpCodes.Ldloc_2));

                // generate the return bit
                var breakInstruction = Instruction.Create(OpCodes.Br, throwExceptionTarget);
                switchInstructions.Add(Instruction.Create(OpCodes.Brtrue, breakInstruction));
                switchInstructions.Add(Instruction.Create(OpCodes.Nop));
                switchInstructions.Add(Instruction.Create(OpCodes.Ldarg_0));
                switchInstructions.Add(
                    Instruction.Create(OpCodes.Ldfld, this.GetField(typeDef, String.Format("__{0}_OldValue", visibleCols.ElementAt(i).Name))));
                if (this.GetProperty(typeDef, visibleCols.ElementAt(i).Name).PropertyType.IsValueType) {
                    switchInstructions.Add(
                        Instruction.Create(
                            OpCodes.Box,
                            this.GetField(typeDef, String.Format("__{0}_OldValue", visibleCols.ElementAt(i).Name)).FieldType));
                }

                switchInstructions.Add(Instruction.Create(OpCodes.Stloc_0));
                switchInstructions.Add(Instruction.Create(OpCodes.Br, returnTarget));
                switchInstructions.Add(breakInstruction);
            }

            // add a br
            getBodyInstructions.Add(Instruction.Create(OpCodes.Br, throwExceptionTarget));

            // run them
            foreach (var instruction in switchInstructions) {
                getBodyInstructions.Add(instruction);
            }

            // handle the exception
            getBodyInstructions.Add(Instruction.Create(OpCodes.Nop));
            getBodyInstructions.Add(throwExceptionTarget);
            getBodyInstructions.Add(
                Instruction.Create(OpCodes.Ldstr, "Either the property doesn't exist or it's not dirty. Consult GetDirtyProperties first"));
            getBodyInstructions.Add(
                Instruction.Create(
                    OpCodes.Newobj,
                    typeDef.Module.Import(
                        typeof(ArgumentOutOfRangeException).GetConstructors()
                                                           .First(
                                                               c =>
                                                               c.GetParameters().All(p => p.ParameterType == typeof(string))
                                                               && c.GetParameters().Count() == 2))));
            getBodyInstructions.Add(Instruction.Create(OpCodes.Throw));
            getBodyInstructions.Add(returnTarget);
            getBodyInstructions.Add(Instruction.Create(OpCodes.Ret));
            typeDef.Methods.Add(getOldValue);
        }
Example #29
0
        public IList<TestataSollecitoDTO> GetSolleciti(int? idEsercizio, Dictionary<int, TipoIndirizzo> idCondomini, bool groupByPersone, DateTime? dataRate, DateTime? dataVersamenti, decimal? importoLimite, decimal? importoCompetenza, DateTime dataSollecito, bool stampaProprietario, int? idBanca, int idModelloLettera, string testoModelloLettera, DateTime? dataRegistrazioneContabile, int? idConto, int? idSottoConto, bool storico, bool sollecitaProprietarioConduzione)
        {
            try
            {
                var solleciti = new List<TestataSollecitoDTO>(idCondomini.Count);
                var listaSolleciti = new List<Sollecito>(idCondomini.Count);

                Esercizio esercizio = null;
                if (idEsercizio != null)
                    esercizio = _daoFactory.GetEsercizioDao().GetById(idEsercizio.Value, false);

                var dataFinale = new DateTime(DateTime.Today.Year, 12, 31);

                var modello = _daoFactory.GetModelloLetteraTestoDao().Find(idModelloLettera, false);

                // ==========================================================================================
                //  Leggo subito tutti i soggetti le rate e i versamenti
                // ==========================================================================================
                var idCondominiList = idCondomini.Select(item => item.Key).ToList();

                // rate
                var rateSoggetti = !groupByPersone ? _daoFactory.GetRataSoggettoDao().GetByEsercizioSoggetti(idEsercizio, null, idCondominiList, dataRate) : _daoFactory.GetRataSoggettoDao().GetByEsercizioPersone(idEsercizio, null, idCondominiList, dataRate);

                // soggetti
                IList<SoggettoCondominio> soggetti = null;
                IList<SoggettoCondominio> soggettiStampa = null;
                IList<Persona> persone = null;
                if (!groupByPersone)
                    soggetti = _daoFactory.GetSoggettoCondominioDao().GetAttiviByEsercizioSoggetti(esercizio, idCondominiList);
                else
                {
                    persone = _daoFactory.GetPersonaDao().GetAttiviByEsercizioSoggetti(esercizio, idCondominiList);
                    soggettiStampa = esercizio != null ? _daoFactory.GetSoggettoCondominioDao().GetAttiviByEsercizio(esercizio, dataFinale) : _daoFactory.GetSoggettoCondominioDao().GetAttiviByAzienda(modello.Azienda.ID);
                }

                // versamenti
                IList<VersamentoSoggetto> versamentiSoggetto;
                IList<VersamentiRate> versamentiRate;
                if (!groupByPersone)
                {
                    versamentiSoggetto = _daoFactory.GetVersamentoSoggettoDao().GetByEsercizioSoggetti(idEsercizio, idCondominiList);
                    versamentiRate = _daoFactory.GetVersamentiRateDao().GetByEsercizioSoggetti(idEsercizio, idCondominiList);
                }
                else
                {
                    versamentiSoggetto = _daoFactory.GetVersamentoSoggettoDao().GetByEsercizioPersone(idEsercizio, idCondominiList);
                    versamentiRate = _daoFactory.GetVersamentiRateDao().GetByEsercizioPersone(idEsercizio, idCondominiList);
                }

                DatiBancariCondomini bancaSollecito = null;
                if (idBanca != null)
                    bancaSollecito = _daoFactory.GetDatiBancariCondominiDao().Find(idBanca.Value, false);

                // ==========================================================================================
                //  Loop per i soggetti per generare i dati di stampa
                // ==========================================================================================
                foreach (var kvp in idCondomini)
                {
                    var id = kvp.Key;

                    try
                    {
                        SoggettoCondominio soggetto = null;
                        Persona persona = null;
                        if (soggetti != null)
                            soggetto = soggetti.FirstOrDefault(item => item.ID == kvp.Key) ?? _daoFactory.GetSoggettoCondominioDao().Find(id, false);
                        else if (persone != null)
                            persona = persone.FirstOrDefault(item => item.ID == kvp.Key) ?? _daoFactory.GetPersonaDao().Find(id, false);

                        if (persona == null && soggetto == null)
                        {
                            _log.ErrorFormat("Non trovata persona/soggetto - {0} - id:{1} - idCondomini:{2}", Utility.GetMethodDescription(), id, idEsercizio.GetValueOrDefault(), idCondomini != null ? string.Join(",", idCondomini.SelectMany(item => item.Key.ToString())) : "<NULL>");
                            continue;
                        }

                        var rateScadute = !groupByPersone ? rateSoggetti.Where(item => item.Soggetto.ID == kvp.Key).ToList() : rateSoggetti.Where(item => item.Soggetto.Persona.ID == kvp.Key).ToList();

                        // -----------------------------
                        // Calcolo importi
                        // -----------------------------
                        var importoScaduto = rateScadute.Sum(rata => rata.Importo);
                        var importoVersato = rateScadute.Sum(rata => rata.GetImportoVersato(dataVersamenti));

                        decimal importoVersatoSenzaRata;
                        IList<VersamentoSoggetto> altriVersamenti;
                        IList<VersamentiRate> altriVersamentiRate;
                        if (soggetto != null)
                        {
                            altriVersamenti = versamentiSoggetto.Where(item => item.Soggetto.ID == kvp.Key).ToList();
                            altriVersamentiRate = versamentiRate.Where(item => item.Versamento.Soggetto.ID == kvp.Key).ToList();
                            importoVersatoSenzaRata = altriVersamenti.Sum(versamento => versamento.Importo) - altriVersamentiRate.Sum(item => item.Importo);
                        }
                        else
                        {
                            altriVersamenti = versamentiSoggetto.Where(item => item.Soggetto.Persona.ID == kvp.Key).ToList();
                            altriVersamentiRate = versamentiRate.Where(item => item.Versamento.Soggetto.Persona.ID == kvp.Key).ToList();
                            importoVersatoSenzaRata = altriVersamenti.Sum(versamento => versamento.Importo) - altriVersamentiRate.Sum(item => item.Importo);
                        }

                        var importoDaSollecitare = importoScaduto - importoVersato - importoVersatoSenzaRata;

                        if (importoLimite == null || Math.Abs(importoDaSollecitare) >= importoLimite.Value)
                        {
                            if (persona == null)
                                persona = soggetto.Persona;
                            var condominio = soggetto != null ? soggetto.UnitaImmobiliare.GruppoStabileRiferimento.PalazzinaRiferimento.CondominioRiferimento : persona.SoggettiCondominio.Select(item => item.UnitaImmobiliare.GruppoStabileRiferimento.PalazzinaRiferimento.CondominioRiferimento).FirstOrDefault();

                            var recapito = _personaService.GetRecapito(persona, kvp.Value);

                            if (bancaSollecito == null)
                                bancaSollecito = condominio.DatiBancariPrincipale;

                            var testata = new TestataSollecitoDTO
                            {
                                Nominativo = getNominativoPresso(persona, soggetto, recapito),
                                Indirizzo = recapito != null ? recapito.GetIndirizzoCompleto() : string.Empty,
                                Cap = recapito.Cap,
                                Comune = recapito.ComuneDisplayName,
                                Titolo = Decodifica.Instance.GetElement("TitoloPersona", persona.Titolo).Descrizione,
                                ImportoCompetenza = importoCompetenza,
                                DataLettera = dataSollecito,
                                DataRate = dataRate.GetValueOrDefault(),
                                StampaProprietario = stampaProprietario,
                                GroupByPersona = groupByPersone,
                                OggettoLettera = string.IsNullOrEmpty(modello.Oggetto) ? string.Empty : modello.Oggetto.Trim(),
                                TestoLettera = formattaTestoLettera(condominio, bancaSollecito, string.IsNullOrEmpty(testoModelloLettera) ? modello.Testo : testoModelloLettera.Trim()),
                            };

                            if (soggetto != null)
                            {
                                testata.Id = soggetto.ID;
                                testata.IdSoggettoCondominio = soggetto.ID;
                                testata.IdPersona = soggetto.Persona.ID;
                                testata.IdUnitaImmobiliare = soggetto.UnitaImmobiliare.ID;
                                testata.Interno = soggetto.UnitaImmobiliare.InternoCompleto;
                                testata.Piano = soggetto.UnitaImmobiliare.Piano;
                                testata.Ordine = soggetto.UnitaImmobiliare.Ordine.GetValueOrDefault();
                                testata.DescrizioneUnitaImmobiliare = soggetto.UnitaImmobiliare.Descrizione;
                                testata.Subalterno = soggetto.UnitaImmobiliare.Subalterno;
                            }
                            else if (persona != null)
                            {
                                testata.Id = persona.ID;
                                testata.IdPersona = persona.ID;
                            }

                            var righeCondominio = condominio.IndirizzoCompleto.Split('&');
                            testata.DescrizioneCompletaCondominio = $"Condominio: {righeCondominio[0]}{Environment.NewLine}{righeCondominio[1]} - {righeCondominio[2]} - {righeCondominio[3]}";

                            // Se la stampa è per persona e viee richiesta la stampa per conoscenza al proprietario occorre leggere il soggettocondominio (soggettoStampa) bugid#8573
                            var soggettoStampa = soggetto;
                            if (soggettoStampa == null && persona != null)
                                soggettoStampa = soggettiStampa.Where(item => item.Persona.ID == persona.ID).OrderBy(item => item.UnitaImmobiliare.TipoUnitaImmobiliare.ID).FirstOrDefault();

                            if (stampaProprietario && soggettoStampa != null && soggettoStampa.Tipo == TipoSoggetto.Conduttore)
                            {
                                var proprietario = soggettoStampa.UnitaImmobiliare.GetProprietarioPrincipale(dataFinale) ??
                                                   soggettoStampa.UnitaImmobiliare.Proprietari.OrderByDescending(item => item.DataInizio.GetValueOrDefault()).FirstOrDefault();
                                if (proprietario != null)
                                    testata.NominativoProprietario = proprietario.DisplayName;

                                if (proprietario != null)
                                {
                                    var recapitoProprietario = _personaService.GetRecapito(proprietario.Persona, kvp.Value);
                                    if (recapitoProprietario != null)
                                    {
                                        testata.IndirizzoProprietario = recapitoProprietario.GetIndirizzoCompleto();
                                        testata.ComuneProprietario = recapitoProprietario.ComuneDisplayName;
                                        testata.CapProprietario = recapitoProprietario.Cap;
                                    }
                                }
                            }

                            if (recapito.Comune != null)
                                testata.Provincia = recapito.Comune.ProvinciaAppartenenza.Codice;

                            // ----------------------------------------------
                            //  Dettaglio Rate
                            // ----------------------------------------------
                            decimal importoTotaleDaVersare = 0;

                            // Rate con versamenti
                            foreach (var rata in rateScadute)
                            {
                                try
                                {
                                    var dettaglio = new DettaglioSollecitoDTO
                                    {
                                        Id = rata.ID,
                                        DataScadenza = rata.DataScadenza,
                                        IdTestataSollecito = testata.Id,
                                        ProgressivoRata = rata.PianoRatealeDettaglio?.Progressivo ?? rata.Progressivo,
                                        Importo = rata.Importo,
                                        ImportoPagato = rata.GetImportoVersato(dataVersamenti),
                                        CodiceRata = rata.ID,
                                        IdEsercizio = rata.Esercizio.ID,
                                        IdSoggetto = rata.Soggetto.ID,
                                        DescrizioneSoggetto = rata.Soggetto.DisplayName,
                                        DescrizioneEsercizio = rata.Esercizio.DisplayName
                                    };

                                    if (groupByPersone)
                                    {
                                        dettaglio.IdUnitaImmobiliare = rata.Soggetto.UnitaImmobiliare.ID;
                                        dettaglio.Interno = rata.Soggetto.UnitaImmobiliare.InternoCompleto;
                                        dettaglio.Piano = rata.Soggetto.UnitaImmobiliare.Piano;
                                        dettaglio.Ordine = rata.Soggetto.UnitaImmobiliare.Ordine.GetValueOrDefault();
                                        dettaglio.DescrizioneUnitaImmobiliare = rata.Soggetto.UnitaImmobiliare.TipoUnitaImmobiliare.Descrizione + " - " + rata.Soggetto.UnitaImmobiliare.Descrizione;
                                        dettaglio.Subalterno = rata.Soggetto.UnitaImmobiliare.Subalterno;
                                    }

                                    if (soggetto?.PercentualeRiferimento != null)
                                        dettaglio.PercentualePossesso = Convert.ToInt32(soggetto.PercentualeRiferimento.Value);
                                    dettaglio.ImportoDaVersare = dettaglio.Importo - dettaglio.ImportoPagato;

                                    if (rata.Versamenti.Count > 0)
                                        dettaglio.DataUltimoPagamento = IesiGenericCollections<VersamentiRate>.GetByIndex(rata.Versamenti, rata.Versamenti.Count - 1).Versamento.Data;

                                    testata.Dettagli.Add(dettaglio);
                                    importoTotaleDaVersare += dettaglio.ImportoDaVersare;
                                }
                                catch (Exception ex)
                                {
                                    _log.ErrorFormat("Errore inaspettato nel calcolo del sollecito per soggetto - DETTAGLIO RATE CON VERSAMENTI - {0} - soggetto:{1} - rata:{2}", ex, Utility.GetMethodDescription(), id, rata.ID);
                                    throw;
                                }
                            }

                            // Versamenti senza rate associate
                            // TODO: elaborare versamenti rate e versamentisoggetto per ottenere una lista dei versamenti fuori piano rateale
                            foreach (var versamento in altriVersamenti)
                            {
                                try
                                {
                                    var versamento1 = versamento;
                                    var importoPagato = versamento.Importo - altriVersamentiRate.Where(item => item.Versamento.ID == versamento1.ID).Sum(item => item.Importo);
                                    if (importoPagato > 0)
                                    {
                                        var dettaglio = new DettaglioSollecitoDTO
                                        {
                                            DataScadenza = DateTime.MaxValue,
                                            DataUltimoPagamento = versamento.Data,
                                            IdTestataSollecito = testata.Id,
                                            ImportoPagato = importoPagato,
                                            IdEsercizio = versamento.Esercizio.ID,
                                            IdSoggetto = versamento.Soggetto.ID,
                                            DescrizioneSoggetto = versamento.Soggetto.DisplayName,
                                            DescrizioneEsercizio = versamento.Esercizio.DisplayName,
                                            ImportoDaVersare = importoPagato * -1
                                        };

                                        if (groupByPersone)
                                        {
                                            dettaglio.IdUnitaImmobiliare = versamento.Soggetto.UnitaImmobiliare.ID;
                                            dettaglio.Interno = versamento.Soggetto.UnitaImmobiliare.InternoCompleto;
                                            dettaglio.Piano = versamento.Soggetto.UnitaImmobiliare.Piano;
                                            dettaglio.Ordine = versamento.Soggetto.UnitaImmobiliare.Ordine.GetValueOrDefault();
                                            dettaglio.DescrizioneUnitaImmobiliare = versamento.Soggetto.UnitaImmobiliare.TipoUnitaImmobiliare.Descrizione + " - " + versamento.Soggetto.UnitaImmobiliare.Descrizione;
                                            dettaglio.Subalterno = versamento.Soggetto.UnitaImmobiliare.Subalterno;
                                        }

                                        if (soggetto?.PercentualeRiferimento != null)
                                            dettaglio.PercentualePossesso = Convert.ToInt32(soggetto.PercentualeRiferimento.Value);

                                        testata.Dettagli.Add(dettaglio);
                                        importoTotaleDaVersare -= dettaglio.ImportoPagato;
                                    }
                                }
                                catch (Exception ex)
                                {
                                    _log.ErrorFormat("Errore inaspettato nel calcolo del sollecito per soggetto - VERSAMENTO SENZA RATE ASSOCIATE - {0} - Id:{1} - versamento:{2}", ex, Utility.GetMethodDescription(), id, versamento.ID);
                                    throw;
                                }
                            }

                            testata.ImportoTotaleDaVersare = importoTotaleDaVersare;
                            testata.TipoIndirizzo = kvp.Value;
                            solleciti.Add(testata);
                            
                            // ================================================================================
                            //  Se richiesto aggiungo per i proprietari le rate di conduzione
                            // ================================================================================
                            if (sollecitaProprietarioConduzione)
                            {
                                if (soggetto != null)
                                {
                                    var conduttori = soggetto.UnitaImmobiliare.Conduttori;
                                    if (conduttori.Count > 0)
                                    {
                                        var idConduttori = new List<int>(conduttori.Count);
                                        idConduttori.AddRange(conduttori.Select(soggettoCondominio => soggettoCondominio.ID));
                                        var rateConduttori = _rateService.GetRataByEsercizioSoggetti(idEsercizio, idConduttori, dataRate, false);
                                        var versamentiConduttori = _versamentiService.GetVersamentiByEsercizioSoggetti(idEsercizio, idConduttori);

                                        var importoCompetenzaConduzione = rateConduttori.Sum(item => item.Importo.GetValueOrDefault());
                                        var importoVersatoConduzione = versamentiConduttori.Sum(item => item.Importo);
                                        testata.ImportoCompetenza += importoCompetenzaConduzione;
                                        testata.ImportoTotaleDaVersare += (importoCompetenzaConduzione - importoVersatoConduzione);

                                        // Dettaglio rate
                                        IList<VersamentoSoggetto> versamentiElaborati = new List<VersamentoSoggetto>();
                                        foreach (var rataSoggettoDTO in rateConduttori)
                                        {
                                            var dettaglio = new DettaglioSollecitoDTO
                                            {
                                                Id = rataSoggettoDTO.ID,
                                                DataScadenza = rataSoggettoDTO.DataScadenza,
                                                IdTestataSollecito = testata.Id,
                                                ProgressivoRata = rataSoggettoDTO.Progressivo,
                                                Importo = rataSoggettoDTO.Importo.GetValueOrDefault(),
                                                ImportoPagato = rataSoggettoDTO.ImportoPagato.GetValueOrDefault(),
                                                CodiceRata = rataSoggettoDTO.ID,
                                                IdEsercizio = rataSoggettoDTO.IdEsercizio,
                                                IdSoggetto = rataSoggettoDTO.IdSoggettoCondominio,
                                                DescrizioneSoggetto = rataSoggettoDTO.DescrizioneSoggettoCondominio,
                                                DescrizioneEsercizio = rataSoggettoDTO.DescrizioneEsercizio
                                            };

                                            if (groupByPersone)
                                            {
                                                dettaglio.IdUnitaImmobiliare = rataSoggettoDTO.IdUnitaImmobiliare;
                                                dettaglio.Ordine = rataSoggettoDTO.OrdineUnitaImmobiliare;
                                                dettaglio.DescrizioneUnitaImmobiliare = rataSoggettoDTO.DescrizioneUnitaImmobiliare;
                                                dettaglio.Subalterno = rataSoggettoDTO.Subalterno;
                                            }

                                            if (soggetto?.PercentualeRiferimento != null)
                                                dettaglio.PercentualePossesso = Convert.ToInt32(soggetto.PercentualeRiferimento.Value);
                                            dettaglio.ImportoDaVersare = dettaglio.Importo - dettaglio.ImportoPagato;

                                            var rata = _daoFactory.GetRataSoggettoDao().Find(rataSoggettoDTO.ID, false);
                                            if (rata != null && rata.Versamenti.Count > 0)
                                            {
                                                foreach (var rateVersamenti in rata.Versamenti)
                                                    versamentiElaborati.Add(rateVersamenti.Versamento);

                                                dettaglio.DataUltimoPagamento = IesiGenericCollections<VersamentiRate>.GetByIndex(rata.Versamenti, rata.Versamenti.Count - 1).Versamento.Data;
                                            }

                                            testata.Dettagli.Add(dettaglio);
                                        }
                                        
                                        // Versamenti fuori piano rateale
                                        foreach (var versamentoSoggetto in versamentiConduttori)
                                        {
                                            if (!versamentiElaborati.Contains(versamentoSoggetto) && versamentoSoggetto.Importo > 0)
                                            {
                                                var dettaglioVersamento = new DettaglioSollecitoDTO
                                                {
                                                    DataScadenza = DateTime.MaxValue,
                                                    DataUltimoPagamento = versamentoSoggetto.Data,
                                                    IdTestataSollecito = testata.Id,
                                                    ImportoPagato = versamentoSoggetto.Importo,
                                                    IdEsercizio = versamentoSoggetto.Esercizio.ID,
                                                    IdSoggetto = versamentoSoggetto.Soggetto.ID,
                                                    DescrizioneSoggetto = versamentoSoggetto.Soggetto.DisplayName,
                                                    DescrizioneEsercizio = versamentoSoggetto.Esercizio.DisplayName,
                                                    ImportoDaVersare = versamentoSoggetto.Importo * -1
                                                };

                                                if (groupByPersone)
                                                {
                                                    dettaglioVersamento.IdUnitaImmobiliare = versamentoSoggetto.Soggetto.UnitaImmobiliare.ID;
                                                    dettaglioVersamento.Interno = versamentoSoggetto.Soggetto.UnitaImmobiliare.InternoCompleto;
                                                    dettaglioVersamento.Piano = versamentoSoggetto.Soggetto.UnitaImmobiliare.Piano;
                                                    dettaglioVersamento.Ordine = versamentoSoggetto.Soggetto.UnitaImmobiliare.Ordine.GetValueOrDefault();
                                                    dettaglioVersamento.DescrizioneUnitaImmobiliare = versamentoSoggetto.Soggetto.UnitaImmobiliare.TipoUnitaImmobiliare.Descrizione + " - " + versamentoSoggetto.Soggetto.UnitaImmobiliare.Descrizione;
                                                    dettaglioVersamento.Subalterno = versamentoSoggetto.Soggetto.UnitaImmobiliare.Subalterno;
                                                }

                                                testata.Dettagli.Add(dettaglioVersamento);
                                            }
                                        }
                                    }

                                }
                            }

                            // ================================================================
                            // Creo gli oggetti sollecito se richiesto
                            // ================================================================
                            if (storico)
                            {
                                var esercizioSollecito = (esercizio ?? _daoFactory.GetEsercizioDao().GetEsercizioCompetenza(condominio, DateTime.Today)) ?? _esercizioService.GetUltimoEsercizioOrdinario(condominio.ID);
                                if (esercizioSollecito != null)
                                {
                                    Sollecito sollecito;

                                    var testoLettera = testoModelloLettera;
                                    if (string.IsNullOrEmpty(testoLettera))
                                        testoLettera = modello.Testo;
                                    if (!string.IsNullOrEmpty(testoLettera))
                                        testoLettera = testoLettera.Trim();
                                    if (soggetto != null)
                                    {
                                        sollecito = new Sollecito(esercizioSollecito, soggetto, dataSollecito, dataRate.GetValueOrDefault(), importoLimite.GetValueOrDefault(), testata.ImportoTotaleDaVersare, bancaSollecito, modello.Oggetto, testoLettera)
                                        {
                                            ImportoCompetenza = importoCompetenza,
                                            TipoIndirizzo = kvp.Value,
                                            StampaProprietario = stampaProprietario,
                                            GroupByPersona = groupByPersone
                                        };
                                    }
                                    else
                                    {
                                        sollecito = new Sollecito(esercizioSollecito, persona, dataSollecito, dataRate.GetValueOrDefault(), importoLimite.GetValueOrDefault(), testata.ImportoTotaleDaVersare, bancaSollecito, modello.Oggetto, testoLettera)
                                        {
                                            ImportoCompetenza = importoCompetenza,
                                            TipoIndirizzo = kvp.Value,
                                            StampaProprietario = stampaProprietario,
                                            GroupByPersona = groupByPersone
                                        };
                                    }

                                    foreach (var dett in testata.Dettagli)
                                    {
                                        var dettaglio = new DettaglioSollecito(sollecito, dett.Importo, dett.ImportoDaVersare, dett.ImportoPagato)
                                        {
                                            DataUltimoPagamento = dett.DataUltimoPagamento
                                        };

                                        if (dett.DataScadenza != DateTime.MaxValue)
                                            dettaglio.DataScadenzaRata = dett.DataScadenza;

                                        if (dett.CodiceRata != null)
                                            dettaglio.Rata = rateSoggetti.FirstOrDefault(item => item.ID == dett.CodiceRata) ?? _daoFactory.GetRataSoggettoDao().GetById(dett.CodiceRata.Value, false);
                                    }
                                    listaSolleciti.Add(sollecito);
                                    _daoFactory.GetSollecitoDao().SaveOrUpdate(sollecito);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.ErrorFormat("Errore inaspettato nel calcolo del sollecito per soggetto - {0} - esercizio:{1} - soggetto:{2}", ex, Utility.GetMethodDescription(), idEsercizio, id);
                        throw;
                    }
                }

                // ================================================================================================================
                // Rimuovo eventuali dettagli con importo a 0
                // ================================================================================================================
                foreach (var testataSollecitoDTO in solleciti)
                {
                    var dettagliDaRimuovere = testataSollecitoDTO.Dettagli.Where(dettaglioSollecitoDTO => dettaglioSollecitoDTO.Importo == 0 && dettaglioSollecitoDTO.ImportoDaVersare == 0 && dettaglioSollecitoDTO.ImportoPagato == 0).ToList();

                    foreach (var dettaglioSollecitoDTO in dettagliDaRimuovere)
                        testataSollecitoDTO.Dettagli.Remove(dettaglioSollecitoDTO);
                }

                // ================================================================================================================
                // Creo i movimenti di addebito - una testata per ogni Esercizio (possibile solo se è stato richiesto lo STORICO)
                // ================================================================================================================
                try
                {
                    if (importoCompetenza > 0)
                    {
                        var sollecitiPerEsercizio = listaSolleciti.GroupBy(item => item.Esercizio);

                        foreach (var sollecitiEsercizio in sollecitiPerEsercizio)
                        {
                            var esercizioAddebito = sollecitiEsercizio.Key;
                            Conto contoAddebito = null;
                            SottoConto sottoContoAddebito = null;
                            if (idConto != null)
                            {
                                contoAddebito = _daoFactory.GetContoDao().Find(idConto.Value, false);
                                if (idSottoConto != null)
                                    sottoContoAddebito = _daoFactory.GetSottoContoDao().GetById(idSottoConto.Value, false);
                            }
                            if (contoAddebito == null)
                            {
                                sottoContoAddebito = _daoFactory.GetSottoContoDao().GetAddebitoCompetenzeByEsercizio(esercizioAddebito.ID, esercizioAddebito.CondominioRiferimento.ID);
                                if (sottoContoAddebito != null)
                                    contoAddebito = sottoContoAddebito.ContoRiferimento;
                            }

                            if (contoAddebito != null && esercizioAddebito != null)
                            {
                                var testata = _movimentiContabileService.SetMovimentiSollecito(esercizioAddebito, sollecitiEsercizio.ToList(), dataRegistrazioneContabile.GetValueOrDefault(), contoAddebito, sottoContoAddebito);

                                // -------------------------------------------
                                // Genero il protocollo di archiviazione
                                // -------------------------------------------
                                var progressivo = _protocolloService.GetProgressivo(TipoProtocollo.Fattura, testata.EsercizioRiferimento.DataApertura.GetValueOrDefault().Year, testata.EsercizioRiferimento.CondominioRiferimento);
                                if (progressivo.Progressivo != null)
                                {
                                    testata.NumeroProtocollo = progressivo.Progressivo.Value;
                                    testata.AnnoArchiviazioneOttica = testata.EsercizioRiferimento.DataApertura.GetValueOrDefault().Year;
                                }
                                else
                                {
                                    _log.ErrorFormat("Errore imprevisto nella generazione del protocollo di archiviazione - {0} - esercizio:{1} - testata:{2} - message:{3}", Utility.GetMethodDescription(), esercizioAddebito.ID, testata.ID, progressivo.Message);
                                }

                            }

                        }
                    }
                }
                catch (Exception ex)
                {
                    _log.ErrorFormat("Errore inaspettato nel calcolo del sollecito per soggetto - CREAZIONE MOVIMENTI CONTABILI - {0} - esercizio:{1}", ex, Utility.GetMethodDescription(), idEsercizio);
                    throw;
                }

                return solleciti;

            }
            catch (Exception ex)
            {
                _log.ErrorFormat("Errore inaspettato nel calcolo del sollecito per soggetto - CREAZIONE MOVIMENTI CONTABILI - {0} - esercizio:{1} - groupByPersone:{2} - dataRate:{3} - dataVersamenti:{4} - importoLimite:{5} - importoCompetenza:{6} - dataSollecito:{7} - stampaProprietario:{8} - idBanca:{9} - idModelloLettera:{10} - dataRegistrazioneContabile:{11} - idConto:{12} - idSottoConto:{13} - storico:{14} - esercizio:{15}", ex, Utility.GetMethodDescription(), idEsercizio.GetValueOrDefault(), groupByPersone, dataRate, dataVersamenti, importoLimite, importoCompetenza, dataSollecito, stampaProprietario, idBanca, idModelloLettera, dataRegistrazioneContabile, idConto, idSottoConto, storico, idEsercizio);
                throw;
            }

        }
        private static async Task<HashSet<SourceDependencyInfo>> GatherPackageDependencyInfo(ResolutionContext context,
            IEnumerable<string> primaryTargetIds,
            IEnumerable<string> allTargetIds,
            IEnumerable<PackageIdentity> primaryTargets,
            IEnumerable<PackageIdentity> allTargets,
            NuGetFramework targetFramework,
            IEnumerable<SourceRepository> primarySources,
            IEnumerable<SourceRepository> allSources,
            CancellationToken token)
        {
            // get a distinct set of packages from all repos
            var combinedResults = new HashSet<SourceDependencyInfo>(PackageIdentity.Comparer);

            // get the dependency info resources for each repo
            // primary and all may share the same resources
            var depResources = new Dictionary<SourceRepository, Task<DepedencyInfoResource>>();
            foreach (var source in allSources.Concat(primarySources))
            {
                if (!depResources.ContainsKey(source))
                {
                    depResources.Add(source, source.GetResourceAsync<DepedencyInfoResource>(token));
                }
            }

            // a resource may be null, if it is exclude this source from the gather
            var primaryDependencyResources = new List<Tuple<SourceRepository, DepedencyInfoResource>>();

            foreach (var source in primarySources)
            {
                var resource = await depResources[source];

                if (source != null)
                {
                    primaryDependencyResources.Add(new Tuple<SourceRepository, DepedencyInfoResource>(source, resource));
                }
            }

            var allDependencyResources = new List<Tuple<SourceRepository, DepedencyInfoResource>>();

            foreach (var source in allSources)
            {
                var resource = await depResources[source];

                if (source != null)
                {
                    allDependencyResources.Add(new Tuple<SourceRepository, DepedencyInfoResource>(source, resource));
                }
            }

            // track which sources have been searched for each package id
            Dictionary<SourceRepository, HashSet<string>> sourceToPackageIdsChecked = new Dictionary<SourceRepository, HashSet<string>>();

            UpdateSourceToPackageIdsChecked(sourceToPackageIdsChecked, primaryDependencyResources);
            UpdateSourceToPackageIdsChecked(sourceToPackageIdsChecked, allDependencyResources);
            
            if (primaryTargetIds != null && allTargetIds != null)
            {
                // First, check for primary targets alone against primary source repositories alone
                var primaryIdsAsAllDiscoveredIds = new HashSet<string>(primaryTargetIds);
                await ProcessMissingPackageIds(combinedResults, primaryIdsAsAllDiscoveredIds, sourceToPackageIdsChecked,
                    primaryDependencyResources, targetFramework, context, false, token);

                string missingPrimaryPackageId = primaryTargetIds.Where(p => !combinedResults.Any(c => c.Id.Equals(p, StringComparison.OrdinalIgnoreCase))).FirstOrDefault();
                if (!String.IsNullOrEmpty(missingPrimaryPackageId))
                {
                    throw new InvalidOperationException(String.Format(Strings.PackageNotFound, missingPrimaryPackageId));
                }

                var allIdsAsAllDiscoveredIds = new HashSet<string>(allTargetIds);
                await ProcessMissingPackageIds(combinedResults, allIdsAsAllDiscoveredIds, sourceToPackageIdsChecked,
                    primaryDependencyResources, targetFramework, context, false, token);
            }
            else
            {
                Debug.Assert(primaryTargets != null && allTargets != null);

                // First, check for primary targets alone against primary source repositories alone
                await ProcessMissingPackageIdentities(combinedResults, primaryTargets, sourceToPackageIdsChecked,
                    primaryDependencyResources, targetFramework, context, false, token);

                PackageIdentity missingPrimaryPackageIdentity = primaryTargets.Where(p => !combinedResults.Any(c => c.Equals(p))).FirstOrDefault();
                if (missingPrimaryPackageIdentity != null)
                {
                    throw new InvalidOperationException(String.Format(Strings.PackageNotFound, missingPrimaryPackageIdentity));
                }

                await ProcessMissingPackageIdentities(combinedResults, allTargets, sourceToPackageIdsChecked,
                    allDependencyResources, targetFramework, context, true, token);
            }

            // loop until we finish a full iteration with no new ids discovered
            bool complete = false;

            while (!complete)
            {
                HashSet<string> allDiscoveredIds = new HashSet<string>(sourceToPackageIdsChecked.SelectMany(e => e.Value), StringComparer.OrdinalIgnoreCase);
                complete = await ProcessMissingPackageIds(combinedResults, allDiscoveredIds, sourceToPackageIdsChecked, allDependencyResources, targetFramework, context, true, token);
            }

            return combinedResults;
        }