Пример #1
0
        public override ACL GetACL(Type type)
        {
            ACL acl = base.GetACL(type);

            acl.Add(new ACLEveryoneAllowRetrieve());
            acl.Add(new ACLAccount(mInstance.AccountBlog.Account, DataOperation.All));

            if (ManagedDiscussion.IsDiscussionType(type))
            {
                if (mInstance.EnableComments && mInstance.AccountBlog.EnableComments)
                {
                    acl.Add(new ACLAuthenticatedAllowCreate());
                }
            }

            foreach (AccountBlogAuthor author in Collection <AccountBlogAuthor> .GetSafeCollection(mInstance.AccountBlog.AccountBlogAuthors))
            {
                int op = (int)DataOperation.None;
                if (author.AllowDelete)
                {
                    op |= (int)DataOperation.Delete;
                }
                if (author.AllowEdit)
                {
                    op |= (int)DataOperation.Update;
                }
                if (author.AllowPost)
                {
                    op |= (int)DataOperation.Create;
                }
                acl.Add(new ACLAccount(author.Account, op));
            }
            return(acl);
        }
Пример #2
0
        public override ACL GetACL(Type type)
        {
            if (ManagedDiscussion.IsDiscussionType(type))
            {
                ACL acl = base.GetACL(type);
                // members can post articles, admins can edit and delete
                foreach (AccountGroupAccount account in Collection <AccountGroupAccount> .GetSafeCollection(mInstance.AccountGroupAccounts))
                {
                    acl.Add(new ACLAccount(account.Account, account.IsAdministrator
                        ? DataOperation.All
                        : DataOperation.Create | DataOperation.Retreive));
                }

                return(acl);
            }
            else
            {
                ACL acl = base.GetACL(type);
                // everyone can create a group
                acl.Add(new ACLAuthenticatedAllowCreate());
                // everyone is able to see a group (only name/description)
                acl.Add(new ACLEveryoneAllowRetrieve());
                // members can edit or see the group depending on their permissions
                foreach (AccountGroupAccount account in Collection <AccountGroupAccount> .GetSafeCollection(mInstance.AccountGroupAccounts))
                {
                    acl.Add(new ACLAccount(account.Account, account.IsAdministrator
                        ? DataOperation.All
                        : DataOperation.Retreive));
                }
                return(acl);
            }
        }
Пример #3
0
        public void MigrateToAccount(Account newowner, ManagedSecurityContext sec)
        {
            // migrate pictures
            IList <AccountEventPicture> pictures = Session.CreateCriteria(typeof(AccountEventPicture))
                                                   .Add(Expression.Eq("Account.Id", mInstance.Account.Id))
                                                   .Add(Expression.Eq("AccountEvent.Id", mInstance.Id))
                                                   .List <AccountEventPicture>();

            foreach (AccountEventPicture pp in pictures)
            {
                ManagedAccountEventPicture mpp = new ManagedAccountEventPicture(Session, pp);
                mpp.MigrateToAccount(newowner, sec);
            }

            // migrate review discussion
            Discussion d = ManagedDiscussion.Find(
                Session, mInstance.Account.Id, typeof(AccountEvent), mInstance.Id, sec);

            if (d != null)
            {
                ManagedDiscussion md = new ManagedDiscussion(Session, d);
                md.MigrateToAccount(newowner, sec);
            }

            mInstance.Account = newowner;
            Session.Save(mInstance);
        }
Пример #4
0
        public static Discussion Find(
            ISession session,
            int accountid,
            Type type,
            int objectid,
            ManagedSecurityContext sec)
        {
            DataObject dataobject = ManagedDataObject.FindObject(session, type);

            Discussion instance = (Discussion)
                                  session.CreateCriteria(typeof(Discussion))
                                  .Add(Expression.Eq("DataObject.Id", dataobject.Id))
                                  .Add(Expression.Eq("Account.Id", accountid))
                                  .Add(Expression.Eq("ObjectId", objectid))
                                  .Add(Expression.Eq("Personal", true))
                                  .SetMaxResults(1)
                                  .UniqueResult();

            if (instance == null)
            {
                return(null);
            }

            ManagedDiscussion m_instance = new ManagedDiscussion(session, instance);

            m_instance.GetACL().Check(sec, DataOperation.Retreive);
            return(instance);
        }
