diff --git a/README.md b/README.md
index 7b99f601f6986b9e61f9897f7771bfc2b980f7a4..bed041d3e6c042d7f2d990cadf78ab90155bc5fc 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@ This is the query-conversion package. It holds the code that translates the JSON
 
 ## Creating a new converter
 ```go
-import "git.science.uu.nl/datastrophe/query-conversion"
+import "git.science.uu.nl/graphpolaris/query-conversion"
 
 queryservice := cypher.NewService()
 ```
@@ -17,7 +17,7 @@ query, err := queryservice.ConvertQuery(JSONquery)
 
 ## Creating a mock converter
 ```go
-import "git.science.uu.nl/datastrophe/query-conversion"
+import "git.science.uu.nl/graphpolaris/query-conversion"
 
 mockService := NewMockService()
 ```
\ No newline at end of file
diff --git a/aql/convertQuery.go b/aql/convertQuery.go
index bc15ba79fec8dcc1ee18f6b4d4a915cd9ed6fab0..e02227adf727ca8306dc07ff22ecc6e9379caaf0 100644
--- a/aql/convertQuery.go
+++ b/aql/convertQuery.go
@@ -6,10 +6,13 @@ This program has been developed by students from the bachelor Computer Science a
 package aql
 
 import (
+	//"encoding/json"
+	"encoding/json"
 	"errors"
 	"fmt"
+	"strconv"
 
-	"git.science.uu.nl/datastrophe/query-conversion/entity"
+	"git.science.uu.nl/graphpolaris/query-conversion/entity"
 )
 
 // Version 1.13
