Index: uspace/app/hdisk/func_gpt.c
===================================================================
--- uspace/app/hdisk/func_gpt.c	(revision 8f6c778597143e8b7a55779be0e07007930e4f3c)
+++ uspace/app/hdisk/func_gpt.c	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
@@ -65,4 +65,10 @@
 
 	return EOK;
+}
+
+int new_gpt_table(tinput_t * in, union table_data * data)
+{
+	data->gpt.gpt = gpt_alloc_gpt_header();
+	data->gpt.parts = gpt_alloc_partitions();
 }
 
Index: uspace/app/hdisk/func_gpt.h
===================================================================
--- uspace/app/hdisk/func_gpt.h	(revision 8f6c778597143e8b7a55779be0e07007930e4f3c)
+++ uspace/app/hdisk/func_gpt.h	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
@@ -44,4 +44,5 @@
 extern int add_gpt_part(tinput_t * in, union table_data * data);
 extern int delete_gpt_part(tinput_t * in, union table_data * data);
+extern int new_gpt_table(tinput_t *, union table_data *);
 extern int print_gpt_parts(union table_data * data);
 extern int write_gpt_parts(service_id_t dev_handle, union table_data * data);
Index: uspace/app/hdisk/func_mbr.c
===================================================================
--- uspace/app/hdisk/func_mbr.c	(revision 8f6c778597143e8b7a55779be0e07007930e4f3c)
+++ uspace/app/hdisk/func_mbr.c	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
@@ -75,4 +75,10 @@
 
 	return EOK;
+}
+
+int new_mbr_table(tinput_t * in, union table_data * data)
+{
+	data->mbr.mbr = mbr_alloc_mbr();
+	data->mbr.parts = mbr_alloc_partitions();
 }
 
Index: uspace/app/hdisk/func_mbr.h
===================================================================
--- uspace/app/hdisk/func_mbr.h	(revision 8f6c778597143e8b7a55779be0e07007930e4f3c)
+++ uspace/app/hdisk/func_mbr.h	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
@@ -44,4 +44,5 @@
 extern int add_mbr_part(tinput_t * in, union table_data * data);
 extern int delete_mbr_part(tinput_t * in, union table_data * data);
+extern int new_mbr_table(tinput_t *, union table_data *);
 extern int print_mbr_parts(union table_data * data);
 extern int write_mbr_parts(service_id_t dev_handle, union table_data * data);