Пример #5
0
        public override void Delete(ManagedSecurityContext sec)
        {
            ManagedDiscussion.FindAndDelete(
                Session, mInstance.Account.Id, typeof(Place), mInstance.Id, sec);

            foreach (PlacePicture pic in Collection <PlacePicture> .GetSafeCollection(mInstance.PlacePictures))
            {
                new ManagedPlacePicture(Session, pic).Delete(sec);
            }

            foreach (AccountEvent evt in Collection <AccountEvent> .GetSafeCollection(mInstance.AccountEvents))
            {
                new ManagedAccountEvent(Session, evt).Delete(sec);
            }

            ManagedMadLibInstance.Delete(Session, sec, "Place", Id);
            Session.Delete(string.Format("FROM AccountPlace f WHERE f.Place.Id = {0}", Id));
            Session.Delete(string.Format("FROM AccountGroupPlace f WHERE f.Place.Id = {0}", Id));
            Session.Delete(string.Format("FROM AccountPlaceRequest f WHERE f.Place.Id = {0}", Id));
            Session.Delete(string.Format("FROM AccountPlaceFavorite f WHERE f.Place.Id = {0}", Id));
            Session.Delete(string.Format("FROM PlaceQueueItem q WHERE q.Place.Id = {0}", Id));
            Session.Delete(string.Format("FROM PlaceChangeRequest r WHERE r.Place.Id = {0}", Id));
            ManagedFeature.Delete(Session, "Place", Id);
            base.Delete(sec);
        }
Пример #6
0
        private static int GetOrCreateDiscussionId(
            ISession session,
            int accountid,
            Type type,
            int objectid,
            ManagedSecurityContext sec)
        {
            Discussion d = Find(session, accountid, type, objectid, sec);

            if (d != null)
            {
                return(d.Id);
            }

            ManagedDiscussionMapEntry mapentry = ManagedDiscussionMap.Find(type);

            TransitDiscussion td = new TransitDiscussion();

            td.AccountId    = accountid;
            td.Name         = mapentry.Name;
            td.Personal     = true;
            td.Description  = string.Empty;
            td.Created      = td.Modified = DateTime.UtcNow;
            td.ObjectId     = objectid;
            td.DataObjectId = ManagedDataObject.Find(session, type);

            // creating a discussion that belongs to a different user (commenting on someone's items)
            ManagedDiscussion      m_d   = new ManagedDiscussion(session);
            ManagedSecurityContext o_sec = new ManagedSecurityContext(session, accountid);

            return(m_d.CreateOrUpdate(td, o_sec));
        }
Пример #7
0
 public override void Delete(ManagedSecurityContext sec)
 {
     ManagedDiscussion.FindAndDelete(
         Session, mInstance.AccountFeed.Account.Id, typeof(AccountFeedItem), mInstance.Id, sec);
     ManagedFeature.Delete(Session, "AccountFeedItem", Id);
     base.Delete(sec);
 }
Пример #8
0
        public override void Delete(ManagedSecurityContext sec)
        {
            ManagedDiscussion.FindAndDelete(Session, mInstance.Place.Account.Id, typeof(PlacePicture), mInstance.Id, sec);
            ManagedPictureServiceImpl <PlacePicture> .Delete(Session, mInstance, mInstance.Place.PlacePictures);

            base.Delete(sec);
        }
Пример #9
0
        public override void Delete(ManagedSecurityContext sec)
        {
            ManagedDiscussion.FindAndDelete(Session, mInstance.Account.Id, typeof(AccountEvent), mInstance.Id, sec);
            ManagedFeature.Delete(Session, "AccountEvent", Id);
            Collection <AccountEvent> .GetSafeCollection(mInstance.Account.AccountEvents).Remove(mInstance);

            base.Delete(sec);
        }
Пример #10
0
        public override TransitAccountFeedItem GetTransitInstance(ManagedSecurityContext sec)
        {
            TransitAccountFeedItem t_instance = base.GetTransitInstance(sec);

            t_instance.CommentCount = ManagedDiscussion.GetDiscussionPostCount(
                Session, mInstance.AccountFeed.Account.Id, typeof(AccountFeedItem), mInstance.Id);
            return(t_instance);
        }
