Support legacy fields
diff --git a/mapper/mapper.go b/mapper/mapper.go
index 0377c88..424896e 100644
--- a/mapper/mapper.go
+++ b/mapper/mapper.go
@@ -178,17 +178,36 @@
 			replacement = token.Wrap
 		}
 
-		// Apply foundry and layer overrides
-		if opts.Direction { // true means AtoB
-			applyFoundryAndLayerOverrides(pattern, opts.FoundryA, opts.LayerA)
-			applyFoundryAndLayerOverrides(replacement, opts.FoundryB, opts.LayerB)
-		} else {
-			applyFoundryAndLayerOverrides(pattern, opts.FoundryB, opts.LayerB)
-			applyFoundryAndLayerOverrides(replacement, opts.FoundryA, opts.LayerA)
+		// Create deep copies of pattern and replacement to avoid modifying the original parsed rules
+		patternBytes, err := parser.SerializeToJSON(pattern)
+		if err != nil {
+			return nil, fmt.Errorf("failed to serialize pattern for copying: %w", err)
+		}
+		patternCopy, err := parser.ParseJSON(patternBytes)
+		if err != nil {
+			return nil, fmt.Errorf("failed to parse pattern copy: %w", err)
 		}
 
-		// Create matcher and apply replacement
-		m, err := matcher.NewMatcher(ast.Pattern{Root: pattern}, ast.Replacement{Root: replacement})
+		replacementBytes, err := parser.SerializeToJSON(replacement)
+		if err != nil {
+			return nil, fmt.Errorf("failed to serialize replacement for copying: %w", err)
+		}
+		replacementCopy, err := parser.ParseJSON(replacementBytes)
+		if err != nil {
+			return nil, fmt.Errorf("failed to parse replacement copy: %w", err)
+		}
+
+		// Apply foundry and layer overrides to the copies
+		if opts.Direction { // true means AtoB
+			applyFoundryAndLayerOverrides(patternCopy, opts.FoundryA, opts.LayerA)
+			applyFoundryAndLayerOverrides(replacementCopy, opts.FoundryB, opts.LayerB)
+		} else {
+			applyFoundryAndLayerOverrides(patternCopy, opts.FoundryB, opts.LayerB)
+			applyFoundryAndLayerOverrides(replacementCopy, opts.FoundryA, opts.LayerA)
+		}
+
+		// Create matcher and apply replacement using the copies
+		m, err := matcher.NewMatcher(ast.Pattern{Root: patternCopy}, ast.Replacement{Root: replacementCopy})
 		if err != nil {
 			return nil, fmt.Errorf("failed to create matcher: %w", err)
 		}
@@ -293,8 +312,38 @@
 
 	// Restore rewrites if they existed
 	if oldRewrites != nil {
-		if resultMap, ok := resultData.(map[string]any); ok {
-			resultMap["rewrites"] = oldRewrites
+		// Process old rewrites through AST to ensure backward compatibility
+		if rewritesList, ok := oldRewrites.([]any); ok {
+			processedRewrites := make([]any, len(rewritesList))
+			for i, rewriteData := range rewritesList {
+				// Marshal and unmarshal each rewrite to apply backward compatibility
+				rewriteBytes, err := json.Marshal(rewriteData)
+				if err != nil {
+					return nil, fmt.Errorf("failed to marshal old rewrite %d: %w", i, err)
+				}
+				var rewrite ast.Rewrite
+				if err := json.Unmarshal(rewriteBytes, &rewrite); err != nil {
+					return nil, fmt.Errorf("failed to unmarshal old rewrite %d: %w", i, err)
+				}
+				// Marshal back to get the transformed version
+				transformedBytes, err := json.Marshal(&rewrite)
+				if err != nil {
+					return nil, fmt.Errorf("failed to marshal transformed rewrite %d: %w", i, err)
+				}
+				var transformedRewrite any
+				if err := json.Unmarshal(transformedBytes, &transformedRewrite); err != nil {
+					return nil, fmt.Errorf("failed to unmarshal transformed rewrite %d: %w", i, err)
+				}
+				processedRewrites[i] = transformedRewrite
+			}
+			if resultMap, ok := resultData.(map[string]any); ok {
+				resultMap["rewrites"] = processedRewrites
+			}
+		} else {
+			// If it's not a list, restore as-is
+			if resultMap, ok := resultData.(map[string]any); ok {
+				resultMap["rewrites"] = oldRewrites
+			}
 		}
 	}
 
diff --git a/mapper/mapper_test.go b/mapper/mapper_test.go
index c97238b..b2fb377 100644
--- a/mapper/mapper_test.go
+++ b/mapper/mapper_test.go
@@ -263,6 +263,149 @@
 			}`,
 			expectError: false,
 		},
+		{
+			name:      "Query with legacy rewrite field names",
+			mappingID: "test-mapper",
+			opts: MappingOptions{
+				Direction: AtoB,
+			},
+			input: `{
+				"@type": "koral:token",
+				"rewrites": [
+					{
+						"@type": "koral:rewrite",
+						"_comment": "Legacy rewrite with source instead of editor",
+						"source": "LegacyEditor",
+						"operation": "operation:legacy",
+						"origin": "LegacySource"
+					}
+				],
+				"wrap": {
+					"@type": "koral:term",
+					"foundry": "opennlp",
+					"key": "PIDAT",
+					"layer": "p",
+					"match": "match:eq"
+				}
+			}`,
+			expected: `{
+				"@type": "koral:token",
+				"rewrites": [
+					{
+						"@type": "koral:rewrite",
+						"_comment": "Legacy rewrite with source instead of editor",
+						"editor": "LegacyEditor",
+						"operation": "operation:legacy",
+						"src": "LegacySource"
+					}
+				],
+				"wrap": {
+					"@type": "koral:termGroup",
+					"operands": [
+						{
+							"@type": "koral:term",
+							"foundry": "opennlp",
+							"key": "PIDAT",
+							"layer": "p",
+							"match": "match:eq"
+						},
+						{
+							"@type": "koral:term",
+							"foundry": "opennlp",
+							"key": "AdjType",
+							"layer": "p",
+							"match": "match:eq",
+							"value": "Pdt"
+						}
+					],
+					"relation": "relation:and"
+				}
+			}`,
+		},
+		{
+			name:      "Query with mixed legacy and modern rewrite fields",
+			mappingID: "test-mapper",
+			opts: MappingOptions{
+				Direction: AtoB,
+			},
+			input: `{
+				"@type": "koral:token",
+				"rewrites": [
+					{
+						"@type": "koral:rewrite",
+						"_comment": "Modern rewrite",
+						"editor": "ModernEditor",
+						"operation": "operation:modern",
+						"original": {
+							"@type": "koral:term",
+							"foundry": "original",
+							"key": "original-key"
+						}
+					},
+					{
+						"@type": "koral:rewrite",
+						"_comment": "Legacy rewrite with precedence test",
+						"editor": "PreferredEditor",
+						"source": "IgnoredSource",
+						"operation": "operation:precedence",
+						"original": "PreferredOriginal",
+						"src": "IgnoredSrc",
+						"origin": "IgnoredOrigin"
+					}
+				],
+				"wrap": {
+					"@type": "koral:term",
+					"foundry": "opennlp",
+					"key": "PIDAT",
+					"layer": "p",
+					"match": "match:eq"
+				}
+			}`,
+			expected: `{
+				"@type": "koral:token",
+				"rewrites": [
+					{
+						"@type": "koral:rewrite",
+						"_comment": "Modern rewrite",
+						"editor": "ModernEditor",
+						"operation": "operation:modern",
+						"original": {
+							"@type": "koral:term",
+							"foundry": "original",
+							"key": "original-key"
+						}
+					},
+					{
+						"@type": "koral:rewrite",
+						"_comment": "Legacy rewrite with precedence test",
+						"editor": "PreferredEditor",
+						"operation": "operation:precedence",
+						"original": "PreferredOriginal"
+					}
+				],
+				"wrap": {
+					"@type": "koral:termGroup",
+					"operands": [
+						{
+							"@type": "koral:term",
+							"foundry": "opennlp",
+							"key": "PIDAT",
+							"layer": "p",
+							"match": "match:eq"
+						},
+						{
+							"@type": "koral:term",
+							"foundry": "opennlp",
+							"key": "AdjType",
+							"layer": "p",
+							"match": "match:eq",
+							"value": "Pdt"
+						}
+					],
+					"relation": "relation:and"
+				}
+			}`,
+		},
 	}
 
 	for _, tt := range tests {