Index: uspace/app/hdisk/func_none.c
===================================================================
--- uspace/app/hdisk/func_none.c	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
+++ uspace/app/hdisk/func_none.c	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012, 2013 Dominik Taborsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /** @addtogroup hdisk
+ * @{
+ */
+/** @file
+ */
+
+
+#include <loc.h>
+#include <tinput.h>
+#include <libmbr.h>
+
+#include "common.h"
+#include "func_none.h"
+
+static void not_implemented();
+
+int add_none_part(tinput_t * in, union table_data * data)
+{
+	not_implemented();
+	return EOK;
+}
+
+int delete_none_part(tinput_t * in, union table_data * data)
+{
+	not_implemented();
+	return EOK;
+}
+
+int new_none_table(tinput_t * in, union table_data * data)
+{
+	not_implemented();
+	return EOK;
+}
+
+int print_none_parts(union table_data * data)
+{
+	not_implemented();
+	return EOK;
+}
+
+int write_none_parts(service_id_t dev_handle, union table_data * data)
+{
+	not_implemented();
+	return EOK;
+}
+
+int extra_none_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data)
+{
+	not_implemented();
+	return EOK;
+}
+
+static void not_implemented()
+{
+	printf("No format selected.\n");
+}
Index: uspace/app/hdisk/func_none.h
===================================================================
--- uspace/app/hdisk/func_none.h	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
+++ uspace/app/hdisk/func_none.h	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 2013 Dominik Taborsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /** @addtogroup hdisk
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __FUNC_MBR_H__
+#define	__FUNC_MBR_H__
+
+#include <loc.h>
+#include <tinput.h>
+#include <libmbr.h>
+
+#include "common.h"
+
+extern int add_none_part(tinput_t * in, union table_data * data);
+extern int delete_none_part(tinput_t * in, union table_data * data);
+extern int new_none_table(tinput_t *, union table_data *);
+extern int print_none_parts(union table_data * data);
+extern int write_none_parts(service_id_t dev_handle, union table_data * data);
+extern int extra_none_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data);
+
+#endif
Index: uspace/app/hdisk/hdisk.c
===================================================================
--- uspace/app/hdisk/hdisk.c	(revision 8f6c778597143e8b7a55779be0e07007930e4f3c)
+++ uspace/app/hdisk/hdisk.c	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
@@ -53,4 +53,5 @@
 int interact(service_id_t dev_handle);
 void print_help(void);
+void select_table_format(void);
 void fill_table_funcs(void);
 void free_table(void);
@@ -94,26 +95,30 @@
 		set_table_mbr_parts(parts);
 		fill_table_funcs();
-	} else {
+		goto interact;
+	}
+	
+	
+	mbr_free_mbr(mbr);
+	gpt_t * gpt = gpt_read_gpt_header(dev_handle);
+	
+	if(gpt != NULL) {
 		table.layout = LYT_GPT;
-		mbr_free_mbr(mbr);
-		gpt_t * gpt = gpt_read_gpt_header(dev_handle);
-		printf("here3\n");
-		if(gpt == NULL) {
-			printf("Failed to read and parse GPT header. Exiting.\n");
-			return -1;
-		}
 		set_table_gpt(gpt);
-		printf("here4\n");
+		
 		gpt_partitions_t * parts = gpt_read_partitions(gpt);
-		printf("here5\n");
+		
 		if(parts == NULL) {
 			printf("Failed to read and parse partitions.\n"	\
 				   "Creating new partition table.");
-			//parts = gpt_alloc_partitions();
+			parts = gpt_alloc_partitions();
 		}
 		set_table_gpt_parts(parts);
 		fill_table_funcs();
-	}
-
+		goto interact;
+	}
+	printf("No partition table recognized. Create a new one.\n");
+	table.layout = LYT_NONE;
+	
+interact:
 	rc = interact(dev_handle);
 	
@@ -122,55 +127,11 @@
 	return rc;
 }
-
-/*
-int get_input(tinput_t * in, char ** str)
-{
-	int c;
-	size_tat
-
-	 pos = 0;
-	size_t size = 256;
-
-	*str = malloc(size * sizeof(char));
-	if (*str == NULL)
-		return ENOMEM;
-
-	while ((c = getchar()) != '\n') {
-		if (c >= 32 && c <= 126) {	//a printable character
-
-			(*str)[pos] = c;
-			++pos;
-			putchar(c);
-
-			if (pos == size) {
-				char * temp = malloc(2 * size * sizeof(char));
-				memcpy(temp, *str, size);
-				free(*str);
-				*str = temp;
-				size *= 2;
-			}
-		} else if (c == 8) {		//backspace
-			(*str)[pos] = 0;
-			--pos;
-			putchar(c);
-		}
-	}
-
-	putchar('\n');
-
-	(*str)[pos] = 0;
-
-	return EOK;
-}
-*/
-
 
 /** Interact with user */
 int interact(service_id_t dev_handle)
 {
-	//int rc;
 	int input;
 	tinput_t * in;
-
+	
 	in = tinput_new();
 	if (in == NULL) {
@@ -179,32 +140,12 @@
 	}
 	tinput_set_prompt(in, "");
-
+	
 	printf("Welcome to hdisk.\nType 'h' for help.\n");
-
-	//printf("# ");
-	//input = getchar();
-	//printf("%c\n", input);
-
+	
 	while (1) {
-
 		printf("# ");
 		input = getchar();
 		printf("%c\n", input);
-
-
-		//rc = tinput_read(in, &str);
-		//if (rc == ENOENT) {
-			//// User requested exit
-			//putchar('\n');
-			//return rc;
-		//}
-		//if (rc != EOK) {
-			//printf("Failed reading input. Exiting...\n");
-			//return rc;
-		//}
-		//// Check for empty input.
-		//if (str_cmp(str, "") == 0)
-			//continue;
-
+		
 		switch(input) {
 			case 'a':
@@ -217,6 +158,14 @@
 				table.extra_funcs(in, dev_handle, &table.data);
 				break;
+			case 'f':
+				free_table();
+				select_table_format(in);
+				break;
 			case 'h':
 				print_help();
+				break;
+			case 'n':
+				free_table();
+				table.new_table(in);
 				break;
 			case 'p':
@@ -233,13 +182,9 @@
 				break;
 		}
-		//printf("# ");
-		//input = getchar();
-		//printf("%c\n", input);
-
-	}
-
+	}
+	
 end:
 	tinput_destroy(in);
-
+	
 	return EOK;
 }
@@ -250,10 +195,37 @@
 		"\t 'a' \t\t Add partition.\n"
 		"\t 'd' \t\t Delete partition.\n"
-		"\t 'h' \t\t Prints help. See help for more.\n" \
-		"\t 'p' \t\t Prints the table contents.\n" \
-		"\t 'w' \t\t Write table to disk.\n" \
-		"\t 'q' \t\t Quit.\n" \
+		"\t 'e' \t\t Extra functions (per table format).\n"
+		"\t 'f' \t\t Switch the format of the partition table."
+		"\t 'h' \t\t Prints help. See help for more.\n"
+		"\t 'n' \t\t Create new partition table (discarding the old one).\n"
+		"\t 'p' \t\t Prints the table contents.\n"
+		"\t 'w' \t\t Write table to disk.\n"
+		"\t 'q' \t\t Quit.\n"
 		);
 
