diff --git a/api.c b/api.c
index d697ed56835b2e28750ced7ed204162a42dd9968..cd46a5d00a736f1aad9dd4e111ba3b9b79894aee 100644
--- a/api.c
+++ b/api.c
@@ -66,126 +66,274 @@ out:
 	return NULL;
 }
 
+int get_idx(char *key, int *idx, char *out)
+{
+	char *open_brace;
+	int len = 0;
+	char buffer[64] = {0};
+	char *ptr;
+
+	printf("%s %d key=%s\n", __func__, __LINE__, key);
+
+	if(!key)
+		return -1;
+
+
+	strncpy(buffer, key, sizeof(buffer) - 1);
+	ptr = (char *)buffer;
+	printf("%s %d ptr=%s\n", __func__, __LINE__, ptr);
+
+	while((open_brace = strchr(ptr, '['))) {
+		char *close_brace = strchr(open_brace, ']');
+
+		if (close_brace) {
+			int str_len;
+			char *idx_str;
+
+			str_len = close_brace - open_brace;
+			idx_str = calloc(1, str_len);
+			strncpy(idx_str, open_brace + 1, str_len-1);
+			idx[len++] = atoi(idx_str);
+
+			*open_brace = '\0';
+			free(idx_str);
+			ptr = close_brace;
+		}
+	}
+
+	strncpy(out, buffer, 31);
+	printf("%s %d, out=%s, buffer=%s", __func__, __LINE__, out, buffer);
+	return len;
+}
+
+struct json_object *dummy_val(char *val, enum json_type type)
+{
+	struct json_object *j_val;
+
+	switch(type) {
+	case json_type_array:
+		j_val = json_tokener_parse(val);
+	break;
+	case json_type_boolean:
+		;;
+	break;
+	case json_type_object:
+		j_val = json_tokener_parse(val);
+	break;
+	case json_type_string:
+		j_val = json_object_new_string(val);
+	break;
+	case json_type_double:
+		j_val = json_object_new_double(atof(val));
+	break;
+	case json_type_int:
+		j_val = json_object_new_int(atoi(val));
+	break;
+	default:
+		return NULL;
+	break;
+	}
+
+	return j_val;
+}
+
+int add_array(struct json_object *ptr, int *idx, int len, char *val, enum json_type type, char *key)
+{
+	struct json_object *tmp, *tmp1;
+	struct json_object *j_val;
+
+	j_val = dummy_val(val, type);
+	if (!j_val)
+		return -1;
+
+	json_object_object_get_ex(ptr, key, &tmp);
+	if (!tmp || !json_object_is_type(tmp, json_type_array)) {
+		tmp = json_object_new_array();
+		json_object_object_add(ptr, key, tmp);
+	}
+
+	for (int i = 0; i < len; i++) {
+		struct json_object *tmp1;
+
+		tmp1 = json_object_array_get_idx(tmp, idx[i]);
+		printf("%s %d ptr = %s, tmp = %s\n", __func__, __LINE__, json_object_get_string(ptr), json_object_get_string(tmp));
+		if (i < len -1) {
+			if (!tmp1 || !json_object_is_type(tmp1, json_type_array)) {
+				tmp1 = json_object_new_array();
+				if (idx[i] > -1)
+					json_object_array_put_idx(tmp, idx[i], tmp1);
+				else
+					json_object_array_add(tmp, tmp1);
+			}
+			tmp = tmp1;
+		} else {
+			printf("%s %d ptr = %s, tmp = %s, tmp1=%s\n", __func__, __LINE__, json_object_get_string(ptr), json_object_get_string(tmp), json_object_get_string(tmp1));
+			if (idx[i] > -1)
+				json_object_array_put_idx(tmp, idx[i], j_val);
+			else
+				json_object_array_add(tmp, j_val);
+		}
+
+	}
+
+	printf("%s %d ptr = %s, tmp = %s\n", __func__, __LINE__, json_object_get_string(ptr), json_object_get_string(tmp));
+
+
+	return 0;
+}
+
+int add_val(struct json_object *ptr, char *key, char *val, enum json_type type)
+{
+	struct json_object *j_val;
+	int idx[32];
+	int len;
+	char parsed_key[32] = {0};
+
+	len = get_idx(key, idx, parsed_key);
+	printf("%s %d parsed_key=%s\n", __func__, __LINE__, parsed_key);
+	j_val = dummy_val(val, type);
+	if (!j_val || !json_object_is_type(j_val, type)) {
+		fprintf(stderr, "Invalid input value!\n");
+		return -1;
+	}
+
+	printf("%s %d val=%s, j_val=%s, ptr=%s\n", __func__, __LINE__, val, json_object_get_string(j_val), json_object_get_string(ptr));
+
+	if (json_type_object == type) {
+		printf("%s %d\n", __func__, __LINE__);
+		/* TODO: does this actually work? what would be the test case for this? */
+		if (len < 1) {
+			struct json_object *tmp = ptr;
+
+			if (key)
+				ptr = json_object_new_object();
+
+			json_object_object_foreach(j_val, key1, val1)
+				json_object_object_add(ptr, key1, val1);
+			if (key) {
+				printf("%s %d\n", __func__, __LINE__);
+				json_object_object_add(tmp, parsed_key, ptr);
+			}
+		} else {
+			printf("%s %d\n", __func__, __LINE__);
+			add_array(ptr, idx, len, val, type, parsed_key);
+		}
+
+		return 0;
+	}
+
+
+	if (len < 1 || type == json_type_array)
+		json_object_object_add(ptr, parsed_key, j_val);
+	else {
+		add_array(ptr, idx, len, val, type, parsed_key);
+	}
+
+	return 0;
+}
+
 int set_by_string(char *fmt, struct json_object **src, char *val, enum json_type type)
 {
-	struct json_object *ptr, *tmp, *tar;
+	struct json_object *ptr, *tmp;
 	const char *delimiter = ".";
-	char buffer[1024] = {0};
-	char *p, *prev = fmt;
+	char fmt_cpy[1024] = {0}, parsed_key[32] = {0};
+	char *p, *key = fmt;
+	int idx[32];
+	int len;
 
 	if (!*src) {
 		printf("lets allocate new object\n");
 		*src = json_object_new_object();
 	}
 
+	printf("format = %s\n", fmt);
+	printf("set val = %s\n", val);
+
 	ptr = tmp = *src;
+	if (!fmt)
+		goto add_key;
 
-	strcpy(buffer, fmt);
+	strcpy(fmt_cpy, fmt);
+	p = strtok(fmt_cpy,delimiter);
 
-	p = strtok(buffer,delimiter);
 	while (p != NULL) {
-		prev = p;
+		key = p;
 		p = strtok(NULL, delimiter);
 
-		/* if next key exists, parse prev key, let switch-case add/alter last key */
+		/* if next key exists, parse key, let switch-case add/alter last key */
 		if (p) {
-			json_object_object_get_ex(tmp, prev, &ptr);
-
-			printf("p=%s\n", p);
-
-			/* TODO: if prev contains [x], get idx of x */
-			char *open_brace = strchr(prev, '[');
-			printf("open_brace=%s\n", open_brace);
-			if (open_brace) {
-				char *close_brace = strchr(open_brace, ']');
-				if (close_brace) {
-					int len = close_brace - open_brace;
-					printf("len=%d\n", len);
-					char *idx_str = calloc(1, len);
-					strncpy(idx_str, open_brace + 1, len-1);
-					printf("idx_str = %s\n", idx_str);
-					int idx = atoi(idx_str);
-					printf("idx = %d\n", idx);
-					*open_brace = '\0';
-					printf("prev=%s\n", prev);
+			/* TODO: pretty wonky order with get idx first to overwrite braces?*/
+
+			memset(idx, 0, sizeof(idx));
+
+			len = get_idx(key, idx, parsed_key);
+
+			printf("parsed_key=%s\n", parsed_key);
+			printf("len=%d\n", len);
+
 
+			/* if we need to step further and currently marked value isnt an object, we need to overwrite it */
+			json_object_object_get_ex(tmp, parsed_key, &ptr);
+			if (!json_object_is_type(ptr, json_type_object) && !json_object_is_type(ptr, json_type_array)) {
+				ptr = json_object_new_object();
+				json_object_object_add(tmp, parsed_key, ptr);
+			}
+
+
+			/* TODO: make enums for rv of get_idx */
+			if (len > 0) {
+				for (int i = 0; i < len; i++) {
+					printf("%s %d, ptr = %s\n", __func__, __LINE__, json_object_get_string(ptr));
 					if (ptr && json_object_get_type(ptr) == json_type_array) {
-						ptr = json_object_array_get_idx(ptr, idx);
+						printf("%s %d\n", __func__, __LINE__);
+						if (idx[i] > -1 && idx[i] < json_object_array_length(ptr))
+							ptr = json_object_array_get_idx(ptr, idx[i]);
+						else {
+							printf("%s %d\n", __func__, __LINE__);
+							if (i == len - 1)
+								json_object_array_add(ptr, json_object_new_object());
+							else if (i < len -1)
+								json_object_array_add(ptr, json_object_new_array());
+							printf("ptr=%s\n", json_object_get_string(ptr));
+							ptr = json_object_array_get_idx(ptr, json_object_array_length(ptr) - 1);
+							printf("ptr=%s\n", json_object_get_string(ptr));
+						}
 					} else {
 						ptr = json_object_new_array();
-						json_object_object_add(tmp, prev, ptr);
+						printf("%s %d type=%s, ptr_type=%s\n", __func__, __LINE__, json_type_to_name(json_object_get_type(tmp)), json_type_to_name(json_object_get_type(ptr)));
+						printf("tmp=%s\n", json_object_get_string(tmp));
+						printf("ptr=%s\n", json_object_get_string(ptr));
+						printf("key=%s\n", key);
+						json_object_object_add(tmp, parsed_key, ptr);
+						if (i == len - 1) {
+							json_object_array_add(ptr, json_object_new_object());
+							ptr = json_object_array_get_idx(ptr, json_object_array_length(ptr) - 1);
+						}
+						//json_object_array_add(tmp, ptr);
 					}
 				}
 			}
 
-			/* create prev object if it does not exist */
+			/* create key object if it does not exist */
 			if (!ptr) {
 				ptr = json_object_new_object();
-				json_object_object_add(tmp, prev, ptr);
+				if (json_object_get_type(tmp) == json_type_array)
+					json_object_array_add(tmp, ptr);
+				else if (json_object_get_type(tmp) == json_type_object)
+					json_object_object_add(tmp, parsed_key, ptr);
+				printf("%s %d: ptr=%s\n", __func__, __LINE__, json_object_get_string(ptr));
+				printf("%s %d: tmp=%s\n", __func__, __LINE__, json_object_get_string(tmp));
 			}
 		}
 
 		tmp = ptr;
 	}
 
-	json_object_object_get_ex(ptr, prev, &tar);
-
-	switch(type) {
-	case json_type_object:
-	{
-		struct json_object *parsed_val = json_tokener_parse(val);
-
-		if (!parsed_val) {
-			fprintf(stderr, "Invalid object format\n");
-			return -1;
-		} else if (type != json_object_get_type(parsed_val)) {
-			fprintf(stderr, "Types don't match!\n");
-			return -1;
-		}
-
-		json_object_object_foreach(parsed_val, key1, val1)
-			json_object_object_add(*src, key1, val1);
-	}
-	break;
-	case json_type_string:
-		json_object_object_add(ptr, prev, json_object_new_string(val));
-	break;
-	case json_type_int:
-		json_object_object_add(ptr, prev, json_object_new_int(atoi(val)));
-	break;
-	case json_type_array:
-	{
-		struct json_object *parsed_val = json_tokener_parse(val);
-
-		if (!parsed_val) {
-			fprintf(stderr, "Invalid array format\n");
-			return -1;
-		} else if (type != json_object_get_type(parsed_val)) {
-			fprintf(stderr, "Types don't match!\n");
-			return -1;
-		}
-
-		json_object_object_add(ptr, prev, parsed_val);
-	}
-	break;
-	case json_type_double:
-		json_object_object_add(ptr, prev, json_object_new_int(atof(val)));
-	break;
-	case json_type_boolean:
-	{
-		bool bool_val = false;
-
-		if (strncasecmp(val, "true", 4) || atoi(val) == 1)
-			bool_val = true;
+	printf("%s %d key=%s\n", __func__, __LINE__, parsed_key);
 
-
-		json_object_object_add(ptr, prev, json_object_new_boolean(bool_val));
-	}
-	break;
-	default:
-		fprintf(stderr, "Not valid input type!\n");
-	break;
-	}
+add_key:
+printf("%s %d\n", __func__, __LINE__);
+	add_val(ptr, key, val, type);
 
 	return 0;
 }
@@ -193,7 +341,7 @@ int set_by_string(char *fmt, struct json_object **src, char *val, enum json_type
 int set(char *fmt, struct json_object *src, struct json_object *val)
 {
 	const char *delimiter = ".";
-	char buffer[1024] = {0};
+	char fmt_cpy[1024] = {0};
 	char *p;
 
 	if (json_object_get_type(val) != json_type_object) {
@@ -203,10 +351,10 @@ int set(char *fmt, struct json_object *src, struct json_object *val)
 
 	src = get(fmt, src);
 
-	strcpy(buffer, fmt);
+	strcpy(fmt_cpy, fmt);
 
 	/* TODO: put this in some separate function */
-	for (p = strtok(buffer,delimiter); p != NULL; p = strtok(NULL, delimiter)) {
+	for (p = strtok(fmt_cpy,delimiter); p != NULL; p = strtok(NULL, delimiter)) {
 		struct json_object *ptr, *tmp = src;
 
 		json_object_object_get_ex(tmp, p, &ptr);
@@ -228,11 +376,11 @@ struct json_object *get(char *fmt, struct json_object *src)
 {
 	struct json_object *ptr, *tmp = src;
 	const char *delimiter = ".";
-	char buffer[1024] = {0};
+	char fmt_cpy[1024] = {0};
 
-	strcpy(buffer, fmt);
+	strcpy(fmt_cpy, fmt);
 
-	for (char *p = strtok(buffer,delimiter); p != NULL; p = strtok(NULL, delimiter)) {
+	for (char *p = strtok(fmt_cpy,delimiter); p != NULL; p = strtok(NULL, delimiter)) {
 		json_object_object_get_ex(tmp, p, &ptr);
 		tmp = ptr;
 	}
@@ -242,18 +390,26 @@ struct json_object *get(char *fmt, struct json_object *src)
 
 int main()
 {
-	struct json_object *obj = path_to_obj("/home/jakob/git/json-editor-api/test.json");
+	struct json_object *obj = path_to_obj("/home/jakob/git/json-editor/test.json");
 	struct json_object *ptr;
 
-	printf("%s %d obj=%s\n", __func__, __LINE__, json_object_get_string(obj));
+	printf("%s %d\n", __func__, __LINE__);
+	struct json_object *arr = json_object_new_array();
+	struct json_object *obj_arr = json_object_new_object();
+
+	json_object_object_add(obj_arr, "test_arr", arr);
+	printf("tets_arr = %s\n", json_object_get_string(obj_arr));
+
+
+	printf("original obj=%s\n", json_object_get_string(obj));
 
 	ptr = get("nested", obj);
 
 	printf("%s\n", json_object_get_string(ptr));
 
-	set_by_string("nested.api[1].test", &obj, "1", json_type_string);
+	set_by_string("test.asd[-1].test.tested", &obj, "{\"api_test\":\"hej\"}", json_type_object);
 
-	printf("%s\n", json_object_get_string(obj));
+	printf("result: %s\n", json_object_get_string(obj));
 
 	json_object_put(obj);
 	return 0;
diff --git a/test/api_test.c b/test/api_test.c
index f7af316f2ec7e5ca7c7711e26870d0019bc90bd5..73bb48dbc46ca562dd246d6aeb592dec02ba65bb 100644
--- a/test/api_test.c
+++ b/test/api_test.c
@@ -43,18 +43,21 @@ static void test_build_from_scratch(void **state)
 	struct json_object *file = path_to_obj("/home/jakob/git/json-editor-api/test.json");
     struct json_object *jobj = NULL;
 
-    set_by_string("", &jobj, "{ \"test\":\"success\", \"nested\": { \"api\":\"test2\"} }", json_type_object);
+    set_by_string(NULL, &jobj, "{ \"test\":\"success\", \"nested\": { \"api\":\"test2\"} }", json_type_object);
 
-    assert_int_equal(1, json_object_equal(file, jobj));
+    printf("file_obj=%s\n", json_object_get_string(file));
+    printf("modify_obj=%s\n", json_object_get_string(jobj));
 
+    assert_int_equal(1, json_object_equal(file, jobj));
 }
 
 static void test_json_add_object(void **state)
 {
     (void) state;
 
-	//struct json_object *obj = json_object_new_object();
-    json_object_object_add(file_obj, "test2", json_object_new_string("success"));
+	struct json_object *obj = json_object_new_object();
+    json_object_object_add(obj, "test2", json_object_new_string("success"));
+    json_object_object_add(file_obj, "string", obj);
     //json_object_object_add(file_obj, "string", json_object_new_string("1"));
 
     set_by_string("string", &modify_obj, "{\"test2\":\"success\"}", json_type_object);
@@ -138,7 +141,7 @@ static void test_json_add_multi_obj(void **state)
     json_object_object_add(file_obj, "string", json_object_new_string("1"));
     json_object_object_add(file_obj, "integer", json_object_new_int(1));
 
-    set_by_string("", &modify_obj, "{ \"nested0\": {\"nested1\": {\"integer\": 1}}, \"ints\": [1, 2, 3], \"string\":\"1\", \"integer\": 1}", json_type_object);
+    set_by_string(NULL, &modify_obj, "{ \"nested0\": {\"nested1\": {\"integer\": 1}}, \"ints\": [1, 2, 3], \"string\":\"1\", \"integer\": 1}", json_type_object);
 
     printf("file_obj=%s\n", json_object_get_string(file_obj));
     printf("modify_obj=%s\n", json_object_get_string(modify_obj));
@@ -226,6 +229,118 @@ static void test_json_add_int_nested(void **state)
     assert_int_equal(1, json_object_equal(modify_obj, file_obj));
 }
 
+static void test_json_add_array_int(void **state)
+{
+    (void) state;
+
+    struct json_object *arr = json_object_new_array();
+    struct json_object *obj = json_object_new_object();
+
+    json_object_array_add(arr, json_object_new_int(1));
+    json_object_object_add(file_obj, "array", arr);
+    json_object_object_add(obj, "array", json_object_get(arr));
+    json_object_object_add(file_obj, "inner", obj);
+
+    set_by_string("array[-1]", &modify_obj, "1", json_type_int);
+    set_by_string("inner.array[-1]", &modify_obj, "1", json_type_int);
+
+    printf("file_obj=%s\n", json_object_get_string(file_obj));
+    printf("modify_obj=%s\n", json_object_get_string(modify_obj));
+
+    assert_int_equal(1, json_object_equal(modify_obj, file_obj));
+}
+
+
+static void test_json_add_array_object(void **state)
+{
+    (void) state;
+
+    struct json_object *arr = json_object_new_array();
+    struct json_object *obj = json_object_new_object();
+
+    json_object_object_add(obj, "integer", json_object_new_int(1));
+    json_object_object_add(obj, "string", json_object_new_string("test"));
+
+    json_object_array_add(arr, obj);
+    json_object_array_add(arr, json_object_get(obj)); // array will now hold two references to the same object (will double free otherwise)
+    json_object_object_add(file_obj, "array", arr);
+
+    set_by_string("array[-1].integer", &modify_obj, "1", json_type_int);
+    set_by_string("array[0].string", &modify_obj, "test", json_type_string);
+    set_by_string("array[-1]", &modify_obj, "{\"integer\": 1, \"string\":\"test\"}", json_type_object);
+
+    printf("file_obj=%s\n", json_object_get_string(file_obj));
+    printf("modify_obj=%s\n", json_object_get_string(modify_obj));
+
+    assert_int_equal(1, json_object_equal(modify_obj, file_obj));
+}
+
+static void test_json_add_array_nested_object(void **state)
+{
+    (void) state;
+
+    struct json_object *arr = json_object_new_array();
+    struct json_object *obj = json_object_new_object();
+    struct json_object *nested = json_object_new_object();
+    struct json_object *nested1 = json_object_new_object();
+
+    json_object_object_add(nested, "integer", json_object_new_int(1));
+    json_object_object_add(nested1, "nested1", nested);
+    json_object_object_add(obj, "nested", nested1);
+    json_object_array_add(arr, obj);
+    json_object_array_add(arr, json_object_get(obj));
+    json_object_array_add(arr, json_object_get(obj));
+    json_object_array_add(arr, json_object_get(obj));
+    json_object_array_add(arr, json_object_get(obj));
+    json_object_object_add(file_obj, "array", arr);
+
+    set_by_string(NULL, &modify_obj, "{\"array\": [{\"nested\": {\"nested1\": {\"integer\": 1}}}]}", json_type_object);
+    set_by_string("array[5].nested.nested1.integer", &modify_obj, "1", json_type_int);
+    set_by_string("array[-1].nested.nested1", &modify_obj, "{\"integer\": 1}", json_type_object);
+    set_by_string("array[-1].nested", &modify_obj, "{\"nested1\": {\"integer\": 1}}", json_type_object);
+    set_by_string("array[-1]", &modify_obj, "{\"nested\": {\"nested1\": {\"integer\": 1}}}", json_type_object);
+
+    printf("file_obj=%s\n", json_object_get_string(file_obj));
+    printf("modify_obj=%s\n", json_object_get_string(modify_obj));
+
+    assert_int_equal(1, json_object_equal(modify_obj, file_obj));
+}
+
+static void test_json_add_array_nested_array(void **state)
+{
+    (void) state;
+
+    struct json_object *arr = json_object_new_array();
+    struct json_object *nested_arr = json_object_new_array();
+    struct json_object *nested1_arr = json_object_new_array();
+
+    json_object_array_add(nested_arr, json_object_new_int(1));
+    json_object_array_add(nested_arr, json_object_new_int(2));
+    json_object_array_add(nested_arr, json_object_new_int(3));
+    json_object_array_add(nested1_arr, json_object_new_int(5));
+    json_object_array_add(nested1_arr, json_object_new_int(6));
+    json_object_array_add(nested1_arr, json_object_new_int(7));
+
+    json_object_array_add(arr, nested_arr);
+    json_object_array_add(arr, nested1_arr);
+
+    json_object_object_add(file_obj, "array", arr);
+
+    //set_by_string("array[0][0].test", &modify_obj, "1", json_type_int);
+    set_by_string("array[0][0]", &modify_obj, "1", json_type_int);
+    set_by_string("array[0][1]", &modify_obj, "2", json_type_int);
+    set_by_string("array[0][2]", &modify_obj, "3", json_type_int);
+
+    set_by_string("array[1][-1]", &modify_obj, "5", json_type_int);
+    set_by_string("array[1][-1]", &modify_obj, "6", json_type_int);
+    set_by_string("array[1][-1]", &modify_obj, "7", json_type_int);
+
+    printf("file_obj=%s\n", json_object_get_string(file_obj));
+    printf("modify_obj=%s\n", json_object_get_string(modify_obj));
+
+    assert_int_equal(1, json_object_equal(modify_obj, file_obj));
+}
+
 static int setup (void** state) {
     file_obj = path_to_obj("/home/jakob/git/json-editor-api/test.json");
     modify_obj = path_to_obj("/home/jakob/git/json-editor-api/test.json");
@@ -251,6 +366,10 @@ int main(void) {
         cmocka_unit_test_setup_teardown(test_json_add_multi_types, setup, teardown),
         cmocka_unit_test_setup_teardown(test_json_add_multi_obj, setup, teardown),
         cmocka_unit_test_setup_teardown(test_json_overwrite_string, setup, teardown),
+        cmocka_unit_test_setup_teardown(test_json_add_array_int, setup, teardown),
+        cmocka_unit_test_setup_teardown(test_json_add_array_object, setup, teardown),
+        cmocka_unit_test_setup_teardown(test_json_add_array_nested_object, setup, teardown),
+        cmocka_unit_test_setup_teardown(test_json_add_array_nested_array, setup, teardown),
 	};
 
 	return cmocka_run_group_tests(tests, NULL, NULL);