/// <summary>
 /// Слить тред с его частью.
 /// </summary>
 /// <param name="src">Исходный тред.</param>
 /// <param name="part">Часть треда.</param>
 public void MergeTree(ThreadTree src, ThreadTreePartial part)
 {
     var linkHashService = Services.GetServiceOrThrow<ILinkHashService>();
     if (src.Posts == null)
     {
         src.Posts = new List<PostTree>();
     }
     var oldPosts = src.Posts.DeduplicateToDictionary(p => linkHashService.GetLinkHash(p.Link));
     foreach (var np in part.Posts)
     {
         oldPosts[linkHashService.GetLinkHash(np.Link)] = np;
     }
     src.Posts = oldPosts.Values.ToList();
     for (int i = 0; i < src.Posts.Count; i++)
     {
         src.Posts[i].Counter = i + 1;
     }
 }
 /// <summary>
 /// Парсить частичные данные треда.
 /// </summary>
 /// <param name="data">Данные.</param>
 /// <param name="link">Ссылка.</param>
 /// <returns>Результат.</returns>
 public ThreadTreePartial ParseThreadPartial(BoardPost2[] data, ThreadPartLink link)
 {
     var threadLink = new ThreadLink()
     {
         Engine = CoreConstants.Engine.Makaba,
         Board = link.Board,
         Thread = link.Thread
     };
     var result = new ThreadTreePartial()
     {
         Link = threadLink,
         Posts = data.OrderBy(p => p.Number.TryParseWithDefault()).Select(p => Parse(p, threadLink, false)).ToList(),
         Extensions = new List<PostTreeCollectionExtension>(),
         ParentLink = new BoardLink()
         {
             Engine = CoreConstants.Engine.Makaba,
             Board = link.Board,
         },
     };
     return result;
 }