+}
+
+void select_table_format(tinput_t * in)
+{
+	printf("Available formats are: \n"
+			"1) MBR\n"
+			"2) GPT\n"
+		);
+	
+	uint8_t val = get_input_uint8(in);
+	switch(val) {
+		case 0:
+			table.layout = LYT_NONE;
+			fill_table_funcs();
+			break;
+		case 1:
+			table.layout = LYT_MBR;
+			fill_table_funcs();
+			break;
+		case 2:
+			table.layout = LYT_GPT;
+			fill_table_funcs();
+			break;
+	}
 }
 
@@ -264,4 +236,5 @@
 			table.add_part = add_mbr_part;
 			table.delete_part = delete_mbr_part;
+			table.new_table = new_mbr_table;
 			table.print_parts = print_mbr_parts;
 			table.write_parts = write_mbr_parts;
@@ -271,4 +244,5 @@
 			table.add_part = add_gpt_part;
 			table.delete_part = delete_gpt_part;
+			table.new_table	= new_gpt_table;
 			table.print_parts = print_gpt_parts;
 			table.write_parts = write_gpt_parts;
@@ -276,4 +250,10 @@
 			break;
 		default:
+			table.add_part = add_none_part;
+			table.delete_part = delete_none_part;
+			table.new_table = new_none_table;
+			table.print_parts = print_none_parts;
+			table.write_parts = write_none_parts;
+			table.extra_funcs = extra_none_funcs;
 			break;
 	}
@@ -284,10 +264,22 @@
 	switch(table.layout) {
 		case LYT_MBR:
-			mbr_free_partitions(table.data.mbr.parts);
-			mbr_free_mbr(table.data.mbr.mbr);
+			if (table.data.mbr.parts != NULL) {
+				mbr_free_partitions(table.data.mbr.parts);
+				table.data.mbr.parts = NULL;
+			}
+			if (table.data.mbr.mbr != NULL) {
+				mbr_free_mbr(table.data.mbr.mbr);
+				table.data.mbr.mbr = NULL;
+			}
 			break;
 		case LYT_GPT:
-			gpt_free_partitions(table.data.gpt.parts);
-			gpt_free_gpt(table.data.gpt.gpt);
+			if (table.data.gpt.parts != NULL) {
+				gpt_free_partitions(table.data.gpt.parts);
+				table.data.gpt.parts = NULL;
+			}
+			if (table.data.gpt.gpt != NULL) {
+				gpt_free_gpt(table.data.gpt.gpt);
+				table.data.gpt.gpt = NULL;
+			}
 			break;
 		default:
@@ -296,2 +288,4 @@
 }
 
+
+
Index: uspace/app/hdisk/hdisk.h
===================================================================
--- uspace/app/hdisk/hdisk.h	(revision 8f6c778597143e8b7a55779be0e07007930e4f3c)
+++ uspace/app/hdisk/hdisk.h	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
@@ -46,4 +46,5 @@
 	int (* add_part)(tinput_t *, union table_data *);
 	int (* delete_part)(tinput_t *, union table_data *);
+	int (* new_table)(tinput_t *, union table_data *);
 	int (* print_parts)();
 	int (* write_parts)(service_id_t, union table_data *);
Index: uspace/lib/gpt/libgpt.c
===================================================================
--- uspace/lib/gpt/libgpt.c	(revision 8f6c778597143e8b7a55779be0e07007930e4f3c)
+++ uspace/lib/gpt/libgpt.c	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
@@ -58,4 +58,10 @@
 static int gpt_memcmp(const void * a, const void * b, size_t len);
 
+/** Allocate memory for gpt header */
+gpt_t * gpt_alloc_gpt_header()
+{
+	return malloc(sizeof(gpt_t));
+}
+
 /** Read GPT from specific device
  * @param	dev_handle	device to read GPT from
@@ -162,4 +168,10 @@
 
 	return 0;
+}
+
+/** Alloc partition array */
+gpt_partitions_t *	gpt_alloc_partitions()
+{
+	return alloc_part_array(128);
 }
 
Index: uspace/lib/gpt/libgpt.h
===================================================================
--- uspace/lib/gpt/libgpt.h	(revision 8f6c778597143e8b7a55779be0e07007930e4f3c)
+++ uspace/lib/gpt/libgpt.h	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
@@ -139,8 +139,9 @@
 
 
-
+extern gpt_t * gpt_alloc_gpt_header();
 extern gpt_t * gpt_read_gpt_header(service_id_t dev_handle);
 extern int gpt_write_gpt_header(gpt_t * header, service_id_t dev_handle);
 
+extern gpt_partitions_t *	gpt_alloc_partitions();
 extern gpt_partitions_t *	gpt_read_partitions	(gpt_t * gpt);
 extern int 					gpt_write_partitions	(gpt_partitions_t * parts, gpt_t * header, service_id_t dev_handle);
Index: uspace/lib/mbr/libmbr.c
===================================================================
--- uspace/lib/mbr/libmbr.c	(revision 8f6c778597143e8b7a55779be0e07007930e4f3c)
+++ uspace/lib/mbr/libmbr.c	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
@@ -53,5 +53,9 @@
 static int check_preceeds(mbr_part_t * preceeder, mbr_part_t * precedee);
 