Пример #11
0
        public override void Delete(ManagedSecurityContext sec)
        {
            ManagedDiscussion.FindAndDelete(Session, mInstance.AccountStory.Account.Id, typeof(AccountStoryPicture), mInstance.Id, sec);
            ManagedPictureServiceImpl <AccountStoryPicture> .Delete(Session, mInstance, mInstance.AccountStory.AccountStoryPictures);

            Collection <AccountStoryPicture> .Remove(mInstance.AccountStory.AccountStoryPictures, mInstance);

            base.Delete(sec);
        }
Пример #12
0
        public override TransitAccountStoryPicture GetTransitInstance(ManagedSecurityContext sec)
        {
            TransitAccountStoryPicture t_instance = base.GetTransitInstance(sec);

            t_instance.Counter = ManagedStats.FindByUri(Session, "AccountStoryPictureView.aspx", mInstance.Id, sec);
            t_instance.SetWithinCollection(mInstance, mInstance.AccountStory.AccountStoryPictures);
            t_instance.CommentCount = ManagedDiscussion.GetDiscussionPostCount(
                Session, mInstance.AccountStory.Account.Id, typeof(AccountStoryPicture), mInstance.Id);
            return(t_instance);
        }
Пример #13
0
        public override int CreateOrUpdate(TransitDiscussionPost t_instance, ManagedSecurityContext sec)
        {
            Nullable <DateTime> lastModified = new Nullable <DateTime>();

            if (mInstance != null)
            {
                lastModified = mInstance.Modified;
            }

            // discussion admin can update stickyness
            bool fStickyModified = false;

            if (mInstance != null && mInstance.Sticky != t_instance.Sticky)
            {
                fStickyModified = true;
            }
            if (mInstance == null && t_instance.Sticky)
            {
                fStickyModified = true;
            }
            if (fStickyModified)
            {
                ManagedDiscussion m_discussion = new ManagedDiscussion(Session, mInstance != null
                    ? mInstance.DiscussionThread.Discussion.Id
                    : t_instance.DiscussionId);
                m_discussion.GetACL().Check(sec, DataOperation.Update);
            }

            int id = base.CreateOrUpdate(t_instance, sec);

            try
            {
                ManagedAccount ra = new ManagedAccount(Session, mInstance.AccountId);
                ManagedAccount ma = new ManagedAccount(Session, mInstance.DiscussionPostParent != null
                    ? mInstance.DiscussionPostParent.AccountId
                    : mInstance.DiscussionThread.Discussion.Account.Id);

                // if the author is editing the post, don't notify within 30 minute periods
                if (ra.Id != ma.Id && (t_instance.Id == 0 ||
                                       (lastModified.HasValue && lastModified.Value.AddMinutes(30) > DateTime.UtcNow)))
                {
                    Session.Flush();

                    ManagedSiteConnector.TrySendAccountEmailMessageUriAsAdmin(
                        Session, ma, string.Format("EmailDiscussionPost.aspx?id={0}", mInstance.Id));
                }
            }
            catch (ObjectNotFoundException)
            {
                // replying to an account that does not exist
            }

            return(id);
        }
Пример #14
0
 public override void Delete(ManagedSecurityContext sec)
 {
     ManagedDiscussion.FindAndDelete(Session, typeof(AccountGroup), Id, sec);
     Session.Delete(string.Format("FROM AccountGroupAccountRequest r WHERE r.AccountGroup.Id = {0}", Id));
     Session.Delete(string.Format("FROM AccountGroupAccountInvitation i WHERE i.AccountGroup.Id = {0}", Id));
     Session.Delete(string.Format("FROM AccountGroupPlace p WHERE p.AccountGroup.Id = {0}", Id));
     Session.Delete(string.Format("FROM AccountRssWatch w WHERE w.Url = 'AccountGroupRss.aspx?id={0}'", Id));
     Session.Delete(string.Format("FROM AccountInvitation i WHERE i.AccountGroup.Id = {0}", Id));
     ManagedFeature.Delete(Session, "AccountGroup", Id);
     base.Delete(sec);
 }
