Optimize mappings
diff --git a/ast/ast_test.go b/ast/ast_test.go
index 0daaf7c..49fdbe3 100644
--- a/ast/ast_test.go
+++ b/ast/ast_test.go
@@ -343,49 +343,39 @@
 }
 
 func TestComplexNestedStructures(t *testing.T) {
-	// Create a complex nested structure
-	innerGroup1 := &TermGroup{
+	// Test nested tokens and term groups
+	termGroup := &TermGroup{
 		Operands: []Node{
-			&Term{Foundry: "f1", Key: "k1", Layer: "l1", Match: MatchEqual},
-			&Term{Foundry: "f2", Key: "k2", Layer: "l2", Match: MatchNotEqual},
+			&Term{
+				Foundry: "opennlp",
+				Key:     "DET",
+				Layer:   "p",
+				Match:   MatchEqual,
+			},
+			&Term{
+				Foundry: "opennlp",
+				Key:     "AdjType",
+				Layer:   "m",
+				Match:   MatchEqual,
+				Value:   "Pdt",
+			},
 		},
 		Relation: AndRelation,
 	}
 
-	innerGroup2 := &TermGroup{
-		Operands: []Node{
-			&Term{Foundry: "f3", Key: "k3", Layer: "l3", Match: MatchEqual},
-			&Term{Foundry: "f4", Key: "k4", Layer: "l4", Match: MatchEqual, Value: "test"},
-		},
-		Relation: OrRelation,
+	token := &Token{
+		Wrap: termGroup,
 	}
 
-	topGroup := &TermGroup{
-		Operands: []Node{
-			innerGroup1,
-			innerGroup2,
-			&Token{Wrap: &Term{Foundry: "f5", Key: "k5", Layer: "l5", Match: MatchEqual}},
-		},
-		Relation: AndRelation,
-	}
-
-	assert.Equal(t, TermGroupNode, topGroup.Type())
-	assert.Len(t, topGroup.Operands, 3)
-	assert.Equal(t, AndRelation, topGroup.Relation)
-
-	// Test inner groups
-	group1 := topGroup.Operands[0].(*TermGroup)
-	assert.Len(t, group1.Operands, 2)
-	assert.Equal(t, AndRelation, group1.Relation)
-
-	group2 := topGroup.Operands[1].(*TermGroup)
-	assert.Len(t, group2.Operands, 2)
-	assert.Equal(t, OrRelation, group2.Relation)
-
-	// Test token wrapping
-	token := topGroup.Operands[2].(*Token)
+	assert.Equal(t, TokenNode, token.Type())
 	assert.NotNil(t, token.Wrap)
-	assert.Equal(t, TermNode, token.Wrap.Type())
+	assert.Equal(t, TermGroupNode, token.Wrap.Type())
+
+	// Test that the nested structure is correct
+	if tg, ok := token.Wrap.(*TermGroup); ok {
+		assert.Equal(t, 2, len(tg.Operands))
+		assert.Equal(t, AndRelation, tg.Relation)
+	}
 }
 
 func TestEdgeCases(t *testing.T) {
@@ -462,3 +452,402 @@
 		t.Run(tt.name, tt.test)
 	}
 }
+
+func TestCloneMethod(t *testing.T) {
+	tests := []struct {
+		name string
+		node Node
+	}{
+		{
+			name: "Clone Term",
+			node: &Term{
+				Foundry: "opennlp",
+				Key:     "DET",
+				Layer:   "p",
+				Match:   MatchEqual,
+				Value:   "test",
+				Rewrites: []Rewrite{
+					{
+						Editor: "test",
+						Scope:  "foundry",
+					},
+				},
+			},
+		},
+		{
+			name: "Clone Token",
+			node: &Token{
+				Wrap: &Term{
+					Foundry: "opennlp",
+					Key:     "DET",
+					Layer:   "p",
+					Match:   MatchEqual,
+				},
+				Rewrites: []Rewrite{
+					{
+						Editor: "test",
+						Scope:  "layer",
+					},
+				},
+			},
+		},
+		{
+			name: "Clone TermGroup",
+			node: &TermGroup{
+				Operands: []Node{
+					&Term{
+						Foundry: "opennlp",
+						Key:     "DET",
+						Layer:   "p",
+						Match:   MatchEqual,
+					},
+					&Term{
+						Foundry: "opennlp",
+						Key:     "AdjType",
+						Layer:   "m",
+						Match:   MatchEqual,
+						Value:   "Pdt",
+					},
+				},
+				Relation: AndRelation,
+				Rewrites: []Rewrite{
+					{
+						Editor: "test",
+						Scope:  "foundry",
+					},
+				},
+			},
+		},
+		{
+			name: "Clone CatchallNode",
+			node: &CatchallNode{
+				NodeType:   "koral:unknown",
+				RawContent: []byte(`{"@type":"koral:unknown","test":"value"}`),
+				Wrap: &Term{
+					Foundry: "opennlp",
+					Key:     "DET",
+					Layer:   "p",
+					Match:   MatchEqual,
+				},
+				Operands: []Node{
+					&Term{
+						Foundry: "opennlp",
+						Key:     "AdjType",
+						Layer:   "m",
+						Match:   MatchEqual,
+						Value:   "Pdt",
+					},
+				},
+			},
+		},
+		{
+			name: "Clone Rewrite",
+			node: &Rewrite{
+				Editor:    "termMapper",
+				Operation: "injection",
+				Scope:     "foundry",
+				Src:       "test",
+				Comment:   "test comment",
+				Original:  "original_value",
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			cloned := tt.node.Clone()
+
+			// Check that the clone is not the same instance
+			assert.NotSame(t, tt.node, cloned)
+
+			// Check that the clone has the same type
+			assert.Equal(t, tt.node.Type(), cloned.Type())
+
+			// Check that nodes are equal (deep comparison)
+			assert.True(t, NodesEqual(tt.node, cloned))
+
+			// Test that modifying the clone doesn't affect the original
+			switch original := tt.node.(type) {
+			case *Term:
+				clonedTerm := cloned.(*Term)
+				clonedTerm.Foundry = "modified"
+				assert.NotEqual(t, original.Foundry, clonedTerm.Foundry)
+
+			case *Token:
+				clonedToken := cloned.(*Token)
+				if clonedToken.Wrap != nil {
+					if termWrap, ok := clonedToken.Wrap.(*Term); ok {
+						termWrap.Foundry = "modified"
+						if originalWrap, ok := original.Wrap.(*Term); ok {
+							assert.NotEqual(t, originalWrap.Foundry, termWrap.Foundry)
+						}
+					}
+				}
+
+			case *TermGroup:
+				clonedGroup := cloned.(*TermGroup)
+				clonedGroup.Relation = OrRelation
+				assert.NotEqual(t, original.Relation, clonedGroup.Relation)
+
+			case *CatchallNode:
+				clonedCatchall := cloned.(*CatchallNode)
+				clonedCatchall.NodeType = "modified"
+				assert.NotEqual(t, original.NodeType, clonedCatchall.NodeType)
+
+			case *Rewrite:
+				clonedRewrite := cloned.(*Rewrite)
+				clonedRewrite.Editor = "modified"
+				assert.NotEqual(t, original.Editor, clonedRewrite.Editor)
+			}
+		})
+	}
+}
+
+func TestCloneNilNodes(t *testing.T) {
+	// Test cloning nodes with nil fields
+	tests := []struct {
+		name string
+		node Node
+	}{
+		{
+			name: "Token with nil wrap",
+			node: &Token{Wrap: nil},
+		},
+		{
+			name: "TermGroup with empty operands",
+			node: &TermGroup{
+				Operands: []Node{},
+				Relation: AndRelation,
+			},
+		},
+		{
+			name: "CatchallNode with nil wrap and operands",
+			node: &CatchallNode{
+				NodeType:   "koral:unknown",
+				RawContent: nil,
+				Wrap:       nil,
+				Operands:   nil,
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			cloned := tt.node.Clone()
+			assert.NotSame(t, tt.node, cloned)
+			assert.Equal(t, tt.node.Type(), cloned.Type())
+			assert.True(t, NodesEqual(tt.node, cloned))
+		})
+	}
+}
+
+func TestApplyFoundryAndLayerOverrides(t *testing.T) {
+	tests := []struct {
+		name            string
+		node            Node
+		foundry         string
+		layer           string
+		expectedChanges func(t *testing.T, node Node)
+	}{
+		{
+			name: "Apply foundry and layer to Term",
+			node: &Term{
+				Foundry: "original",
+				Key:     "DET",
+				Layer:   "original",
+				Match:   MatchEqual,
+			},
+			foundry: "new_foundry",
+			layer:   "new_layer",
+			expectedChanges: func(t *testing.T, node Node) {
+				term := node.(*Term)
+				assert.Equal(t, "new_foundry", term.Foundry)
+				assert.Equal(t, "new_layer", term.Layer)
+			},
+		},
+		{
+			name: "Apply only foundry to Term",
+			node: &Term{
+				Foundry: "original",
+				Key:     "DET",
+				Layer:   "original",
+				Match:   MatchEqual,
+			},
+			foundry: "new_foundry",
+			layer:   "",
+			expectedChanges: func(t *testing.T, node Node) {
+				term := node.(*Term)
+				assert.Equal(t, "new_foundry", term.Foundry)
+				assert.Equal(t, "original", term.Layer) // Should remain unchanged
+			},
+		},
+		{
+			name: "Apply to TermGroup",
+			node: &TermGroup{
+				Operands: []Node{
+					&Term{
+						Foundry: "original1",
+						Key:     "DET",
+						Layer:   "original1",
+						Match:   MatchEqual,
+					},
+					&Term{
+						Foundry: "original2",
+						Key:     "AdjType",
+						Layer:   "original2",
+						Match:   MatchEqual,
+						Value:   "Pdt",
+					},
+				},
+				Relation: AndRelation,
+			},
+			foundry: "new_foundry",
+			layer:   "new_layer",
+			expectedChanges: func(t *testing.T, node Node) {
+				termGroup := node.(*TermGroup)
+				for _, operand := range termGroup.Operands {
+					if term, ok := operand.(*Term); ok {
+						assert.Equal(t, "new_foundry", term.Foundry)
+						assert.Equal(t, "new_layer", term.Layer)
+					}
+				}
+			},
+		},
+		{
+			name: "Apply to Token with wrapped Term",
+			node: &Token{
+				Wrap: &Term{
+					Foundry: "original",
+					Key:     "DET",
+					Layer:   "original",
+					Match:   MatchEqual,
+				},
+			},
+			foundry: "new_foundry",
+			layer:   "new_layer",
+			expectedChanges: func(t *testing.T, node Node) {
+				token := node.(*Token)
+				if term, ok := token.Wrap.(*Term); ok {
+					assert.Equal(t, "new_foundry", term.Foundry)
+					assert.Equal(t, "new_layer", term.Layer)
+				}
+			},
+		},
+		{
+			name: "Apply to CatchallNode",
+			node: &CatchallNode{
+				NodeType: "koral:unknown",
+				Wrap: &Term{
+					Foundry: "original",
+					Key:     "DET",
+					Layer:   "original",
+					Match:   MatchEqual,
+				},
+				Operands: []Node{
+					&Term{
+						Foundry: "original2",
+						Key:     "AdjType",
+						Layer:   "original2",
+						Match:   MatchEqual,
+						Value:   "Pdt",
+					},
+				},
+			},
+			foundry: "new_foundry",
+			layer:   "new_layer",
+			expectedChanges: func(t *testing.T, node Node) {
+				catchall := node.(*CatchallNode)
+				if term, ok := catchall.Wrap.(*Term); ok {
+					assert.Equal(t, "new_foundry", term.Foundry)
+					assert.Equal(t, "new_layer", term.Layer)
+				}
+				for _, operand := range catchall.Operands {
+					if term, ok := operand.(*Term); ok {
+						assert.Equal(t, "new_foundry", term.Foundry)
+						assert.Equal(t, "new_layer", term.Layer)
+					}
+				}
+			},
+		},
+		{
+			name: "Apply to nested structure",
+			node: &Token{
+				Wrap: &TermGroup{
+					Operands: []Node{
+						&Term{
+							Foundry: "original1",
+							Key:     "DET",
+							Layer:   "original1",
+							Match:   MatchEqual,
+						},
+						&Token{
+							Wrap: &Term{
+								Foundry: "original2",
+								Key:     "AdjType",
+								Layer:   "original2",
+								Match:   MatchEqual,
+								Value:   "Pdt",
+							},
+						},
+					},
+					Relation: AndRelation,
+				},
+			},
+			foundry: "new_foundry",
+			layer:   "new_layer",
+			expectedChanges: func(t *testing.T, node Node) {
+				token := node.(*Token)
+				if termGroup, ok := token.Wrap.(*TermGroup); ok {
+					for _, operand := range termGroup.Operands {
+						switch op := operand.(type) {
+						case *Term:
+							assert.Equal(t, "new_foundry", op.Foundry)
+							assert.Equal(t, "new_layer", op.Layer)
+						case *Token:
+							if innerTerm, ok := op.Wrap.(*Term); ok {
+								assert.Equal(t, "new_foundry", innerTerm.Foundry)
+								assert.Equal(t, "new_layer", innerTerm.Layer)
+							}
+						}
+					}
+				}
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			// Clone the node to avoid modifying the original test data
+			cloned := tt.node.Clone()
+
+			// Apply the overrides
+			ApplyFoundryAndLayerOverrides(cloned, tt.foundry, tt.layer)
+
+			// Check the expected changes
+			tt.expectedChanges(t, cloned)
+		})
+	}
+}
+
+func TestApplyFoundryAndLayerOverridesNilNode(t *testing.T) {
+	// Test that applying overrides to a nil node doesn't panic
+	assert.NotPanics(t, func() {
+		ApplyFoundryAndLayerOverrides(nil, "foundry", "layer")
+	})
+}
+
+func TestApplyFoundryAndLayerOverridesEmptyValues(t *testing.T) {
+	// Test applying empty foundry and layer values
+	term := &Term{
+		Foundry: "original_foundry",
+		Key:     "DET",
+		Layer:   "original_layer",
+		Match:   MatchEqual,
+	}
+
+	ApplyFoundryAndLayerOverrides(term, "", "")
+
+	// Values should remain unchanged
+	assert.Equal(t, "original_foundry", term.Foundry)
+	assert.Equal(t, "original_layer", term.Layer)
+}