-static void debug_print(unsigned char * data, size_t bytes);
+/** Allocate memory for mbr_t */
+mbr_t * mbr_alloc_mbr()
+{
+	return alloc_br();
+}
 
 /** Read MBR from specific device
@@ -71,4 +75,5 @@
 	rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
 	if (rc != EOK) {
+		free(mbr);
 		return NULL;
 	}
@@ -76,4 +81,5 @@
 	rc = block_read_direct(dev_handle, 0, 1, &(mbr->raw_data));
 	if (rc != EOK) {
+		free(mbr);
 		block_fini(dev_handle);
 		return NULL;
@@ -83,5 +89,4 @@
 
 	mbr->device = dev_handle;
-	//mbr->partitions = NULL;
 
 	return mbr;
@@ -93,5 +98,5 @@
  * 							from the device in 'mbr')
  *
- * @return				0 on success, -1 on block_init error, -2 on write error
+ * @return				0 on success, otherwise libblock error code
  */
 int mbr_write_mbr(mbr_t * mbr, service_id_t dev_handle)
@@ -149,5 +154,4 @@
 			continue;
 		
-		//p = malloc(sizeof(mbr_part_t));
 		p = mbr_alloc_partition();
 		if (p == NULL) {
@@ -156,5 +160,5 @@
 			return NULL;
 		}
-		//list_append(&(p->link), &(parts->list));
+		
 		rc_ext = decode_part(&(mbr->raw_data.pte[i]), p, 0);
 		mbr_set_flag(p, ST_LOGIC, false);
@@ -179,6 +183,4 @@
 	}
 	
-	//DEBUG:
-	//debug_print((unsigned char *) list_get_instance(list_last(&(parts->list)), mbr_part_t, link)->ebr, 512);
 	return parts;
 }
@@ -193,5 +195,4 @@
 int mbr_write_partitions(mbr_partitions_t * parts, mbr_t * mbr, service_id_t dev_handle)
 {
-	//bool logical = false;
 	int i = 0;
 	int rc;
@@ -200,43 +201,9 @@
 					: list_get_instance(parts->l_extended, mbr_part_t, link);
 	
-	//br_block_t * last_ebr = NULL;
-	//link_t * it;
-	
-	DEBUG_PRINT_3(LIBMBR_NAME "Writing partitions: n_primary: %u, n_logical:%u, l_extended:%p", parts->n_primary, parts->n_logical, parts->l_extended);
-	
 	rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
 	if (rc != EOK) {
-		DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
+		printf(LIBMBR_NAME ": Error while initializing libblock: %d - %s.\n", rc, str_error(rc));
 		return rc;
 	}
-	/*
-	// Encoding primary partitions
-	for (i = 0; i < parts->n_primary; i++) {
-		encode_part(p, &(mbr->raw_data.pte[i]), 0);
-	}
-
-	// Writing MBR
-	rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
-	if (rc != EOK) {
-		DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
-		goto end;
-	}
-
-	uint32_t base = ext->start_addr;
-	uint32_t addr = base;
-
-	// Encoding and writing logical partitions
-	mbr_part_foreach(parts, p) {
-		if (p->ebr == NULL) {
-			p->ebr = alloc_br();
-			if (p->ebr == NULL)
-			{
-				rc = ENOMEM;
-				goto end;
-			}
-		}
-
-
-	}*/
 	
 	link_t * l = parts->list.head.next;
@@ -252,18 +219,19 @@
 	rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
 	if (rc != EOK) {
-		DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
+		printf(LIBMBR_NAME ": Error while writing MBR : %d - %s.\n", rc, str_error(rc));
 		goto end;
 	}
 	
 	if (ext == NULL)
-		goto no_extended;
-	
-	//DEBUG:
-	//debug_print((unsigned char *) list_get_instance(list_last(&(parts->list)), mbr_part_t, link)->ebr, 512);
+		goto end;
+	
 	uint32_t base = ext->start_addr;
-	//uint32_t addr = base;
-	//uint32_t prev_addr;
-	//mbr_part_t * tmp;
 	mbr_part_t * prev_p;
+	
+	/* Note for future changes: Some thought has been put into design
+	 * and implementation. If you don't have to change it, don't. Other
+	 * designs have been tried, this came out as the least horror with
+	 * as much power over it as you can get. Thanks. */
+	
 	// Encoding and writing first logical partition
 	if (l != &(parts->list.head)) {
@@ -271,27 +239,19 @@
 		p->ebr_addr = base;
 		encode_part(p, &(p->ebr->pte[0]), base, false);
-		
-		/*if (l->next == &(parts->list.head))
-			encode_part(NULL, &(p->ebr->pte[1]), base, false);
-		else {
-			tmp = list_get_instance(l->next, mbr_part_t, link);
-			//debug_print((unsigned char*) p->ebr, 512);
-			printf("DEBUG: base: %u, tmp: start: %u, end: %u\n", base, tmp->start_addr, tmp->start_addr + tmp->length);
-			//encode_part(tmp, &(p->ebr->pte[1]), base);
-			encode_part(tmp, &(p->ebr->pte[1]), base, true);
-			debug_print(((unsigned char*) p->ebr) + 446, 32);
-		}
-		
-		rc = block_write_direct(dev_handle, base, 1, p->ebr);
+		l = l->next;
+	} else {
+		/* If there was an extended but no logical, we should overwrite
+		 * the space where the first logical's EBR would have been. There
+		 * might be some garbage from the past. */
+		br_block_t * tmp = alloc_br();
+		rc = block_write_direct(dev_handle, base, 1, tmp);
 		if (rc != EOK) {
-			DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
+			printf(LIBMBR_NAME ": Error while writing EBR: %d - %s.\n", rc, str_error(rc));
 			goto end;
-		}*/
-		
-		l = l->next;
-	} else
-		goto no_logical;
-	
-	//prev_addr = base;
+		}
+		free(tmp);
+		goto end;
+	}
+	
 	prev_p = p;
 	