Пример #15
0
        public int MoveToDiscussion(ManagedSecurityContext sec, int targetid)
        {
            GetACL().Check(sec, DataOperation.Delete);

            ManagedDiscussion target_discussion = new ManagedDiscussion(Session, targetid);

            target_discussion.GetACL().Check(sec, DataOperation.Create);

            // create the target thread
            DiscussionThread target_thread = new DiscussionThread();

            target_thread.Discussion = target_discussion.Instance;
            target_thread.Modified   = mInstance.Modified;
            target_thread.Created    = mInstance.Created;
            Session.Save(target_thread);
            if (target_discussion.Instance.Modified < mInstance.Modified)
            {
                target_discussion.Instance.Modified = mInstance.Modified;
                Session.Save(target_discussion.Instance);
            }
            // copy the post to a discusison post
            DiscussionPost target_post = new DiscussionPost();

            target_post.AccountId        = mInstance.AccountId;
            target_post.Body             = mInstance.Body;
            target_post.Created          = mInstance.Created;
            target_post.Modified         = mInstance.Modified;
            target_post.Sticky           = false;
            target_post.Subject          = mInstance.Title;
            target_post.DiscussionThread = target_thread;
            Session.Save(target_post);
            // set the new post as parent of all replies
            int comments_discussion_id = ManagedDiscussion.GetOrCreateDiscussionId(
                Session, typeof(AccountBlogPost).Name, mInstance.Id, sec);
            Discussion comments_discussion = Session.Load <Discussion>(comments_discussion_id);

            foreach (DiscussionThread thread in Collection <DiscussionThread> .GetSafeCollection(comments_discussion.DiscussionThreads))
            {
                foreach (DiscussionPost post in thread.DiscussionPosts)
                {
                    post.DiscussionThread = target_thread;
                    if (post.DiscussionPostParent == null)
                    {
                        post.DiscussionPostParent = target_post;
                    }
                }
                Session.Delete(thread);
            }
            // delete the current post that became a discussion post
            Session.Delete(mInstance);
            return(target_post.Id);
        }
Пример #16
0
        public override TransitAccountBlogPost GetTransitInstance(ManagedSecurityContext sec)
        {
            ManagedAccountBlog     m_blog = new ManagedAccountBlog(Session, mInstance.AccountBlog);
            TransitAccountBlogPost t_post = base.GetTransitInstance(sec);

            t_post.CanEdit          = (GetACL().Apply(sec, DataOperation.Update) == ACLVerdict.Allowed);
            t_post.CanDelete        = (GetACL().Apply(sec, DataOperation.Delete) == ACLVerdict.Allowed);
            t_post.AccountName      = ManagedAccount.GetAccountNameWithDefault(Session, mInstance.AccountId);
            t_post.AccountPictureId = ManagedAccount.GetRandomAccountPictureId(Session, mInstance.AccountId);
            t_post.CommentCount     = ManagedDiscussion.GetDiscussionPostCount(
                Session, mInstance.AccountBlog.Account.Id, typeof(AccountBlogPost), mInstance.Id);
            return(t_post);
        }
Пример #17
0
        public override ACL GetACL(Type type)
        {
            ACL acl = base.GetACL(type);

            acl.Add(new ACLEveryoneAllowRetrieve());
            acl.Add(new ACLAccount(mInstance.AccountFeed.Account, DataOperation.All));

            if (ManagedDiscussion.IsDiscussionType(type))
            {
                acl.Add(new ACLAuthenticatedAllowCreate());
            }

            return(acl);
        }
Пример #18
0
        public void MigrateToAccount(Account newowner, ManagedSecurityContext sec)
        {
            // migrate review discussion
            Discussion d = ManagedDiscussion.Find(
                Session, mInstance.Place.Account.Id, typeof(Place), mInstance.Id, sec);

            if (d != null)
            {
                ManagedDiscussion md = new ManagedDiscussion(Session, d);
                md.MigrateToAccount(newowner, sec);
            }

            mInstance.Account = newowner;
            Session.Save(mInstance);
        }
