diff --git a/src/test/java/org/olat/portfolio/FunctionalArtefactTest.java b/src/test/java/org/olat/portfolio/FunctionalArtefactTest.java
index e15b60ee8ec778e87abc9eee3e95b24faa376242..fe4b826ddd1e9f341d252174a1171a43695a2173 100644
--- a/src/test/java/org/olat/portfolio/FunctionalArtefactTest.java
+++ b/src/test/java/org/olat/portfolio/FunctionalArtefactTest.java
@@ -40,6 +40,7 @@ import org.olat.restapi.support.vo.RepositoryEntryVO;
 import org.olat.test.ArquillianDeployments;
 import org.olat.user.restapi.UserVO;
 import org.olat.util.FunctionalCourseUtil;
+import org.olat.util.FunctionalCourseUtil.AccessOption;
 import org.olat.util.FunctionalEPortfolioUtil;
 import org.olat.util.FunctionalHomeSiteUtil;
 import org.olat.util.FunctionalRepositorySiteUtil;
@@ -165,7 +166,7 @@ public class FunctionalArtefactTest {
 		
 		/* create binder, page or structure if necessary */
 		Assert.assertTrue(functionalEportfolioUtil.createElements(browser, FORUM_BINDER, FORUM_PAGE, FORUM_STRUCTURE));
-
+		
 		//FIXME:JK: really ugly
 		try {
 			Thread.sleep(500);
@@ -194,7 +195,7 @@ public class FunctionalArtefactTest {
 		
 		/* create binder, page or structure if necessary */
 		Assert.assertTrue(functionalEportfolioUtil.createElements(browser, WIKI_BINDER, WIKI_PAGE, WIKI_STRUCTURE));
-		
+
 		//FIXME:JK: really ugly
 		try {
 			Thread.sleep(500);
@@ -202,7 +203,7 @@ public class FunctionalArtefactTest {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-
+		
 		/* create an article for the wiki */
 		Assert.assertTrue(functionalCourseUtil.createWikiArticle(browser, vo.getKey(), WIKI_ARTICLE_PAGENAME, WIKI_ARTICLE_CONTENT));
 		
@@ -215,18 +216,35 @@ public class FunctionalArtefactTest {
 	@Test
 	@RunAsClient
 	public void checkCollectBlogPost() throws URISyntaxException, IOException{
-		/* import blog via rest */
-		long repoKey = functionalRepositorySiteUtil.createBlog(browser, BLOG_TITLE, BLOG_DESCRIPTION);
+		/* deploy course with REST */
+		CourseVO course = functionalVOUtil.importCourseIncludingBlog(deploymentUrl);
+		
+//		long repoKey = functionalRepositorySiteUtil.createBlog(browser, BLOG_TITLE, BLOG_DESCRIPTION);
+		
+		/*  */
+//		Assert.assertTrue(functionalUtil.login(browser, user.getLogin(), user.getPassword(), true));
+//		Assert.assertTrue(functionalCourseUtil.openBlog(browser, repoKey));
+//		Assert.assertTrue(functionalCourseUtil.openCourseEditor(browser));
+//		Assert.assertTrue(functionalCourseUtil.disableAccessOption(browser, AccessOption.BLOCKED_FOR_LEARNERS, 1)); //TODO:JK: don't use hard coded form index
+		
 		
 		/* login for test setup */
 		Assert.assertTrue(functionalUtil.login(browser, user.getLogin(), user.getPassword(), true));
-		
 
 		/* create binder, page or structure if necessary */
 		Assert.assertTrue(functionalEportfolioUtil.createElements(browser, BLOG_BINDER, BLOG_PAGE, BLOG_STRUCTURE));
 		
+		//FIXME:JK: really ugly
+		try {
+			Thread.sleep(500);
+		} catch (InterruptedException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
 		/* blog */
-		Assert.assertTrue(functionalCourseUtil.createBlogEntry(browser, repoKey, BLOG_POST_TITLE, BLOG_POST_DESCRIPTION, BLOG_POST_CONTENT));
+		Assert.assertTrue(functionalCourseUtil.createBlogEntry(browser, course.getRepoEntryKey(), 0,
+				BLOG_POST_TITLE, BLOG_POST_DESCRIPTION, BLOG_POST_CONTENT));
 		
 		/* add artefact */
 		Assert.assertTrue(functionalCourseUtil.addToEportfolio(browser, BLOG_BINDER, BLOG_PAGE, BLOG_STRUCTURE,
@@ -270,5 +288,7 @@ public class FunctionalArtefactTest {
 		Assert.assertTrue(functionalEportfolioUtil.createLearningJournal(browser, LEARNING_JOURNAL_BINDER, LEARNING_JOURNAL_PAGE, LEARNING_JOURNAL_STRUCTURE,
 				LEARNING_JOURNAL_TITLE, LEARNING_JOURNAL_DESCRIPTION,
 				LEARNING_JOURNAL_TAGS));
+		
+		System.out.println();
 	}
 }
diff --git a/src/test/java/org/olat/util/FunctionalCourseUtil.java b/src/test/java/org/olat/util/FunctionalCourseUtil.java
index d2220f4c7d6869dc2d5732e25a01490a12c9f343..b3fde027458c61e7bb3ee2c0dfa2f97fc6ccd992 100644
--- a/src/test/java/org/olat/util/FunctionalCourseUtil.java
+++ b/src/test/java/org/olat/util/FunctionalCourseUtil.java
@@ -34,6 +34,7 @@ public class FunctionalCourseUtil {
 	public final static String EPORTFOLIO_ADD_CSS = "b_eportfolio_add";
 	
 	public final static String FORUM_ICON_CSS = "o_fo_icon";
+	public final static String BLOG_ICON_CSS = "o_blog_icon";
 	
 	public final static String FORUM_TOOLBAR_CSS = "o_forum_toolbar";
 	public final static String FORUM_THREAD_NEW_CSS = "o_sel_forum_thread_new";
@@ -45,12 +46,73 @@ public class FunctionalCourseUtil {
 	public final static String WIKI_EDIT_FORM_WRAPPER_CSS = "o_wikimod_editform_wrapper";
 	
 	public final static String BLOG_CREATE_ENTRY_CSS = "o_sel_feed_item_new";
+	public final static String BLOG_FORM_CSS = "o_sel_blog_form";
+	
+	public enum CourseNodeTab {
+		TITLE_AND_DESCRIPTION,
+		VISIBILITY,
+		ACCESS,
+		CONTENT;
+	};
+	
+	public enum VisibilityOption {
+		BLOCKED_FOR_LEARNERS,
+		DEPENDING_ON_DATE,
+		DEPENDING_ON_GROUP,
+		DEPENDING_ON_ASSESSMENT,
+		APPLY_TO_OWNERS_AND_TUTORS(DEPENDING_ON_ASSESSMENT);
+		
+		private VisibilityOption requires;
+		
+		VisibilityOption(){
+			this(null);
+		}
+		
+		VisibilityOption(VisibilityOption requires){
+			setRequires(requires);
+		}
+
+		public VisibilityOption getRequires() {
+			return requires;
+		}
+
+		public void setRequires(VisibilityOption requires) {
+			this.requires = requires;
+		}
+	};
+	
+	public enum AccessOption {
+		BLOCKED_FOR_LEARNERS,
+		DEPENDING_ON_DATE,
+		DEPENDING_ON_GROUP,
+		DEPENDING_ON_ASSESSMENT,
+		APPLY_TO_OWNERS_AND_TUTORS(DEPENDING_ON_ASSESSMENT);
+		
+		private AccessOption requires;
+		
+		AccessOption(){
+			this(null);
+		}
+		
+		AccessOption(AccessOption requires){
+			setRequires(requires);
+		}
+
+		public AccessOption getRequires() {
+			return requires;
+		}
+
+		public void setRequires(AccessOption requires) {
+			this.requires = requires;
+		}
+	}
 	
 	private String courseRunCss;
 	
 	private String eportfolioAddCss;
 	
 	private String forumIconCss;
+	private String blogIconCss;
 	
 	private String forumToolbarCss;
 	private String forumThreadNewCss;
@@ -62,6 +124,7 @@ public class FunctionalCourseUtil {
 	private String wikiEditFormWrapperCss;
 	
 	private String blogCreateEntryCss;
+	private String blogFormCss;
 	
 	private FunctionalUtil functionalUtil;
 	private FunctionalRepositorySiteUtil functionalRepositorySiteUtil;
@@ -75,6 +138,7 @@ public class FunctionalCourseUtil {
 		setEportfolioAddCss(EPORTFOLIO_ADD_CSS);
 		
 		setForumIconCss(FORUM_ICON_CSS);
+		setBlogIconCss(BLOG_ICON_CSS);
 		
 		setForumToolbarCss(FORUM_TOOLBAR_CSS);
 		setForumThreadNewCss(FORUM_THREAD_NEW_CSS);
@@ -86,6 +150,7 @@ public class FunctionalCourseUtil {
 		setWikiEditFormWrapperCss(WIKI_EDIT_FORM_WRAPPER_CSS);
 		
 		setBlogCreateEntryCss(BLOG_CREATE_ENTRY_CSS);
+		setBlogFormCss(BLOG_FORM_CSS);
 	}
 	
 	/**
@@ -135,6 +200,45 @@ public class FunctionalCourseUtil {
 		return(true);
 	}
 	
+	/**
+	 * @param browser
+	 * @return true on success
+	 * 
+	 * Opens the course editor but the course must be open.
+	 */
+	public boolean openCourseEditor(Selenium browser){
+		//TODO:JK: implement me
+		return(false);
+	}
+	
+	/**
+	 * @param browser
+	 * @param option
+	 * @param nthForm
+	 * @return true on success
+	 * 
+	 * Disables the specified access option, the course editor should be open.
+	 */
+	public boolean disableAccessOption(Selenium browser, AccessOption option, int nthForm){
+		//TODO:JK: implement me
+		
+		return(false);
+	}
+	
+	/**
+	 * @param browser
+	 * @param option
+	 * @param nthForm
+	 * @return true on success
+	 * 
+	 * Enables the specified access option, the course editor should be open.
+	 */
+	public boolean enableAccessOption(Selenium browser, AccessOption option, int nthForm){
+		//TODO:JK: implement me
+		
+		return(false);
+	}
+	
 	/**
 	 * @param browser
 	 * @return true on success
@@ -173,8 +277,7 @@ public class FunctionalCourseUtil {
 			
 			/* click finish */
 			functionalUtil.clickWizardFinish(browser);
-			
-			functionalUtil.waitForPageToLoad(browser);
+			functionalUtil.waitForPageToUnloadElement(browser, selector);
 		}
 
 		return(true);
@@ -272,7 +375,7 @@ public class FunctionalCourseUtil {
 	 * Opens the wiki specified by id.
 	 */
 	public boolean openWiki(Selenium browser, long id){
-		browser.open(functionalUtil.getDeploymentUrl() + "url/RepositoryEntry/" + id);
+		browser.open(functionalUtil.getDeploymentPath() + "/url/RepositoryEntry/" + id);
 		functionalUtil.waitForPageToLoad(browser);
 		
 		return(true);
@@ -356,7 +459,36 @@ public class FunctionalCourseUtil {
 	 * Opens the blog specified by id.
 	 */
 	public boolean openBlog(Selenium browser, long id){
-		browser.open(functionalUtil.getDeploymentUrl() + "url/RepositoryEntry/" + id);
+		browser.open(functionalUtil.getDeploymentPath() + "/url/RepositoryEntry/" + id);
+		functionalUtil.waitForPageToLoad(browser);
+		
+		return(true);
+	}
+	
+	/**
+	 * @param browser
+	 * @param courseId
+	 * @param nth
+	 * @return
+	 * 
+	 * Opens the course with courseId and nth blog within the specified
+	 * course.
+	 */
+	public boolean openBlogWithoutBusinessPath(Selenium browser, long courseId, int nth){
+		if(!functionalRepositorySiteUtil.openCourse(browser, courseId))
+			return(false);
+		
+		StringBuffer selectorBuffer = new StringBuffer();
+
+		selectorBuffer.append("xpath=(//ul//li//a[contains(@class, '")
+		.append(getBlogIconCss())
+		.append("')])[")
+		.append(nth + 1)
+		.append("]");
+		
+		functionalUtil.waitForPageToLoadElement(browser, selectorBuffer.toString());
+		browser.click(selectorBuffer.toString());
+		
 		functionalUtil.waitForPageToLoad(browser);
 		
 		return(true);
@@ -372,8 +504,9 @@ public class FunctionalCourseUtil {
 	 * 
 	 * Create a new blog entry.
 	 */
-	public boolean createBlogEntry(Selenium browser, long blogId, String title, String description, String content){
-		if(!openBlog(browser, blogId))
+	public boolean createBlogEntry(Selenium browser, long courseId, int nth,
+			String title, String description, String content){
+		if(!openBlogWithoutBusinessPath(browser, courseId, nth))
 			return(false);
 		
 		StringBuffer selectorBuffer = new StringBuffer();
@@ -387,40 +520,31 @@ public class FunctionalCourseUtil {
 		/* fill in form - title */
 		selectorBuffer = new StringBuffer();
 		
-		selectorBuffer.append("xpath=//form//div[contains(@class, '")
-		.append(functionalUtil.getWizardCss())
-		.append("')]//input[@type='text' and position = 1]");
+		selectorBuffer.append("xpath=(//form//div[contains(@class, '")
+		.append(getBlogFormCss())
+		.append("')]//input[@type='text'])[1]");
+		
+		functionalUtil.waitForPageToLoadElement(browser, selectorBuffer.toString());
 		
 		browser.type(selectorBuffer.toString(), title);
 		
 		/* fill in form - description */
-		selectorBuffer = new StringBuffer();
-		
-		selectorBuffer.append("xpath=//form//div[contains(@class, '")
-		.append(functionalUtil.getWizardCss())
-		.append("')]//textarea[0]");
-		
-		browser.type(selectorBuffer.toString(), description);
+		functionalUtil.typeMCE(browser, getBlogFormCss(), description);
 		
 		/* fill in form - content */
-		selectorBuffer = new StringBuffer();
-		
-		selectorBuffer.append("xpath=//form//div[contains(@class, '")
-		.append(functionalUtil.getWizardCss())
-		.append("')]//textarea[1]");
-		
-		browser.type(selectorBuffer.toString(), content);
+		functionalUtil.typeMCE(browser, getBlogFormCss(), content);
 		
 		/* save form */
 		selectorBuffer = new StringBuffer();
 		
 		selectorBuffer.append("xpath=//form//div[contains(@class, '")
-		.append(functionalUtil.getWizardCss())
+		.append(getBlogFormCss())
 		.append("')]//button[last()]");
 		
 		browser.click(selectorBuffer.toString());
+		functionalUtil.waitForPageToLoad(browser);
 		
-		return(false);
+		return(true);
 	}
 	
 	public FunctionalUtil getFunctionalUtil() {
@@ -464,6 +588,14 @@ public class FunctionalCourseUtil {
 		this.forumIconCss = forumIconCss;
 	}
 
+	public String getBlogIconCss() {
+		return blogIconCss;
+	}
+
+	public void setBlogIconCss(String blogIconCss) {
+		this.blogIconCss = blogIconCss;
+	}
+
 	public String getForumToolbarCss() {
 		return forumToolbarCss;
 	}
@@ -527,5 +659,13 @@ public class FunctionalCourseUtil {
 	public void setBlogCreateEntryCss(String blogCreateEntryCss) {
 		this.blogCreateEntryCss = blogCreateEntryCss;
 	}
+
+	public String getBlogFormCss() {
+		return blogFormCss;
+	}
+
+	public void setBlogFormCss(String blogFormCss) {
+		this.blogFormCss = blogFormCss;
+	}
 	
 }
diff --git a/src/test/java/org/olat/util/FunctionalRepositorySiteUtil.java b/src/test/java/org/olat/util/FunctionalRepositorySiteUtil.java
index 886204a462737ae55e99e855d3966f271fc8fcaf..5d72b25dbf4ea7e2247f83bc025d13b7d7991866 100644
--- a/src/test/java/org/olat/util/FunctionalRepositorySiteUtil.java
+++ b/src/test/java/org/olat/util/FunctionalRepositorySiteUtil.java
@@ -126,6 +126,14 @@ public class FunctionalRepositorySiteUtil {
 		GLOSSARY;
 	}
 	
+	public enum AccessSettings {
+		ONLY_OWNERS,
+		OWNERS_AND_AUTHORS,
+		USERS,
+		USERS_AND_GUESTS,
+		MEMBERS_ONLY;
+	}
+	
 	public final static String TOOLBOX_CONTENT_CSS = "b_toolbox_content";
 	public final static String TOOLBOX_COURSE_CSS = "o_toolbox_course";
 	public final static String TOOLBOX_CONTENT_PACKAGE_CSS = "o_toolbox_content";
@@ -373,7 +381,7 @@ public class FunctionalRepositorySiteUtil {
 	 * Opens a course by using business path.
 	 */
 	public boolean openCourse(Selenium browser, long key){
-		browser.open(functionalUtil.getDeploymentUrl() + "url/RepositoryEntry/" + key);
+		browser.open(functionalUtil.getDeploymentPath() + "/url/RepositoryEntry/" + key);
 		functionalUtil.waitForPageToLoad(browser);
 		
 		return(true);
@@ -425,6 +433,30 @@ public class FunctionalRepositorySiteUtil {
 		return(true);
 	}
 	
+	/**
+	 * @param browser
+	 * @param key
+	 * @return
+	 * 
+	 * Opens the appropriate detailed view.
+	 */
+	public boolean openDetailedView(Selenium browser, Long key){
+		//TODO:JK: implement me
+		
+		return(false);
+	}
+	
+	/**
+	 * @param browser
+	 * @param settings
+	 * @return
+	 */
+	public boolean modifySettings(Selenium browser, AccessSettings settings){
+		//TODO:JK: implement me
+		
+		return(false);
+	}
+	
 	public String findCssClassOfCourseAlias(String descriptor){
 		//TODO:JK: implement me
 		
diff --git a/src/test/java/org/olat/util/FunctionalUtil.java b/src/test/java/org/olat/util/FunctionalUtil.java
index 8e84818f57baa3163890017f113953e8e82b37d0..749a4dcefaa27af572b2327f5b3cafd426593b93 100644
--- a/src/test/java/org/olat/util/FunctionalUtil.java
+++ b/src/test/java/org/olat/util/FunctionalUtil.java
@@ -43,7 +43,8 @@ import com.thoughtworks.selenium.Selenium;
 public class FunctionalUtil {
 	private final static OLog log = Tracing.createLoggerFor(FunctionalUtil.class);
 	
-	public final static String DEPLOYMENT_URL = "http://localhost:8080/olat";
+	public final static String DEPLOYMENT_URL = "http://localhost:8080/openolat";
+	public final static String DEPLOYMENT_PATH = "/openolat";
 	public final static String WAIT_LIMIT = "5000";
 	
 	public final static String LOGIN_PAGE = "dmz";
@@ -109,6 +110,7 @@ public class FunctionalUtil {
 	private String password;
 	
 	private String deploymentUrl;
+	private String deploymentPath;
 	private String waitLimit;
 	
 	private String loginPage;
@@ -165,6 +167,7 @@ public class FunctionalUtil {
 		}
 		
 		deploymentUrl = DEPLOYMENT_URL;
+		deploymentPath = DEPLOYMENT_PATH;
 		waitLimit = WAIT_LIMIT;
 		
 		loginPage = LOGIN_PAGE;
@@ -284,6 +287,57 @@ public class FunctionalUtil {
 		return(false);
 	}
 	
+	
+	/**
+	 * @param browser
+	 * @param locator
+	 * @return true on success otherwise false
+	 * 
+	 * Waits at most (waitLimit + WaitLimitAttribute.VERY_SAVE) amount of time for element to load
+	 * specified by locator.
+	 */
+	public boolean waitForPageToUnloadElement(Selenium browser, String locator){
+		return(waitForPageToUnloadElement(browser, locator, WaitLimitAttribute.VERY_SAVE));
+	}
+	
+	/**
+	 * @param browser
+	 * @param locator
+	 * @param wait
+	 * @return true on success otherwise false
+	 * 
+	 * Waits at most (waitLimit + wait) amount of time for element to load
+	 * specified by locator.
+	 */
+	public boolean waitForPageToUnloadElement(Selenium browser, String locator, WaitLimitAttribute wait){
+		long startTime = Calendar.getInstance().getTimeInMillis();
+		long currentTime = startTime;
+		long waitLimit = Long.parseLong(getWaitLimit()) + Long.parseLong(wait.getExtend());
+
+		log.info("waiting for page to unload element");
+		
+		do{
+			if(!browser.isElementPresent(locator)){
+				log.info("found element after " + (currentTime - startTime) + "ms");
+				
+				return(true);
+			}
+			
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+			
+			
+			currentTime = Calendar.getInstance().getTimeInMillis();
+		}while(waitLimit >  currentTime - startTime);
+		
+		log.warn("giving up after " + waitLimit + "ms");
+		
+		return(false);
+	}
+	
 	/**
 	 * @param site
 	 * @return the matching CSS class
@@ -735,6 +789,25 @@ public class FunctionalUtil {
 		return(true);
 	}
 	
+	public boolean typeMCE(Selenium browser, String cssClass, String content){
+		if(content == null)
+			return(true);
+		
+		StringBuffer selectorBuffer = new StringBuffer();
+		
+		selectorBuffer.append("dom=document.getElementsByClassName('")
+		.append(cssClass)
+		.append("')[0].getElementsByClassName('")
+		.append("mceIframeContainer")
+		.append("')[0].getElementsByTagName('iframe')[0].contentDocument.body");
+		
+		waitForPageToLoadElement(browser, selectorBuffer.toString());
+		
+		browser.type(selectorBuffer.toString(), content);
+		
+		return(true);
+	}
+	
 	/**
 	 * @param browser
 	 * @param entryCss
@@ -814,6 +887,9 @@ public class FunctionalUtil {
 		.append(getWizardFinishCss())
 		.append("')]");
 		
+		waitForPageToLoadElement(browser, locatorBuffer.toString());
+		
+		browser.focus(locatorBuffer.toString());
 		browser.click(locatorBuffer.toString());
 		
 		return(true);
@@ -843,6 +919,14 @@ public class FunctionalUtil {
 		this.deploymentUrl = deploymentUrl;
 	}
 
+	public String getDeploymentPath() {
+		return deploymentPath;
+	}
+
+	public void setDeploymentPath(String deploymentPath) {
+		this.deploymentPath = deploymentPath;
+	}
+
 	public String getWaitLimit() {
 		return waitLimit;
 	}
diff --git a/src/test/java/org/olat/util/FunctionalVOUtil.java b/src/test/java/org/olat/util/FunctionalVOUtil.java
index 82140b106e354272cbc8bf6bb1ba9257bcedee92..9d36fe070cb403bca0143d767a60a3b3cfa4548c 100644
--- a/src/test/java/org/olat/util/FunctionalVOUtil.java
+++ b/src/test/java/org/olat/util/FunctionalVOUtil.java
@@ -216,6 +216,18 @@ public class FunctionalVOUtil {
 		return(importCourse(deploymentUrl, "/org/olat/portfolio/Course_including_Forum.zip", "Course_including_Forum.zip", "Course including Forum", "Course including Forum"));
 	}
 	
+	/**
+	 * @param deploymentUrl
+	 * @return
+	 * @throws URISyntaxException
+	 * @throws IOException
+	 * 
+	 * Imports the "Course including Blog" via REST.
+	 */
+	public CourseVO importCourseIncludingBlog(URL deploymentUrl) throws URISyntaxException, IOException{
+		return(importCourse(deploymentUrl, "/org/olat/portfolio/Course_including_Blog.zip", "Course_including_Blog.zip", "Course including Blog", "Course including Blog"));
+	}
+	
 	/**
 	 * @param deploymentUrl
 	 * @return
diff --git a/src/test/resources/org/olat/portfolio/Course_including_Blog.zip b/src/test/resources/org/olat/portfolio/Course_including_Blog.zip
new file mode 100644
index 0000000000000000000000000000000000000000..62ec56d7e6f1321396de9cc7e58a1a2969ca585e
Binary files /dev/null and b/src/test/resources/org/olat/portfolio/Course_including_Blog.zip differ
diff --git a/src/test/resources/org/olat/portfolio/blog.zip b/src/test/resources/org/olat/portfolio/blog.zip
index b7d10f9788d15a05f30964506dff03f298495d35..faac98707d2b2959672b11c56b4cd6f8f7c9134c 100644
Binary files a/src/test/resources/org/olat/portfolio/blog.zip and b/src/test/resources/org/olat/portfolio/blog.zip differ