@@ -20,36 +23,53 @@ ConvertQuery converts an IncomingQueryJSON object into AQL
 	Returns: *string, the AQL query and a possible error
 */
 func (s *Service) ConvertQuery(JSONQuery *entity.IncomingQueryJSON) (*string, error) {
-
+	// TODO: MICHAEL WANT A SINGLE ENTITY TO RETURN A SUMMARY OF ATTRIBUTE VALUES (HISTOGRAM THINGIES)
 	// Check to make sure all indexes exist
-	// The largest possible id for an entity
-	largestEntityID := len(JSONQuery.Entities) - 1
-	// The largest possible id for a relation
-	largestRelationID := len(JSONQuery.Relations) - 1
+	// The count of entities
+	entityCount := len(JSONQuery.Entities)
+	// The count of relations
+	relationCount := len(JSONQuery.Relations)
+	// There are no entities or relations, our query is empty
+	if entityCount <= 0 && relationCount <= 0 {
+		fmt.Println("Empty query sent, returning default response")
+		return defaultReturn()
+	}
+	// There are no enities or there are no relations
+	if entityCount <= 0 || relationCount <= 0 {
+		return nil, errors.New("no relations or entities sent")
+	}
 
-	// Make sure no entity should be returned that is outside the range of that list
-	for _, e := range JSONQuery.Return.Entities {
-		// If this entity references an entity that is outside the range
-		if e > largestEntityID || e < 0 {
-			return nil, errors.New("non-existing entity referenced in return")
+	potentialErrors := entity.ValidateStruct(*JSONQuery)
+	// If we find the JSONQuery to be invalid we return a error
+	if len(potentialErrors) != 0 {
+		for _, err := range potentialErrors {
+			fmt.Printf("err: %v\n", err)
 		}
+		return nil, errors.New("JSONQuery invalid")
 	}
 
-	// Make sure that no relation mentions a non-existing entity
-	for _, r := range JSONQuery.Relations {
-		if r.EntityFrom > largestEntityID || r.EntityTo > largestEntityID {
-			return nil, errors.New("non-exisiting entity referenced in relation")
-		}
+	entityMap, relationMap, _ := entity.FixIndices(JSONQuery)
+
+	var tree []entity.Tree
+	var topNode entity.QueryEntityStruct
+	if len(JSONQuery.Entities) != 0 && len(JSONQuery.Relations) != 0 {
+		tree, topNode = createHierarchy(JSONQuery, entityMap, relationMap)
 	}
 
-	// Make sure no non-existing relation is tried to be returned
-	for _, r := range JSONQuery.Return.Relations {
-		if r > largestRelationID || r < 0 {
-			return nil, errors.New("non-existing relation referenced in return")
+	for i, treeElement := range tree {
+		fmt.Println("I am triple(from,rel,to): " + strconv.Itoa(treeElement.Self.FromNode.ID) + "," + strconv.Itoa(treeElement.Self.Rel.ID) + "," + strconv.Itoa(treeElement.Self.ToNode.ID))
+		fmt.Println("My relation contains the following nodes(from,to): " + strconv.Itoa(treeElement.Self.Rel.FromID) + "," + strconv.Itoa(treeElement.Self.Rel.ToID))
+		fmt.Println("My index is: " + strconv.Itoa(i))
+		fmt.Println("My parent index is: " + strconv.Itoa(treeElement.Parent))
+		fmt.Println("My children's indices are: ")
+		for j := range treeElement.Children {
+			fmt.Println(treeElement.Children[j])
 		}
+		fmt.Println("Next please!")
 	}
-
-	result := createQuery(JSONQuery)
+	fuckshitprinter, _ := json.Marshal(tree)
+	fmt.Println(string(fuckshitprinter))
+	result := createQuery(JSONQuery, tree, topNode, entityMap, relationMap)
 	return result, nil
 }
 
@@ -58,281 +78,227 @@ createQuery generates a query based on the json file provided
 	JSONQuery: *entity.IncomingQueryJSON, this is a parsedJSON struct holding all the data needed to form a query,
 	Return: *string, a string containing the corresponding AQL query and an error
 */
-func createQuery(JSONQuery *entity.IncomingQueryJSON) *string {
-	// Note: Case #4, where there is an edge only query (without any entity), is not supported by frontend
-
-	// If a modifier is used, disable the limit
+func createQuery(JSONQuery *entity.IncomingQueryJSON, tree []entity.Tree, topNode entity.QueryEntityStruct, entityMap map[int]int, relationMap map[int]int) *string {
+	modName := ""
 	if len(JSONQuery.Modifiers) > 0 {
-		JSONQuery.Limit = -1
-	}
-
-	var (
-		relationsToReturn []string
-		nodesToReturn     []string
-		nodeUnion         string
-		relationUnion     string
-	)
-
-	// Loop over all relations
-	ret := ""
-
-	// Add a WITH statement for entityTo
-	includedTypes := make(map[string]bool)
-	allTypes := make(map[string]bool)
-	for _, relation := range JSONQuery.Relations {
-		if relation.EntityFrom >= 0 {
-			includedTypes[JSONQuery.Entities[relation.EntityFrom].Type] = true
-			allTypes[JSONQuery.Entities[relation.EntityFrom].Type] = true
-
-			// If the type is in the entityTo it is a valid type but not yet included
-			if relation.EntityTo >= 0 {
-				allTypes[JSONQuery.Entities[relation.EntityTo].Type] = true
-			}
-		}
-		if relation.EntityFrom == -1 && relation.EntityTo >= 0 {
-			includedTypes[JSONQuery.Entities[relation.EntityTo].Type] = true
-			allTypes[JSONQuery.Entities[relation.EntityTo].Type] = true
+		modifier := JSONQuery.Modifiers[0]
+		fmt.Println(modifier.SelectedType + ", " + strconv.Itoa(modifier.SelectedTypeID))
+		if modifier.SelectedType == "entity" && modifier.SelectedTypeID == topNode.ID {
+			modName = fmt.Sprintf("e_%v", topNode.ID)
 		}
 	}
-
-	// Include all types that are not yet included
-	first := true
-	for k := range allTypes {
-		if !includedTypes[k] {
-			if first {
-				ret += fmt.Sprintf("WITH %v", k)
-				first = false
+	output := createLetFor("result", fmt.Sprintf("e_%v", topNode.ID), topNode.Name, 0)
+	for constraint := range topNode.Constraints {
+		output += createFilter(topNode.Constraints[constraint], fmt.Sprintf("e_%v", topNode.ID))
+	}
+	subQuery, subName := createQueryRecurse(JSONQuery, tree, 0, topNode, 1)
+	subNames := []string{subName}
+	output += subQuery
+	output += createZeroFilter(append(subNames, fmt.Sprintf("e_%v", topNode.ID)))
+	output += createReturn(fmt.Sprintf("e_%v", topNode.ID), "", modName, subNames)
+	output += ")\n"
+	//output += "LET nodes = union_distinct(flatten(result[**].nodes),[])\nLET edges = union_distinct(flatten(result[**].rel),[])\nLET modif = union_distinct(flatten(result[**].mod),[])\n"
+	if len(JSONQuery.Modifiers) == 0 {
+		output += "LET nodes = union_distinct(flatten(result[**].nodes),[])\nLET edges = union_distinct(flatten(result[**].rel),[])\nRETURN {\"vertices\":nodes,\"edges\":edges}"
+	} else {
+		output += "LET modif = union_distinct(flatten(result[**].mod),[])\n"
+		modifier := JSONQuery.Modifiers[0]
+		if modifier.AttributeIndex == -1 {
+			output += "RETURN " + getModifierType(modifier) + "(modif)"
+		} else {
+			var attribute string
+			// Selecting the right attribute from either the entity constraint or relation constraint
+			if modifier.SelectedType == "entity" {
+				attribute = JSONQuery.Entities[entityMap[modifier.SelectedTypeID]].Constraints[modifier.AttributeIndex].Attribute
 			} else {
-				ret += fmt.Sprintf(", %v", k)
+				attribute = JSONQuery.Relations[relationMap[modifier.SelectedTypeID]].Constraints[modifier.AttributeIndex].Attribute
 			}
+			output += "RETURN " + getModifierType(modifier) + "(modif[**]." + attribute + ")"
 		}
 	}
-	if !first {
-		ret += "\n"
-	}
-
-	for i, relation := range JSONQuery.Relations {
-
-		relationName := fmt.Sprintf("r%v", i)
-
-		if relation.EntityFrom >= 0 {
-			// if there is a from-node
-			// create the let for this node
-			fromName := fmt.Sprintf("n%v", relation.EntityFrom)
-
-			ret += *createNodeLet(&JSONQuery.Entities[relation.EntityFrom], &fromName)
-
-			ret += *createRelationLetWithFromEntity(&relation, relationName, &JSONQuery.Entities, JSONQuery.Limit)
-		} else if relation.EntityTo >= 0 {
-			// if there is only a to-node
-			toName := fmt.Sprintf("n%v", relation.EntityTo)
-
-			ret += *createNodeLet(&JSONQuery.Entities[relation.EntityTo], &toName)
+	return &output
+}
 
-			ret += *createRelationLetWithOnlyToEntity(&relation, relationName, &JSONQuery.Entities, JSONQuery.Limit)
-			// Add this relation to the list
-		} else {
-			fmt.Println("Relation-only queries are currently not supported")
-			continue
+func createQueryRecurse(JSONQuery *entity.IncomingQueryJSON, tree []entity.Tree, currentindex int, topNode entity.QueryEntityStruct, indentindex int) (string, string) {
+	currentTree := tree[currentindex]
+	newNode := getTreeNewNode(currentTree, tree, topNode)
+	modName := ""
+	if len(JSONQuery.Modifiers) > 0 {
+		modifier := JSONQuery.Modifiers[0]
+		if modifier.SelectedType == "entity" && modifier.SelectedTypeID == newNode.ID {
+			modName = fmt.Sprintf("e_%v", newNode.ID)
+		} else if modifier.SelectedType == "relation" && modifier.SelectedTypeID == currentTree.Self.Rel.ID {
+			modName = fmt.Sprintf("r%v", currentTree.Self.Rel.ID)
 		}
-
-		// Add this relation to the list
-		relationsToReturn = append(relationsToReturn, relationName)
 	}
-
-	// Add node let statements for nodes that are not yet returned
-	// Create a set from all the entity-from's and entity-to's, to check if they are returned
-	nodeSet := make(map[int]bool)
-	for _, relation := range JSONQuery.Relations {
-		nodeSet[relation.EntityFrom] = true
-		nodeSet[relation.EntityTo] = true
+	output := ""
+	output += fixIndent(createLetFor(fmt.Sprintf("e%v", newNode.ID), fmt.Sprintf("e_%v", newNode.ID), newNode.Name, indentindex), indentindex)
+	output += fixIndent(fmt.Sprintf("\tFOR r%v IN %v\n", currentTree.Self.Rel.ID, currentTree.Self.Rel.Name), indentindex)
+	for constraint := range newNode.Constraints {
+		output += fixIndent(createFilter(newNode.Constraints[constraint], fmt.Sprintf("e_%v", newNode.ID)), indentindex)
 	}
-
-	// Check if the entities to return are already returned
-	for _, entityIndex := range JSONQuery.Return.Entities {
-		if !nodeSet[entityIndex] {
-			// If not, return this node
-			name := fmt.Sprintf("n%v", entityIndex)
-			ret += *createNodeLet(&JSONQuery.Entities[entityIndex], &name)
-
-			// Add this node to the list
-			nodesToReturn = append(nodesToReturn, name)
-		}
+	for constraint := range currentTree.Self.Rel.Constraints {
+		output += fixIndent(createFilter(currentTree.Self.Rel.Constraints[constraint], fmt.Sprintf("r%v", currentTree.Self.Rel.ID)), indentindex)
 	}
+	output += fixIndent(fmt.Sprintf("\tFILTER r%v._from == e_%v._id AND r%v._to == e_%v._id\n", currentTree.Self.Rel.ID, currentTree.Self.FromNode.ID, currentTree.Self.Rel.ID, currentTree.Self.ToNode.ID), indentindex)
+	var subNames []string
+	for i := range currentTree.Children {
+		subQuery, subName := createQueryRecurse(JSONQuery, tree, currentTree.Children[i], topNode, indentindex+1)
+		output += subQuery
+		subNames = append(subNames, subName)
+	}
+	output += fixIndent(createZeroFilter(append(subNames, fmt.Sprintf("e_%v", newNode.ID), fmt.Sprintf("r%v", currentTree.Self.Rel.ID))), indentindex)
+	output += fixIndent(createReturn(fmt.Sprintf("e_%v", newNode.ID), fmt.Sprintf("r%v", currentTree.Self.Rel.ID), modName, subNames), indentindex)
+	output += fixIndent(")\n", indentindex)
+	return output, fmt.Sprintf("e%v", newNode.ID)
+}
 
-	//If there are modifiers within the query, we run a different set of checks which focus on quantifiable aspects
-	if len(JSONQuery.Modifiers) > 0 {
-		modifier := JSONQuery.Modifiers[0]
-		// There is a distinction between (relations and entities) and (relations or entities)
-		if len(JSONQuery.Return.Relations) > 0 && len(JSONQuery.Return.Entities) > 0 {
-
-			var pathDistinction string // .vertices or .edges
-
-			// Select the correct addition to the return of r0[**]
-			if modifier.SelectedType == "entity" {
-				// ASSUMING THERE IS ONLY 1 RELATION
-				if JSONQuery.Relations[0].EntityFrom == modifier.SelectedTypeID {
-					// This should always be 0, because that is the start of the path
-					pathDistinction = ".vertices[0]"
-
-				} else {
-					// Otherwise take the depth.max -1 to get the last
-					pathDistinction = fmt.Sprintf(".vertices[%v]", JSONQuery.Relations[0].Depth.Max)
-
-				}
-			} else {
-				pathDistinction = ".edges[**]"
-			}
-
-			// Getting the attribute if there is one
-			if modifier.AttributeIndex != -1 {
-				if modifier.SelectedType == "entity" {
-					pathDistinction += fmt.Sprintf(".%v", JSONQuery.Entities[modifier.SelectedTypeID].Constraints[modifier.AttributeIndex].Attribute)
-
-				} else {
-					pathDistinction += fmt.Sprintf(".%v", JSONQuery.Relations[modifier.SelectedTypeID].Constraints[modifier.AttributeIndex].Attribute)
-
-				}
-			}
-
-			// If count is used it has to be replaced with Length + unique else use the modifier type
-			if modifier.Type == "COUNT" {
-				ret += fmt.Sprintf("RETURN LENGTH (unique(r0[*]%v))", pathDistinction)
-
-			} else {
-				ret += fmt.Sprintf("RETURN %v (r0[*]%v)", modifier.Type, pathDistinction)
-
-			}
-
+func getTreeNewNode(currentTree entity.Tree, tree []entity.Tree, topNode entity.QueryEntityStruct) entity.QueryEntityStruct {
+	if currentTree.Parent < 0 {
+		if currentTree.Self.FromNode.ID == topNode.ID {
+			return currentTree.Self.ToNode
 		} else {
-			// Check if the modifier is on an attribute
-			if modifier.AttributeIndex == -1 {
-				ret += fmt.Sprintf("RETURN LENGTH (n%v)", modifier.SelectedTypeID)
-			} else {
-				var attribute string
-
-				// Selecting the right attribute from either the entity constraint or relation constraint
-				if modifier.SelectedType == "entity" {
-					attribute = JSONQuery.Entities[modifier.SelectedTypeID].Constraints[modifier.AttributeIndex].Attribute
-
-				} else {
-					attribute = JSONQuery.Relations[modifier.SelectedTypeID].Constraints[modifier.AttributeIndex].Attribute
-
-				}
-
-				// If count is used it has to be replaced with Length + unique else use the modifier type
-				if modifier.Type == "COUNT" {
-					ret += fmt.Sprintf("RETURN LENGTH (unique(n%v[*].%v))", modifier.SelectedTypeID, attribute)
-
-				} else {
-					ret += fmt.Sprintf("RETURN %v (n%v[*].%v)", modifier.Type, modifier.SelectedTypeID, attribute)
-
-				}
-			}
+			return currentTree.Self.FromNode
 		}
-
+	} else if currentTree.Self.FromNode.ID == tree[currentTree.Parent].Self.FromNode.ID || currentTree.Self.FromNode.ID == tree[currentTree.Parent].Self.ToNode.ID {
+		return currentTree.Self.ToNode
 	} else {
+		return currentTree.Self.FromNode
+	}
+}
 
-		// Create UNION statements that create unique lists of all the nodes and relations
-		// Thus removing all duplicates
-		nodeUnion = "\nLET nodes = first(RETURN UNION_DISTINCT("
-		for _, relation := range relationsToReturn {
-			nodeUnion += fmt.Sprintf("flatten(%v[**].vertices), ", relation)
-		}
+func createLetFor(variableName string, forName string, enumerableName string, indentindex int) string {
+	output := "LET " + variableName + " = (\n"
+	for i := 0; i < indentindex; i++ {
+		output += "\t"
+	}
+	output += "\tFOR " + forName + " IN " + enumerableName + "\n"
+	return output
+}
 
-		for _, node := range nodesToReturn {
-			nodeUnion += fmt.Sprintf("%v,", node)
-		}
-		nodeUnion += "[],[]))\n"
+func createFilter(constraint entity.QueryConstraintStruct, filtered string) string {
+	output := "\tFILTER " + filtered + "." + constraint.Attribute + " " + wordsToLogicalSign(constraint)
+	if constraint.DataType == "string" {
+		output += " \""
+	} else {
+		output += " "
+	}
+	if constraint.MatchType == "contains" {
+		output += "%"
+	}
+	output += constraint.Value
+	if constraint.MatchType == "contains" {
+		output += "%"
+	}
+	if constraint.DataType == "string" {
+		output += "\" "
+	} else {
+		output += " "
+	}
+	output += " \n"
+	return output
+}
 
-		relationUnion = "LET edges = first(RETURN UNION_DISTINCT("
-		for _, relation := range relationsToReturn {
-			relationUnion += fmt.Sprintf("flatten(%v[**].edges), ", relation)
+func createZeroFilter(subNames []string) string {
+	output := "\tFILTER"
+	for i := range subNames {
+		output += fmt.Sprintf(" length(%v) != 0", subNames[i])
+		if i < len(subNames)-1 {
+			output += " AND"
 		}
-		relationUnion += "[],[]))\n"
-
-		ret += nodeUnion + relationUnion
-		ret += "RETURN {\"vertices\":nodes, \"edges\":edges }"
-
 	}
-
-	return &ret
+	output += "\n"
+	return output
 }
 
-/*
-createNodeLet generates a 'LET' statement for a node related query
-	node: *entity.QueryEntityStruct, node is an entityStruct containing the information of a single nod,
-	name: *string, is the autogenerated name of the node consisting of "n" + the index of the node,
-	Return: *string, a string containing a single LET-statement in AQL
-*/
-func createNodeLet(node *entity.QueryEntityStruct, name *string) *string {
-	header := fmt.Sprintf("LET %v = (\n\tFOR x IN %v \n", *name, node.Type)
-	footer := "\tRETURN x\n)\n"
-	constraints := *createConstraintStatements(&node.Constraints, "x", false)
-
-	ret := header + constraints + footer
-	return &ret
+func createReturn(nodeName string, relName string, modName string, subNames []string) string {
+	output := "\tRETURN {\"nodes\":union_distinct("
+	for i := range subNames {
+		output += fmt.Sprintf("flatten(%v[**].nodes), ", subNames[i])
+	}
+	output += "[" + nodeName + "]"
+	if len(subNames) == 0 {
+		output += ", []"
+	}
+	output += "), \"rel\": union_distinct("
+	for i := range subNames {
+		output += fmt.Sprintf("flatten(%v[**].rel), ", subNames[i])
+	}
+	output += "[" + relName + "]"
+	if len(subNames) == 0 {
+		output += ", []"
+	}
+	output += "), \"mod\": union_distinct("
+	for i := range subNames {
+		output += fmt.Sprintf("flatten(%v[**].mod), ", subNames[i])
+	}
+	output += "[" + modName + "]"
+	if len(subNames) == 0 {
+		output += ", []"
+	}
+	output += ")}\n"
+	return output
 }
 
-/*
-createRelationLetWithFromEntity generates a 'LET' statement for relations with an 'EntityFrom' property and optionally an 'EntitiyTo' property
-	relation: *entity.QueryRekationStruct, relation is a relation struct containing the information of a single relation,
-	name: string, is the autogenerated name of the node consisting of "r" + the index of the relation,
-	entities: *[]entity.QueryEntityStrucy, is a list of entityStructs that are needed to form the relation LET-statement,
-	Return: *string, a string containing a single LET-statement in AQL
-*/
-func createRelationLetWithFromEntity(relation *entity.QueryRelationStruct, name string, entities *[]entity.QueryEntityStruct, limit int) *string {
-	header := fmt.Sprintf("LET %v = (\n\tFOR x IN n%v \n", name, relation.EntityFrom)
-	forStatement := fmt.Sprintf("\tFOR v, e, p IN %v..%v OUTBOUND x %s \n", relation.Depth.Min, relation.Depth.Max, relation.Type)
-
-	// Guarantees that there is no path returned with a duplicate edge
-	// This way there are no cycle paths possible, TODO: more research about this needed
-	optionStmtn := "\tOPTIONS { uniqueEdges: \"path\" }\n"
-
-	vFilterStmnt := ""
-	if relation.EntityTo != -1 {
-		// If there is a to-node, generate the filter statement
-		toConstraints := (*entities)[relation.EntityTo].Constraints
-		vFilterStmnt += *createConstraintStatements(&toConstraints, "v", false)
+func wordsToLogicalSign(element entity.QueryConstraintStruct) string {
+	var match string
+	switch element.DataType {
+	case "string":
+		switch element.MatchType {
+		case "NEQ":
+			match = "!="
+		case "contains":
+			match = "LIKE"
+		case "excludes":
+			match = "NOT LIKE"
+		default: //EQ
+			match = "=="
+		}
+	case "int":
+		switch element.MatchType {
+		case "NEQ":
+			match = "!="
+		case "GT":
+			match = ">"
+		case "LT":
+			match = "<"
+		case "GET":
+			match = ">="
+		case "LET":
+			match = "<="
+		default: //EQ
+			match = "=="
+		}
+	default: /*bool*/
+		switch element.MatchType {
+		case "NEQ":
+			match = "!="
+		default: //EQ
+			match = "=="
+		}
 	}
+	return match
+}
 
-	relationFilterStmnt := *createConstraintStatements(&relation.Constraints, "p", true)
-
-	// Dont use a limit on quantifing queries
-	footer := ""
-	if limit != -1 {
-		footer += fmt.Sprintf("\tLIMIT %v \n", limit)
+func fixIndent(input string, indentCount int) string {
+	output := ""
+	for i := 0; i < indentCount; i++ {
+		output += "\t"
 	}
-	footer += "RETURN DISTINCT p )\n"
-
-	ret := header + forStatement + optionStmtn + vFilterStmnt + relationFilterStmnt + footer
-	return &ret
+	output += input
+	return output
 }
 
-/*
-createRelationLetWithOnlyToEntity generates a 'LET' statement for relations with only an 'EntityTo' property
-	relation: *entity.QueryRelationStruct, relation is a relation struct containing the information of a single relation,
-	name: string, is the autogenerated name of the node consisting of "r" + the index of the relation,
-	entities: *[]entity.QueryEntityStruct, is a list of entityStructs that are needed to form the relation LET-statement,
-	Return: *string, a string containing a single LET-statement in AQL
-*/
-func createRelationLetWithOnlyToEntity(relation *entity.QueryRelationStruct, name string, entities *[]entity.QueryEntityStruct, limit int) *string {
-	header := fmt.Sprintf("LET %v = (\n\tFOR x IN n%v \n", name, relation.EntityTo)
-	forStatement := fmt.Sprintf("\tFOR v, e, p IN %v..%v INBOUND x %s \n", relation.Depth.Min, relation.Depth.Max, relation.Type)
-
-	// Guarantees that there is no path returned with a duplicate edge
-	// This way there are no cycle paths possible, TODO: more research about this needed
-	optionStmtn := "\tOPTIONS { uniqueEdges: \"path\" }\n"
-
-	relationFilterStmnt := *createConstraintStatements(&relation.Constraints, "p", true)
-
-	// Dont use a limit on quantifing queries
-	footer := ""
-	if limit != -1 {
-		footer += fmt.Sprintf("\tLIMIT %v \n", limit)
+func getModifierType(modifier entity.QueryModifierStruct) string {
+	if modifier.Type == "COUNT" {
+		return "LENGTH"
 	}
-	footer += "RETURN DISTINCT p )\n"
+	return modifier.Type
+}
 
-	ret := header + forStatement + optionStmtn + relationFilterStmnt + footer
-	return &ret
+func defaultReturn() (*string, error) {
+	defaultReturn := `LET nodes = first(RETURN UNION_DISTINCT([],[]))
+		LET edges = first(RETURN UNION_DISTINCT([],[]))
+		RETURN {"vertices":nodes, "edges":edges }`
+	return &defaultReturn, nil
 }
diff --git a/aql/convertQueryBenchmark_test.go b/aql/convertQueryBenchmark_test.go
index 2506fe36b12162bc8e9d2b9f577be8896d3ee83a..6e87714a9f1dcfd74f291885ee83d319091b8276 100644
--- a/aql/convertQueryBenchmark_test.go
+++ b/aql/convertQueryBenchmark_test.go
@@ -9,7 +9,7 @@ import (
 	"encoding/json"
 	"testing"
 
-	"git.science.uu.nl/datastrophe/query-conversion/entity"
+	"git.science.uu.nl/graphpolaris/query-conversion/entity"
 )
 
 /*
diff --git a/aql/convertQuery_test.go b/aql/convertQuery_test.go
index f083a12123332994a623938178fdd1c973e02887..4546451e185dbe09e07dec42561a351d869a8488 100644
--- a/aql/convertQuery_test.go
+++ b/aql/convertQuery_test.go
@@ -8,10 +8,10 @@ package aql
 import (
 	"encoding/json"
 	"errors"
-	"strings"
+	"regexp"
 	"testing"
 
-	"git.science.uu.nl/datastrophe/query-conversion/entity"
+	"git.science.uu.nl/graphpolaris/query-conversion/entity"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -31,6 +31,8 @@ func TestEmptyQueryConversion(t *testing.T) {
 		},
 		"entities": [],
 		"relations": [],
+		"groupBys": [],
+		"filters": [],
 		"limit": 5000
 	}`)
 
@@ -44,72 +46,67 @@ func TestEmptyQueryConversion(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `
-LET nodes = first(RETURN UNION_DISTINCT([],[]))
+	correctConvertedResult := `LET nodes = first(RETURN UNION_DISTINCT([],[]))
 LET edges = first(RETURN UNION_DISTINCT([],[]))
 RETURN {"vertices":nodes, "edges":edges }`
-	assert.Equal(t, correctConvertedResult, *convertedResult)
+	regExCleaner := regexp.MustCompile(`\s+`)
+	correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
+	convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
+	assert.Equal(t, correctCleanedResult, convertedCleanedResult)
 }
 
 /*
-Tests multiple entity types
+Tests two entities (two types) without a filter
+Query description: Give me all parties connected to their respective parliament members
 	t: *testing.T, makes go recognise this as a test
 */
-func TestMultipleEntityTypes(t *testing.T) {
+func TestTwoEntitiesNoFilter(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
 
 	query := []byte(`{
-		"databaseName": "test",
+		"databaseName": "TweedeKamer",
 		"return": {
-		  "entities": [
-			0,
-			1
-		  ],
-		  "relations": [
-			0
-		  ]
+			"entities": [
+				0,
+				1
+			],
+			"relations": [
+				0
+			]
 		},
 		"entities": [
-		  {
-			"type": "kamerleden",
-			"constraints": [
-			  {
-				"attribute": "partij",
-				"value": "GL",
-				"dataType": "text",
-				"matchType": "exact"
-			  }
-			]
-		  },
-		  {
-			"type": "partijen",
-			"constraints": [
-			  {
-				"attribute": "zetels",
-				"value": "6",
-				"dataType": "number",
-				"matchType": "GT"
-			  }
-			]
-		  }
+			{
+				"name": "parliament",
+				"ID": 0,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 1,
+				"constraints": []
+			}
 		],
 		"relations": [
-		  {
-			"type": "lid_van",
-			"depth": {
-			  "min": 1,
-			  "max": 1
-			},
-			"entityFrom": 0,
-			"entityTo": 1,
-			"constraints": []
-		  }
+			{
+				"ID": 0,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 1,
+				"constraints":[]
+			}
 		],
+		"groupBys": [],		
 		"limit": 5000,
 		"modifiers": []
-	  }`)
+	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
 	var JSONQuery entity.IncomingQueryJSON
@@ -121,46 +118,86 @@ func TestMultipleEntityTypes(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := "WITH partijen\nLET n0 = (\n\tFOR x IN kamerleden \n\tFILTER x.partij == \"GL\" \n\tRETURN x\n)\nLET r0 = (\n\tFOR x IN n0 \n\tFOR v, e, p IN 1..1 OUTBOUND x lid_van \n\tOPTIONS { uniqueEdges: \"path\" }\n\tFILTER v.zetels > 6 \n\tLIMIT 5000 \nRETURN DISTINCT p )\n\nLET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), [],[]))\nLET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), [],[]))\nRETURN {\"vertices\":nodes, \"edges\":edges }"
-	cleanedResult := strings.ReplaceAll(correctConvertedResult, "\n", "")
-	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
-	convertedCleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
-	convertedCleanedResult = strings.ReplaceAll(convertedCleanedResult, "\t", "")
-
-	assert.Equal(t, convertedCleanedResult, cleanedResult)
+	correctConvertedResult := []byte(`LET result = (
+        FOR e_0 IN parliament
+        LET e1 = (
+                FOR e_1 IN parties
+                FOR r0 IN member_of
+                FILTER r0._from == e_0._id AND r0._to == e_1._id
+                FILTER length(e_1) != 0 AND length(r0) != 0
+                RETURN {"nodes":union_distinct([e_1], []), "rel": union_distinct([r0], []), "mod": union_distinct([], [])}
+        )
+        FILTER length(e1) != 0 AND length(e_0) != 0
+        RETURN {"nodes":union_distinct(flatten(e1[**].nodes), [e_0]), "rel": union_distinct(flatten(e1[**].rel), []), "mod": union_distinct(flatten(e1[**].mod), [])}
+)
+LET nodes = union_distinct(flatten(result[**].nodes),[])
+LET edges = union_distinct(flatten(result[**].rel),[])
+RETURN {"vertices":nodes,"edges":edges}`)
+	regExCleaner := regexp.MustCompile(`\s+`)
+	correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
+	convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
+
+	assert.Equal(t, correctCleanedResult, convertedCleanedResult)
 }
 
 /*
-Tests a query with one attribute
+Tests two entities (two types) with one entity filter
+Query description: Give me all parties, with less than 10 seats, connected to their respective parliament members
 	t: *testing.T, makes go recognise this as a test
 */
-func TestEntityOneAttributeQuery(t *testing.T) {
+func TestTwoEntitiesOneEntityFilter(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
 
 	query := []byte(`{
+		"databaseName": "TweedeKamer",
 		"return": {
 			"entities": [
-				0
+				0,
+				1
 			],
-			"relations": []
+			"relations": [
+				0
+			]
 		},
 		"entities": [
 			{
-				"type": "airports",
+				"name": "parliament",
+				"ID": 0,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 1,
 				"constraints": [
 					{
-						"attribute": "state",
-						"value": "HI",
-						"dataType": "string",
-						"matchType": "exact"
+						"attribute": "seats",
+						"value": "10",
+						"dataType": "int",
+						"matchType": "LT"
 					}
 				]
 			}
 		],
-		"relations": [],
-		"limit": 5000
+		"relations": [
+			{
+				"ID": 0,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 1,
+				"constraints":[]
+			}
+		],
+		"groupBys": [],		
+		"limit": 5000,
+		"modifiers": []
 	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
@@ -173,25 +210,44 @@ func TestEntityOneAttributeQuery(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET nodes = first(RETURN UNION_DISTINCT(n0,[],[]))LET edges = first(RETURN UNION_DISTINCT([],[]))RETURN {"vertices":nodes, "edges":edges }`
-	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
-	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
-	assert.Equal(t, correctConvertedResult, cleanedResult)
+	correctConvertedResult := []byte(`LET result = (
+        FOR e_0 IN parliament
+        LET e1 = (
+                FOR e_1 IN parties
+                FOR r0 IN member_of
+                FILTER e_1.seats < 10
+                FILTER r0._from == e_0._id AND r0._to == e_1._id
+                FILTER length(e_1) != 0 AND length(r0) != 0
+                RETURN {"nodes":union_distinct([e_1], []), "rel": union_distinct([r0], []), "mod": union_distinct([], [])}
+        )
+        FILTER length(e1) != 0 AND length(e_0) != 0
+        RETURN {"nodes":union_distinct(flatten(e1[**].nodes), [e_0]), "rel": union_distinct(flatten(e1[**].rel), []), "mod": union_distinct(flatten(e1[**].mod), [])}
+)
+LET nodes = union_distinct(flatten(result[**].nodes),[])
+LET edges = union_distinct(flatten(result[**].rel),[])
+RETURN {"vertices":nodes,"edges":edges}`)
+	regExCleaner := regexp.MustCompile(`\s+`)
+	correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
+	convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
+	assert.Equal(t, correctCleanedResult, convertedCleanedResult)
 }
 
 /*
-Test a relation with a constraint
+Tests two entities (two types) with two entity filters
+Query description: Give me all parties, with less than 10 seats, connected to their respective parliament members, who are more than 45 years old
 	t: *testing.T, makes go recognise this as a test
 */
-func TestRelationWithConstraint(t *testing.T) {
+func TestTwoEntitiesTwoEntityFilters(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
 
 	query := []byte(`{
+		"databaseName": "TweedeKamer",
 		"return": {
 			"entities": [
-				0
+				0,
+				1
 			],
 			"relations": [
 				0
@@ -199,37 +255,48 @@ func TestRelationWithConstraint(t *testing.T) {
 		},
 		"entities": [
 			{
-				"type": "airports",
+				"name": "parliament",
+				"ID": 0,
 				"constraints": [
 					{
-						"attribute": "state",
-						"value": "HI",
-						"dataType": "string",
-						"matchType": "exact"
+						"attribute": "age",
+						"value": "45",
+						"dataType": "int",
+						"matchType": "GT"
+					}
+				]
+			},
+			{
+				"name": "parties",
+				"ID": 1,
+				"constraints": [
+					{
+						"attribute": "seats",
+						"value": "10",
+						"dataType": "int",
+						"matchType": "LT"
 					}
 				]
 			}
 		],
 		"relations": [
 			{
-				"type": "flights",
+				"ID": 0,
+				"name": "member_of",
 				"depth": {
 					"min": 1,
 					"max": 1
 				},
-				"entityFrom": 0,
-				"entityTo": -1,
-				"constraints": [
-					{
-						"attribute": "Day",
-						"value": "15",
-						"dataType": "int",
-						"matchType": "EQ"
-					}
-				]
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 1,
+				"constraints":[]
 			}
 		],
-		"limit": 5000
+		"groupBys": [],		
+		"limit": 5000,
+		"modifiers": []
 	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
@@ -242,51 +309,100 @@ func TestRelationWithConstraint(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER p.edges[*].Day ALL == 15 LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), [],[]))RETURN {"vertices":nodes, "edges":edges }`
-	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
-	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
-	assert.Equal(t, correctConvertedResult, cleanedResult)
+	correctConvertedResult := []byte(`LET result = (
+        FOR e_0 IN parliament
+        FILTER e_0.age > 45
+        LET e1 = (
+                FOR e_1 IN parties
+                FOR r0 IN member_of
+                FILTER e_1.seats < 10
+                FILTER r0._from == e_0._id AND r0._to == e_1._id
+                FILTER length(e_1) != 0 AND length(r0) != 0
+                RETURN {"nodes":union_distinct([e_1], []), "rel": union_distinct([r0], []), "mod": union_distinct([], [])}
+        )
+        FILTER length(e1) != 0 AND length(e_0) != 0
+        RETURN {"nodes":union_distinct(flatten(e1[**].nodes), [e_0]), "rel": union_distinct(flatten(e1[**].rel), []), "mod": union_distinct(flatten(e1[**].mod), [])}
+)
+LET nodes = union_distinct(flatten(result[**].nodes),[])
+LET edges = union_distinct(flatten(result[**].rel),[])
+RETURN {"vertices":nodes,"edges":edges}`)
+	regExCleaner := regexp.MustCompile(`\s+`)
+	correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
+	convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
+	assert.Equal(t, correctCleanedResult, convertedCleanedResult)
 }
 
 /*
-Tests the count modifier
+Tests three entities (three types) without a filter
+Query description: Give me all parties, connected to their respective parliament members, who are then connected to the resolutions they submitted
 	t: *testing.T, makes go recognise this as a test
 */
-func TestModifierCountEntity(t *testing.T) {
+func TestThreeEntitiesNoFilter(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
 
 	query := []byte(`{
+		"databaseName": "TweedeKamer",
 		"return": {
 			"entities": [
-				0
+				0,
+				1,
+				2
 			],
-			"relations": []
+			"relations": [
+				0,
+				1
+			]
 		},
 		"entities": [
 			{
-				"type": "airports",
-				"constraints": [
-					{
-						"attribute": "state",
-						"value": "HI",
-						"dataType": "string",
-						"matchType": "exact"
-					}
-				]
+				"name": "parliament",
+				"ID": 0,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 1,
+				"constraints": []
+			},
+			{
+				"name": "resolutions",
+				"ID": 2,
+				"constraints": []
 			}
 		],
-		"relations": [],
-		"limit": 5000,
-		"modifiers": [
+		"relations": [
+			{
+				"ID": 0,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 1,
+				"constraints":[]
+			},
 			{
-				"type": "COUNT",
-				"selectedType": "entity",
-				"id": 0,
-				"attributeIndex": -1
+				"ID": 1,
+				"name": "submits",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 2,
+				"constraints":[]
 			}
-		]
+		],
+		"groupBys": [],		
+		"limit": 5000,
+		"modifiers": []
 	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
@@ -299,51 +415,112 @@ func TestModifierCountEntity(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)RETURN LENGTH (n0)`
-	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
-	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
-	assert.Equal(t, correctConvertedResult, cleanedResult)
+	correctConvertedResult := []byte(`LET result = (
+        FOR e_1 IN parties
+        LET e0 = (
+                FOR e_0 IN parliament
+                FOR r0 IN member_of
+                FILTER r0._from == e_0._id AND r0._to == e_1._id
+                LET e2 = (
+                        FOR e_2 IN resolutions
+                        FOR r1 IN submits
+                        FILTER r1._from == e_0._id AND r1._to == e_2._id
+                        FILTER length(e_2) != 0 AND length(r1) != 0
+                        RETURN {"nodes":union_distinct([e_2], []), "rel": union_distinct([r1], []), "mod": union_distinct([], [])}
+                )
+                FILTER length(e2) != 0 AND length(e_0) != 0 AND length(r0) != 0
+                RETURN {"nodes":union_distinct(flatten(e2[**].nodes), [e_0]), "rel": union_distinct(flatten(e2[**].rel), [r0]), "mod": union_distinct(flatten(e2[**].mod), [])}
+        )
+        FILTER length(e0) != 0 AND length(e_1) != 0
+        RETURN {"nodes":union_distinct(flatten(e0[**].nodes), [e_1]), "rel": union_distinct(flatten(e0[**].rel), []), "mod": union_distinct(flatten(e0[**].mod), [])}
+)
+LET nodes = union_distinct(flatten(result[**].nodes),[])
+LET edges = union_distinct(flatten(result[**].rel),[])
+RETURN {"vertices":nodes,"edges":edges}`)
+	regExCleaner := regexp.MustCompile(`\s+`)
+	correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
+	convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
+	assert.Equal(t, correctCleanedResult, convertedCleanedResult)
 }
 
 /*
-Tests the count modifer with an attribute
+Tests three entities (three types) with one entity filter
+Query description: Give me all parties, connected to their respective parliament members, whose name has "Geert" in it (this results in only "Geert Wilders"), who are/is then connected to the resolutions they submitted
 	t: *testing.T, makes go recognise this as a test
 */
-func TestModifierCountEntityAttribute(t *testing.T) {
+func TestThreeEntitiesOneEntityFilter(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
 
 	query := []byte(`{
+		"databaseName": "TweedeKamer",
 		"return": {
 			"entities": [
-				0
+				0,
+				1,
+				2
 			],
-			"relations": []
+			"relations": [
+				0,
+				1
+			]
 		},
 		"entities": [
 			{
-				"type": "airports",
+				"name": "parliament",
+				"ID": 0,				
 				"constraints": [
 					{
-						"attribute": "state",
-						"value": "HI",
+						"attribute": "name",
+						"value": "Geert",
 						"dataType": "string",
-						"matchType": "exact"
+						"matchType": "contains"
 					}
 				]
+			},
+			{
+				"name": "parties",
+				"ID": 1,
+				"constraints": []
+			},
+			{
+				"name": "resolutions",
+				"ID": 2,
+				"constraints": []
 			}
 		],
-		"relations": [],
-		"limit": 5000,
-		"modifiers": [
+		"relations": [
+			{
+				"ID": 0,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 1,
+				"constraints":[]
+			},
 			{
-				"type": "SUM",
-				"selectedType": "entity",
-				"id": 0,
-				"attributeIndex": 0
+				"ID": 1,
+				"name": "submits",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 2,
+				"constraints":[]
 			}
-		]
+		],
+		"groupBys": [],		
+		"limit": 5000,
+		"modifiers": []
 	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
@@ -356,71 +533,120 @@ func TestModifierCountEntityAttribute(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)RETURN SUM (n0[*].state)`
-	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
-	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
-	assert.Equal(t, correctConvertedResult, cleanedResult)
+	correctConvertedResult := []byte(`LET result = (
+        FOR e_1 IN parties
+        LET e0 = (
+                FOR e_0 IN parliament
+                FOR r0 IN member_of
+                FILTER e_0.name LIKE "%Geert%"
+                FILTER r0._from == e_0._id AND r0._to == e_1._id
+                LET e2 = (
+                        FOR e_2 IN resolutions
+                        FOR r1 IN submits
+                        FILTER r1._from == e_0._id AND r1._to == e_2._id
+                        FILTER length(e_2) != 0 AND length(r1) != 0
+                        RETURN {"nodes":union_distinct([e_2], []), "rel": union_distinct([r1], []), "mod": union_distinct([], [])}
+                )
+                FILTER length(e2) != 0 AND length(e_0) != 0 AND length(r0) != 0
+                RETURN {"nodes":union_distinct(flatten(e2[**].nodes), [e_0]), "rel": union_distinct(flatten(e2[**].rel), [r0]), "mod": union_distinct(flatten(e2[**].mod), [])}
+        )
+        FILTER length(e0) != 0 AND length(e_1) != 0
+        RETURN {"nodes":union_distinct(flatten(e0[**].nodes), [e_1]), "rel": union_distinct(flatten(e0[**].rel), []), "mod": union_distinct(flatten(e0[**].mod), [])}
+)
+LET nodes = union_distinct(flatten(result[**].nodes),[])
+LET edges = union_distinct(flatten(result[**].rel),[])
+RETURN {"vertices":nodes,"edges":edges}`)
+	regExCleaner := regexp.MustCompile(`\s+`)
+	correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
+	convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
+	assert.Equal(t, correctCleanedResult, convertedCleanedResult)
 }
 
 /*
-Tests the count modifier on a relation
+Tests three entities (three types) with two entity filters
+Query description: Give me all parties, connected to their respective parliament members, whose name has "Geert" in it (this results in only "Geert Wilders"), who are/is then connected to the resolutions they submitted, but only those submitted in May
 	t: *testing.T, makes go recognise this as a test
 */
-func TestModifierCountRelation(t *testing.T) {
+func TestThreeEntitiesTwoEntityFilters(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
 
 	query := []byte(`{
+		"databaseName": "TweedeKamer",
 		"return": {
 			"entities": [
-				0
+				0,
+				1,
+				2
 			],
 			"relations": [
-				0
+				0,
+				1
 			]
 		},
 		"entities": [
 			{
-				"type": "airports",
+				"name": "parliament",
+				"ID": 0,				
 				"constraints": [
 					{
-						"attribute": "state",
-						"value": "HI",
+						"attribute": "name",
+						"value": "Geert",
 						"dataType": "string",
-						"matchType": "exact"
+						"matchType": "contains"
+					}
+				]
+			},
+			{
+				"name": "parties",
+				"ID": 1,
+				"constraints": []
+			},
+			{
+				"name": "resolutions",
+				"ID": 2,
+				"constraints": [
+					{
+						"attribute": "date",
+						"value": "mei",
+						"dataType": "string",
+						"matchType": "contains"
 					}
 				]
 			}
 		],
 		"relations": [
 			{
-				"type": "flights",
+				"ID": 0,
+				"name": "member_of",
 				"depth": {
 					"min": 1,
 					"max": 1
 				},
-				"entityFrom": 0,
-				"entityTo": -1,
-				"constraints": [
-					{
-						"attribute": "Day",
-						"value": "15",
-						"dataType": "int",
-						"matchType": "EQ"
-					}
-				]
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 1,
+				"constraints":[]
+			},
+			{
+				"ID": 1,
+				"name": "submits",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 2,
+				"constraints":[]
 			}
 		],
+		"groupBys": [],		
 		"limit": 5000,
-		"modifiers": [
-			{
-				"type": "COUNT",
-				"selectedType": "relation",
-				"id": 0,
-				"attributeIndex": -1
-			}
-		]
+		"modifiers": []
 	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
@@ -433,144 +659,225 @@ func TestModifierCountRelation(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER p.edges[*].Day ALL == 15 RETURN DISTINCT p )RETURN LENGTH (unique(r0[*].edges[**]))`
-	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
-	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
-	assert.Equal(t, correctConvertedResult, cleanedResult)
+	correctConvertedResult := []byte(`LET result = (
+        FOR e_1 IN parties
+        LET e0 = (
+                FOR e_0 IN parliament
+                FOR r0 IN member_of
+                FILTER e_0.name LIKE "%Geert%"
+                FILTER r0._from == e_0._id AND r0._to == e_1._id
+                LET e2 = (
+                        FOR e_2 IN resolutions
+                        FOR r1 IN submits
+                        FILTER e_2.date LIKE "%mei%"
+                        FILTER r1._from == e_0._id AND r1._to == e_2._id
+                        FILTER length(e_2) != 0 AND length(r1) != 0
+                        RETURN {"nodes":union_distinct([e_2], []), "rel": union_distinct([r1], []), "mod": union_distinct([], [])}
+                )
+                FILTER length(e2) != 0 AND length(e_0) != 0 AND length(r0) != 0
+                RETURN {"nodes":union_distinct(flatten(e2[**].nodes), [e_0]), "rel": union_distinct(flatten(e2[**].rel), [r0]), "mod": union_distinct(flatten(e2[**].mod), [])}
+        )
+        FILTER length(e0) != 0 AND length(e_1) != 0
+        RETURN {"nodes":union_distinct(flatten(e0[**].nodes), [e_1]), "rel": union_distinct(flatten(e0[**].rel), []), "mod": union_distinct(flatten(e0[**].mod), [])}
+)
+LET nodes = union_distinct(flatten(result[**].nodes),[])
+LET edges = union_distinct(flatten(result[**].rel),[])
+RETURN {"vertices":nodes,"edges":edges}`)
+	regExCleaner := regexp.MustCompile(`\s+`)
+	correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
+	convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
+	assert.Equal(t, correctCleanedResult, convertedCleanedResult)
 }
 
 /*
-Tests the count modifier with an entity swap
-	t: *testing.T, makes go recognise this as a test
-*/
-func TestModifierCountEntitySwap(t *testing.T) {
-	// Setup for test
-	// Create query conversion service
-	service := NewService()
-
-	query := []byte(`{
-		"databaseName": "TweedeKamer",
-		"return": {
-		  "entities": [
-			0,
-			1
-		  ],
-		  "relations": [
-			0
-		  ]
-		},
-		"entities": [
-		  {
-			"type": "partijen",
-			"constraints": []
-		  },
-		  {
-			"type": "kamerleden",
-			"constraints": []
-		  }
-		],
-		"relations": [
-		  {
-			"type": "lid_van",
-			"depth": {
-			  "min": 1,
-			  "max": 1
-			},
-			"entityFrom": 1,
-			"entityTo": 0,
-			"constraints": []
-		  }
-		],
-		"limit": 5000,
-		"modifiers": [
-		  {
-			"type": "COUNT",
-			"selectedType": "entity",
-			"selectedTypeId": 1,
-			"attributeIndex": -1
-		  }
-		]
-	  }`)
-
-	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
-	json.Unmarshal(query, &JSONQuery)
-	convertedResult, err := service.ConvertQuery(&JSONQuery)
-
-	// Assert that there is no error
-	assert.NoError(t, err)
-
-	// Assert that the result and the expected result are the same
-	correctConvertedResult := `WITH partijenLET n1 = (FOR x IN kamerleden RETURN x)LET r0 = (FOR x IN n1 FOR v, e, p IN 1..1 OUTBOUND x lid_van OPTIONS { uniqueEdges: "path" }RETURN DISTINCT p )RETURN LENGTH (unique(r0[*].vertices[0]))`
-	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
-	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
-	assert.Equal(t, correctConvertedResult, cleanedResult)
-}
+Tests five entities (three types) with four entity filters
+Query description: Give me all parties, which have less than 10 seats, connected to their respective parliament members, whose name has "A" in it, who are/is then connected to the resolutions they submitted, but only those submitted in May, which are then also connected to all other persons who were part of that submission, who are part of the "VVD"
+Translator's note: This returns a member of the PvdA who submitted a motion alongside a member of the VVD
+hmmmmmmmmmmmmmmmmmmmmmmmmmmyo+/oooooooooooooooo+/+oymmmmmmmmmhso++/+++oo+++/++ohmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmmmmmmmmmmmmmmmmmmmmmho/+ooooooooooooooooooooooo+/oymdyo+/+ooooooooooooooooo++ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmmmmmmmmmmmmmmmmmmmh++ooooooooooooooooooooooooooooo+/:+ooooooooooooooooooooooo++dmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmmmmmmmmmmmmmmmmmdo/ooooooooooooooooooooooooooooooooo//oooooooooooooooooooooooo+/dmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmmmmmmmmmmmmmmmmy/+ooooooooooooo++////////////++oooooo//ooooooooooooooooooooooooo/dmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmmmmmmmmmmmmmmmo/ooooooooooo+///++++oooooooo++++///++oo:+oooooooooooooooooooooooo++mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmmmmmmmmmmmmmd++ooooooooo+//++oooooooooooooooooooo++////:+++////////////////////++:ydmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmmmmmmmmmmmmd/+oooooooooo++ooooooooooooooooooooooooooo+/:/++ooooooooooooooooo+o+++++++oshmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmmmmmmmmmmmd/+oooooooooooooooooooooooooooooo+++++++++++++//+ooooooooooooooooooooooooooo+++ohmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmmmmmmmmmmm++oooooooooooooooooooooooo+++////++++++++++++++/://+ooooo+++++////////////////++//mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmmmmmmmmmms/oooooooooooooooooooooo++//+++++//////////////++++++:++///++/++++///////////////+/+ohmmmmNmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmmmmmdhs++:ooooooooooooooooooo+++//+++////+++++sosysssso+++++//://////++++++++//////+o+++++///+/smmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmmmms+++o+/ooooooooooooooo+///+++++//+osyy+:+:...-:yNMMNmddyso++/++ooooooyho--o-````-+dmddyo+++//ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmmd++oooo:+oooooooooooo+++++++////+oydNMy. `s: `:-` :mMMMMMMMMNmy/oooydNMMo` .o- .+:` -mMMMNdhhso/ommmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmmmh/oooooo:ooooooooooooo//+++++oooymMMMMN.   .. :dh.  +MMMMMMMMMMMoodNMMMMN`   -. :hs`  oMMMMMMMMNyommmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmdy/ooooooo/ooooooooooooo+//////:yNMMMMMMm`   :-  `    :MMMMMMMMMMNsMMMMMMMd    -.       /MMMMMMMMMN+mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hmy/ooooooooooooooooooooooooooooo++smNMMMMN.           `sMMMMMMMMMNsmMMMMMMMm.           .hMMMMMMNmhshmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+hh/ooooooooooooooooooooooooooooooo+o++oymNNd:`       `:hMMMMMNNmyo+:sdmNNNNMMd:``      `+dNmmhysoo++mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+y/oooooooooooooooooooooooooooooooo///+o+++osys+/://+shdddysoo+++oo+:++++++ooosso/-----/++/++++o++oydmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+-+ooooooooooooooooooooooooooooooooooo+////+++++++////++++oooo+/////ooooooooooooooooooooooooooo+ommmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/ooooooooooooooooooooooooooooooooooooooooo++/////////////////+oooooooooooooooooooooooooooooo++ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/ooooooooooooooooooooooooooooooooooooooooooooooooooooooo+/+//ooooooooo+/+oooooooooooooo+/ossdmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/oooooooooooooooooooooooooooooooooooooooooooooooooo++///+oooooooooooooo+////:////////////ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/oooooooooooooooooooooooooooooooooooooooooooooo+///+oooooooooooooooooooooooo+/+oooooooooo++ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo++dmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+/dmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+/mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo/ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/ooooooooooooooooooooooooooooooo++++++++++ooooooooooooooooooooooooooooooooooooooooooooooooooooo/mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/oooooooooooooooooooooooooooo+//++++++++///////++++++ooooooooooooooooooooooooooooooooooooo+++///+smmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/oooooooooooooooooooooooooo+/++oooooooooooooo++++++////////+++++++oooooooooooooooo+++++////+++oo+:mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/ooooooooooooooooooooooooo+:+oooo+///////++++++ooooooooo++++++++///////////////////++++++ooooo+++ymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/ooooooooooooooooooooooooo:+ooooo++++++++++++//////++++++++ooooooooooooooooooooooooooooo++++++oydmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/ooooooooooooooooooooooooo+/++++oooooooooooooooo++++++++///////////+/++++++++++////////////+:smmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/ooooooooooooooooooooo/+ooo+///////////////+++++++oooooooooooo+++++++++++++++++++++++ooooooo+/mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+/+ooooooooooooooooooooo//ooooooooooooooooo++++++/////++++++++++++++oooooooooooooooooooooo++++hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+y++ooooooooooooooooooooo+//+++ooooooooooooooooooooooo++++////////////////////////++//++++osymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+yd//++ooooooooooooooooooooo+++oooooooooooooooooooooooooooooooooooooooooooo++++++++//sddmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+::::////++oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+++ohmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+:/:::://+/////+oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+++oymmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+://////::://+++///////+++ooooooooooooooooooooooooooooooooooooooooooooo++++sydmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+://////////::::/++ooo+++////////////++++++ooooooooooooooooo+++++/////shdmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
+-///////////////::::://+++oooooooooo+++++////////////////////+++/::::odmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
 
-/*
-Tests the count modifier on a relation and attribute
 	t: *testing.T, makes go recognise this as a test
 */
-func TestModifierCountRelationAttribute(t *testing.T) {
+func TestFiveEntitiesFourEntityFilters(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
 
 	query := []byte(`{
+		"databaseName": "TweedeKamer",
 		"return": {
 			"entities": [
-				0
+				0,
+				1,
+				2,
+				3,
+				4
 			],
 			"relations": [
-				0
+				0,
+				1,
+				2,
+				3
 			]
 		},
 		"entities": [
 			{
-				"type": "airports",
+				"name": "parliament",
+				"ID": 0,
 				"constraints": [
 					{
-						"attribute": "state",
-						"value": "HI",
+						"attribute": "name",
+						"value": "A",
 						"dataType": "string",
-						"matchType": "exact"
+						"matchType": "contains"
 					}
 				]
-			}
-		],
-		"relations": [
+			},
 			{
-				"type": "flights",
-				"depth": {
-					"min": 1,
-					"max": 1
-				},
-				"entityFrom": 0,
-				"entityTo": -1,
+				"name": "parties",
+				"ID": 1,
 				"constraints": [
 					{
-						"attribute": "Day",
-						"value": "15",
+						"attribute": "seats",
+						"value": "10",
 						"dataType": "int",
-						"matchType": "EQ"
+						"matchType": "LT"
 					}
 				]
-			}
-		],
-		"limit": 5000,
-		"modifiers": [
+			},
 			{
-				"type": "AVG",
-				"selectedType": "relation",
-				"id": 0,
-				"attributeIndex": 0
-			}
-		]
-	}`)
-
-	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
-	json.Unmarshal(query, &JSONQuery)
+				"name": "resolutions",
+				"ID": 2,
+				"constraints": [
+					{
+						"attribute": "date",
+						"value": "mei",
+						"dataType": "string",
+						"matchType": "contains"
+					}
+				]
+			},
+			{
+				"name": "parliament",
+				"ID": 3,
+				"constraints":[]
+			},
+			{
+				"name": "parties",
+				"ID": 4,
+				"constraints": [
+					{
+						"attribute": "name",
+						"value": "Volkspartij voor Vrijheid en Democratie",
+						"dataType": "string",
+						"matchType": "=="
+					}
+				]
+			}
+		],
+		"relations": [
+			{
+				"ID": 0,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 1,
+				"constraints": []
+			},
+			{
+				"ID": 1,
+				"name": "submits",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 2,
+				"constraints": []
+			},
+			{
+				"ID": 2,
+				"name": "submits",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 3,
+				"toType": "entity",
+				"toID": 2,
+				"constraints": []
+			},
+			{
+				"ID": 3,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 3,
+				"toType": "entity",
+				"toID": 4,
+				"constraints": []
+			}
+		],
+		"groupBys": [],
+		"limit": 5000,
+		"modifiers": []
+	}`)
+
+	// Unmarshall the incoming message into an IncomingJSONQuery object
+	var JSONQuery entity.IncomingQueryJSON
+	json.Unmarshal(query, &JSONQuery)
 
 	convertedResult, err := service.ConvertQuery(&JSONQuery)
 
@@ -578,17 +885,58 @@ func TestModifierCountRelationAttribute(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER p.edges[*].Day ALL == 15 RETURN DISTINCT p )RETURN AVG (r0[*].edges[**].Day)`
-	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
-	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
-	assert.Equal(t, correctConvertedResult, cleanedResult)
+	correctConvertedResult := []byte(`LET result = (
+        FOR e_1 IN parties
+        FILTER e_1.seats < 10
+        LET e0 = (
+                FOR e_0 IN parliament
+                FOR r0 IN member_of
+                FILTER e_0.name LIKE "%A%"
+                FILTER r0._from == e_0._id AND r0._to == e_1._id
+                LET e2 = (
+                        FOR e_2 IN resolutions
+                        FOR r1 IN submits
+                        FILTER e_2.date LIKE "%mei%"
+                        FILTER r1._from == e_0._id AND r1._to == e_2._id
+                        LET e3 = (
+                                FOR e_3 IN parliament
+                                FOR r2 IN submits
+                                FILTER r2._from == e_3._id AND r2._to == e_2._id
+                                LET e4 = (
+                                        FOR e_4 IN parties
+                                        FOR r3 IN member_of
+                                        FILTER e_4.name == "Volkspartij voor Vrijheid en Democratie"
+                                        FILTER r3._from == e_3._id AND r3._to == e_4._id
+                                        FILTER length(e_4) != 0 AND length(r3) != 0
+                                        RETURN {"nodes":union_distinct([e_4], []), "rel": union_distinct([r3], []), "mod": union_distinct([], [])}
+                                )
+                                FILTER length(e4) != 0 AND length(e_3) != 0 AND length(r2) != 0
+                                RETURN {"nodes":union_distinct(flatten(e4[**].nodes), [e_3]), "rel": union_distinct(flatten(e4[**].rel), [r2]), "mod": union_distinct(flatten(e4[**].mod), [])}
+                        )
+                        FILTER length(e3) != 0 AND length(e_2) != 0 AND length(r1) != 0
+                        RETURN {"nodes":union_distinct(flatten(e3[**].nodes), [e_2]), "rel": union_distinct(flatten(e3[**].rel), [r1]), "mod": union_distinct(flatten(e3[**].mod), [])}
+                )
+                FILTER length(e2) != 0 AND length(e_0) != 0 AND length(r0) != 0
+                RETURN {"nodes":union_distinct(flatten(e2[**].nodes), [e_0]), "rel": union_distinct(flatten(e2[**].rel), [r0]), "mod": union_distinct(flatten(e2[**].mod), [])}
+        )
+        FILTER length(e0) != 0 AND length(e_1) != 0
+        RETURN {"nodes":union_distinct(flatten(e0[**].nodes), [e_1]), "rel": union_distinct(flatten(e0[**].rel), []), "mod": union_distinct(flatten(e0[**].mod), [])}
+)
+LET nodes = union_distinct(flatten(result[**].nodes),[])
+LET edges = union_distinct(flatten(result[**].rel),[])
+RETURN {"vertices":nodes,"edges":edges}`)
+	regExCleaner := regexp.MustCompile(`\s+`)
+	correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
+	convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
+	assert.Equal(t, correctCleanedResult, convertedCleanedResult)
 }
 
 /*
-Tests a relation with an in out constraint
+Tests five entities (four types) with three entity filters and one junction
+Query description: Give me all parties, with less than 10 seats, connected to their respective parliament members, who are then connected to the resolutions they submitted, but only those submitted in May, and connected to the comissions they're in, which are then connected to all of their members, but only those with "Geert" in their name (resulting in only "Geert Wilders")
 	t: *testing.T, makes go recognise this as a test
 */
-func TestRelationWithInOutConstraint(t *testing.T) {
+func TestSingleJunctionFiveEntitiesThreeEntityFilters(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
@@ -597,53 +945,120 @@ func TestRelationWithInOutConstraint(t *testing.T) {
 		"return": {
 			"entities": [
 				0,
-				1
+				1,
+				2,
+				3,
+				4
 			],
 			"relations": [
-				0
+				0,
+				1,
+				2,
+				3
 			]
 		},
 		"entities": [
 			{
-				"type": "airports",
+				"name": "parliament",
+				"ID": 0,
 				"constraints": [
 					{
-						"attribute": "city",
-						"value": "San Francisco",
+						"attribute": "name",
+						"value": "Geert",
 						"dataType": "string",
-						"matchType": "exact"
+						"matchType": "contains"
 					}
 				]
 			},
 			{
-				"type": "airports",
+				"name": "commissions",
+				"ID": 1,
+				"constraints": []
+			},
+			{
+				"name": "parliament",
+				"ID": 2,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 3,
 				"constraints": [
 					{
-						"attribute": "state",
-						"value": "HI",
+						"attribute": "seats",
+						"value": "10",
+						"dataType": "int",
+						"matchType": "LT"
+					}
+				]
+			},
+			{
+				"name": "resolutions",
+				"ID": 4,
+				"constraints": [
+					{
+						"attribute": "date",
+						"value": "mei",
 						"dataType": "string",
-						"matchType": "exact"
+						"matchType": "contains"
 					}
 				]
 			}
+			
 		],
+		"groupBys": [],
 		"relations": [
 			{
-				"type": "flights",
+				"ID": 0,
+				"name": "part_of",
 				"depth": {
 					"min": 1,
-					"max": 3
+					"max": 1
 				},
-				"entityFrom": 1,
-				"entityTo": 0,
-				"constraints": [
-					{
-						"attribute": "Day",
-						"value": "15",
-						"dataType": "int",
-						"matchType": "EQ"
-					}
-				]
+				"fromType": "entity",
+				"fromId": 0,
+				"toType": "entity",
+				"toID": 1,
+				"constraints": []
+			},
+			{
+				"ID": 1,
+				"name": "part_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromId": 2,
+				"toType": "entity",
+				"toID": 1,
+				"constraints": []
+			},
+			{
+				"ID": 2,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromId": 2,
+				"toType": "entity",
+				"toID": 3,
+				"constraints": []
+			},
+			{
+				"ID": 3,
+				"name": "submits",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromId": 2,
+				"toType": "entity",
+				"toID": 4,
+				"constraints": []
 			}
 		],
 		"limit": 5000
@@ -659,17 +1074,57 @@ func TestRelationWithInOutConstraint(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `LET n1 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n1 FOR v, e, p IN 1..3 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER v.city == "San Francisco" FILTER p.edges[*].Day ALL == 15 LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), [],[]))RETURN {"vertices":nodes, "edges":edges }`
-	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
-	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
-	assert.Equal(t, correctConvertedResult, cleanedResult)
+	correctConvertedResult := []byte(`LET result = (
+        FOR e_0 IN parliament
+        FILTER e_0.name LIKE "%Geert%"
+        LET e1 = (
+                FOR e_1 IN commissions
+                FOR r0 IN part_of
+                FILTER r0._from == e_0._id AND r0._to == e_1._id
+                LET e2 = (
+                        FOR e_2 IN parliament
+                        FOR r1 IN part_of
+                        FILTER r1._from == e_2._id AND r1._to == e_1._id
+                        LET e3 = (
+                                FOR e_3 IN parties
+                                FOR r2 IN member_of
+                                FILTER e_3.seats < 10
+                                FILTER r2._from == e_2._id AND r2._to == e_3._id
+                                FILTER length(e_3) != 0 AND length(r2) != 0
+                                RETURN {"nodes":union_distinct([e_3], []), "rel": union_distinct([r2], []), "mod": union_distinct([], [])}
+                        )
+                        LET e4 = (
+                                FOR e_4 IN resolutions
+                                FOR r3 IN submits
+                                FILTER e_4.date LIKE "%mei%"
+                                FILTER r3._from == e_2._id AND r3._to == e_4._id
+                                FILTER length(e_4) != 0 AND length(r3) != 0
+                                RETURN {"nodes":union_distinct([e_4], []), "rel": union_distinct([r3], []), "mod": union_distinct([], [])}
+                        )
+                        FILTER length(e3) != 0 AND length(e4) != 0 AND length(e_2) != 0 AND length(r1) != 0
+                        RETURN {"nodes":union_distinct(flatten(e3[**].nodes), flatten(e4[**].nodes), [e_2]), "rel": union_distinct(flatten(e3[**].rel), flatten(e4[**].rel), [r1]), "mod": union_distinct(flatten(e3[**].mod), flatten(e4[**].mod), [])}
+                )
+                FILTER length(e2) != 0 AND length(e_1) != 0 AND length(r0) != 0
+                RETURN {"nodes":union_distinct(flatten(e2[**].nodes), [e_1]), "rel": union_distinct(flatten(e2[**].rel), [r0]), "mod": union_distinct(flatten(e2[**].mod), [])}
+        )
+        FILTER length(e1) != 0 AND length(e_0) != 0
+        RETURN {"nodes":union_distinct(flatten(e1[**].nodes), [e_0]), "rel": union_distinct(flatten(e1[**].rel), []), "mod": union_distinct(flatten(e1[**].mod), [])}
+)
+LET nodes = union_distinct(flatten(result[**].nodes),[])
+LET edges = union_distinct(flatten(result[**].rel),[])
+RETURN {"vertices":nodes,"edges":edges}`)
+	regExCleaner := regexp.MustCompile(`\s+`)
+	correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
+	convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
+	assert.Equal(t, correctCleanedResult, convertedCleanedResult)
 }
 
 /*
-Tests two relations
+Tests nine entities (four types) with three entity filters and two junctions
+Query description: Give me all parties, with less than 10 seats, connected to their respective parliament members, who are then connected to the resolutions they submitted, but only those submitted in May, and connected to the comissions they're in, which are then connected to all of their members, but only those with "Geert" in their name (resulting in only "Geert Wilders"), who is then connected to their submited resolutions and their party, which is connected to all of its members
 	t: *testing.T, makes go recognise this as a test
 */
-func TestTwoRelations(t *testing.T) {
+func TestDoubleJunctionNineEntitiesThreeEntityFilters(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
@@ -679,74 +1134,180 @@ func TestTwoRelations(t *testing.T) {
 			"entities": [
 				0,
 				1,
-				2
+				2,
+				3,
+				4,
+				5,
+				6,
+				7
 			],
 			"relations": [
 				0,
-				1
+				1,
+				2,
+				3,
+				4,
+				5,
+				6
 			]
 		},
 		"entities": [
 			{
-				"type": "airports",
+				"name": "parliament",
+				"ID": 0,
 				"constraints": [
 					{
-						"attribute": "city",
-						"value": "New York",
+						"attribute": "name",
+						"value": "Geert",
 						"dataType": "string",
-						"matchType": "exact"
+						"matchType": "contains"
 					}
 				]
 			},
 			{
-				"type": "airports",
+				"name": "commissions",
+				"ID": 1,
+				"constraints": []
+			},
+			{
+				"name": "parliament",
+				"ID": 2,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 3,
 				"constraints": [
 					{
-						"attribute": "city",
-						"value": "San Francisco",
-						"dataType": "string",
-						"matchType": "exact"
+						"attribute": "seats",
+						"value": "10",
+						"dataType": "int",
+						"matchType": "LT"
 					}
 				]
 			},
 			{
-				"type": "airports",
+				"name": "resolutions",
+				"ID": 4,
 				"constraints": [
 					{
-						"attribute": "state",
-						"value": "HI",
+						"attribute": "date",
+						"value": "mei",
 						"dataType": "string",
-						"matchType": "exact"
+						"matchType": "contains"
 					}
 				]
+			},
+			{
+				"name": "resolutions",
+				"ID": 5,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 6,
+				"constraints": []
 			}
+			,
+			{
+				"name": "parliament",
+				"ID": 7,
+				"constraints": []
+			}
+			
 		],
+		"groupBys": [],
 		"relations": [
 			{
-				"type": "flights",
+				"ID": 0,
+				"name": "part_of",
 				"depth": {
 					"min": 1,
-					"max": 3
+					"max": 1
 				},
-				"entityFrom": 2,
-				"entityTo": 1,
-				"constraints": [
-					{
-						"attribute": "Day",
-						"value": "15",
-						"dataType": "int",
-						"matchType": "EQ"
-					}
-				]
+				"fromType": "entity",
+				"fromId": 0,
+				"toType": "entity",
+				"toID": 1,
+				"constraints": []
 			},
 			{
-				"type": "flights",
+				"ID": 1,
+				"name": "part_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromId": 2,
+				"toType": "entity",
+				"toID": 1,
+				"constraints": []
+			},
+			{
+				"ID": 2,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromId": 2,
+				"toType": "entity",
+				"toID": 3,
+				"constraints": []
+			},
+			{
+				"ID": 3,
+				"name": "submits",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromId": 2,
+				"toType": "entity",
+				"toID": 4,
+				"constraints": []
+			},
+			{
+				"ID": 4,
+				"name": "submits",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromId": 0,
+				"toType": "entity",
+				"toID": 5,
+				"constraints": []
+			},
+			{
+				"ID": 5,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromId": 0,
+				"toType": "entity",
+				"toID": 6,
+				"constraints": []
+			}
+			,
+			{
+				"ID": 6,
+				"name": "member_of",
 				"depth": {
 					"min": 1,
 					"max": 1
 				},
-				"entityFrom": 0,
-				"entityTo": -1,
+				"fromType": "entity",
+				"fromId": 7,
+				"toType": "entity",
+				"toID": 6,
 				"constraints": []
 			}
 		],
@@ -763,57 +1324,138 @@ func TestTwoRelations(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `LET n2 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n2 FOR v, e, p IN 1..3 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER v.city == "San Francisco" FILTER p.edges[*].Day ALL == 15 LIMIT 5000 RETURN DISTINCT p )LET n0 = (FOR x IN airports FILTER x.city == "New York" RETURN x)LET r1 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), flatten(r1[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), flatten(r1[**].edges), [],[]))RETURN {"vertices":nodes, "edges":edges }`
-	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
-	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
-	assert.Equal(t, correctConvertedResult, cleanedResult)
+	correctConvertedResult := []byte(`LET result = (
+        FOR e_3 IN parties
+        FILTER e_3.seats < 10
+        LET e2 = (
+                FOR e_2 IN parliament
+                FOR r2 IN member_of
+                FILTER r2._from == e_2._id AND r2._to == e_3._id
+                LET e1 = (
+                        FOR e_1 IN commissions
+                        FOR r1 IN part_of
+                        FILTER r1._from == e_2._id AND r1._to == e_1._id
+                        LET e0 = (
+                                FOR e_0 IN parliament
+                                FOR r0 IN part_of
+                                FILTER e_0.name LIKE "%Geert%"
+                                FILTER r0._from == e_0._id AND r0._to == e_1._id
+                                LET e5 = (
+                                        FOR e_5 IN resolutions
+                                        FOR r4 IN submits
+                                        FILTER r4._from == e_0._id AND r4._to == e_5._id
+                                        FILTER length(e_5) != 0 AND length(r4) != 0
+                                        RETURN {"nodes":union_distinct([e_5], []), "rel": union_distinct([r4], []), "mod": union_distinct([], [])}
+                                )
+                                LET e6 = (
+                                        FOR e_6 IN parties
+                                        FOR r5 IN member_of
+                                        FILTER r5._from == e_0._id AND r5._to == e_6._id
+                                        LET e7 = (
+                                                FOR e_7 IN parliament
+                                                FOR r6 IN member_of
+                                                FILTER r6._from == e_7._id AND r6._to == e_6._id
+                                                FILTER length(e_7) != 0 AND length(r6) != 0
+                                                RETURN {"nodes":union_distinct([e_7], []), "rel": union_distinct([r6], []), "mod": union_distinct([], [])}
+                                        )
+                                        FILTER length(e7) != 0 AND length(e_6) != 0 AND length(r5) != 0
+                                        RETURN {"nodes":union_distinct(flatten(e7[**].nodes), [e_6]), "rel": union_distinct(flatten(e7[**].rel), [r5]), "mod": union_distinct(flatten(e7[**].mod), [])}
+                                )
+                                FILTER length(e5) != 0 AND length(e6) != 0 AND length(e_0) != 0 AND length(r0) != 0
+                                RETURN {"nodes":union_distinct(flatten(e5[**].nodes), flatten(e6[**].nodes), [e_0]), "rel": union_distinct(flatten(e5[**].rel), flatten(e6[**].rel), [r0]), "mod": union_distinct(flatten(e5[**].mod), flatten(e6[**].mod), [])}
+                        )
+                        FILTER length(e0) != 0 AND length(e_1) != 0 AND length(r1) != 0
+                        RETURN {"nodes":union_distinct(flatten(e0[**].nodes), [e_1]), "rel": union_distinct(flatten(e0[**].rel), [r1]), "mod": union_distinct(flatten(e0[**].mod), [])}
+                )
+                LET e4 = (
+                        FOR e_4 IN resolutions
+                        FOR r3 IN submits
+                        FILTER e_4.date LIKE "%mei%"
+                        FILTER r3._from == e_2._id AND r3._to == e_4._id
+                        FILTER length(e_4) != 0 AND length(r3) != 0
+                        RETURN {"nodes":union_distinct([e_4], []), "rel": union_distinct([r3], []), "mod": union_distinct([], [])}
+                )
+                FILTER length(e1) != 0 AND length(e4) != 0 AND length(e_2) != 0 AND length(r2) != 0
+                RETURN {"nodes":union_distinct(flatten(e1[**].nodes), flatten(e4[**].nodes), [e_2]), "rel": union_distinct(flatten(e1[**].rel), flatten(e4[**].rel), [r2]), "mod": union_distinct(flatten(e1[**].mod), flatten(e4[**].mod), [])}
+        )
+        FILTER length(e2) != 0 AND length(e_3) != 0
+        RETURN {"nodes":union_distinct(flatten(e2[**].nodes), [e_3]), "rel": union_distinct(flatten(e2[**].rel), []), "mod": union_distinct(flatten(e2[**].mod), [])}
+)
+LET nodes = union_distinct(flatten(result[**].nodes),[])
+LET edges = union_distinct(flatten(result[**].rel),[])
+RETURN {"vertices":nodes,"edges":edges}`)
+	regExCleaner := regexp.MustCompile(`\s+`)
+	correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
+	convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
+	assert.Equal(t, correctCleanedResult, convertedCleanedResult)
 }
 
 /*
-Tests a relation with only a to node
+Tests two entities (one type) with one entity filter and one relation filter
+Query description: Give me all airports, in the state "HI", connected to any other airport by flight, but only the flights on "day" 15
 	t: *testing.T, makes go recognise this as a test
 */
-func TestRelationWithOnlyToNode(t *testing.T) {
+func TestTwoEntitiesOneEntityFilterOneRelationFilter(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
 
 	query := []byte(`{
-			"return": {
-				"entities": [
-					0
-				],
-				"relations": [
-					0
-				]
-			},
+		"return": {
 			"entities": [
-				{
-					"type": "airports",
-					"constraints": [
-						{
-							"attribute": "city",
-							"value": "San Francisco",
-							"dataType": "string",
-							"matchType": "exact"
-						}
-					]
-				}
+				0,
+				1
 			],
 			"relations": [
-				{
-					"type": "flights",
-					"depth": {
-						"min": 1,
-						"max": 1
-					},
-					"entityFrom": -1,
-					"entityTo": 0,
-					"constraints": []
-				}
-			],
-			"limit": 5000
-		}`)
+				0
+			]
+		},
+		"entities": [
+			{
+				"ID": 0,
+				"name": "airports",
+				"constraints": [
+					{
+						"attribute": "state",
+						"value": "HI",
+						"dataType": "string",
+						"matchType": "exact"
+					}
+				]
+			},
+			{
+				"ID": 1,
+				"name": "airports",
+				"constraints":[]
+			}
+		],
+		"relations": [
+			{
+				"ID": 0,
+				"name": "flights",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"FromType": "entity",
+				"fromID": 0,
+				"ToType": "entity",
+				"toID": 1,
+				"constraints": [
+					{	
+						"attribute": "Day",
+						"value": "15",
+						"dataType": "int",
+						"matchType": "EQ",
+						"inType": "",
+						"inID": -1
+					}
+				]
+			}
+		],
+		"groupBys": [],
+		"limit": 5000
+	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
 	var JSONQuery entity.IncomingQueryJSON
@@ -825,59 +1467,65 @@ func TestRelationWithOnlyToNode(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.city == "San Francisco" RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 INBOUND x flights OPTIONS { uniqueEdges: "path" }LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), [],[]))RETURN {"vertices":nodes, "edges":edges }`
-	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
-	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
-	assert.Equal(t, correctConvertedResult, cleanedResult)
+	correctConvertedResult := []byte(`LET result = (
+        FOR e_0 IN airports
+        FILTER e_0.state == "HI"
+        LET e1 = (
+                FOR e_1 IN airports
+                FOR r0 IN flights
+                FILTER r0.Day == 15
+                FILTER r0._from == e_0._id AND r0._to == e_1._id
+                FILTER length(e_1) != 0 AND length(r0) != 0
+                RETURN {"nodes":union_distinct([e_1], []), "rel": union_distinct([r0], []), "mod": union_distinct([], [])}
+        )
+        FILTER length(e1) != 0 AND length(e_0) != 0
+        RETURN {"nodes":union_distinct(flatten(e1[**].nodes), [e_0]), "rel": union_distinct(flatten(e1[**].rel), []), "mod": union_distinct(flatten(e1[**].mod), [])}
+)
+LET nodes = union_distinct(flatten(result[**].nodes),[])
+LET edges = union_distinct(flatten(result[**].rel),[])
+RETURN {"vertices":nodes,"edges":edges}`)
+	regExCleaner := regexp.MustCompile(`\s+`)
+	correctCleanedResult := regExCleaner.ReplaceAllString(string(correctConvertedResult), " ")
+	convertedCleanedResult := regExCleaner.ReplaceAllString(*convertedResult, " ")
+	assert.Equal(t, correctCleanedResult, convertedCleanedResult)
 }
 
+//TODO
+//FIX THESE TESTS, THEY'RE NOT THAT INTERESTING BUT SHOULD BE FIXED ANYWAY
+
 /*
-Tests too manu return entities
+Tests a query with no relation field
 	t: *testing.T, makes go recognise this as a test
 */
-func TestTooManyReturnEntities(t *testing.T) {
+func TestNoRelationsField(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
 
 	query := []byte(`{
-			"return": {
-				"entities": [
-					0,
-					1,
-					2
-				],
-				"relations": [
-					0
-				]
-			},
+		"databaseName": "TweedeKamer",
+		"return": {
 			"entities": [
-				{
-					"type": "airports",
-					"constraints": [
-						{
-							"attribute": "city",
-							"value": "San Francisco",
-							"dataType": "string",
-							"matchType": "exact"
-						}
-					]
-				}
-			],
-			"relations": [
-				{
-					"type": "flights",
-					"depth": {
-						"min": 1,
-						"max": 1
-					},
-					"entityFrom": -1,
-					"entityTo": 0,
-					"constraints": []
-				}
-			],
-			"limit": 5000
-		}`)
+				0,
+				1
+			]
+		},
+		"entities": [
+			{
+				"name": "parliament",
+				"ID": 0,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 1,
+				"constraints": []
+			}
+		],		
+		"groupBys": [],		
+		"limit": 5000,
+		"modifiers": []
+	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
 	var JSONQuery entity.IncomingQueryJSON
@@ -885,57 +1533,60 @@ func TestTooManyReturnEntities(t *testing.T) {
 
 	_, err := service.ConvertQuery(&JSONQuery)
 
-	// Assert that there is no error
-	assert.Equal(t, errors.New("non-existing entity referenced in return"), err)
+	assert.Equal(t, errors.New("no relations or entities sent"), err)
 }
 
 /*
-Tests too manu return relations
+Tests an entity with a lower than -1 in a relation
 	t: *testing.T, makes go recognise this as a test
 */
-func TestTooManyReturnRelations(t *testing.T) {
+func TestIncorrectRelationFrom(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
 
 	query := []byte(`{
-			"return": {
-				"entities": [
-					0
-				],
-				"relations": [
-					0,
-					1,
-					2
-				]
-			},
+		"databaseName": "TweedeKamer",
+		"return": {
 			"entities": [
-				{
-					"type": "airports",
-					"constraints": [
-						{
-							"attribute": "city",
-							"value": "San Francisco",
-							"dataType": "string",
-							"matchType": "exact"
-						}
-					]
-				}
+				0,
+				1
 			],
 			"relations": [
-				{
-					"type": "flights",
-					"depth": {
-						"min": 1,
-						"max": 1
-					},
-					"entityFrom": -1,
-					"entityTo": 0,
-					"constraints": []
-				}
-			],
-			"limit": 5000
-		}`)
+				0
+			]
+		},
+		"entities": [
+			{
+				"name": "parliament",
+				"ID": 0,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 1,
+				"constraints": []
+			}
+		],
+		"relations": [
+			{
+				"ID": 0,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": -4,
+				"constraints":[]
+			}
+		],
+		"groupBys": [],		
+		"limit": 5000,
+		"modifiers": []
+	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
 	var JSONQuery entity.IncomingQueryJSON
@@ -943,58 +1594,86 @@ func TestTooManyReturnRelations(t *testing.T) {
 
 	_, err := service.ConvertQuery(&JSONQuery)
 
-	// Assert that there is no error
-	assert.Equal(t, errors.New("non-existing relation referenced in return"), err)
+	// Assert that there is an error
+	assert.Equal(t, errors.New("JSONQuery invalid"), err)
 }
 
 /*
-Tests negative return entities
+Tests two separated chains consisting of 1 relation each
 	t: *testing.T, makes go recognise this as a test
 */
-func TestNegativeReturnEntities(t *testing.T) {
+func TestSeparatedChainSingleRelationPerChain(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
 
 	query := []byte(`{
-			"return": {
-				"entities": [
-					0,
-					-1
-				],
-				"relations": [
-					0,
-					1,
-					2
-				]
-			},
+		"databaseName": "TweedeKamer",
+		"return": {
 			"entities": [
-				{
-					"type": "airports",
-					"constraints": [
-						{
-							"attribute": "city",
-							"value": "San Francisco",
-							"dataType": "string",
-							"matchType": "exact"
-						}
-					]
-				}
+				0,
+				1,
+				2,
+				3
 			],
 			"relations": [
-				{
-					"type": "flights",
-					"depth": {
-						"min": 1,
-						"max": 1
-					},
-					"entityFrom": -1,
-					"entityTo": 0,
-					"constraints": []
-				}
-			],
-			"limit": 5000
-		}`)
+				0
+			]
+		},
+		"entities": [
+			{
+				"name": "parliament",
+				"ID": 0,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 1,
+				"constraints": []
+			},
+			{
+				"name": "parliament",
+				"ID": 2,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 3,
+				"constraints": []
+			}
+		],
+		"relations": [
+			{
+				"ID": 0,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 1,
+				"constraints":[]
+			},
+			{
+				"ID": 1,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 2,
+				"toType": "entity",
+				"toID": 3,
+				"constraints":[]
+			}
+		],
+		"groupBys": [],		
+		"limit": 5000,
+		"modifiers": []
+	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
 	var JSONQuery entity.IncomingQueryJSON
@@ -1002,186 +1681,230 @@ func TestNegativeReturnEntities(t *testing.T) {
 
 	_, err := service.ConvertQuery(&JSONQuery)
 
-	// Assert that there is no error
-	assert.Equal(t, errors.New("non-existing entity referenced in return"), err)
+	// Assert that there is an error
+	assert.Equal(t, errors.New("JSONQuery invalid"), err)
 }
 
 /*
-Tests a query with no relation field
+Tests two separated chains consisting of 1 relation each
 	t: *testing.T, makes go recognise this as a test
 */
-func TestNoRelationsField(t *testing.T) {
+func TestSeparatedChainDoubleRelationPerChain(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
 
 	query := []byte(`{
-			"return": {
-				"entities": [
-					0
-				]
-			},
+		"databaseName": "TweedeKamer",
+		"return": {
 			"entities": [
-				{
-					"type": "airports",
-					"constraints": [
-						{
-							"attribute": "city",
-							"value": "San Francisco",
-							"dataType": "string",
-							"matchType": "exact"
-						}
-					]
-				}
+				0,
+				1,
+				2,
+				3,
+				4,
+				5
 			],
-			"limit": 5000
-		}`)
-
-	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
-	json.Unmarshal(query, &JSONQuery)
-
-	convertedResult, err := service.ConvertQuery(&JSONQuery)
-
-	// Assert that there is no error
-	assert.NoError(t, err)
-
-	// Assert that the result and the expected result are the same
-	correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.city == "San Francisco" RETURN x)LET nodes = first(RETURN UNION_DISTINCT(n0,[],[]))LET edges = first(RETURN UNION_DISTINCT([],[]))RETURN {"vertices":nodes, "edges":edges }`
-	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
-	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
-	assert.Equal(t, correctConvertedResult, cleanedResult)
-}
-
-/*
-Tests a query with double WITH
-	t: *testing.T, makes go recognise this as a test
-*/
-func TestDoubleWITH(t *testing.T) {
-	// Setup for test
-	// Create query conversion service
-	service := NewService()
-
-	query := []byte(`{
-        "databaseName": "test",
-        "return": {
-          "entities": [
-            0,
-            1,
-            2,
-            3
-          ],
-          "relations": [
-            0,
-            1
-          ]
-        },
-        "entities": [
-          {
-            "type": "kamerleden",
-            "constraints": []
-          },
-          {
-            "type": "partijen",
-            "constraints": []
-          }
-          ,
-          {
-            "type": "kamerleden",
-            "constraints": []
-          },
-          {
-            "type": "commissies",
-            "constraints": []
-          }
-        ],
-        "relations": [
-          {
-            "type": "lid_van",
-            "depth": {
-              "min": 1,
-              "max": 1
-            },
-            "entityFrom": 0,
-            "entityTo": 1,
-            "constraints": []
-          },
-          {
-            "type": "onderdeel_van",
-            "depth": {
-              "min": 1,
-              "max": 1
-            },
-            "entityFrom": 2,
-            "entityTo": 3,
-            "constraints": []
-          }
-        ],
-        "limit": 5000,
-        "modifiers": []
-      }`)
+			"relations": [
+				0
+			]
+		},
+		"entities": [
+			{
+				"name": "parliament",
+				"ID": 0,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 1,
+				"constraints": []
+			},
+			{
+				"name": "parliament",
+				"ID": 2,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 3,
+				"constraints": []
+			},
+			{
+				"name": "resolutions",
+				"ID": 4,
+				"constraints": []
+			},
+			{
+				"name": "resolutions",
+				"ID": 5,
+				"constraints": []
+			}
+		],
+		"relations": [
+			{
+				"ID": 0,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 1,
+				"constraints":[]
+			},
+			{
+				"ID": 1,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 2,
+				"toType": "entity",
+				"toID": 3,
+				"constraints":[]
+			},
+			{
+				"ID": 2,
+				"name": "submits",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 4,
+				"constraints":[]
+			},
+			{
+				"ID": 3,
+				"name": "submits",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 2,
+				"toType": "entity",
+				"toID": 5,
+				"constraints":[]
+			}
+		],
+		"groupBys": [],		
+		"limit": 5000,
+		"modifiers": []
+	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
 	var JSONQuery entity.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
-	convertedResult, err := service.ConvertQuery(&JSONQuery)
-
-	// Assert that there is no error
-	assert.NoError(t, err)
+	_, err := service.ConvertQuery(&JSONQuery)
 
-	// Assert that the result and the expected result are the same
-	correctConvertedResult := "WITH partijen, commissiesLET n0 = (FOR x IN kamerleden RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x lid_van OPTIONS { uniqueEdges: \"path\" }LIMIT 5000 RETURN DISTINCT p )LET n2 = (FOR x IN kamerleden RETURN x)LET r1 = (FOR x IN n2 FOR v, e, p IN 1..1 OUTBOUND x onderdeel_van OPTIONS { uniqueEdges: \"path\" }LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), flatten(r1[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), flatten(r1[**].edges), [],[]))RETURN {\"vertices\":nodes, \"edges\":edges }"
-	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
-	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
-	assert.Equal(t, correctConvertedResult, cleanedResult)
+	// Assert that there is an error
+	assert.Equal(t, errors.New("JSONQuery invalid"), err)
 }
 
 /*
-Tests an entity with a lower than -1 in a relation
+Tests two separated chains with unequal relations per chain
 	t: *testing.T, makes go recognise this as a test
 */
-func TestEntityFromLowerThanNegativeOneInRelation(t *testing.T) {
+func TestSeparatedChainUnequalRelationPerChain(t *testing.T) {
 	// Setup for test
 	// Create query conversion service
 	service := NewService()
 
 	query := []byte(`{
-			"return": {
-				"entities": [
-					0
-				],
-				"relations": [
-					0
-				]
-			},
+		"databaseName": "TweedeKamer",
+		"return": {
 			"entities": [
-				{
-					"type": "airports",
-					"constraints": [
-						{
-							"attribute": "city",
-							"value": "San Francisco",
-							"dataType": "string",
-							"matchType": "exact"
-						}
-					]
-				}
+				0,
+				1,
+				2,
+				3,
+				4
 			],
 			"relations": [
-				{
-					"type": "flights",
-					"depth": {
-						"min": 1,
-						"max": 1
-					},
-					"entityFrom": -4,
-					"entityTo": 0,
-					"constraints": []
-				}
-			],
-			"limit": 5000
-		}`)
+				0
+			]
+		},
+		"entities": [
+			{
+				"name": "parliament",
+				"ID": 0,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 1,
+				"constraints": []
+			},
+			{
+				"name": "parliament",
+				"ID": 2,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 3,
+				"constraints": []
+			},
+			{
+				"name": "resolutions",
+				"ID": 4,
+				"constraints": []
+			}
+		],
+		"relations": [
+			{
+				"ID": 0,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 0,
+				"toType": "entity",
+				"toID": 1,
+				"constraints":[]
+			},
+			{
+				"ID": 1,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 2,
+				"toType": "entity",
+				"toID": 3,
+				"constraints":[]
+			},
+			{
+				"ID": 2,
+				"name": "submits",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromID": 2,
+				"toType": "entity",
+				"toID": 4,
+				"constraints":[]
+			}
+		],
+		"groupBys": [],		
+		"limit": 5000,
+		"modifiers": []
+	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
 	var JSONQuery entity.IncomingQueryJSON
@@ -1189,6 +1912,6 @@ func TestEntityFromLowerThanNegativeOneInRelation(t *testing.T) {
 
 	_, err := service.ConvertQuery(&JSONQuery)
 
-	// Assert that there is no error
-	assert.NoError(t, err)
+	// Assert that there is an error
+	assert.Equal(t, errors.New("JSONQuery invalid"), err)
 }
diff --git a/aql/createConstraints.go b/aql/createConstraints.go
index 0a6c8ed08fca24bbe593323320a6b7b505fcb605..0481bd94cbd9cc15935664b45289007c2e343ffb 100644
--- a/aql/createConstraints.go
+++ b/aql/createConstraints.go
@@ -3,7 +3,7 @@ package aql
 import (
 	"fmt"
 
-	"git.science.uu.nl/datastrophe/query-conversion/entity"
+	"git.science.uu.nl/graphpolaris/query-conversion/entity"
 )
 
 /* createConstraintStatements generates the appropriate amount of constraint lines calling createConstraingBoolExpression
diff --git a/aql/debug.test b/aql/debug.test
deleted file mode 100644
index 934cd9a89adf48e864e89ee0528ad2681abfaa01..0000000000000000000000000000000000000000
Binary files a/aql/debug.test and /dev/null differ
diff --git a/aql/hierarchy.go b/aql/hierarchy.go
new file mode 100644
index 0000000000000000000000000000000000000000..83931158035e4f5856f0dc6a1c2cfa2595e5f9e9
--- /dev/null
+++ b/aql/hierarchy.go
@@ -0,0 +1,112 @@
+package aql
+
+import (
+	"git.science.uu.nl/graphpolaris/query-conversion/entity"
+)
+
+// We use consts to define string to prevent typos
+const ENTITYSTRING = "entity"
+const RELATIONSTRING = "relation"
+const GROUPBYSTRING = "groupBy"
+
+var relationdone map[int]bool
+
+func createHierarchy(JSONQuery *entity.IncomingQueryJSON, entityMap map[int]int, relationMap map[int]int) ([]entity.Tree, entity.QueryEntityStruct) {
+	var treeList []entity.Tree
+	relationdone = make(map[int]bool)
+	topNode := getTopNode(JSONQuery)
+	topTreeSelfTriple := getTripleFromNode(JSONQuery, topNode, entityMap, relationMap)
+	topTree := entity.Tree{
+		Self:     topTreeSelfTriple,
+		Parent:   -1,
+		Children: []int{},
+	}
+	treeList = append(treeList, topTree)
+	treeListIndex := len(treeList) - 1
+	treeList = getChildrenFromTree(JSONQuery, treeList, treeListIndex, 0, entityMap)
+	return treeList, topNode
+}
+
+/*
+Get a entity that has only 1 relation attached an return its index
+*/
+func getTopNode(JSONQuery *entity.IncomingQueryJSON) entity.QueryEntityStruct {
+	indexOfNodeToReturn := -1
+	for i, node := range JSONQuery.Entities {
+		connectionCount := 0
+		for _, relation := range JSONQuery.Relations {
+			if (relation.FromType == ENTITYSTRING && relation.FromID == node.ID) || (relation.ToType == ENTITYSTRING && relation.ToID == node.ID) {
+				connectionCount++
+			}
+		}
+		if connectionCount == 1 {
+			indexOfNodeToReturn = i
+			return JSONQuery.Entities[indexOfNodeToReturn]
+		}
+	}
+	return JSONQuery.Entities[indexOfNodeToReturn]
+}
+
+func getTripleFromNode(JSONQuery *entity.IncomingQueryJSON, node entity.QueryEntityStruct, entityMap map[int]int, relationMap map[int]int) entity.Triple {
+	var tripleToReturn entity.Triple
+	for _, relation := range JSONQuery.Relations {
+		// The initial node was our From so we set the Triple accordingly
+		// TODO
+		// If the To is not an entity we might have to do something different
+		if (relation.FromType == ENTITYSTRING && relation.FromID == node.ID) && relation.ToType == ENTITYSTRING {
+			tripleToReturn.FromNode = node
+			tripleToReturn.Rel = relation
+			tripleToReturn.ToNode = JSONQuery.Entities[entityMap[relation.ToID]]
+		} else if (relation.ToType == ENTITYSTRING && relation.ToID == node.ID) && relation.FromType == ENTITYSTRING {
+			tripleToReturn.FromNode = JSONQuery.Entities[entityMap[relation.FromID]]
+			tripleToReturn.Rel = relation
+			tripleToReturn.ToNode = node
+		}
+	}
+	relationdone[relationMap[tripleToReturn.Rel.ID]] = true
+	return tripleToReturn
+}
+
+func getTripleFromRelation(JSONQuery *entity.IncomingQueryJSON, relation entity.QueryRelationStruct, entityMap map[int]int) entity.Triple {
+	var tripleToReturn entity.Triple
+	tripleToReturn.FromNode = JSONQuery.Entities[entityMap[relation.FromID]]
+	tripleToReturn.Rel = relation
+	tripleToReturn.ToNode = JSONQuery.Entities[entityMap[relation.ToID]]
+	return tripleToReturn
+}
+
+func getChildrenFromTree(JSONQuery *entity.IncomingQueryJSON, treeList []entity.Tree, treeListIndex int, parentIndex int, entityMap map[int]int) []entity.Tree {
+	var childRelationTriples []entity.Triple
+	for i, relation := range JSONQuery.Relations {
+		// We found a relation that is not our parent relation so we can check if it matches on of our nodes
+		// If it matches one of the nodes we can add it
+		if _, ok := relationdone[i]; !ok {
+			if relation.FromType == ENTITYSTRING && relation.FromID == treeList[parentIndex].Self.FromNode.ID {
+				triple := getTripleFromRelation(JSONQuery, relation, entityMap)
+				childRelationTriples = append(childRelationTriples, triple)
+				relationdone[i] = true
+			} else if relation.ToType == ENTITYSTRING && relation.ToID == treeList[parentIndex].Self.ToNode.ID {
+				triple := getTripleFromRelation(JSONQuery, relation, entityMap)
+				childRelationTriples = append(childRelationTriples, triple)
+				relationdone[i] = true
+			}
+		}
+	}
+	// We now have all our children, so we can now make those trees and find their children
+	// We can now also add the indices to the list of children from the tree calling this function
+	if len(childRelationTriples) != 0 {
+		for _, triple := range childRelationTriples {
+			childTree := entity.Tree{
+				Self:     triple,
+				Parent:   parentIndex,
+				Children: []int{},
+			}
+			treeList = append(treeList, childTree)
+			// We get the new treeListIndex, which we can now add to the list of children from the tree calling this function
+			treeListIndex = len(treeList) - 1
+			treeList[parentIndex].Children = append(treeList[parentIndex].Children, treeListIndex)
+			treeList = getChildrenFromTree(JSONQuery, treeList, treeListIndex, treeListIndex, entityMap)
+		}
+	}
+	return treeList
+}
diff --git a/aql/hierarchy_test.go b/aql/hierarchy_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..8f8a507d0d594a6fb6835fe9efb6a7250a82b744
--- /dev/null
+++ b/aql/hierarchy_test.go
@@ -0,0 +1,324 @@
+package aql
+
+import (
+	"encoding/json"
+	"fmt"
+	"strings"
+	"testing"
+
+	"git.science.uu.nl/graphpolaris/query-conversion/entity"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestHierarchyBasic(t *testing.T) {
+	// Setup for test
+	// Create query conversion service
+	query := []byte(`{
+		"return": {
+			"entities": [
+				0,
+				1,
+				2,
+				3,
+				4
+			],
+			"relations": [
+				0,
+				1,
+				2,
+				3
+			]
+		},
+		"entities": [
+			{
+				"name": "parliament",
+				"ID": 0,
+				"constraints": [
+					{
+						"attribute": "name",
+						"value": "Geert",
+						"dataType": "string",
+						"matchType": "CONTAINS"
+					}
+				]
+			},
+			{
+				"name": "commissions",
+				"ID": 1,
+				"constraints": []
+			},
+			{
+				"name": "parliament",
+				"ID": 2,
+				"constraints": []
+			},
+			{
+				"name": "parties",
+				"ID": 3,
+				"constraints": [
+					{
+						"attribute": "seats",
+						"value": "10",
+						"dataType": "int",
+						"matchType": "LT"
+					}
+				]
+			},
+			{
+				"name": "resolutions",
+				"ID": 4,
+				"constraints": [
+					{
+						"attribute": "date",
+						"value": "mei",
+						"dataType": "string",
+						"matchType": "CONTAINS"
+					}
+				]
+			}
+		],
+		"groupBys": [],
+		"relations": [
+			{
+				"ID": 0,
+				"name": "part_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromId": 0,
+				"toType": "entity",
+				"toID": 1,
+				"constraints": []
+			},
+			{
+				"ID": 1,
+				"name": "part_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromId": 2,
+				"toType": "entity",
+				"toID": 1,
+				"constraints": []
+			},
+			{
+				"ID": 2,
+				"name": "member_of",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromId": 2,
+				"toType": "entity",
+				"toID": 3,
+				"constraints": []
+			},
+			{
+				"ID": 3,
+				"name": "submits",
+				"depth": {
+					"min": 1,
+					"max": 1
+				},
+				"fromType": "entity",
+				"fromId": 2,
+				"toType": "entity",
+				"toID": 4,
+				"constraints": []
+			}
+		],
+		"limit": 5000
+	}
+	`)
+
+	// Unmarshall the incoming message into an IncomingJSONQuery object
+	var JSONQuery entity.IncomingQueryJSON
+	json.Unmarshal(query, &JSONQuery)
+	// Get the hierarchy and turn it into JSON so we can turn it into strings later
+	entityMap, relationMap, _ := entity.FixIndices(&JSONQuery)
+	treeList, topNode := createHierarchy(&JSONQuery, entityMap, relationMap)
+	jsonTopNode, err := json.Marshal(topNode)
+	if err != nil {
+		fmt.Println("Marshalling went wrong")
+	}
+	jsonTreeList, err := json.Marshal(treeList)
+	if err != nil {
+		fmt.Println("Marshalling went wrong")
+	}
+	// These are the expected (correct) outputs
+	correctTopNode := []byte(`{"ID":0,"Name":"parliament","Constraints":[{"Attribute":"name","Value":"Geert","DataType":"string","MatchType":"CONTAINS","InID":0,"InType":""}]}`)
+	correctTreeList := []byte(`[
+		{
+			"Self": {
+				"FromNode": {
+					"ID": 0,
+					"Name": "parliament",
+					"Constraints": [
+						{
+							"Attribute": "name",
+							"Value": "Geert",
+							"DataType": "string",
+							"MatchType": "CONTAINS",
+							"InID": 0,
+							"InType": ""
+						}
+					]
+				},
+				"Rel": {
+					"ID": 0,
+					"Name": "part_of",
+					"FromType": "entity",
+					"FromID": 0,
+					"ToType": "entity",
+					"ToID": 1,
+					"Depth": {
+						"Min": 1,
+						"Max": 1
+					},
+					"Constraints": []
+				},
+				"ToNode": {
+					"ID": 1,
+					"Name": "commissions",
+					"Constraints": []
+				}
+			},
+			"Parent": -1,
+			"Children": [
+				1
+			]
+		},
+		{
+			"Self": {
+				"FromNode": {
+					"ID": 2,
+					"Name": "parliament",
+					"Constraints": []
+				},
+				"Rel": {
+					"ID": 1,
+					"Name": "part_of",
+					"FromType": "entity",
+					"FromID": 2,
+					"ToType": "entity",
+					"ToID": 1,
+					"Depth": {
+						"Min": 1,
+						"Max": 1
+					},
+					"Constraints": []
+				},
+				"ToNode": {
+					"ID": 1,
+					"Name": "commissions",
+					"Constraints": []
+				}
+			},
+			"Parent": 0,
+			"Children": [
+				2,
+				3
+			]
+		},
+		{
+			"Self": {
+				"FromNode": {
+					"ID": 2,
+					"Name": "parliament",
+					"Constraints": []
+				},
+				"Rel": {
+					"ID": 2,
+					"Name": "member_of",
+					"FromType": "entity",
+					"FromID": 2,
+					"ToType": "entity",
+					"ToID": 3,
+					"Depth": {
+						"Min": 1,
+						"Max": 1
+					},
+					"Constraints": []
+				},
+				"ToNode": {
+					"ID": 3,
+					"Name": "parties",
+					"Constraints": [
+						{
+							"Attribute": "seats",
+							"Value": "10",
+							"DataType": "int",
+							"MatchType": "LT",
+							"InID": 0,
+							"InType": ""
+						}
+					]
+				}
+			},
+			"Parent": 1,
+			"Children": []
+		},
+		{
+			"Self": {
+				"FromNode": {
+					"ID": 2,
+					"Name": "parliament",
+					"Constraints": []
+				},
+				"Rel": {
+					"ID": 3,
+					"Name": "submits",
+					"FromType": "entity",
+					"FromID": 2,
+					"ToType": "entity",
+					"ToID": 4,
+					"Depth": {
+						"Min": 1,
+						"Max": 1
+					},
+					"Constraints": []
+				},
+				"ToNode": {
+					"ID": 4,
+					"Name": "resolutions",
+					"Constraints": [
+						{
+							"Attribute": "date",
+							"Value": "mei",
+							"DataType": "string",
+							"MatchType": "CONTAINS",
+							"InID": 0,
+							"InType": ""
+						}
+					]
+				}
+			},
+			"Parent": 1,
+			"Children": []
+		}
+	]`)
+	// Clean up the input and expected results
+	cleanedTopNode := strings.ReplaceAll(string(jsonTopNode), "\n", "")
+	cleanedTopNode = strings.ReplaceAll(cleanedTopNode, "\t", "")
+	cleanedTopNode = strings.ReplaceAll(cleanedTopNode, " ", "")
+
+	cleanedTreeList := strings.ReplaceAll(string(jsonTreeList), "\n", "")
+	cleanedTreeList = strings.ReplaceAll(cleanedTreeList, "\t", "")
+	cleanedTreeList = strings.ReplaceAll(cleanedTreeList, " ", "")
+
+	cleanedCorrectTopNode := strings.ReplaceAll(string(correctTopNode), "\n", "")
+	cleanedCorrectTopNode = strings.ReplaceAll(cleanedCorrectTopNode, "\t", "")
+	cleanedCorrectTopNode = strings.ReplaceAll(cleanedCorrectTopNode, " ", "")
+
+	cleanedCorrectTreeList := strings.ReplaceAll(string(correctTreeList), "\n", "")
+	cleanedCorrectTreeList = strings.ReplaceAll(cleanedCorrectTreeList, "\t", "")
+	cleanedCorrectTreeList = strings.ReplaceAll(cleanedCorrectTreeList, " ", "")
+
+	assert.Equal(t, cleanedCorrectTopNode, cleanedTopNode)
+	assert.Equal(t, cleanedCorrectTreeList, cleanedTreeList)
+}
diff --git a/aql/mockConvertQuery.go b/aql/mockConvertQuery.go
index 5f82c691a8cc7477ca6faecb09e7c644f684d295..91139b5c0ecc1beef29e76d2648298b6092e2df4 100644
--- a/aql/mockConvertQuery.go
+++ b/aql/mockConvertQuery.go
@@ -8,7 +8,7 @@ package aql
 import (
 	"errors"
 
-	"git.science.uu.nl/datastrophe/query-conversion/entity"
+	"git.science.uu.nl/graphpolaris/query-conversion/entity"
 )
 
 /*
@@ -39,7 +39,7 @@ func (s *MockService) ConvertQuery(JSONQuery *entity.IncomingQueryJSON) (*string
 	if !s.throwError {
 		return &mockQuery, nil
 	}
-	return nil, errors.New("Failed to convert query")
+	return nil, errors.New("failed to convert query")
 }
 
 /*
diff --git a/cypher/convertQuery.go b/cypher/convertQuery.go
index 3a89ec88c6b66c76c5fe716180db9247d8ac8715..0284e58b031d2b64d1f4c1b9bde218b2137a60a7 100644
--- a/cypher/convertQuery.go
+++ b/cypher/convertQuery.go
@@ -10,7 +10,7 @@ import (
 	"fmt"
 	"strings"
 
-	"git.science.uu.nl/datastrophe/query-conversion/entity"
+	"git.science.uu.nl/graphpolaris/query-conversion/entity/entitycypher"
 )
 
 /*
@@ -18,7 +18,7 @@ ConvertQuery converts an IncomingQueryJSON object into AQL
 	JSONQuery: *entity.IncomingQueryJSON, the query to be converted to AQL
 	Returns: (*string, error), the AQL query and a possible error
 */
-func (s *Service) ConvertQuery(JSONQuery *entity.IncomingQueryJSON) (*string, error) {
+func (s *Service) ConvertQuery(JSONQuery *entitycypher.IncomingQueryJSON) (*string, error) {
 
 	// Check to make sure all indexes exist
 	// How many entities are there
@@ -80,7 +80,7 @@ createQuery generates a query based on the json file provided
 	JSONQuery: *entity.IncomingQueryJSON, jsonQuery is a parsedJSON struct holding all the data needed to form a query
 	Return: *string, a string containing the corresponding AQL query and an error
 */
-func createQuery(JSONQuery *entity.IncomingQueryJSON) *string {
+func createQuery(JSONQuery *entitycypher.IncomingQueryJSON) *string {
 	// Note: Case #4, where there is an edge only query (without any entity), is not supported by frontend
 
 	// If a modifier is used, disable the limit
@@ -200,7 +200,7 @@ createNodeLet generates a 'LET' statement for a node related query
 	name: *string, is the autogenerated name of the node consisting of "n" + the index of the node
 	Return: *string, a string containing a single LET-statement in AQL
 */
-func createNodeMatch(node *entity.QueryEntityStruct, name *string) *string {
+func createNodeMatch(node *entitycypher.QueryEntityStruct, name *string) *string {
 	// hier zat een newline
 	header := fmt.Sprintf("MATCH (%v:%v) ", *name, node.Type)
 	constraints := *createConstraintStatements(&node.Constraints, *name)
@@ -218,7 +218,7 @@ createRelationLetWithFromEntity generates a 'LET' statement for relations with a
 	outbound: bool, checks if the relation is inbound or outbound
 	Return: *string, a string containing a single LET-statement in AQL
 */
-func createRelationMatch(relation *entity.QueryRelationStruct, relationName string, pathName string, entities *[]entity.QueryEntityStruct, limit int, outbound bool) *string {
+func createRelationMatch(relation *entitycypher.QueryRelationStruct, relationName string, pathName string, entities *[]entitycypher.QueryEntityStruct, limit int, outbound bool) *string {
 	relationReturn := ""
 	var relationBounds int
 	if outbound {
diff --git a/cypher/convertQueryBenchmark_test.go b/cypher/convertQueryBenchmark_test.go
index 3794ab92a7434af21c8fcc34fb640a6d1d789f3a..5e14480faaab79b77b0813e02ac740dfd266b579 100644
--- a/cypher/convertQueryBenchmark_test.go
+++ b/cypher/convertQueryBenchmark_test.go
@@ -4,7 +4,7 @@ import (
 	"encoding/json"
 	"testing"
 
-	"git.science.uu.nl/datastrophe/query-conversion/entity"
+	"git.science.uu.nl/graphpolaris/query-conversion/entity/entitycypher"
 )
 
 func BenchmarkConvertEmptyQuery(b *testing.B) {
@@ -23,7 +23,7 @@ func BenchmarkConvertEmptyQuery(b *testing.B) {
 	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	b.ResetTimer()
@@ -63,7 +63,7 @@ func BenchmarkConvertOneAttributeQuery(b *testing.B) {
 	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	b.ResetTimer()
@@ -158,7 +158,7 @@ func BenchmarkConvertTwoRelationQuery(b *testing.B) {
 	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	b.ResetTimer()
diff --git a/cypher/convertQuery_test.go b/cypher/convertQuery_test.go
index c07a06556a6e16f92d52ffae50e7de21d0d75a70..fffb0a0da17d9550ea0a71ae6cdd993dc57a10a8 100644
--- a/cypher/convertQuery_test.go
+++ b/cypher/convertQuery_test.go
@@ -6,7 +6,7 @@ import (
 	"strings"
 	"testing"
 
-	"git.science.uu.nl/datastrophe/query-conversion/entity"
+	"git.science.uu.nl/graphpolaris/query-conversion/entity/entitycypher"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -26,7 +26,7 @@ func TestEmptyQueryConversion(t *testing.T) {
 	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	convertedResult, err := service.ConvertQuery(&JSONQuery)
@@ -69,7 +69,7 @@ func TestEntityOneAttributeQuery(t *testing.T) {
 	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	convertedResult, err := service.ConvertQuery(&JSONQuery)
@@ -78,7 +78,7 @@ func TestEntityOneAttributeQuery(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `MATCH (n0:airports)WHERE n0.state = "HI" RETURN n0`
+	correctConvertedResult := `MATCH (n0:airports) WHERE n0.state = "HI" RETURN n0`
 	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
 	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
 	assert.Equal(t, correctConvertedResult, cleanedResult)
@@ -134,7 +134,7 @@ func TestRelationWithConstraint(t *testing.T) {
 	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	convertedResult, err := service.ConvertQuery(&JSONQuery)
@@ -143,7 +143,7 @@ func TestRelationWithConstraint(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `MATCH (n0:airports)WHERE n0.state = "HI" MATCH p0 = (n0)-[r0:flights*1..1]->()WHERE r0.Day = 15 RETURN n0,p0;`
+	correctConvertedResult := `MATCH (n0:airports) WHERE n0.state = "HI" MATCH p0 = (n0)-[r0:flights*1..1]->() WHERE r0.Day = 15 RETURN n0,p0;`
 	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
 	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
 	assert.Equal(t, correctConvertedResult, cleanedResult)
@@ -462,7 +462,7 @@ func TestRelationWithInOutConstraint(t *testing.T) {
 	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	convertedResult, err := service.ConvertQuery(&JSONQuery)
@@ -471,7 +471,7 @@ func TestRelationWithInOutConstraint(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `MATCH (n1:airports)WHERE n1.state = "HI" MATCH p0 = (n1)-[r0:flights*1..3]->(n0)WHERE r0.Day = 15 RETURN n1,n0,p0;`
+	correctConvertedResult := `MATCH (n1:airports) WHERE n1.state = "HI" MATCH p0 = (n1)-[r0:flights*1..3]->(n0) WHERE r0.Day = 15 RETURN n1,n0,p0;`
 	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
 	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
 	assert.Equal(t, correctConvertedResult, cleanedResult)
@@ -562,7 +562,7 @@ func TestTwoRelations(t *testing.T) {
 	}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	convertedResult, err := service.ConvertQuery(&JSONQuery)
@@ -571,7 +571,7 @@ func TestTwoRelations(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `MATCH (n2:airports)WHERE n2.state = "HI" MATCH p0 = (n2)-[r0:flights*1..3]->(n1)WHERE r0.Day = 15 RETURN n2,n1,p0;MATCH (n0:airports)WHERE n0.city = "New York" MATCH p0 = (n0)-[r0:flights*1..1]->()RETURN n0,p0;`
+	correctConvertedResult := `MATCH (n2:airports) WHERE n2.state = "HI" MATCH p0 = (n2)-[r0:flights*1..3]->(n1) WHERE r0.Day = 15 RETURN n2,n1,p0; MATCH (n0:airports) WHERE n0.city = "New York" MATCH p0 = (n0)-[r0:flights*1..1]->() RETURN n0,p0;`
 	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
 	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
 	assert.Equal(t, correctConvertedResult, cleanedResult)
@@ -620,7 +620,7 @@ func TestRelationWithOnlyToNode(t *testing.T) {
 		}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	convertedResult, err := service.ConvertQuery(&JSONQuery)
@@ -629,7 +629,7 @@ func TestRelationWithOnlyToNode(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `MATCH (n0:airports)WHERE n0.city = "San Francisco" MATCH p0 = (n0)-[r0:flights*1..1]->()RETURN n0,p0;`
+	correctConvertedResult := `MATCH (n0:airports) WHERE n0.city = "San Francisco" MATCH p0 = (n0)-[r0:flights*1..1]->() RETURN n0,p0;`
 	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
 	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
 	assert.Equal(t, correctConvertedResult, cleanedResult)
@@ -680,7 +680,7 @@ func TestTooManyReturnEntities(t *testing.T) {
 		}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	_, err := service.ConvertQuery(&JSONQuery)
@@ -734,7 +734,7 @@ func TestTooManyReturnRelations(t *testing.T) {
 		}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	_, err := service.ConvertQuery(&JSONQuery)
@@ -789,7 +789,7 @@ func TestNegativeReturnEntities(t *testing.T) {
 		}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	_, err := service.ConvertQuery(&JSONQuery)
@@ -826,7 +826,7 @@ func TestNoRelationsField(t *testing.T) {
 		}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	convertedResult, err := service.ConvertQuery(&JSONQuery)
@@ -835,7 +835,7 @@ func TestNoRelationsField(t *testing.T) {
 	assert.NoError(t, err)
 
 	// Assert that the result and the expected result are the same
-	correctConvertedResult := `MATCH (n0:airports)WHERE n0.city = "San Francisco" RETURN n0`
+	correctConvertedResult := `MATCH (n0:airports) WHERE n0.city = "San Francisco" RETURN n0`
 	cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "")
 	cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "")
 	assert.Equal(t, correctConvertedResult, cleanedResult)
@@ -884,7 +884,7 @@ func TestEntityFromLowerThanNegativeOneInRelation(t *testing.T) {
 		}`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
+	var JSONQuery entitycypher.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
 
 	_, err := service.ConvertQuery(&JSONQuery)
diff --git a/cypher/createConstraints.go b/cypher/createConstraints.go
index b24d895f7c9afbccd519bc4c6ec3c9fecd89de9a..d88a374f7705c5c322327784a0b41a6c7e7252b3 100644
--- a/cypher/createConstraints.go
+++ b/cypher/createConstraints.go
@@ -3,7 +3,7 @@ package cypher
 import (
 	"fmt"
 
-	"git.science.uu.nl/datastrophe/query-conversion/entity"
+	"git.science.uu.nl/graphpolaris/query-conversion/entity/entitycypher"
 )
 
 /* createConstraintStatements generates the appropriate amount of constraint lines calling createConstraingBoolExpression
@@ -13,7 +13,7 @@ isRelation is a boolean specifying if this constraint comes from a node or relat
 
 Return: a string containing a FILTER-statement with all the constraints
 */
-func createConstraintStatements(constraints *[]entity.QueryConstraintStruct, name string) *string {
+func createConstraintStatements(constraints *[]entitycypher.QueryConstraintStruct, name string) *string {
 	s := ""
 	if len(*constraints) == 0 {
 		return &s
@@ -38,7 +38,7 @@ isRelation is a boolean specifying if this constraint comes from a node or relat
 
 Return: a string containing an boolean expression of a single constraint
 */
-func createConstraintBoolExpression(constraint *entity.QueryConstraintStruct, name string) *string {
+func createConstraintBoolExpression(constraint *entitycypher.QueryConstraintStruct, name string) *string {
 	var (
 		match string
 		value string
diff --git a/entity/entitycypher/queryStructCypher.go b/entity/entitycypher/queryStructCypher.go
new file mode 100644
index 0000000000000000000000000000000000000000..6db12d36a5974731d7bf9a0c4bfe4f457353f5ed
--- /dev/null
+++ b/entity/entitycypher/queryStructCypher.go
@@ -0,0 +1,62 @@
+package entitycypher
+
+// IncomingQueryJSON describes the query coming into the service in JSON format
+type IncomingQueryJSON struct {
+	DatabaseName string
+	Return       QueryReturnStruct
+	Entities     []QueryEntityStruct
+	Relations    []QueryRelationStruct
+	// Limit is for limiting the amount of paths AQL will return in a relation let statement
+	Limit     int
+	Modifiers []QueryModifierStruct
+}
+
+// QueryReturnStruct holds the indices of the entities and relations that need to be returned
+type QueryReturnStruct struct {
+	Entities  []int
+	Relations []int
+	//Modifiers []int
+}
+
+// QueryEntityStruct encapsulates a single entity with its corresponding constraints
+type QueryEntityStruct struct {
+	Type        string
+	Constraints []QueryConstraintStruct
+}
+
+// QueryRelationStruct encapsulates a single relation with its corresponding constraints
+type QueryRelationStruct struct {
+	Type        string
+	EntityFrom  int
+	EntityTo    int
+	Depth       QuerySearchDepthStruct
+	Constraints []QueryConstraintStruct
+}
+
+// QueryModifierStruct encapsulates a single modifier with its corresponding constraints
+type QueryModifierStruct struct {
+	Type           string // SUM COUNT AVG
+	SelectedType   string // node relation
+	SelectedTypeID int    // ID of the enitity or relation
+	AttributeIndex int    // = -1 if its the node or relation, = > -1 if an attribute is selected
+	InType         string
+	InID           int
+}
+
+// QuerySearchDepthStruct holds the range of traversals for the relation
+type QuerySearchDepthStruct struct {
+	Min int
+	Max int
+}
+
+// QueryConstraintStruct holds the information of the constraint
+// Constraint datatypes
+// 	string     MatchTypes: exact/contains/startswith/endswith
+// 	int   MatchTypes: GT/LT/EQ
+// 	bool     MatchTypes: EQ/NEQ
+type QueryConstraintStruct struct {
+	Attribute string
+	Value     string
+	DataType  string
+	MatchType string
+}
diff --git a/entity/fixIndices.go b/entity/fixIndices.go
new file mode 100644
index 0000000000000000000000000000000000000000..dc97192c46105a0b415fa8775aec60f2c3407049
--- /dev/null
+++ b/entity/fixIndices.go
@@ -0,0 +1,20 @@
+package entity
+
+/*
+A function that maps pill IDs to a range of 0..x
+*/
+func FixIndices(JSONQuery *IncomingQueryJSON) (map[int]int, map[int]int, map[int]int) {
+	entityMap := make(map[int]int)
+	for i, e := range JSONQuery.Entities {
+		entityMap[e.ID] = i
+	}
+	relationMap := make(map[int]int)
+	for i, r := range JSONQuery.Relations {
+		relationMap[r.ID] = i
+	}
+	groupByMap := make(map[int]int)
+	for i, g := range JSONQuery.GroupBys {
+		groupByMap[g.ID] = i
+	}
+	return entityMap, relationMap, groupByMap
+}
diff --git a/entity/hierarchyStruct.go b/entity/hierarchyStruct.go
new file mode 100644
index 0000000000000000000000000000000000000000..fe86cdbdb07f2426b1e76cd117cbd430fbbc1b76
--- /dev/null
+++ b/entity/hierarchyStruct.go
@@ -0,0 +1,38 @@
+package entity
+
+type PdictList []Pdict
+
+type Pdict struct {
+	Typename string
+	Pointer  int
+}
+
+type Triple struct {
+	FromNode QueryEntityStruct
+	Rel      QueryRelationStruct
+	ToNode   QueryEntityStruct
+}
+
+type Tree struct {
+	Self     Triple
+	Parent   int
+	Children []int
+}
+
+func (p PdictList) Len() int {
+	return len(p)
+}
+
+func (p PdictList) Less(i, j int) bool {
+	if p[i].Typename < p[j].Typename {
+		return true
+	} else if p[i].Typename == p[j].Typename && p[i].Pointer < p[j].Pointer {
+		return true
+	} else {
+		return false
+	}
+}
+
+func (p PdictList) Swap(i, j int) {
+	p[i], p[j] = p[j], p[i]
+}
diff --git a/entity/queryStruct.go b/entity/queryStruct.go
index 7b6c2760ac2ad7c0b1a002c516559011a85cdd5d..b74e4f5ae8cba801aea1fa33d9b0a510400dfaee 100644
--- a/entity/queryStruct.go
+++ b/entity/queryStruct.go
@@ -2,10 +2,12 @@ package entity
 
 // IncomingQueryJSON describes the query coming into the service in JSON format
 type IncomingQueryJSON struct {
-	DatabaseName string
-	Return       QueryReturnStruct
-	Entities     []QueryEntityStruct
-	Relations    []QueryRelationStruct
+	DatabaseName    string
+	Return          QueryReturnStruct
+	Entities        []QueryEntityStruct
+	Relations       []QueryRelationStruct
+	GroupBys        []QueryGroupByStruct
+	MachineLearning []QueryMLStruct
 	// Limit is for limiting the amount of paths AQL will return in a relation let statement
 	Limit     int
 	Modifiers []QueryModifierStruct
@@ -15,36 +17,40 @@ type IncomingQueryJSON struct {
 type QueryReturnStruct struct {
 	Entities  []int
 	Relations []int
+	GroupBys  []int
 	//Modifiers []int
 }
 
 // QueryEntityStruct encapsulates a single entity with its corresponding constraints
 type QueryEntityStruct struct {
-	Type        string
+	ID          int
+	Name        string
 	Constraints []QueryConstraintStruct
 }
 
 // QueryRelationStruct encapsulates a single relation with its corresponding constraints
 type QueryRelationStruct struct {
-	Type        string
-	EntityFrom  int
-	EntityTo    int
+	ID          int
+	Name        string
+	FromType    string
+	FromID      int
+	ToType      string
+	ToID        int
 	Depth       QuerySearchDepthStruct
 	Constraints []QueryConstraintStruct
 }
 
-// QueryModifierStruct encapsulates a single modifier with its corresponding constraints
-type QueryModifierStruct struct {
-	Type           string // SUM COUNT AVG
-	SelectedType   string // node relation
-	SelectedTypeID int    // ID of the enitity or relation
-	AttributeIndex int    // = -1 if its the node or relation, = > -1 if an attribute is selected
-}
-
-// QuerySearchDepthStruct holds the range of traversals for the relation
-type QuerySearchDepthStruct struct {
-	Min int
-	Max int
+type QueryGroupByStruct struct {
+	ID              int
+	GroupType       string
+	GroupID         int
+	GroupAttribute  string
+	ByType          string
+	ByID            int
+	ByAttribute     string
+	AppliedModifier string
+	RelationID      int
+	Constraints     []QueryConstraintStruct
 }
 
 // QueryConstraintStruct holds the information of the constraint
@@ -57,4 +63,25 @@ type QueryConstraintStruct struct {
 	Value     string
 	DataType  string
 	MatchType string
+	InID      int
+	InType    string
+}
+
+type QueryMLStruct struct {
+	Queuename  string
+	Parameters []string
+}
+
+// QueryModifierStruct encapsulates a single modifier with its corresponding constraints
+type QueryModifierStruct struct {
+	Type           string // SUM COUNT AVG
+	SelectedType   string // entity relation
+	SelectedTypeID int    // ID of the enitity or relation
+	AttributeIndex int    // = -1 if its the node or relation, = > -1 if an attribute is selected
+}
+
+// QuerySearchDepthStruct holds the range of traversals for the relation
+type QuerySearchDepthStruct struct {
+	Min int
+	Max int
 }
diff --git a/entity/queryStructValidator.go b/entity/queryStructValidator.go
new file mode 100644
index 0000000000000000000000000000000000000000..d25f2d8bc9713fb370c70e611b29c34e741ece09
--- /dev/null
+++ b/entity/queryStructValidator.go
@@ -0,0 +1,167 @@
+package entity
+
+import (
+	"errors"
+)
+
+const ENTITYSTRING = "entity"
+const RELATIONSTRING = "relation"
+const GROUPBYSTRING = "groupBy"
+
+/*
+sliceContains checks if a slice contains the input
+	JSONQuery: IncomingQueryJSON, the query in JSON to be validated
+	Return: []error, a list of specific transgression in this specific JSON query'
+*/
+func ValidateStruct(JSONQuery IncomingQueryJSON) []error {
+	ret := make([]error, 0)
+	minEntityID, maxEntityID := getMinAndMaxEntityID(JSONQuery.Entities)
+	minRelationID, maxRelationID := getMinAndMaxRelationID(JSONQuery.Relations)
+	minGroupByID, maxGroupByID := getMinAndMaxGroupByID(JSONQuery.GroupBys)
+	ret = append(ret, getIllegalToFromInRelation(JSONQuery, minEntityID, maxEntityID, minGroupByID, maxGroupByID)...)
+	if len(JSONQuery.GroupBys) != 0 {
+		ret = append(ret, getIllegalToFromInGroupBy(JSONQuery, minEntityID, maxEntityID, minRelationID, maxRelationID)...)
+	}
+	if len(ret) == 0 {
+		ret = append(ret, separatedChainExists(JSONQuery)...)
+	}
+
+	return ret
+}
+
+func getIllegalToFromInRelation(JSONQuery IncomingQueryJSON, minEntityID int, maxEntityID int, minGroupByID int, maxGroupByID int) []error {
+	ret := make([]error, 0)
+	for _, rel := range JSONQuery.Relations {
+		toEntityValid := relationToValid(rel, ENTITYSTRING, minEntityID, maxEntityID)
+		toGroupByValid := relationToValid(rel, GROUPBYSTRING, minGroupByID, maxGroupByID)
+		fromEntityValid := relationFromValid(rel, ENTITYSTRING, minEntityID, maxEntityID)
+		fromGroupByValid := relationFromValid(rel, GROUPBYSTRING, minGroupByID, maxGroupByID)
+		if !(toEntityValid || toGroupByValid) {
+			err := errors.New("relation has invalid TO type and/or ID")
+			ret = append(ret, err)
+		}
+		if !(fromEntityValid || fromGroupByValid) {
+			err := errors.New("relation has invalid FROM type and/or ID")
+			ret = append(ret, err)
+		}
+	}
+	return ret
+}
+
+func getIllegalToFromInGroupBy(JSONQuery IncomingQueryJSON, minEntityID int, maxEntityID int, minRelationID int, maxRelationID int) []error {
+	ret := make([]error, 0)
+	for _, groupBy := range JSONQuery.GroupBys {
+		groupEntityValid := groupByGroupValid(groupBy, ENTITYSTRING, minEntityID, maxEntityID)
+		groupRelationValid := groupByGroupValid(groupBy, RELATIONSTRING, minRelationID, maxRelationID)
+		byEntityValid := groupByByValid(groupBy, ENTITYSTRING, minEntityID, maxEntityID)
+		byRelationValid := groupByByValid(groupBy, RELATIONSTRING, minRelationID, maxRelationID)
+		if !(groupEntityValid || groupRelationValid) {
+			err := errors.New("relation has invalid TO type and/or ID")
+			ret = append(ret, err)
+		}
+		if !(byEntityValid || byRelationValid) {
+			err := errors.New("relation has invalid FROM type and/or ID")
+			ret = append(ret, err)
+		}
+	}
+	return ret
+}
+
+/*
+Checks if a relation.ToType and relation.ToID are valid
+	Return: bool, whether the ToType and ToID are valid
+*/
+func relationToValid(rel QueryRelationStruct, typeString string, minID int, maxID int) bool {
+	if rel.ToType == typeString && rel.ToID >= minID && rel.ToID <= maxID {
+		return true
+	}
+	return false
+}
+
+/*
+Checks if a relation.FromType and relation.FromID are valid
+	Return: bool, whether the FromType and FromID are valid
+*/
+func relationFromValid(rel QueryRelationStruct, typeString string, minID int, maxID int) bool {
+	if rel.FromType == typeString && rel.FromID >= minID && rel.FromID <= maxID {
+		return true
+	}
+	return false
+}
+
+func groupByGroupValid(groupBy QueryGroupByStruct, typeString string, minID int, maxID int) bool {
+	if groupBy.GroupType == typeString && groupBy.GroupID >= minID && groupBy.GroupID <= maxID {
+		return true
+	}
+	return false
+}
+
+func groupByByValid(groupBy QueryGroupByStruct, typeString string, minID int, maxID int) bool {
+	if groupBy.ByType == typeString && groupBy.ByID >= minID && groupBy.ByID <= maxID {
+		return true
+	}
+	return false
+}
+
+func getMinAndMaxEntityID(entities []QueryEntityStruct) (int, int) {
+	min := 65535
+	max := -65535
+	for _, e := range entities {
+		if e.ID < min {
+			min = e.ID
+		}
+		if e.ID > max {
+			max = e.ID
+		}
+	}
+	// If the min/max values didn't change the query would be invalid, and all consequent validationsteps will fail
+	return min, max
+}
+
+func getMinAndMaxRelationID(relations []QueryRelationStruct) (int, int) {
+	min := 65535
+	max := -65535
+	for _, e := range relations {
+		if e.ID < min {
+			min = e.ID
+		}
+		if e.ID > max {
+			max = e.ID
+		}
+	}
+	// If the min/max values didn't change the query would be invalid, and all consequent validationsteps will fail
+
+	return min, max
+}
+
+func getMinAndMaxGroupByID(groupBys []QueryGroupByStruct) (int, int) {
+	min := 65535
+	max := -65535
+	for _, e := range groupBys {
+		if e.ID < min {
+			min = e.ID
+		}
+		if e.ID > max {
+			max = e.ID
+		}
+	}
+	// If the min/max values didn't change the query would be invalid, and all consequent validationsteps will fail
+
+	return min, max
+}
+
+// Get chains that are not connected to the main chain
+func separatedChainExists(JSONQuery IncomingQueryJSON) []error {
+	ret := make([]error, 0)
+	entityCount := len(JSONQuery.Entities)
+	relationCount := len(JSONQuery.Relations)
+	// A relation always has 2 entities if it's on its own
+	// If there is a chain (e-r-e-r-e) then there will be one more entity than relation
+	// If there is two seperate chains you will always end up adding at least 2 entities more than relations
+	// (e-r-e-r-e) and (e-r-e) has 3 relations but 5 entities, thus we know they are separate
+	if relationCount != entityCount-1 {
+		err := errors.New("separated chain found")
+		ret = append(ret, err)
+	}
+	return ret
+}
diff --git a/go.mod b/go.mod
index 928390fa583a1088a3fb71b1c6010eeb7bbcce37..affb71a91296de6da4964e8a97049d3012de5d1f 100644
--- a/go.mod
+++ b/go.mod
@@ -1,4 +1,4 @@
-module git.science.uu.nl/datastrophe/query-conversion
+module git.science.uu.nl/graphpolaris/query-conversion
 
 go 1.16
 
diff --git a/interface.go b/interface.go
index 3010a43207c4b0e676295e2cb7ac6bcec46a8512..e4a7500893ff7c9b4b18f260574eba79ec5e23d7 100644
--- a/interface.go
+++ b/interface.go
@@ -1,8 +1,14 @@
 package query
 
-import "git.science.uu.nl/datastrophe/query-conversion/entity"
+import (
+	"git.science.uu.nl/graphpolaris/query-conversion/entity"
+	"git.science.uu.nl/graphpolaris/query-conversion/entity/entitycypher"
+)
 
 // A Converter converts an incoming message in our JSON format to a format like AQL or Cypher
 type Converter interface {
 	ConvertQuery(JSONQuery *entity.IncomingQueryJSON) (*string, error)
 }
+type CypherConverterPlaceholder interface {
+	ConvertQuery(JSONQuery *entitycypher.IncomingQueryJSON) (*string, error)
+}
diff --git a/main/main.go b/main/main.go
index 204395ac15bd59e116505e1e9185e193bee4f0f0..18a0f921aa06e4b0db2a9a4abf60d37bdf40bd4f 100644
--- a/main/main.go
+++ b/main/main.go
@@ -7,10 +7,12 @@ package main
 
 import (
 	"encoding/json"
+	"io/ioutil"
 	"log"
+	"os"
 
-	"git.science.uu.nl/datastrophe/query-conversion/aql"
-	"git.science.uu.nl/datastrophe/query-conversion/entity"
+	"git.science.uu.nl/graphpolaris/query-conversion/aql"
+	"git.science.uu.nl/graphpolaris/query-conversion/entity"
 )
 
 /*
@@ -18,66 +20,16 @@ The main function that calls the appropriate functions
 */
 func main() {
 	queryservice := aql.NewService()
-
-	js := []byte(`{
-        "databaseName": "test",
-        "return": {
-          "entities": [
-            0,
-            1,
-            2,
-            3
-          ],
-          "relations": [
-            0,
-            1
-          ]
-        },
-        "entities": [
-          {
-            "type": "kamerleden",
-            "constraints": []
-          },
-          {
-            "type": "partijen",
-            "constraints": []
-          }
-          ,
-          {
-            "type": "kamerleden",
-            "constraints": []
-          },
-          {
-            "type": "commissies",
-            "constraints": []
-          }
-        ],
-        "relations": [
-          {
-            "type": "lid_van",
-            "depth": {
-              "min": 1,
-              "max": 1
-            },
-            "entityFrom": 0,
-            "entityTo": 1,
-            "constraints": []
-          },
-          {
-            "type": "onderdeel_van",
-            "depth": {
-              "min": 1,
-              "max": 1
-            },
-            "entityFrom": 2,
-            "entityTo": 3,
-            "constraints": []
-          }
-        ],
-        "limit": 5000,
-        "modifiers": []
-      }`)
-
+	jsonFile, err := os.Open("../realtest.json")
+	// if we os.Open returns an error then handle it
+	if err != nil {
+		log.Println(err)
+	}
+	log.Println("Successfully Opened users.json")
+	// defer the closing of our jsonFile so that we can parse it later on
+	defer jsonFile.Close()
+	js, _ := ioutil.ReadAll(jsonFile)
+	log.Println(string(js))
 	var inc entity.IncomingQueryJSON
 	json.Unmarshal(js, &inc)
 	result, _ := queryservice.ConvertQuery(&inc)
diff --git a/main/node_modules/.yarn-integrity b/main/node_modules/.yarn-integrity
deleted file mode 100644
index 1a3aded6105fb67caa747e15081dd1543f4cb74b..0000000000000000000000000000000000000000
--- a/main/node_modules/.yarn-integrity
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "systemParams": "win32-x64-72",
-  "modulesFolders": [],
-  "flags": [],
-  "linkedModules": [],
-  "topLevelPatterns": [],
-  "lockfileEntries": {},
-  "files": [],
-  "artifacts": {}
-}
\ No newline at end of file
diff --git a/main/yarn.lock b/main/yarn.lock
deleted file mode 100644
index fb57ccd13afbd082ad82051c2ffebef4840661ec..0000000000000000000000000000000000000000
--- a/main/yarn.lock
+++ /dev/null
@@ -1,4 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
diff --git a/realtest.json b/realtest.json
new file mode 100644
index 0000000000000000000000000000000000000000..dbfd1cbc78a079835f78b6aedb58899a94bc23b3
--- /dev/null
+++ b/realtest.json
@@ -0,0 +1,42 @@
+{
+    "databaseName": "TweedeKamer",
+    "return": {
+        "entities": [
+            0,
+            1
+        ],
+        "relations": [
+            0
+        ]
+    },
+    "entities": [
+        {
+            "name": "parliament",
+            "ID": 0,
+            "constraints": []
+        },
+        {
+            "name": "parties",
+            "ID": 1,
+            "constraints": []
+        }
+    ],
+    "relations": [
+        {
+            "ID": 0,
+            "name": "member_of",
+            "depth": {
+                "min": 1,
+                "max": 1
+            },
+            "fromType": "entity",
+            "fromID": 0,
+            "toType": "entity",
+            "toID": -4,
+            "constraints":[]
+        }
+    ],
+    "groupBys": [],		
+    "limit": 5000,
+    "modifiers": []
+}
\ No newline at end of file
diff --git a/test.json b/test.json
new file mode 100644
index 0000000000000000000000000000000000000000..a0a8ca6f562045486b8c4fcbd34dc5f1c63c2969
--- /dev/null
+++ b/test.json
@@ -0,0 +1,84 @@
+{
+    "return": {
+        "entities": [
+            0,
+            1,
+            2
+        ],
+        "relations": [
+            0,
+            1
+        ]
+    },
+    "entities": [
+        {
+            "ID": 0,
+            "name": "parliament"
+        },
+        {
+            "ID": 1,
+            "name": "commissions"
+        },
+        {
+            "ID": 2,
+            "name": "parliament"
+        }
+    ],
+    "relations": [
+        {
+            "ID": 0,
+            "name": "part_of",
+            "depth": {
+                "min": 1,
+                "max": 1
+            },
+            "fromType": "entity",
+            "fromId": 0,
+            "toType": "entity",
+            "toID": 1
+        },
+        {
+            "ID": 1,
+            "name": "part_of",
+            "depth": {
+                "min": 1,
+                "max": 1
+            },
+            "fromType": "entity",
+            "fromID": 2,
+            "toType": "groupBy",
+            "toID": 0
+        }
+    ],
+    "groupBys": [
+        {
+            "ID": 0,
+            "groupType": "entity",
+            "groupID": 0,
+            "groupAttribute": "age",
+            "byType": "entity",
+            "byID": 1,
+            "byAttribute": "name",
+            "appliedModifier": "AVG",
+            "relationID": 0
+        }
+    ],
+    "filters": [
+        {
+            "ID": 0,
+            "fromType": "groupBy",
+            "fromID": 0,
+            "toType": "relation",
+            "toID": 1,
+            "attribute": "age",
+            "value": "42",
+            "dataType": "number",
+            "matchType": "LT",
+            "inType": "",
+            "inID": 0
+        }
+    ],
+    "limit": 5000,
+    "modifiers": [],
+    "databaseName": "TweedeKamer"
+}
\ No newline at end of file
diff --git a/test2.json b/test2.json
new file mode 100644
index 0000000000000000000000000000000000000000..48e9051faf3177dbabcac610eb59bdb9c7275322
--- /dev/null
+++ b/test2.json
@@ -0,0 +1,58 @@
+{
+    "return": {
+        "entities": [
+            0,
+            1,
+            2
+        ],
+        "relations": [
+            0,
+            1
+        ]
+    },
+    "entities": [
+        {
+            "ID": 0,
+            "name": "parties"
+        },
+        {
+            "ID": 1,
+            "name": "parliament"
+        },
+        {
+            "ID": 2,
+            "name": "commissions"
+        }
+    ],
+    "relations": [
+        {
+            "ID": 0,
+            "name": "member_of",
+            "depth": {
+                "min": 1,
+                "max": 1
+            },
+            "fromType": "entity",
+            "fromID": 1,
+            "toType": "entity",
+            "toID": 0
+        },
+        {
+            "ID": 1,
+            "name": "part_of",
+            "depth": {
+                "min": 1,
+                "max": 1
+            },
+            "fromType": "entity",
+            "fromID": 1,
+            "toType": "entity",
+            "toID": 2
+        }
+    ],
+    "groupBys": [],
+    "filters": [],
+    "limit": 5000,
+    "modifiers": [],
+    "databaseName": "Tweede Kamer Dataset"
+}
\ No newline at end of file
diff --git a/test3.json b/test3.json
new file mode 100644
index 0000000000000000000000000000000000000000..93861fb8dff85a84dbfaeb3c02ef1de0410e29b4
--- /dev/null
+++ b/test3.json
@@ -0,0 +1,67 @@
+{
+    "return": {
+        "entities": [
+            0,
+            1
+        ],
+        "relations": [
+            0
+        ]
+    },
+    "entities": [
+        {
+            "ID": 0,
+            "name": "parliament"
+        },
+        {
+            "ID": 1,
+            "name": "parties"
+        }
+    ],
+    "relations": [
+        {
+            "ID": 0,
+            "name": "member_of",
+            "depth": {
+                "min": 1,
+                "max": 1
+            },
+            "fromType": "entity",
+            "fromID": 0,
+            "toType": "entity",
+            "toID": 1
+        }
+    ],
+    "groupBys": [],
+    "filters": [
+        {
+            "ID": 0,
+            "fromType": "entity",
+            "fromID": 0,
+            "toType": "filter",
+            "toID": 1,
+            "attribute": "age",
+            "value": "40",
+            "dataType": "number",
+            "matchType": "GT",
+            "inType": "",
+            "inID": 0
+        },
+        {
+            "ID": 1,
+            "fromType": "filter",
+            "fromID": 0,
+            "toType": "relation",
+            "toID": 0,
+            "attribute": "seniority",
+            "value": "3000",
+            "dataType": "number",
+            "matchType": "GT",
+            "inType": "",
+            "inID": 0
+        }
+    ],
+    "limit": 5000,
+    "modifiers": [],
+    "databaseName": "Tweede Kamer Dataset"
+}
\ No newline at end of file
diff --git a/unmarshalJSON.go b/unmarshalJSON.go
index 0cac26fd2b8ccd58672e491338654ad54f0cb9a2..3be9df409acd5bcb5f56ba21c3a8dd5510f05ab4 100644
--- a/unmarshalJSON.go
+++ b/unmarshalJSON.go
@@ -3,7 +3,7 @@ package query
 import (
 	"encoding/json"
 
-	"git.science.uu.nl/datastrophe/query-conversion/entity"
+	"git.science.uu.nl/graphpolaris/query-conversion/entity"
 )
 
 /*