Index: H:\Java\eclipse\trunk\src\main\resources\templates\macros\presentation.ftl
===================================================================
--- H:\Java\eclipse\trunk\src\main\resources\templates\macros\presentation.ftl	(revision 207)
+++ H:\Java\eclipse\trunk\src\main\resources\templates\macros\presentation.ftl	(revision 251)
@@ -75,6 +75,7 @@
 	<#if moderator  && openModeration?default(false)>
 		<#if can_remove_posts?default(false)><input type="submit" name="topicRemove" value="&nbsp;&nbsp;${I18n.getMessage("Delete")}&nbsp;&nbsp;" class="liteoption" onclick="return validateModerationDelete();" /></#if>
 		<#if can_move_topics?default(false)><input type="submit" name="topicMove" value="&nbsp;&nbsp;${I18n.getMessage("move")}&nbsp;&nbsp;" class="liteoption" onclick="return verifyModerationCheckedTopics();" /></#if>
+		<#if can_move_topics?default(false)><input type="submit" name="topicSplit" value="&nbsp;&nbsp;${I18n.getMessage("split")}&nbsp;&nbsp;" class="liteoption" onclick="return verifyModerationCheckedTopics();" /></#if>
 		<#if can_lockUnlock_topics?default(false)>
 			<input type="submit" name="topicLock" value="&nbsp;&nbsp;${I18n.getMessage("Lock")}&nbsp;&nbsp;" class="liteoption" onclick="return lockUnlock();" />
 			<input type="submit" name="topicUnlock" value="&nbsp;&nbsp;${I18n.getMessage("Unlock")}&nbsp;&nbsp;" class="liteoption" onclick="return lockUnlock();" />
@@ -105,6 +106,11 @@
 		document.formModeration.submit();
 	}
 