Пример #19
0
        public int MoveToAccountBlog(ManagedSecurityContext sec, int targetid)
        {
            GetACL().Check(sec, DataOperation.Delete);

            ManagedAccountBlog blog = new ManagedAccountBlog(Session, targetid);

            blog.GetACL().Check(sec, DataOperation.Create);

            // copy the post to a blog post
            AccountBlogPost t_post = new AccountBlogPost();

            t_post.AccountBlog    = Session.Load <AccountBlog>(targetid);
            t_post.AccountId      = mInstance.AccountId;
            t_post.EnableComments = true;
            t_post.Created        = mInstance.Created;
            t_post.Modified       = mInstance.Modified;
            t_post.Title          = mInstance.Subject;
            t_post.Body           = mInstance.Body;
            t_post.AccountName    = ManagedAccount.GetAccountNameWithDefault(Session, mInstance.AccountId);
            Session.Save(t_post);

            // move the comments thread to the blog comments
            int        discussion_id     = ManagedDiscussion.GetOrCreateDiscussionId(Session, "AccountBlogPost", t_post.Id, sec);
            Discussion target_discussion = Session.Load <Discussion>(discussion_id);

            // create the target thread
            DiscussionThread target_thread = new DiscussionThread();

            target_thread.Created    = mInstance.Created;
            target_thread.Modified   = mInstance.DiscussionThread.Modified;
            target_thread.Discussion = target_discussion;
            Session.Save(target_thread);

            // attach the post and all child posts to the target thread
            MoveToDiscussionThread(mInstance, target_thread);

            // nullify each child's parent
            foreach (DiscussionPost post in mInstance.DiscussionPosts)
            {
                post.DiscussionPostParent = null;
            }

            // delete the current post that became a blog entry
            Session.Delete(mInstance);
            return(t_post.Id);
        }
Пример #20
0
        public static bool FindAndDelete(
            ISession session,
            int accountid,
            Type type,
            int objectid,
            ManagedSecurityContext sec)
        {
            Discussion discussion = Find(session, accountid, type, objectid, sec);

            if (discussion == null)
            {
                return(false);
            }
            ManagedDiscussion m_instance = new ManagedDiscussion(session, discussion);

            m_instance.Delete(sec);
            return(true);
        }
Пример #21
0
        public override TransitAccountPicture GetTransitInstance(ManagedSecurityContext sec)
        {
            TransitAccountPicture t_instance = base.GetTransitInstance(sec);
            List <AccountPicture> collection = new List <AccountPicture>();

            foreach (AccountPicture pic in Collection <AccountPicture> .GetSafeCollection(mInstance.Account.AccountPictures))
            {
                if (!pic.Hidden)
                {
                    collection.Add(pic);
                }
            }
            t_instance.SetWithinCollection(mInstance, collection);
            t_instance.CommentCount = ManagedDiscussion.GetDiscussionPostCount(
                Session, mInstance.Account.Id,
                typeof(AccountPicture), mInstance.Id);
            t_instance.Counter = ManagedStats.FindByUri(Session, "AccountPicture.aspx", mInstance.Id, sec);
            return(t_instance);
        }
Пример #22
0
        public static bool FindAndDelete(
            ISession session,
            Type type,
            int objectid,
            ManagedSecurityContext sec)
        {
            DataObject         dataobject  = ManagedDataObject.FindObject(session, type);
            IList <Discussion> discussions = session.CreateCriteria(typeof(Discussion))
                                             .Add(Expression.Eq("DataObject.Id", dataobject.Id))
                                             .Add(Expression.Eq("ObjectId", objectid))
                                             .Add(Expression.Eq("Personal", true))
                                             .List <Discussion>();

            foreach (Discussion discussion in discussions)
            {
                ManagedDiscussion m_instance = new ManagedDiscussion(session, discussion);
                m_instance.Delete(sec);
            }

            return(discussions.Count > 0);
        }