@@ -314,16 +274,9 @@
 		
 		encode_part(p, &(p->ebr->pte[0]), p->ebr_addr, false);
-		debug_print(((unsigned char*) p->ebr) + 446, 32);
 		encode_part(p, &(prev_p->ebr->pte[1]), base, true);
-		debug_print(((unsigned char*) prev_p->ebr) + 446, 32);
-		/*if (l->next == &(parts->list.head))
-			encode_part(NULL, &(p->ebr->pte[1]), base, false);
-		else
-			encode_part(list_get_instance(l->next, mbr_part_t, link), &(p->ebr->pte[1]), base, true);
-		*/
 		
 		rc = block_write_direct(dev_handle, prev_p->ebr_addr, 1, prev_p->ebr);
 		if (rc != EOK) {
-			DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
+			printf(LIBMBR_NAME ": Error while writing EBR: %d - %s.\n", rc, str_error(rc));
 			goto end;
 		}
@@ -333,215 +286,11 @@
 	}
 	
+	// write the last EBR
 	encode_part(NULL, &(prev_p->ebr->pte[1]), 0, false);
 	rc = block_write_direct(dev_handle, prev_p->ebr_addr, 1, prev_p->ebr);
 	if (rc != EOK) {
-		DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
+		printf(LIBMBR_NAME ": Error while writing EBR: %d - %s.\n", rc, str_error(rc));
 		goto end;
 	}