+	function splitTopic() {
+		todo("topicSplit");
+		document.formModeration.submit();
+	}
+
 	function lockUnlock(lock) {
 		if (askModerationReason()) {
 			document.formModeration.log_type.value = "3";
@@ -117,10 +123,11 @@
 	<#if isModerator || isAdmin>
 		<#if can_remove_posts?default(false)>
 			<a href="javascript:deleteTopic();"><img class="icon_topic_delete" src="${contextPath}/images/transp.gif" title="${I18n.getMessage("Delete")}" alt="" /></a>
+			<a href="javascript:moveTopic();"><img class="icon_topic_move" src="${contextPath}/images/transp.gif" title="${I18n.getMessage("move")}" alt="" /></a>
 		</#if>
 		
 		<#if can_move_topics?default(false)>
-			<a href="javascript:moveTopic();"><img class="icon_topic_move" src="${contextPath}/images/transp.gif" title="${I18n.getMessage("move")}" alt="" /></a>
+			<a href="javascript:splitTopic();"><img class="icon_topic_split" src="${contextPath}/images/transp.gif" title="${I18n.getMessage("split")}" alt="" /></a>
 		</#if>
 
 		<#if can_lockUnlock_topics?default(false)>			
Index: H:\Java\eclipse\trunk\src\main\resources\templates\macros\presentation.ftl
===================================================================
--- H:\Java\eclipse\trunk\src\main\resources\templates\macros\presentation.ftl	(revision 207)
+++ H:\Java\eclipse\trunk\src\main\resources\templates\macros\presentation.ftl	(revision 251)
@@ -75,6 +75,7 @@
 	<#if moderator  && openModeration?default(false)>
 		<#if can_remove_posts?default(false)><input type="submit" name="topicRemove" value="&nbsp;&nbsp;${I18n.getMessage("Delete")}&nbsp;&nbsp;" class="liteoption" onclick="return validateModerationDelete();" /></#if>
 		<#if can_move_topics?default(false)><input type="submit" name="topicMove" value="&nbsp;&nbsp;${I18n.getMessage("move")}&nbsp;&nbsp;" class="liteoption" onclick="return verifyModerationCheckedTopics();" /></#if>
+		<#if can_move_topics?default(false)><input type="submit" name="topicSplit" value="&nbsp;&nbsp;${I18n.getMessage("split")}&nbsp;&nbsp;" class="liteoption" onclick="return verifyModerationCheckedTopics();" /></#if>
 		<#if can_lockUnlock_topics?default(false)>
 			<input type="submit" name="topicLock" value="&nbsp;&nbsp;${I18n.getMessage("Lock")}&nbsp;&nbsp;" class="liteoption" onclick="return lockUnlock();" />
 			<input type="submit" name="topicUnlock" value="&nbsp;&nbsp;${I18n.getMessage("Unlock")}&nbsp;&nbsp;" class="liteoption" onclick="return lockUnlock();" />
@@ -105,6 +106,11 @@
 		document.formModeration.submit();
 	}
 
+	function splitTopic() {
+		todo("topicSplit");
+		document.formModeration.submit();
+	}
+
 	function lockUnlock(lock) {
 		if (askModerationReason()) {
 			document.formModeration.log_type.value = "3";
@@ -117,10 +123,11 @@
 	<#if isModerator || isAdmin>
 		<#if can_remove_posts?default(false)>
 			<a href="javascript:deleteTopic();"><img class="icon_topic_delete" src="${contextPath}/images/transp.gif" title="${I18n.getMessage("Delete")}" alt="" /></a>
+			<a href="javascript:moveTopic();"><img class="icon_topic_move" src="${contextPath}/images/transp.gif" title="${I18n.getMessage("move")}" alt="" /></a>
 		</#if>
 		
 		<#if can_move_topics?default(false)>
-			<a href="javascript:moveTopic();"><img class="icon_topic_move" src="${contextPath}/images/transp.gif" title="${I18n.getMessage("move")}" alt="" /></a>
+			<a href="javascript:splitTopic();"><img class="icon_topic_split" src="${contextPath}/images/transp.gif" title="${I18n.getMessage("split")}" alt="" /></a>
 		</#if>
 
 		<#if can_lockUnlock_topics?default(false)>			


Index: H:\Java\eclipse\trunk\src\main\config\database\generic\generic_queries.sql
===================================================================
--- H:\Java\eclipse\trunk\src\main\config\database\generic\generic_queries.sql	(revision 207)
+++ H:\Java\eclipse\trunk\src\main\config\database\generic\generic_queries.sql	(revision 251)
@@ -186,6 +186,7 @@
 PostModel.deletePostText = DELETE FROM jforum_posts_text WHERE post_id = ?
 
 PostModel.updatePost = UPDATE jforum_posts SET topic_id = ?, forum_id = ?, enable_bbcode = ?, enable_html = ?, enable_smilies = ?, enable_sig = ?, post_edit_time = ?, post_edit_count = ?, poster_ip = ? WHERE post_id = ?
+PostModel.updatePostWithoutLastEditedBy = UPDATE jforum_posts SET topic_id = ?, forum_id = ?, enable_bbcode = ?, enable_html = ?, enable_smilies = ?, enable_sig = ? WHERE post_id = ?
 PostModel.updatePostText = UPDATE jforum_posts_text SET post_text = ?, post_subject = ? WHERE post_id = ?
 
 PostModel.addNewPost = INSERT INTO jforum_posts (topic_id, forum_id, user_id, post_time, poster_ip, enable_bbcode, enable_html, enable_smilies, enable_sig, need_moderate) \
Index: H:\Java\eclipse\trunk\src\main\config\languages\en_US.properties
===================================================================
--- H:\Java\eclipse\trunk\src\main\config\languages\en_US.properties	(revision 207)
+++ H:\Java\eclipse\trunk\src\main\config\languages\en_US.properties	(revision 251)
@@ -584,6 +584,8 @@
 Moderation.OpenModeration            = Open Moderation Options
 Moderation.SelectTopics              = Please select one or more topics
 Moderation.checkQueue                = The following topics have messages in the moderation queue
+Moderation.split.NoPosts			 = You have not selected any posts from the topic to be split
+Moderation.split.PostError           = One of the posts does not belong to the topic or you are attempting to split the first post
 
 ModerationLog.action          = Action
 ModerationLog.changeReason    = Change reason:
@@ -599,9 +601,11 @@
 ModerationLog.typeEdited      = Message edited
 ModerationLog.typeLockUnlock  = Topic locked or unlocked
 ModerationLog.typeMoved       = Moved to another forum
+ModerationLog.typeSplit		  = Splitted to new topic
 ModerationLog.user            = User
 ModerationLog.viewMessage     = View message
 ModerationLog.viewTopic       = View topic
+ModerationLog.viewNewTopic    = View new topic
 
 Moderator = Moderator
 
@@ -728,6 +732,13 @@
 PostForm.moreSmilies            = More smilies
 PostForm.moveToForum            = Move to the forum
 PostForm.movingTopic            = Moving Topics
+PostForm.split.description		= Using this form you can select the posts which will form the new topic.
+PostForm.split.newTopicTitle	= New topic title
+PostForm.split.forumForNewTopic = Forum for new topic
+PostForm.split.title			= Split Topic
+PostForm.split.emptyForum		= Please select
+PostForm.split.error			= You must specify the subject and select the destination forum.
+PostForm.split.error.selected	= You must select at least one post to be split.
 PostForm.needMorePollOptions    = You must specify at least 2 poll options.
 PostForm.notifyReplies          = Notify when a reply is posted
 PostForm.options                = Options
Index: H:\Java\eclipse\trunk\src\main\config\templatesMapping.properties
===================================================================
--- H:\Java\eclipse\trunk\src\main\config\templatesMapping.properties	(revision 207)
+++ H:\Java\eclipse\trunk\src\main\config\templatesMapping.properties	(revision 251)
@@ -18,6 +18,7 @@
 karma.search.bymonth = user_list_karma.htm
 
 moderation.move.topics = post_move.htm
+moderation.split.topic = post_split.htm
 moderation.done = message.htm
 moderation.denied = message.htm
 moderation.show.activity.log = moderation_acvitity_log.htm
Index: H:\Java\eclipse\trunk\src\main\java\net\jforum\util\preferences\TemplateKeys.java
===================================================================
--- H:\Java\eclipse\trunk\src\main\java\net\jforum\util\preferences\TemplateKeys.java	(revision 207)
+++ H:\Java\eclipse\trunk\src\main\java\net\jforum\util\preferences\TemplateKeys.java	(revision 251)
@@ -70,6 +70,7 @@
 	public static final String KARMA_SEARCH_BYMONTH = "karma.search.bymonth";
 
 	public static final String MODERATION_MOVE_TOPICS = "moderation.move.topics";
+	public static final String MODERATION_SPLIT_TOPIC = "moderation.split.topic";
 	public static final String MODERATION_DONE = "moderation.done";
 	public static final String MODERATION_DENIED = "moderation.denied";
 
Index: H:\Java\eclipse\trunk\src\main\java\net\jforum\entities\ModerationLogType.java
===================================================================
--- H:\Java\eclipse\trunk\src\main\java\net\jforum\entities\ModerationLogType.java	(revision 207)
+++ H:\Java\eclipse\trunk\src\main\java\net\jforum\entities\ModerationLogType.java	(revision 251)
@@ -52,6 +52,7 @@
 	public static final int DELETE = 1;
 	public static final int EDIT = 2;
 	public static final int LOCK_UNLOCK = 3;
+	public static final int SPLIT = 4;
 	
 	private ModerationLogType() {}
 }
Index: H:\Java\eclipse\trunk\src\main\java\net\jforum\dao\PostDAO.java
===================================================================
--- H:\Java\eclipse\trunk\src\main\java\net\jforum\dao\PostDAO.java	(revision 207)
+++ H:\Java\eclipse\trunk\src\main\java\net\jforum\dao\PostDAO.java	(revision 251)
@@ -81,6 +81,14 @@
 	void update(Post post) ;
 	
 	/**
+	 * Updates a Post without modifying the Last Edit By and without touching the text.
+	 * 
+	 * @param post Reference to a <code>Post</code> object to update
+	 * @param skipUpdateCount if true, don't update the edit count, by whom and so on.
+	 */
+	void updateForSplit(Post post);
+	
+	/**
 	 * Adds a new Post.
 	 * 
 	 * @param post Post Reference to a valid and configured <code>Post</code> object
Index: H:\Java\eclipse\trunk\src\main\java\net\jforum\dao\generic\GenericPostDAO.java
===================================================================
--- H:\Java\eclipse\trunk\src\main\java\net\jforum\dao\generic\GenericPostDAO.java	(revision 207)
+++ H:\Java\eclipse\trunk\src\main\java\net\jforum\dao\generic\GenericPostDAO.java	(revision 251)
@@ -237,6 +237,15 @@
 		SearchFacade.update(post);
 	}
 
+	public void updateForSplit(Post post)
+	{
+		this.updatePostsTableForSplit(post);
+		// No text update while splitting.
+		// this.updatePostsTextTable(post);
+
+		SearchFacade.update(post);
+	}
+		
 	protected void updatePostsTextTable(Post post)
 	{
 		PreparedStatement pstmt = null;
@@ -286,6 +295,36 @@
 	}
 
 	/**
+	 * Similar to update updatePostsTable but skips over last edit time, count and user ip.
+	 * 
+	 * @param post
+	 */
+	protected void updatePostsTableForSplit(Post post)
+	{
+		PreparedStatement pstmt = null;
+		
+		try {
+			pstmt = JForumExecutionContext.getConnection().prepareStatement(SystemGlobals.getSql("PostModel.updatePostWithoutLastEditedBy"));
+
+			pstmt.setInt(1, post.getTopicId());
+			pstmt.setInt(2, post.getForumId());
+			pstmt.setInt(3, post.isBbCodeEnabled() ? 1 : 0);
+			pstmt.setInt(4, post.isHtmlEnabled() ? 1 : 0);
+			pstmt.setInt(5, post.isSmiliesEnabled() ? 1 : 0);
+			pstmt.setInt(6, post.isSignatureEnabled() ? 1 : 0);
+			pstmt.setInt(7, post.getId());
+
+			pstmt.executeUpdate();
+		}
+		catch (SQLException e) {
+			throw new DatabaseException(e);
+		}
+		finally {
+			DbUtils.close(pstmt);
+		}
+	}
+	
+	/**
 	 * @see net.jforum.dao.PostDAO#addNew(net.jforum.entities.Post)
 	 */
 	public int addNew(Post post)
Index: H:\Java\eclipse\trunk\src\main\java\net\jforum\view\forum\ModerationAction.java
===================================================================
--- H:\Java\eclipse\trunk\src\main\java\net\jforum\view\forum\ModerationAction.java	(revision 207)
+++ H:\Java\eclipse\trunk\src\main\java\net\jforum\view\forum\ModerationAction.java	(revision 251)
@@ -152,6 +152,10 @@
 		if (JForumExecutionContext.getRequest().getParameter("topicMove") != null) {
 			this.setTemplateName(TemplateKeys.MODERATION_MOVE_TOPICS);
 		}
+		
+		if (JForumExecutionContext.getRequest().getParameter("topicSplit") != null) {			
+			this.setTemplateName(TemplateKeys.MODERATION_SPLIT_TOPIC);
+		}
 	}
 	
 	public void moveTopic()
@@ -159,8 +163,12 @@
 		new ModerationHelper().moveTopicsSave(this.request.getParameter(RETURN_URL));
 	}
 	