Пример #23
0
        protected override void Save(ManagedSecurityContext sec)
        {
            mInstance.Modified = DateTime.UtcNow;
            bool fNew = (mInstance.Id == 0);

            if (mInstance.Id == 0)
            {
                mInstance.Created = mInstance.Modified;
            }
            base.Save(sec);
            // create an admin account that owns the group
            if (fNew)
            {
                TransitAccountGroupAccount t_admin = new TransitAccountGroupAccount();
                t_admin.AccountGroupId  = mInstance.Id;
                t_admin.AccountId       = sec.Account.Id;
                t_admin.IsAdministrator = true;
                ManagedAccountGroupAccount m_admin = new ManagedAccountGroupAccount(Session);
                m_admin.CreateOrUpdate(t_admin, ManagedAccount.GetAdminSecurityContext(Session));
                ManagedDiscussion.GetOrCreateDiscussionId(Session, typeof(AccountGroup).Name, mInstance.Id, sec);
            }
        }
Пример #24
0
        public void Leave(int accountid, ManagedSecurityContext sec)
        {
            GetACL().Check(sec, DataOperation.Retreive);

            Account adminaccount      = null;
            bool    fHasAdministrator = false;
            bool    fMember           = false;

            foreach (AccountGroupAccount account in Collection <AccountGroupAccount> .GetSafeCollection(mInstance.AccountGroupAccounts))
            {
                if (account.Account.Id == accountid)
                {
                    Session.Delete(account);
                    fMember = true;
                }
                else if (account.IsAdministrator)
                {
                    // has at least one administrator left
                    fHasAdministrator = true;
                    adminaccount      = account.Account;
                }
            }

            if (!fMember)
            {
                throw new Exception("Not a member of the group.");
            }

            if (!fHasAdministrator)
            {
                // deleted the last administrator
                AccountGroupAccount admin = new AccountGroupAccount();
                admin.Account = ManagedAccount.GetAdminAccount(Session);
                if (admin.Account.Id == accountid)
                {
                    // the systme administrator tried to leave the group, he was last and is automatically re-added
                    throw new Exception("System administrator cannot be the last to leave a group.");
                }

                adminaccount = admin.Account;

                admin.AccountGroup    = mInstance;
                admin.Created         = admin.Modified = DateTime.UtcNow;
                admin.IsAdministrator = true;
                Session.Save(admin);
            }

            // orphan any invitations that this account sent
            foreach (AccountGroupAccountInvitation invitation in Collection <AccountGroupAccountInvitation> .GetSafeCollection(mInstance.AccountGroupAccountInvitations))
            {
                if (invitation.Requester.Id == accountid)
                {
                    invitation.Requester = adminaccount;
                    Session.Save(invitation);
                }
            }

            // orhphan group discussion
            int        discussion_id = ManagedDiscussion.GetOrCreateDiscussionId(Session, typeof(AccountGroup).Name, Id, sec);
            Discussion discussion    = Session.Load <Discussion>(discussion_id);

            if (discussion.Account.Id == accountid)
            {
                discussion.Account = adminaccount;
                Session.Save(discussion);
            }
        }
Пример #25
0
 public override void Delete(ManagedSecurityContext sec)
 {
     ManagedDiscussion.FindAndDelete(Session, mInstance.AccountId, typeof(AccountAuditEntry), mInstance.Id, sec);
     base.Delete(sec);
 }
Пример #26
0
 public TransitAccountStory(ISession session, AccountStory value)
     : base(value)
 {
     CommentCount = ManagedDiscussion.GetDiscussionPostCount(session, value.Account.Id,
                                                             typeof(AccountStory), value.Id);
 }