-	
-no_logical:
-no_extended:
-	
-	/*if (ext == NULL)
-		goto no_extended;
-
-	uint32_t base = ext->start_addr;
-	uint32_t addr;// = base;
-	uint32_t prev_addr;
-	mbr_part_t * prev_part = NULL;
-
-	list_foreach(parts->list, iter) {
-		p = list_get_instance(iter, mbr_part_t, link);
-		if (mbr_get_flag(p, ST_LOGIC)) {
-			// writing logical partition
-			logical = true;
-
-			if (p->ebr == NULL) {
-				p->ebr = alloc_br();
-				if (p->ebr == NULL)
-				{
-					rc = ENOMEM;
-					goto end;
-				}
-			}
-
-			if (prev_part != NULL) {
-				// addr is the address of EBR
-				addr = p->start_addr - base;
-				// base-1 means start_lba+1
-				encode_part(p, &(p->ebr->pte[0]), addr - 1);
-				encode_part(p, &(prev_part->ebr->pte[1]), base);
-				rc = block_write_direct(dev_handle, prev_addr, 1, prev_part->ebr);
-				if (rc != EOK) {
-					DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
-					goto end;
-				}
-			} else {
-				// addr is the address of EBR
-				addr = base;
-				// base-1 means start_lba+1
-				// Fixed: mbr_add_partition now performs checks!nevim
-				encode_part(p, &(p->ebr->pte[0]), base);
-			}
-
-			//addr = p->start_addr;
-			prev_addr = addr;
-			prev_part = p;
-		} else {
-			// writing primary partition
-			if (i >= 4) {
-				rc = EINVAL;
-				goto end;
-			}
-
-			encode_part(p, &(mbr->raw_data.pte[i]), 0);
-
-			++i;
-		}
-	} //*/
-
-	/* If there was an extended but no logical, we should overwrite
-	 * the space where the first logical's EBR would have been. There
-	 * might be some garbage from the past.
-	 */
-	/*
-	last_ebr = prev_part->ebr;
-
-	if (!logical)
-	{
-		last_ebr = alloc_br();
-		if (last_ebr == NULL) {
-			rc = ENOMEM;
-			goto end;
-		}
-
-		last_ebr->pte[0].ptype = PT_UNUSED;
-	}
-
-
-	encode_part(NULL, &(last_ebr->pte[1]), 0);
-	rc = block_write_direct(dev_handle, addr, 1, last_ebr);
-
-	if (!logical)
-	{
-		free(last_ebr);
-	}
-	*/
-	/*
-	if (rc != EOK) {
-		DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
-		goto end;
-	}
-
-	goto skip;
-
-no_extended:
-	*/
-	/*list_foreach(parts->list, it) {
-		p = list_get_instance(it, mbr_part_t, link);
-		if (mbr_get_flag(p, ST_LOGIC)) {
-			// extended does not exist, fail
-			return EINVAL;
-		} else {
-			// writing primary partition
-			if (i >= 4)
-				return EINVAL;
-
-			encode_part(p, &(mbr->raw_data.pte[i]), 0);
-
-			++i;
-		}
-	}*/
-	/*
-	it = parts->list.head.next;
-	for (i = 0; i < N_PRIMARY; i++) {
-		if (it != &parts->list.head) {
-			p = list_get_instance(it, mbr_part_t, link);
-			if (mbr_get_flag(p, ST_LOGIC)) {
-				// extended does not exist, fail
-				return EINVAL;
-			} else {
-				// writing primary partition
-				if (i >= 4)
-					return EINVAL;
-
-				encode_part(p, &(mbr->raw_data.pte[i]), 0);
-
-			}
-
-			it = it->next;
-		} else {
-			encode_part(NULL, &(mbr->raw_data.pte[i]), 0);
-		}
-	}
-
-
-skip:
-	rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
-	if (rc != EOK) {
-		DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
-		goto end;
-	}
-	*/
-
-	/*
-	for (i = 0; i < N_PRIMARY; ++i) {
-		encode_part(&(p->partition), &(mbr->raw_data.pte[i]), 0);
-		if (p->type == PT_EXTENDED)
-			ext = p;
-
-		//p = list_get_instance(p->link.next, mbr_partitions_t, link);
-		p = p->next;
-	}
-
-	rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
-	if (rc != EOK) {
-		block_fini(dev_handle);
-		return rc;
-	}
-
-	//writing logical partitions
-
-	if (p == NULL && ext != NULL) {
-		//we need an empty EBR to rewrite the old EBR on disk, if we need to delete it
-		br_block_t * temp_ebr = alloc_br();
-		if (temp_ebr == NULL) {
-			block_fini(dev_handle);
-			return ENOMEM;
-		}
-
-		temp_ebr->pte[0].ptype = PT_UNUSED;
-		encode_part(NULL, &(temp_ebr->pte[1]), 0);
-		rc = block_write_direct(dev_handle, ext->start_addr, 1, temp_ebr);
-		free(temp_ebr);
-		block_fini(dev_handle);
-		return rc;
-	}
-
-	if (p != NULL && ext == NULL) {
-		block_fini(dev_handle);
-		//no extended but one or more logical? EINVAL to the rescue!
-		return EINVAL;
-	}
-
-	aoff64_t addr = ext->start_addr;
-
-	while (p != NULL) {
-		if (p->type == PT_UNUSED) {
-			p = p->next;
-			continue;
-		}
-		//encode_part(p, &(p->ebr->pte[0]), p->start_addr - 63 * 512);
-		encode_part(p, &(p->ebr->pte[0]), addr);
-		encode_part(p->next, &(p->ebr->pte[1]), ext->start_addr);
-
-		rc = block_write_direct(dev_handle, p->start_addr, 1, p->ebr);
-		if (rc != EOK) {
-			block_fini(dev_handle);
-			return rc;
-		}
-		addr = p->start_addr;
-		p = p->next;
-	}*/
 	
 	rc = EOK;
@@ -560,4 +309,5 @@
 		return NULL;
 	}
+	
 	link_initialize(&(p->link));
 	p->ebr = NULL;
@@ -571,4 +321,5 @@
 }
 