+	public void splitTopic() {
+		new ModerationHelper().splitTopicSave(this.request.getParameter(RETURN_URL));
+	}
+	
 	public void moderationDone()
 	{
 		this.setTemplateName(new ModerationHelper().moderationDone(this.request.getParameter(RETURN_URL)));
 	}
-}
+}
\ No newline at end of file
Index: H:\Java\eclipse\trunk\src\main\java\net\jforum\view\forum\ModerationHelper.java
===================================================================
--- H:\Java\eclipse\trunk\src\main\java\net\jforum\view\forum\ModerationHelper.java	(revision 207)
+++ H:\Java\eclipse\trunk\src\main\java\net\jforum\view\forum\ModerationHelper.java	(revision 251)
@@ -45,6 +45,8 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import net.jforum.JForumExecutionContext;
 import net.jforum.SessionFacade;
@@ -52,19 +54,30 @@
 import net.jforum.dao.DataAccessDriver;
 import net.jforum.dao.ForumDAO;
 import net.jforum.dao.ModerationLogDAO;
+import net.jforum.dao.PostDAO;
 import net.jforum.dao.TopicDAO;
+import net.jforum.dao.UserDAO;
+import net.jforum.entities.Forum;
 import net.jforum.entities.ModerationLog;
+import net.jforum.entities.Post;
 import net.jforum.entities.Topic;
 import net.jforum.entities.User;
 import net.jforum.repository.ForumRepository;
 import net.jforum.repository.PostRepository;
 import net.jforum.repository.SecurityRepository;
 import net.jforum.repository.TopicRepository;
