public void DeletePost(EntityReference forumPost)
        {
            if (forumPost == null)
            {
                throw new ArgumentNullException("forumPost");
            }

            var serviceContext = Dependencies.GetServiceContextForWrite();

            var post = serviceContext.RetrieveSingle(new Fetch
            {
                Entity = new FetchEntity("adx_communityforumpost")
                {
                    Filters = new[] { new Filter {
                                          Conditions = new[]
                                          {
                                              new Condition("adx_communityforumpostid", ConditionOperator.Equal, forumPost.Id),
                                              new Condition("adx_forumthreadid", ConditionOperator.Equal, this.ForumThread.Id)
                                          }
                                      } }
                }
            });

            if (post == null)
            {
                throw new ArgumentException("Unable to find {0} {1}.".FormatWith(forumPost.LogicalName, forumPost.Id), "forumPost");
            }

            var thread = SelectEntity(serviceContext);

            if (thread == null)
            {
                serviceContext.DeleteObject(post);
                serviceContext.SaveChanges();

                return;
            }

            var postReference = post.ToEntityReference();

            var counterStrategy = Dependencies.GetCounterStrategy();
            var threadPostCount = counterStrategy.GetForumThreadPostCount(serviceContext, thread);
            var threadUpdate    = new Entity(thread.LogicalName)
            {
                Id = thread.Id
            };

            threadUpdate["adx_postcount"] = threadPostCount < 1 ? 0 : threadPostCount - 1;

            // If deleting first post, delete entire thread
            if (Equals(thread.GetAttributeValue <EntityReference>("adx_firstpostid"), postReference))
            {
                var forumDataAdapter = new ForumDataAdapter(thread.GetAttributeValue <EntityReference>("adx_forumid"), Dependencies);

                forumDataAdapter.DeleteThread(thread.ToEntityReference());
            }

            // Determine the new last post in the thread.
            else if (Equals(thread.GetAttributeValue <EntityReference>("adx_lastpostid"), postReference))
            {
                var lastPostFetch = new Fetch
                {
                    Entity = new FetchEntity("adx_communityforumpost")
                    {
                        Filters = new[]
                        {
                            new Filter
                            {
                                Conditions = new[]
                                {
                                    new Condition("adx_forumthreadid", ConditionOperator.Equal, thread.Id),
                                    new Condition("adx_communityforumpostid", ConditionOperator.NotEqual, post.Id)
                                }
                            }
                        },
                        Orders = new[] { new Order("adx_date", OrderType.Descending) }
                    },
                    PageNumber = 1,
                    PageSize   = 1
                };

                var lastPost = serviceContext.RetrieveSingle(lastPostFetch);

                if (lastPost == null)
                {
                    throw new InvalidOperationException("Unable to determine new last post in thread.");
                }

                threadUpdate["adx_lastpostid"]   = lastPost.ToEntityReference();
                threadUpdate["adx_lastpostdate"] = lastPost.GetAttributeValue <DateTime?>("adx_date");

                serviceContext.Detach(thread);
                serviceContext.Attach(threadUpdate);
                serviceContext.UpdateObject(threadUpdate);
                serviceContext.DeleteObject(post);
                serviceContext.SaveChanges();
            }

            var forumId = thread.GetAttributeValue <EntityReference>("adx_forumid");

            if (forumId == null)
            {
                return;
            }

            var forumServiceContext = Dependencies.GetServiceContextForWrite();

            var forum = forumServiceContext.RetrieveSingle("adx_communityforum", "adx_communityforumid", forumId.Id, FetchAttribute.All);

            if (forum == null)
            {
                return;
            }

            // Update forum counts and pointers.
            var forumCounts = counterStrategy.GetForumCounts(forumServiceContext, forum);
            var forumUpdate = new Entity(forum.LogicalName)
            {
                Id = forum.Id
            };

            forumUpdate["adx_postcount"] = forumCounts.PostCount < 1 ? 0 : forumCounts.PostCount - 1;

            var forumLastPost = forum.GetAttributeValue <EntityReference>("adx_lastpostid");

            if (Equals(forumLastPost, postReference))
            {
                var lastUpdatedThreadFetch = new Fetch
                {
                    Entity = new FetchEntity("adx_communityforumthread")
                    {
                        Filters = new[]
                        {
                            new Filter
                            {
                                Conditions = new[]
                                {
                                    new Condition("adx_forumid", ConditionOperator.Equal, forum.Id),
                                    new Condition("adx_lastpostid", ConditionOperator.NotNull)
                                }
                            }
                        },
                        Orders = new[] { new Order("adx_lastpostdate", OrderType.Descending) }
                    },
                    PageNumber = 1,
                    PageSize   = 1
                };

                var lastUpdatedThread = forumServiceContext.RetrieveSingle(lastUpdatedThreadFetch);

                forumUpdate["adx_lastpostid"] = lastUpdatedThread == null
                                        ? null
                                        : lastUpdatedThread.GetAttributeValue <EntityReference>("adx_lastpostid");
            }

            forumServiceContext.Detach(forum);
            forumServiceContext.Attach(forumUpdate);
            forumServiceContext.UpdateObject(forumUpdate);
            forumServiceContext.SaveChanges();

            if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage))
            {
                PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Forum, HttpContext.Current, "delete_forum_post", 1, forumPost, "delete");
            }
        }
        public IForumPost CreatePost(IForumPostSubmission forumPost, bool incrementForumThreadCount = false)
        {
            if (forumPost == null)
            {
                throw new ArgumentNullException("forumPost");
            }

            ADXTrace.Instance.TraceInfo(TraceCategory.Application, "Start");

            var serviceContext = Dependencies.GetServiceContextForWrite();

            var thread = Select();

            var locked = thread.Locked;

            if (locked)
            {
                throw new InvalidOperationException("You can't create a new post because the forum is locked.");
            }

            var entity = new Entity("adx_communityforumpost");

            entity["adx_forumthreadid"]    = ForumThread;
            entity["adx_name"]             = Truncate(forumPost.Name, 100);
            entity["adx_isanswer"]         = forumPost.IsAnswer;
            entity["adx_authorid"]         = forumPost.Author.EntityReference;
            entity["adx_date"]             = forumPost.PostedOn;
            entity["adx_content"]          = forumPost.Content;
            entity["adx_helpfulvotecount"] = forumPost.HelpfulVoteCount;

            serviceContext.AddObject(entity);
            serviceContext.SaveChanges();

            var threadEntity = SelectEntity(serviceContext);
            var threadUpdate = new Entity(threadEntity.LogicalName)
            {
                Id = threadEntity.Id
            };

            threadUpdate["adx_lastpostdate"] = forumPost.PostedOn;
            threadUpdate["adx_lastpostid"]   = entity.ToEntityReference();
            threadUpdate["adx_postcount"]    = threadEntity.GetAttributeValue <int?>("adx_postcount").GetValueOrDefault() + 1;

            if (threadEntity.GetAttributeValue <EntityReference>("adx_firstpostid") == null)
            {
                threadUpdate["adx_firstpostid"] = entity.ToEntityReference();
            }

            serviceContext.Detach(threadEntity);
            serviceContext.Attach(threadUpdate);
            serviceContext.UpdateObject(threadUpdate);
            serviceContext.SaveChanges();

            var entityReference = entity.ToEntityReference();

            var forumDataAdapter = new ForumDataAdapter(threadEntity.GetAttributeValue <EntityReference>("adx_forumid"), Dependencies);

            forumDataAdapter.UpdateLatestPost(entityReference, incrementForumThreadCount);

            foreach (var attachment in forumPost.Attachments)
            {
                IAnnotationDataAdapter da = new AnnotationDataAdapter(Dependencies);
                da.CreateAnnotation(entityReference, string.Empty, string.Empty, attachment.Name, attachment.ContentType,
                                    attachment.Content);
            }

            var post = SelectPost(entityReference.Id);

            ADXTrace.Instance.TraceInfo(TraceCategory.Application, "End");

            if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage))
            {
                PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Forum, HttpContext.Current, "create_forum_post", 1, post.Entity.ToEntityReference(), "create");
            }

            return(post);
        }