+/** mbr_partitions_t constructor */
 mbr_partitions_t * mbr_alloc_partitions(void)
 {
@@ -579,5 +330,4 @@
 
 	list_initialize(&(parts->list));
-
 	parts->n_primary = 0;
 	parts->n_logical = 0;
@@ -589,18 +339,23 @@
 /** Add partition
  * 	Performs checks, sorts the list.
- */
-int mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * p)
+ * 
+ * @param parts			partition list to add to
+ * @param p				partition to add
+ * 
+ * @return				ERR_OK (0) on success, other MBR_ERR_VAL otherwise
+ */
+MBR_ERR_VAL mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * p)
 {
 	if (mbr_get_flag(p, ST_LOGIC)) { // adding logical part
-		if (parts->l_extended == NULL) {
+		// is there any extended partition?
+		if (parts->l_extended == NULL)
 			return ERR_NO_EXTENDED;
-		}
+		
+		// is the logical partition inside the extended one?
 		mbr_part_t * ext = list_get_instance(parts->l_extended, mbr_part_t, link);
-		if (!check_encaps(p, ext)) {
-			//printf("DEBUG: OOB: start: %u, end: %u\n", h->start_addr, h->start_addr + h->length);
-			//printf("DEBUG: OOB: start: %u, end: %u\n", p->start_addr, p->start_addr + p->length);
+		if (!check_encaps(p, ext))
 			return ERR_OUT_BOUNDS;
-		}
-
+		
+		// find a place for the new partition in a sorted linked list
 		mbr_part_t * last = list_get_instance(list_last(&(parts->list)), mbr_part_t, link);
 		mbr_part_t * iter;
@@ -608,9 +363,6 @@
 		mbr_part_foreach(parts, iter) {
 			if (mbr_get_flag(iter, ST_LOGIC)) {
-				if (check_overlap(p, iter)) {
-					//printf("DEBUG: overlap: start: %u, end: %u\n", iter->start_addr, iter->start_addr + iter->length);
-					//printf("DEBUG: overlap: start: %u, end: %u\n", p->start_addr, p->start_addr + p->length);
+				if (check_overlap(p, iter)) 
 					return ERR_OVERLAP;
-				}
 				if (check_preceeds(iter, p)) {
 					last = iter;
@@ -622,5 +374,4 @@
 		
 		// checking if there's at least one sector of space preceeding
-		
 		if (ebr_space < 1)
 			return ERR_NO_EBR;
@@ -628,9 +379,9 @@
 		// checking if there's at least one sector of space following (for following partitions's EBR)
 		if (last->link.next != &(parts->list.head)) {
-			if (list_get_instance(&(last->link.next), mbr_part_t, link)->start_addr <= p->start_addr + p->length + 1) {
+			if (list_get_instance(&(last->link.next), mbr_part_t, link)->start_addr <= p->start_addr + p->length + 1)
 				return ERR_NO_EBR;
-			}
-		}
-		
+		}
+		
+		// alloc EBR if it's not already there
 		if (p->ebr == NULL) {
 			p->ebr = alloc_br();
@@ -640,23 +391,23 @@
 		}
 		
-		//printf("DEBUG: last: start: %u\n", last->start_addr);
-		//list_prepend(&(p->link), &(parts->list));
+		// add it
 		list_insert_after(&(p->link), &(last->link));
 		parts->n_logical += 1;
-	} else {
-		// adding primary
+	} else { // adding primary
 		if (parts->n_primary == 4) {
 			return ERR_PRIMARY_FULL;
 		}
 		
-		// should we check if it's inside the drive's upper boundary?
+		// TODO: should we check if it's inside the drive's upper boundary?
 		if (p->start_addr == 0) {
 			return ERR_OUT_BOUNDS;
 		}
 		
+		// if it's extended, is there any other one?
 		if (p->type == PT_EXTENDED && parts->l_extended != NULL) {
 			return ERR_EXTENDED_PRESENT;
 		}
-
+		
+		// find a place and add it
 		if (list_empty(&(parts->list))) {
 			list_append(&(p->link), &(parts->list));
@@ -667,39 +418,67 @@
 					list_insert_before(&(p->link), &(iter->link));
 					break;
-				} else if (check_overlap(p, iter)) {
+				} else if (check_overlap(p, iter))
 					return ERR_OVERLAP;
-				}
 			}
-			if (iter == list_get_instance(&(parts->list.head.prev), mbr_part_t, link)) {
+			if (iter == list_get_instance(&(parts->list.head.prev), mbr_part_t, link))
 				list_append(&(p->link), &(parts->list));
+		}
+		parts->n_primary += 1;
+	}
+
+	return ERR_OK;
+}
+
+/** Remove partition
+ * 	Removes partition by index, indexed from zero. When removing extended
+ * partition, all logical partitions get removed as well.
+ * 
+ * @param parts			partition list to remove from
+ * @param idx			index of the partition to remove
+ * 
+ * @return				EOK on success, EINVAL if idx invalid
+ */
+int mbr_remove_partition(mbr_partitions_t * parts, size_t idx)
+{
+	link_t * l = list_nth(&(parts->list), idx);
+	if (l == NULL)
+		return EINVAL;
+	
+	mbr_part_t * p;
+	
+	/* TODO: if it is extended partition, should we also remove all logical?
+	 * If we don't, we break the consistency of the list. If we do,
+	 * the user will have to input them all over again. So yes. */
+	if (l == parts->l_extended) {
+		parts->l_extended = NULL;
+		
+		link_t * it = l->next;
+		link_t * next_it;
+		while (it != &(parts->list.head)) {
+			next_it = it->next;
+			
+			p = list_get_instance(it, mbr_part_t, link);
+			if (mbr_get_flag(p, ST_LOGIC)) {
+				list_remove(it);
+				parts->n_logical -= 1;
+				mbr_free_partition(p);
 			}
 			
-		}
-		parts->n_primary += 1;
-	}
-
-	return ERR_OK;
-}
-
-/** Remove partition */
-int mbr_remove_partition(mbr_partitions_t * parts, size_t idx)
-{
-	DEBUG_PRINT_1(LIBMBR_NAME "Removing partition: %zu\n", idx);
-	link_t * l = list_nth(&(parts->list), idx);
-	if (l == parts->l_extended) {
-		DEBUG_PRINT_0(LIBMBR_NAME "Removing extended partition.\n");
-		parts->l_extended = NULL;
-	}
+			it = next_it;
+		}
+		
+	}
+	
 	list_remove(l);