+import net.jforum.security.PermissionControl;
 import net.jforum.security.SecurityConstants;
 import net.jforum.util.I18n;
+import net.jforum.util.preferences.ConfigKeys;
+import net.jforum.util.preferences.SystemGlobals;
 import net.jforum.util.preferences.TemplateKeys;
+import net.jforum.view.forum.common.AttachmentCommon;
 import net.jforum.view.forum.common.ForumCommon;
+import net.jforum.view.forum.common.PostCommon;
+import net.jforum.view.forum.common.TopicsCommon;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
 
 import freemarker.template.SimpleHash;
@@ -103,6 +116,13 @@
 					status = IGNORE;
 				}
 			}
+			else if (request.getParameter("topicSplit") != null) {
+				if (SecurityRepository.canAccess(SecurityConstants.PERM_MODERATION_TOPIC_MOVE)) {
+					this.splitTopic();
+					
+					status = IGNORE;
+				}
+			}
 			else if (request.getParameter("topicLock") != null) {
 				if (SecurityRepository.canAccess(SecurityConstants.PERM_MODERATION_TOPIC_LOCK_UNLOCK)) {
 					this.lockUnlockTopics(Topic.STATUS_LOCKED);
@@ -329,6 +349,267 @@
 		
 		return status;
 	}
+
+	private void splitTopic()
+	{
+		SimpleHash context = JForumExecutionContext.getTemplateContext();
+		RequestContext request = JForumExecutionContext.getRequest();
+	
+		int userId = SessionFacade.getUserSession().getUserId();
+		int topicId = request.getIntParameter("topic_id");
+		
+		TopicDAO topicDao = DataAccessDriver.getInstance().newTopicDAO();
+		PostDAO postDao = DataAccessDriver.getInstance().newPostDAO();
+		ForumDAO forumDao = DataAccessDriver.getInstance().newForumDAO();
+		
+		Topic topic = TopicRepository.getTopic(new Topic(topicId));
+		
+		if (topic == null) {
+			topic = topicDao.selectById(topicId);
+		}
+
+		if (!TopicsCommon.isTopicAccessible(topic.getForumId())) {
+			return;
+		}
+		
+		Forum forum = forumDao.selectById(topic.getForumId());
+
+		PermissionControl pc = SecurityRepository.get(userId);
+		
+		context.put("persistData", JForumExecutionContext.getRequest().getParameter("persistData"));
+		context.put("allCategories", ForumCommon.getAllCategoriesAndForums(false));
+		context.put("attachmentsEnabled", pc.canAccess(SecurityConstants.PERM_ATTACHMENTS_ENABLED, Integer.toString(topic.getForumId())));
+		context.put("canDownloadAttachments", pc.canAccess(SecurityConstants.PERM_ATTACHMENTS_DOWNLOAD));
+		context.put("thumbShowBox", SystemGlobals.getBoolValue(ConfigKeys.ATTACHMENTS_IMAGES_THUMB_BOX_SHOW));
+		context.put("am", new AttachmentCommon(request, topic.getForumId()));
+		context.put("forum", forum);
+				
+		Map<Integer, User> usersMap = topicDao.topicPosters(topic.getId());
+		List<Post> posts = PostCommon.topicPosts(postDao, false, userId, topic.getId(), 0, Integer.MAX_VALUE - 1);
+
+		context.put("topic", topic);
+		context.put("posts", posts);
+		context.put("users", usersMap);
+		context.put("forum_id", topic.getForumId());
+		context.put("topic_id", topicId);
+	}
+	
+	public int splitTopicSave(String successUrl)
+	{
+		
+		if (!SecurityRepository.canAccess(SecurityConstants.PERM_MODERATION_TOPIC_MOVE)) {
+			this.denied(I18n.getMessage("Moderation.Denied"));
+			return FAILURE;
+		}
+		else {
+			RequestContext request = JForumExecutionContext.getRequest();
+
+			int fromForumId = Integer.parseInt(request.getParameter("forum_id"));
+			int toForumId = Integer.parseInt(request.getParameter("to_forum"));
+			int oldTopicId = Integer.parseInt(request.getParameter("topic_id"));
+			String[] selectedPosts = request.getParameterValues("selectedPosts");
+			String subject = request.getParameter("subject");
+
+			// Validate
+			if (StringUtils.isBlank(subject)) {
+				this.denied(I18n.getMessage("PostForm.subjectEmpty"));
+				return FAILURE;
+			}
+			
+			if (selectedPosts == null || selectedPosts.length == 0) {
+				this.denied(I18n.getMessage("Moderation.split.NoPosts"));
+				return FAILURE;
+			}
+				
+			// Split consists in two parts
+			// - create a new topic in the new forum with the credentials of the user that posted the first selected post
+			// - move the posts to the new topic without sending an email.
+			
+			PostDAO postDao = DataAccessDriver.getInstance().newPostDAO();
+			TopicDAO topicDao = DataAccessDriver.getInstance().newTopicDAO();
+			ForumDAO forumDao = DataAccessDriver.getInstance().newForumDAO();
+			UserDAO userDao = DataAccessDriver.getInstance().newUserDAO();
+			
+			Forum newForum = forumDao.selectById(toForumId);
+			
+			// Create new topic as the user of the first post.
+			
+			Topic newTopic = new Topic();
+			
+			newTopic.setType(Topic.TYPE_NORMAL);
+			newTopic.setTitle(subject);
+			newTopic.setModerated(false);
+			newTopic.setForumId(toForumId);
+			
+			boolean foundAttachments = false;
+			
+			List<Integer> usersToSubscribe = new ArrayList<Integer>();
+			
+			for (int count = 0; count < selectedPosts.length; count ++ ) {
+				int postId = Integer.parseInt(selectedPosts[count]);
+				Post post = postDao.selectById(postId);
+				
+				// keep track of the users to be subscribed to new topic.
+				if (topicDao.isUserSubscribed(oldTopicId, post.getUserId())) {
+					usersToSubscribe.add(post.getUserId());
+				}
+				
+				// The topic has to have the first* values populated from the its new post
+				if (count == 0) {
+					newTopic.setPostedBy(userDao.selectById(post.getUserId()));
+					newTopic.setTime(post.getTime());
+					newTopic.setFirstPostTime(post.getFormattedTime());
+
+					newTopic.setFirstPostId(postId);
+					
+					// Add the new topic here, since we need a posted by from the first post.
+					int newTopicId = topicDao.addNew(newTopic);
+					newTopic.setId(newTopicId);
+					
+					// check -> verify if it is ok to send notifications now or at the end when
+					//  everything has been completed.
+					// checked : it works, it sends the notification for new topic on the forum
+					ForumCommon.notifyUsers(newForum, newTopic, post);
+				}
+				
+				// The topic last* values have to be populated with the values from the last post
+				if (count == selectedPosts.length - 1) {
+					
+					newTopic.setLastPostId(postId);
+					newTopic.setLastPostBy(userDao.selectById(post.getUserId()));
+					newTopic.setLastPostDate(post.getTime());
+					newTopic.setLastPostTime(post.getFormattedTime());
+				}
+				
+				// Handle posts here
+				post.setForumId(toForumId);
+				post.setTopicId(newTopic.getId()); 
+				foundAttachments |= post.hasAttachments();
+			
+				postDao.updateForSplit(post);
+
+				// Only increment the total number of replies from post 1 onwards since post 0
+				//  is not considered a reply.
+				if (count != 0) {
+					topicDao.incrementTotalReplies(newTopic.getId());
+				}
+				
+				topicDao.decrementTotalReplies(oldTopicId);
+				
+				// Update posts cache for the new posts
+				if (SystemGlobals.getBoolValue(ConfigKeys.POSTS_CACHE_ENABLED)) {
+					PostRepository.append(post.getTopicId(), PostCommon.preparePostForDisplay(post));
+				}
+				
+				// check: see how to move attachments to new forumId
+				// checked: they are not moved, forumId is just to check if attachments are allowed in the new forum.
+				// by default, the threads that are split WILL contain the attachments and if the destination
+				// forum doesn't allow downloads, well, they won't be available for download.
+				
+				// checked: investigate read status of the topic
+				
+				// check if topic count for new user increased
+				//  checked: it does.
+				
+				// test splitting into a new forum
+				//  cheched: it works.
+
+				// Cum functioneaza
+				// 1. topicul nou nu poate fi preluat cu tot cu poll
+				// 2. nu se poate splitui primul post
+				// 3. cum este creeat de un moderator (sau cineva cu permisiunea de move) - topicul va fi creeat direct fara posibilitatea de a fi moderat.
+				// 4. se pastreaza notificarile pe mail (daca cineva a ales sa urmeasca topicul vechi, si postul este splituit, va primi mailuri si de la noul topic). Nu stiu cum se comporta daca va primi mailuri si de la vechiul topic.
+				// 5. topicul nou nu poate este facut sticky chiar daca cel vechi poate era.
+				// 6. timpul noului topic este timpul primului post
+				// 7. toate posturile mutate vor apare ca fiind editate cu data cand s-a facut mutarea.
+				// 8. posturile cu atasamente sunt mutate chiar daca forumul destinatie are atasamente dezactivate.
+				// 9. topicurile locked pot fi splituite - dar noul topic nu este inchis automat.
+				// 10 UI validation Javascript
+			}
+	
+			// check: Apparently not saved in database for topics since the table doesn't have a column for it - maybe 
+			//  it is computed at runtime just for caching purposes ? 
+			// check: attachments flag for old topic
+			// checked: it is computed at runtime so we need it for caching purposes only. The old topic is also
+			//  reloaded with the cache instructions below, so its flag is automatically recomputed too.
+			newTopic.setHasAttach(foundAttachments);
+			
+			int maxPostId = topicDao.getMaxPostId(newTopic.getId());
+			if (maxPostId > -1) {
+				topicDao.setLastPostId(newTopic.getId(), maxPostId);
+			}
+			
+			int minPostId = topicDao.getMinPostId(newTopic.getId());
+			if (minPostId > -1) {
+			  topicDao.setFirstPostId(newTopic.getId(), minPostId);
+			}
+			
+			// Reset values for old topic
+			
+			maxPostId = topicDao.getMaxPostId(oldTopicId);
+			if (maxPostId > -1) {
+				topicDao.setLastPostId(oldTopicId, maxPostId);
+			}
+			
+			minPostId = topicDao.getMinPostId(oldTopicId);
+			if (minPostId > -1) {
+			  topicDao.setFirstPostId(oldTopicId, minPostId);
+			}
+			   
+			// reset values for new forum
+			maxPostId = forumDao.getMaxPostId(toForumId);
+			if (maxPostId > -1) {
+				forumDao.setLastPost(toForumId, maxPostId);
+			}
+			
+			// check: increment the total number of topics in new forum (but it doesn't work ?)
+			// checked: it does
+			forumDao.incrementTotalTopics(toForumId, 1);
+			
+			// reset values for old forum
+			maxPostId = forumDao.getMaxPostId(fromForumId);
+			if (maxPostId > -1) {
+				forumDao.setLastPost(fromForumId, maxPostId);
+			}
+						
+			// subscribe users and unsubscribe from old topic
+			Map<Integer, User> remainingUsersInOldTopicMap = topicDao.topicPosters(oldTopicId);
+			Set<Integer> userIdsOldTopic = remainingUsersInOldTopicMap.keySet();
+			for(Integer userId: usersToSubscribe) {
+				if (!topicDao.isUserSubscribed(newTopic.getId(), userId)) {
+					topicDao.subscribeUser(newTopic.getId(), userId);
+				}
+				
+				// if the userId subscribed to the new thread is not anymore in the old thread
+				//  then unubscribe him - otherwise, let them watch.
+				// we know they had a subscription to the old topic because otherwise they would not
+				//  be in the usersToSubscribe list.
+				if (!userIdsOldTopic.contains(userId)) {
+					topicDao.removeSubscription(oldTopicId, userId);
+				}
+			}
+			
+			ModerationLog log = this.buildModerationLogFromRequest();
+			log.setTopicId(oldTopicId);
+			log.setOriginalMessage(String.valueOf(newTopic.getId()));
+			this.saveModerationLog(log);
+
+			ForumRepository.reloadForum(fromForumId);
+			ForumRepository.reloadForum(toForumId);
+			
+			TopicRepository.clearCache(fromForumId);
+			TopicRepository.clearCache(toForumId);
+			
+			TopicRepository.loadMostRecentTopics();
+			TopicRepository.loadHottestTopics();
+			
+			PostRepository.clearCache(oldTopicId);
+		}
+		
+		this.moderationDone(successUrl);
+		
+		return SUCCESS;
+	}
 	
 	public String moderationDone(String redirectUrl)
 	{
Index: H:\Java\eclipse\trunk\src\main\resources\templates\default\moderation_acvitity_log.htm
===================================================================
--- H:\Java\eclipse\trunk\src\main\resources\templates\default\moderation_acvitity_log.htm	(revision 207)
+++ H:\Java\eclipse\trunk\src\main\resources\templates\default\moderation_acvitity_log.htm	(revision 251)
@@ -63,14 +63,20 @@
 							${I18n.getMessage("ModerationLog.typeDeleted")}
 						<#elseif log.type == 2>
 							${I18n.getMessage("ModerationLog.typeEdited")}
-						<#else>
+						<#elseif log.type == 3>
 							${I18n.getMessage("ModerationLog.typeLockUnlock")}
+						<#else>
+							${I18n.getMessage("ModerationLog.typeSplit")}
 						</#if>
 					</td>
 					<td class="row1" valign="top">${log.description?html}</td>
 
 					<#if canAccessFullModerationLog>
-						<td class="row2" valign="top">${log.originalMessage?default("&nbsp;")}</td>
+						<td class="row2" valign="top">
+						<#if log.type != 4>
+							${log.originalMessage?default("&nbsp;")}
+						</#if>	
+						</td>
 					</#if>
 
 					<td class="row2 gensmall" valign="top" align="center" width="100">
@@ -78,7 +84,11 @@
 							[<a href="${JForumContext.encodeURL("/posts/list/${log.topicId}")}">${I18n.getMessage("ModerationLog.viewTopic")}</a>]<br />
 						</#if>
 
-						<#if log.type != 1>
+						<#if log.type == 4>						
+							[<a href="${JForumContext.encodeURL("/posts/list/${log.originalMessage}")}">${I18n.getMessage("ModerationLog.viewNewTopic")}</a>]<br />
+						</#if>
+						
+						<#if log.type != 1 && log.type != 4>
 							[<a href="${JForumContext.encodeURL("/posts/preList/${log.topicId}/${log.postId}")}">${I18n.getMessage("ModerationLog.viewMessage")}</a>]
 						</#if>
 					</td>
Index: H:\Java\eclipse\trunk\src\main\resources\templates\default\post_split.htm
===================================================================
--- H:\Java\eclipse\trunk\src\main\resources\templates\default\post_split.htm	(revision 0)
+++ H:\Java\eclipse\trunk\src\main\resources\templates\default\post_split.htm	(revision 251)
@@ -0,0 +1,228 @@
+<#include "header.htm"/>
+
+<script type="text/javascript" src="${JForumContext.encodeURL("/js/list/moderation")}"></script>
+
+<script type="text/javascript">
+function validateSplit() {
+	
+	// Check subject
+	var subjectField = document.formModeration.subject;
+	if (subjectField) {
+		var trimSubject = subjectField.value.replace(/^\s+|\s+$/g, '');
+	}
+	
+	// Check forum
+	var toForum = document.formModeration.to_forum;
+	if (toForum) {
+		var toForumVal = toForum.options[toForum.selectedIndex].value;
+	}
+	
+	if (!trimSubject || trimSubject.length == 0 || toForumVal == -1) {
+		alert('${I18n.getMessage("PostForm.split.error")}');
+		return false;
+	}
+	
+	// Check one post selected
+	var atLeastOneSelectedPost = false;
+	var f = document.formModeration.selectedPosts;
+	if (f.length == undefined) {
+		if (f.checked) {
+			atLeastOneSelectedPost = true;
+		}
+	}
+	for (var i = 0; i < f.length; i++) {
+		if (f[i].checked) {
+			atLeastOneSelectedPost = true;
+		}
+	}
+	
+	if (!atLeastOneSelectedPost) {
+		alert('${I18n.getMessage("PostForm.split.error.selected")}');
+		return false;
+	}
+	
+	return askModerationReason();
+}
+</script>
+
+<form action="${JForumContext.encodeURL("/jforum")}" method="post" name="formModeration" id="formModeration" onsubmit="return validateSplit();" accept-charset="${encoding}">
+<input type="hidden" name="action" value="splitTopic" />
+<input type="hidden" name="module" value="${moduleName}" />
+<input type="hidden" name="returnUrl" value="${returnUrl?if_exists}" />
+<input type="hidden" name="forum_id" value="${forum_id}" />
+<input type="hidden" name="topic_id" value="${topic_id}" />
+<input type="hidden" name="log_type" value="4" />
+<input type="hidden" name="log_description" />
+<!-- value below is overwritten with the URL to the newly created topic after split -->
+<input type="hidden" name="log_original_description"/>
+
+<table width="100%" cellspacing="0" cellpadding="10" align="center">
+	<tr>
+		<td class="bodyline">
+			<br />
+			<table width="100%" cellspacing="2" cellpadding="2" align="center">
+				<tr>
+					<td align="left" class="nav">
+						<a class="nav" href="${JForumContext.encodeURL("/forums/list")}">${I18n.getMessage("ForumListing.forumIndex")}</a>
+						&raquo; <a class="nav" href="${JForumContext.encodeURL("/forums/show/${forum.id}")}">${forum.name}</a></span>
+					</td>
+				</tr>
+			</table>
+			
+			<table class="forumline" width="100%" cellspacing="1" cellpadding="3">
+				<tr>
+					<th class="thhead"><b>${I18n.getMessage("PostForm.split.title")}</b></th>
+				</tr>
+				
+				<tr>
+					<td class="row1">
+						<table width="100%" cellspacing="0" cellpadding="1">
+							<tr>
+								<td colspan="2"><span class="gen">${I18n.getMessage("PostForm.split.description")}</span></td>
+							</tr>  
+							
+							<tr>
+								<td class="row1" width="15%"><span class="gen"><b>${I18n.getMessage("PostForm.split.newTopicTitle")}</b></span></td>
+								<td class="row2" width="85%">
+									<span class="gen">
+										<input class="subject" type="text" tabindex="2" maxlength="100" name="subject" value="${subject?default("")}" /> 
+									</span>
+								</td>
+							</tr>
+							
+							<tr>
+								<td class="row1" width="15%"><span class="gen"><b>${I18n.getMessage("PostForm.split.forumForNewTopic")}</b></span></td>
+								<td class="row2" width="85%">
+									<span class="gen">
+										<select name="to_forum" id="to_forum">
+											<option value="-1">[${I18n.getMessage("PostForm.split.emptyForum")}]</option>
+											<#list allCategories as category>
+												<optgroup label="${category.name}">
+													<#list category.getForums() as forum>
+														<option value="${forum.id}">&nbsp;&nbsp;${forum.name}</option>
+													</#list>
+												</optgroup>
+											</#list>
+										</select> 
+									</span>
+								</td>
+							</tr>
+	
+							<!-- POST LISTING --> 
+
+							<tr><td colspan="2">
+								<tr>
+									<th class="thleft" nowrap="nowrap" width="150">${I18n.getMessage("PostShow.author")}</th>
+									<th class="thright" nowrap="nowrap">${I18n.getMessage("PostShow.messageTitle")}</th>
+								</tr>
+				
+								<#assign rowColor = ""/>
+								<#list posts as post>
+									<#if post_index % 2 == 0>
+										<#assign rowColor = "row1">
+									<#else>
+										<#assign rowColor = "row2">
+									</#if>
+					
+									<#if post_index == 0>
+										<#assign disabledFirstSelect = "disabled">
+									<#else>
+										<#assign disabledFirstSelect = "">
+									</#if>
+					
+									<#assign user = users.get(post.userId)/>
+
+									<tr>
+										<td colspan="2">
+											<div class="postinfo">
+												<div class="date">
+													<#assign startStr = "0/"/>
+													<a href="${JForumContext.encodeURL("/posts/list/${startStr}${post.topicId}")}#p${post.id}">
+													<img src="${contextPath}/templates/${templateName}/images/icon_minipost_new.gif" alt="[Post New]" /></a>${post.formattedTime}
+												</div>
+												<div class="subject">&nbsp;&nbsp; &nbsp;<b>${I18n.getMessage("PostShow.subject")}:</b> <a name="p${post.id}">${post.subject?default("")?html}</a></div>
+												<div class="action">
+													<table>
+														<tr>
+														<td>
+															<a class="nav" href="#top"><img src="${contextPath}/templates/${templateName}/images/icon_up.gif" alt="[Up]" /></a>
+															#${post_index+1}
+														</td>
+														<td>Select:</td>
+														<td><input type="checkbox" name="selectedPosts" ${disabledFirstSelect} value="${post.id}"></td>
+														</tr>
+													</table>											
+												</div>
+											</div>
+										</td>
+									</tr>
+				
+									<tr>
+										<!-- Username -->
+										<#assign rowspan = "3"/>
+										<#assign useSignature = (user.attachSignatureEnabled && user.signature?exists && user.signature?length > 0 && post.isSignatureEnabled())/>
+				
+										<#if useSignature>
+											<#assign rowspan = "3"/>
+										<#else>
+											<#assign rowspan = "2"/>
+										</#if>
+				
+										<td class="${rowColor}" valign="top" align="left" rowspan="${rowspan}">
+											<span class="genmed"><b>${user.username?html}</b></span>
+										</td>
+						
+										<!-- Message -->
+										<td class="${rowColor}" valign="top" id="post_text_${post.id}">
+											<div class="postbody">
+												${post.text}
+											</div>
+				
+											<!-- Attachments -->
+											<#if post.hasAttachments() && (canDownloadAttachments || attachmentsEnabled)>
+												<#assign attachments = am.getAttachments(post.id, post.forumId)/>
+				
+												<#include "post_show_attachments_inc.htm"/>
+											</#if>
+				
+											<#if (post.editCount > 0) && post.editTime?exists>
+												<#if post.editCount == 1>
+													<#assign editCountMessage = "PostShow.editCountSingle"/>
+												<#else>
+													<#assign editCountMessage = "PostShow.editCountMany"/>
+												</#if>
+												
+												<p><i><span class="gensmall">${I18n.getMessage(editCountMessage, [post.editCount, post.editTime?datetime?string])}</span></i></p>
+											</#if>
+										</td>
+									</tr>
+				
+									<#if useSignature>
+										<tr>
+											<td colspan="2" class="${rowColor}" width="100%"><hr/><span class="gensmall">${user.signature}</span></td>
+										</tr>
+									</#if>
+												
+									<tr>
+										<td class="spacerow" colspan="2"><img src="${contextPath}/templates/${templateName}/images/spacer.gif" alt="" width="1" /></td>
+									</tr>
+								</#list>
+								<!-- END OF POST LISTING -->
+							</td></tr>
+								
+							<tr>
+								<td align="center" class="catbottom" colspan="2">
+									<input type="submit" name="submit" class="liteoption" value="${I18n.getMessage("split")}" />
+									&nbsp;
+									<input type="button" value="${I18n.getMessage("previousPage")}" onclick="history.go(-1)" class="liteoption" />
+								</td>
+							</tr>			
+						</table>
+					</td>
+				</tr>  
+			</table>  
+		</td>
+	</tr>
+</table>
+</form>
+<#include "bottom.htm"/>
\ No newline at end of file

Property changes on: H:\Java\eclipse\trunk\src\main\resources\templates\default\post_split.htm
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: H:\Java\eclipse\trunk\src\main\resources\templates\default\styles\style.css
===================================================================
--- H:\Java\eclipse\trunk\src\main\resources\templates\default\styles\style.css	(revision 207)
+++ H:\Java\eclipse\trunk\src\main\resources\templates\default\styles\style.css	(revision 251)
@@ -166,6 +166,7 @@
 .icon_topic_move { background-image: url(../images/topic_move.gif); width: 19px; height: 18px; display: inline; }
 .icon_topic_unlock { background-image: url(../images/topic_unlock.gif); width: 19px; height: 18px; display: inline; }
 .icon_topic_lock { background-image: url(../images/topic_lock.gif); width: 19px; height: 18px; display: inline; }
+.icon_topic_split { background-image: url(../images/topic_split.gif); width: 19px; height: 18px; display: inline; }
 .icon_latest_reply { background-image: url(../images/icon_latest_reply.gif); width: 18px; height: 9px; display: inline; }
 
 