Пример #27
0
        public void Merge(ManagedSecurityContext sec, int id)
        {
            if (id == mInstance.Id)
            {
                throw new Exception("Cannot merge a place into itself.");
            }

            ManagedPlace p = new ManagedPlace(Session, id);

            #region Merge AccountEvents

            foreach (AccountEvent inst in p.Instance.AccountEvents)
            {
                inst.Place = mInstance;
                Session.Save(inst);
            }

            #endregion

            #region Merge AccountGroupPlace

            foreach (AccountGroupPlace inst in p.Instance.AccountGroupPlaces)
            {
                if (!HasAccountGroup(inst.AccountGroup.Id))
                {
                    inst.Place = mInstance;
                    Session.Save(inst);
                }
            }

            #endregion

            #region Merge AccountPlaceFavorite

            foreach (AccountPlaceFavorite inst in p.Instance.AccountPlaceFavorites)
            {
                bool found = false;
                foreach (AccountPlaceFavorite curr in inst.Account.AccountPlaceFavorites)
                {
                    if (curr.Place.Id == mInstance.Id)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    inst.Place = mInstance;
                    Session.Save(inst);
                }
            }

            #endregion

            #region Merge AccountPlaceRequests

            foreach (AccountPlaceRequest inst in p.Instance.AccountPlaceRequests)
            {
                bool found = false;
                foreach (AccountPlaceRequest curr in inst.Account.AccountPlaceRequests)
                {
                    if (curr.Place.Id == mInstance.Id)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    inst.Place = mInstance;
                    Session.Save(inst);
                }
            }

            #endregion

            #region Merge AccountPlaces

            foreach (AccountPlace inst in p.Instance.AccountPlaces)
            {
                bool found = false;
                foreach (AccountPlace curr in inst.Account.AccountPlaces)
                {
                    if (curr.Place.Id == mInstance.Id)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    inst.Place = mInstance;
                    Session.Save(inst);
                }
            }

            #endregion

            #region Merge PlaceAttribute

            foreach (PlaceAttribute inst in p.Instance.PlaceAttributes)
            {
                if (!HasPlaceAttribute(inst.Attribute.Id))
                {
                    inst.Place = mInstance;
                    Session.Save(inst);
                }
            }

            #endregion

            #region Merge PlaceNames

            // merge place names
            foreach (PlaceName inst in p.Instance.PlaceNames)
            {
                if (!HasPlaceName(inst.Name))
                {
                    inst.Place = mInstance;
                    Session.Save(inst);
                }
            }

            #endregion

            #region Merge PlacePictures

            foreach (PlacePicture inst in p.Instance.PlacePictures)
            {
                inst.Place = mInstance;
                Session.Save(inst);
            }

            #endregion

            #region Merge PlacePropertyValues

            foreach (PlacePropertyValue inst in p.Instance.PlacePropertyValues)
            {
                if (!HasPlacePropertyValue(inst.PlaceProperty.Id))
                {
                    inst.Place = mInstance;
                    Session.Save(inst);
                }
            }

            #endregion

            #region Merge PlaceQueueItems

            foreach (PlaceQueueItem inst in p.Instance.PlaceQueueItems)
            {
                bool found = false;
                foreach (PlaceQueue queue in inst.PlaceQueue.Account.PlaceQueues)
                {
                    foreach (PlaceQueueItem curr in queue.PlaceQueueItems)
                    {
                        if (curr.Place.Id == mInstance.Id)
                        {
                            found = true;
                            break;
                        }
                    }

                    if (found)
                    {
                        break;
                    }
                }

                if (!found)
                {
                    inst.Place = mInstance;
                    Session.Save(inst);
                }
            }

            #endregion

            #region Merge Discussion

            // TODO: move into ManagedDiscussion

            Discussion d_keep   = ManagedDiscussion.Find(Session, mInstance.Account.Id, typeof(Place), mInstance.Id, sec);
            Discussion d_delete = ManagedDiscussion.Find(Session, p.Instance.Account.Id, typeof(Place), p.Instance.Id, sec);

            if (d_keep == null && d_delete != null)
            {
                d_delete.ObjectId = mInstance.Id;
                Session.Save(d_delete);
            }
            else if (d_delete != null)
            {
                foreach (DiscussionThread t in d_delete.DiscussionThreads)
                {
                    t.Discussion = d_keep;
                    if (t.Modified > d_keep.Modified)
                    {
                        d_keep.Modified = t.Modified;
                        Session.Save(d_keep);
                    }
                    Session.Save(t);
                }
            }

            #endregion

            #region Merge MadLibs

            IList <MadLibInstance> madlibs = ManagedMadLibInstance.GetMadLibs(Session, "Place", p.Id);
            foreach (MadLibInstance madlib in madlibs)
            {
                madlib.ObjectId = mInstance.Id;
                Session.Save(madlib);
            }

            #endregion

            #region Merge Features

            IList <Feature> features = ManagedFeature.GetFeatures(Session, "Place", p.Id);
            foreach (Feature feature in features)
            {
                feature.DataRowId = mInstance.Id;
                Session.Save(feature);
            }

            #endregion

            Session.Delete(p.Instance);
        }