-	mbr_part_t * p = list_get_instance(l, mbr_part_t, link);
-	if (mbr_get_flag(p, ST_LOGIC)) {
+	
+	p = list_get_instance(l, mbr_part_t, link);
+	if (mbr_get_flag(p, ST_LOGIC))
 		parts->n_logical -= 1;
-	} else {
+	else
 		parts->n_primary -= 1;
-	}
-
-
+	
+	
 	mbr_free_partition(p);
-
+	
 	return EOK;
 }
@@ -769,6 +548,4 @@
 	
 	memset(br, 0, 512);
-	br->media_id = 0;
-	br->pad0 = 0;
 	br->signature = host2uint16_t_le(BR_SIGNATURE);
 	
@@ -847,12 +624,8 @@
 	p->ebr_addr = addr;
 	rc = mbr_add_partition(parts, p);
-	if (rc != ERR_OK) {
-		printf(LIBMBR_NAME ": Error occured during decoding the MBR. (%d)\n" \
-			   LIBMBR_NAME ": Partition list may be incomplete.\n", rc);
+	if (rc != ERR_OK) 
 		return EINVAL;
-	}
 	
 	addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
-	printf("DEBUG: b: %u, a: %u, start: %u\n", base, addr, ebr->pte[1].first_lba);
 	
 	while (ebr->pte[1].ptype != PT_UNUSED) {
@@ -879,5 +652,5 @@
 		}
 		
-		//printf("DEBUG: b: %u, a: %u, start: %u\n", base, addr, ebr->pte[0].first_lba);
+		
 		decode_part(&(ebr->pte[0]), p, addr);
 		mbr_set_flag(p, ST_LOGIC, true);
@@ -885,9 +658,6 @@
 		p->ebr_addr = addr;
 		rc = mbr_add_partition(parts, p);
-		if (rc != ERR_OK) {
-			printf(LIBMBR_NAME ": Error occured during decoding the MBR. (%d)\n" \
-				   LIBMBR_NAME ": Partition list may be incomplete.\n", rc);
+		if (rc != ERR_OK)
 			return EINVAL;
-		}
 		
 		addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
@@ -934,4 +704,8 @@
 }
 
+/** Check whether two partitions overlap
+ * 
+ * @return		1 for yes, 0 for no
+ */
 static int check_overlap(mbr_part_t * p1, mbr_part_t * p2)
 {
@@ -945,4 +719,8 @@
 }
 
+/** Check whether one partition encapsulates the other
+ * 
+ * @return		1 for yes, 0 for no
+ */
 static int check_encaps(mbr_part_t * inner, mbr_part_t * outer)
 {
@@ -956,4 +734,8 @@
 }
 
+/** Check whether one partition preceeds the other
+ * 
+ * @return		1 for yes, 0 for no
+ */
 static int check_preceeds(mbr_part_t * preceeder, mbr_part_t * precedee)
 {
@@ -961,27 +743,5 @@
 }
 
-static void debug_print(unsigned char * data, size_t bytes)
-{
-	size_t addr = 0;
-	int i;
-	
-	while (bytes >= 16) {
-		printf("%8x ", addr);
-		for (i = 0; i < 8; i++) {
-			printf(" %2hhx", data[addr + i]);
-		}
-		printf(" ");
-		for (i = 0; i < 8; i++) {
-			printf(" %2hhx", data[addr + i + 8]);
-		}
-		printf("\n");
-		
-		bytes -= 16;
-		addr += 16;
-	}
-	
-	
-}
-
-
-
+
+
+
Index: uspace/lib/mbr/libmbr.h
===================================================================
--- uspace/lib/mbr/libmbr.h	(revision 8f6c778597143e8b7a55779be0e07007930e4f3c)
+++ uspace/lib/mbr/libmbr.h	(revision 700f89ec90c0d82b5e2a3bfa99e10cdac6785fec)
@@ -188,4 +188,5 @@
  * then partitions. The MBR headers' raw_data is NOT updated to follow
  * partition changes. */
+extern mbr_t * mbr_alloc_mbr();
 extern mbr_t * mbr_read_mbr(service_id_t dev_handle);
 extern int mbr_write_mbr(mbr_t * mbr, service_id_t dev_handle);
@@ -198,5 +199,5 @@
 extern mbr_part_t *	mbr_alloc_partition(void);
 extern mbr_partitions_t * mbr_alloc_partitions(void);
-extern int			mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * partition);
+extern MBR_ERR_VAL	mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * partition);
 extern int			mbr_remove_partition(mbr_partitions_t * parts, size_t idx);
 extern int			mbr_get_flag(mbr_part_t * p, MBR_FLAGS flag);
