diff --git a/termmapper.go b/termmapper.go
new file mode 100644
index 0000000..b2d41fe
--- /dev/null
+++ b/termmapper.go
@@ -0,0 +1,454 @@
+package termmapper
+
+/*
+$(	=>	PUNCT	PunctType=Brck	``, '', *RRB*, *LRB*, -
+$,	=>	PUNCT	PunctType=Comm	,
+$.	=>	PUNCT	PunctType=Peri	., :, ?, ;, !
+ADJA	=>	ADJ	_	neuen, neue, deutschen, ersten, anderen
+ADJD	=>	ADJ	Variant=Short	gut, rund, knapp, deutlich, möglich
+ADV	=>	ADV	_	auch, nur, noch, so, aber
+APPO	=>	ADP	AdpType=Post	zufolge, nach, gegenüber, wegen, über
+APPR	=>	ADP	AdpType=Prep	in, von, mit, für, auf
+APPRART	=>	ADP	AdpType=Prep|PronType=Art	im, am, zum, zur, vom
+APZR	=>	ADP	AdpType=Circ	an, hinaus, aus, her, heraus
+ART	=>	DET	PronType=Art	der, die, den, des, das
+CARD	=>	NUM	NumType=Card	000, zwei, drei, vier, fünf
+FM	=>	X	Foreign=Yes	New, of, de, Times, the
+ITJ	=>	INTJ	_	naja, Ach, äh, Na, piep
+KOKOM	=>	CCONJ	ConjType=Comp	als, wie, denn, wir
+KON	=>	CCONJ	_	und, oder, sondern, sowie, aber
+KOUI	=>	SCONJ	_	um, ohne, statt, anstatt, Ums
+KOUS	=>	SCONJ	_	daß, wenn, weil, ob, als
+NE	=>	PROPN	_	SPD, Deutschland, USA, dpa, Bonn
+NN	=>	NOUN	_	Prozent, Mark, Millionen, November, Jahren
+PAV	=>	ADV	PronType=Dem
+PDAT	=>	DET	PronType=Dem	dieser, diese, diesem, dieses, diesen
+PDS	=>	PRON	PronType=Dem	das, dies, die, diese, der
+PIAT	=>	DET	PronType=Ind,Neg,Tot	keine, mehr, alle, kein, beiden
+PIDAT	=>	DET	AdjType=Pdt|PronType=Ind,Neg,Tot
+PIS	=>	PRON	PronType=Ind,Neg,Tot	man, allem, nichts, alles, mehr
+PPER	=>	PRON	PronType=Prs	es, sie, er, wir, ich
+PPOSAT	=>	DET	Poss=Yes|PronType=Prs	ihre, seine, seiner, ihrer, ihren
+PPOSS	=>	PRON	Poss=Yes|PronType=Prs	ihren, Seinen, seinem, unsrigen, meiner
+PRELAT	=>	DET	PronType=Rel	deren, dessen, die
+PRELS	=>	PRON	PronType=Rel	die, der, das, dem, denen
+PRF	=>	PRON	PronType=Prs|Reflex=Yes	sich, uns, mich, mir, dich
+PTKA	=>	PART	_	zu, am, allzu, Um
+PTKANT	=>	PART	PartType=Res	nein, ja, bitte, Gewiß, Also
+PTKNEG	=>	PART	Polarity=Neg	nicht
+PTKVZ	=>	ADP	PartType=Vbp	an, aus, ab, vor, auf
+PTKZU	=>	PART	PartType=Inf	zu, zur, zum
+PWAT	=>	DET	PronType=Int	welche, welchen, welcher, wie, welchem
+PWAV	=>	ADV	PronType=Int	wie, wo, warum, wobei, wonach
+PWS	=>	PRON	PronType=Int	was, wer, wem, wen, welches
+TRUNC	=>	X	Hyph=Yes	Staats-, Industrie-, Finanz-, Öl-, Lohn-
+VAFIN	=>	AUX	Mood=Ind|VerbForm=Fin	ist, hat, wird, sind, sei
+VAIMP	=>	AUX	Mood=Imp|VerbForm=Fin	Seid, werde, Sei
+VAINF	=>	AUX	VerbForm=Inf	werden, sein, haben, worden, Dabeisein
+VAPP	=>	AUX	Aspect=Perf|VerbForm=Part	worden, gewesen, geworden, gehabt, werden
+VMFIN	=>	VERB	Mood=Ind|VerbForm=Fin|VerbType=Mod	kann, soll, will, muß, sollen
+VMINF	=>	VERB	VerbForm=Inf|VerbType=Mod	können, müssen, wollen, dürfen, sollen
+VMPP	=>	VERB	Aspect=Perf|VerbForm=Part|VerbType=Mod	gewollt
+VVFIN	=>	VERB	Mood=Ind|VerbForm=Fin	sagte, gibt, geht, steht, kommt
+VVIMP	=>	VERB	Mood=Imp|VerbForm=Fin	siehe, sprich, schauen, Sagen, gestehe
+VVINF	=>	VERB	VerbForm=Inf	machen, lassen, bleiben, geben, bringen
+VVIZU	=>	VERB	VerbForm=Inf	einzusetzen, durchzusetzen, aufzunehmen, abzubauen, umzusetzen
+VVPP	=>	VERB	Aspect=Perf|VerbForm=Part	gemacht, getötet, gefordert, gegeben, gestellt
+XY	=>	X	_	dpa, ap, afp, rtr, wb
+*/
+
+import (
+	"strconv"
+	"strings"
+
+	"github.com/rs/zerolog/log"
+	"github.com/tidwall/gjson"
+	"github.com/tidwall/sjson"
+)
+
+/*
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"strings"
+)
+
+var mapping = map[string]string{
+	"$(":"PUNCT",
+}
+
+// Recursive function to turn the UPos query into a STTS query
+func koralRewriteUpos2Stts(koralquery interface{}) interface{} {
+	switch v := koralquery.(type) {
+	case map[string]interface{}:
+		// Check for '@type' key and act accordingly
+		if typ, ok := v["@type"].(string); ok {
+			switch typ {
+			case "koral:term":
+
+        // Modify the key to use STTS
+// This may require to turn object into a koral:token with terms like:
+
+
+				if key, ok := v["key"].(string); ok {
+					v["key"] = "hallo-" + key
+				}
+			case "operation":
+				// Handle the 'operators' key by recursively modifying each operator
+				if operators, ok := v["operators"].([]interface{}); ok {
+					for i, operator := range operators {
+						operators[i] = modifyJSON(operator)
+					}
+					v["operators"] = operators
+				}
+			}
+		}
+		// Recursively modify any nested maps
+		for k, val := range v {
+			v[k] = modifyJSON(val)
+		}
+		return v
+	case []interface{}:
+		// Recursively modify elements of arrays
+		for i, item := range v {
+			v[i] = modifyJSON(item)
+		}
+		return v
+	}
+	return koralquery
+}
+
+func main() {
+	// Sample JSON input string
+	jsonStr := `{
+		"@type": "operation",
+		"operators": [
+			{
+				"@type": "term",
+				"key": "example1"
+			},
+			{
+				"@type": "term",
+				"key": "example2"
+			},
+			{
+				"@type": "operation",
+				"operators": [
+					{
+						"@type": "term",
+						"key": "nested"
+					}
+				]
+			}
+		]
+	}`
+
+	// Parse the JSON string into a generic interface{}
+	var data interface{}
+	err := json.Unmarshal([]byte(jsonStr), &data)
+	if err != nil {
+		log.Fatal("Error unmarshaling JSON:", err)
+	}
+
+	// Modify the JSON structure recursively
+	modifiedData := modifyJSON(data)
+
+	// Marshal the modified data back into a JSON string
+	modifiedJSON, err := json.MarshalIndent(modifiedData, "", "  ")
+	if err != nil {
+		log.Fatal("Error marshaling JSON:", err)
+	}
+
+	// Output the modified JSON string
+	fmt.Println(string(modifiedJSON))
+}
+
+
+
+func turnupostostts(json string, targetFoundry string, targetLayer string) {
+	if targetLayer == "" {
+		targetLayer = "p"
+	}
+
+  ldType := "@type"
+
+  if ldType == "koral:span" {
+    next
+  }
+  if ldType == "koral:term"  {
+      if foundry == if layer === key -> rewrite
+  }
+
+	// Iterate through the query and whenever a term is requested without a foundry, and without a layser or layer p,
+  // change the key following the mapping
+
+
+}
+
+func addupostooutput(json string, reffoundry string, foundry string) {
+	// https://universaldependencies.org/tagset-conversion/de-stts-uposf.html
+	// Iterate through all matches and add to all xml snippets a line of foundry
+
+}
+
+*/
+
+func Hui() string {
+	return "test"
+}
+
+func Map2(json []byte) string {
+	/*
+		result := gjson.GetBytes(json, "query")
+		var raw []byte
+		if result.Index > 0 {
+			raw = json[result.Index:result.Index+len(result.Raw)]
+		} else {
+			raw = []byte(result.Raw)
+		}
+
+		if result.IsObject() {
+			koralType := gjson.GetBytes(raw, "@type").String()
+			switch koralType {
+				case "koral:term":
+
+			}
+		}
+	*/
+
+	koralObj := gjson.ParseBytes(json)
+
+	switch koralObj.Get("@type").String() {
+	case "koral:term":
+		{
+			if koralObj.Get("value").String() == "KOKOM" {
+				// TODO: Turn this in a token, if it isn't already!
+				newJson, _ := sjson.Set(string(json), "value", "CCONJ")
+				return newJson
+			}
+		}
+
+	case "koral:operation":
+		{
+
+		}
+
+	}
+	/*
+
+		var raw []byte
+		if result.Index > 0 {
+			raw = json[result.Index:result.Index+len(result.Raw)]
+		} else {
+			raw = []byte(result.Raw)
+		}
+	*/
+	return "jj"
+}
+
+// token writes a token to the string builder
+func token(strBuilder *strings.Builder, foundry string, layer string, keys []string) {
+	strBuilder.WriteString(`{"@type":"koral:token","wrap":`)
+	if len(keys) > 1 {
+		termGroup(strBuilder, foundry, layer, keys)
+	} else {
+		term(strBuilder, foundry, layer, keys[0], true)
+	}
+	strBuilder.WriteString(`}`)
+}
+
+// termGroup writes a termGroup to the string builder
+func termGroup(strBuilder *strings.Builder, foundry string, layer string, keys []string) {
+	strBuilder.WriteString(`{"@type":"koral:termGroup","relation":"relation:and","operation":"operation:and","operands":[`)
+	for i, key := range keys {
+		term(strBuilder, foundry, layer, key, true) // temporary
+		if i < len(keys)-1 {
+			strBuilder.WriteString(",")
+		}
+	}
+	strBuilder.WriteString(`]}`)
+}
+
+// term writes a term to the string builder
+func term(strBuilder *strings.Builder, foundry string, layer string, key string, match bool) {
+
+	// TODO: May have ne!!!!
+	strBuilder.WriteString(`{"@type":"koral:term","match":"match:`)
+	if match {
+		strBuilder.WriteString("eq")
+	} else {
+		strBuilder.WriteString("ne")
+	}
+	strBuilder.WriteString(`","foundry":"`)
+	strBuilder.WriteString(foundry)
+	strBuilder.WriteString(`","layer":"`)
+	strBuilder.WriteString(layer)
+	strBuilder.WriteString(`","key":"`)
+	strBuilder.WriteString(key)
+	strBuilder.WriteString(`"}`)
+}
+
+func flatten() {
+
+	// if a termGroup isan operand in a termGroup with the same relation/operation:
+	// flatten the termGroup into the parent termGroup
+
+	// if a termGroup has only a single term, remove the group
+}
+
+func replaceWrappedTerm(jsonString string, foundry string, layer string, key string) string {
+	var err error
+	jsonString, err = sjson.Set(jsonString, "foundry", foundry)
+	if err != nil {
+		log.Error().Err(err).Msg("Error setting foundry")
+	}
+	jsonString, err = sjson.Set(jsonString, "layer", layer)
+	if err != nil {
+		log.Error().Err(err).Msg("Error setting layer")
+	}
+	jsonString, err = sjson.Set(jsonString, "key", key)
+	if err != nil {
+		log.Error().Err(err).Msg("Error setting key")
+	}
+	return jsonString
+}
+
+func replaceGroupedTerm(jsonString string, op []int, foundry string, layer string, key string) string {
+	var err error
+
+	strInt := "operands." + strconv.Itoa(op[0]) + "."
+	jsonString, err = sjson.Set(jsonString, strInt+"foundry", foundry)
+	if err != nil {
+		log.Error().Err(err).Msg("Error setting foundry")
+	}
+	jsonString, err = sjson.Set(jsonString, strInt+"layer", layer)
+	if err != nil {
+		log.Error().Err(err).Msg("Error setting layer")
+	}
+	jsonString, err = sjson.Set(jsonString, strInt+"key", key)
+	if err != nil {
+		log.Error().Err(err).Msg("Error setting key")
+	}
+
+	if len(op) > 1 {
+		for i := 1; i < len(op); i++ {
+			jsonString, err = sjson.Delete(jsonString, "operands."+strconv.Itoa(op[i]))
+			if err != nil {
+				log.Error().Err(err).Msg("Error deleting operand")
+			}
+		}
+	}
+
+	return jsonString
+}
+
+/*
+func replaceTermWithToken(jsonString string) string {
+	// Replace the term with the token
+	replacedString, err := sjson.Set(jsonString, "wrap.operands.0", token())
+	if err != nil {
+		return jsonString // Return the original string in case of an error
+	}
+	return replacedString
+
+// case1: 1 -> 1 the term is an operand in a termGroup with the same relation/operation
+// case2: 1 -> 1 the term is wrapped
+// case3: 1 -> 1 the term is an operand in a termGroup with a different relation/operation
+// case4: n -> 1 the term is an operand in a termGroup with the same relation/operation
+// case5: n -> 1 the term is wrapped
+// case6: n -> 1 the term is an operand in a termGroup with a different relation/operation
+// case7: 1 -> n the term is an operand in a termGroup with the same relation/operation
+// case8: 1 -> n the term is wrapped
+// case9: 1 -> n the term is an operand in a termGroup with a different relation/operation
+	}
+*/
+
+func Map(jsonStr string) string {
+
+	obj := gjson.Get(jsonStr, "query")
+
+	// value := gjson.Get(json, "name.last")
+
+	/*
+
+	   	// Modify the JSON structure recursively
+	   	modifiedData := modifyJSON(ast.NewAny(data))
+
+	   // Marshal the modified data back into a JSON string
+	   	modifiedJSON, err := sonic.MarshalString(modifiedData)
+
+	   	// Parse the JSON string into a generic interface{}
+	   	var data interface{}
+
+	   	err := sonic.UnmarshalString(jsonStr, data)
+
+	   	if err != nil {
+	   		log.Fatal("Error unmarshaling JSON:", err)
+	   		return ""
+	   	}
+
+
+
+	   	if err != nil {
+	   		log.Fatal("Error marshaling JSON:", err)
+	   	}
+	*/
+	// Output the modified JSON string
+	return obj.String() //modifyJSON(obj)
+}
+
+// Recursive function to modify JSON using Sonic library
+//func modifyJSON(data gjson.Result) string {
+
+// Check if data is a map
+// if data.IsObject() {
+/*
+	dataMap := data.Map()
+
+	koralType := dataMap["@type"].String()
+
+	// Look for @type key
+
+	switch koralType {
+	case "koral:term":
+		// Modify the key by adding 'hallo-' prefix
+
+		// sjson.SetRaw(data.String())
+		sjson.Set(data.Path(data.Bytes()), "key", "hallo-"+dataMap["key"].String())
+
+		dataMap["key"] = "hallo-" + dataMap["key"].String()
+		/*
+			if key, found := data.GetString("key"); found {
+				data.Set("key", "hallo-"+key)
+			}
+*/
+/*
+	case "koral:operation":
+			// Handle the 'operators' key by recursively modifying each operator
+			if operators, found := data.GetArray("operators"); found {
+				for i := range operators {
+					operators[i] = modifyJSON(operators[i])
+				}
+				data.Set("operators", operators)
+			}
+		}*/
+/*
+	// Recursively modify any nested objects
+	data.ForEach(func(k string, v sonic.Any) {
+		data.Set(k, modifyJSON(v))
+	})
+*/
+//}
+// Handle arrays by modifying elements recursively
+/*
+	if data.IsArray() {
+		for i := range data.GetArray() {
+			data.Set(i, modifyJSON(data.GetArray()[i]))
+		}
+	}
+*/
+/*
+	return data
+}
+*/
