diff --git a/matcher/matcher.go b/matcher/matcher.go
index 3b496b2..1630b1a 100644
--- a/matcher/matcher.go
+++ b/matcher/matcher.go
@@ -93,109 +93,61 @@
 		return &ast.Token{Wrap: wrap}
 	}
 
-	// If this node matches the pattern
-	if m.Match(node) {
-		// For TermGroups that contain a matching Term, preserve unmatched operands
-		if tg, ok := node.(*ast.TermGroup); ok {
-			// Check if any operand matches the pattern exactly
-			hasExactMatch := false
-			for _, op := range tg.Operands {
-				if m.matchNode(op, m.pattern.Root) {
-					hasExactMatch = true
-					break
-				}
-			}
-
-			// If we have an exact match, replace matching operands
-			if hasExactMatch {
-				hasMatch := false
-				newOperands := make([]ast.Node, 0, len(tg.Operands))
-				for _, op := range tg.Operands {
-					if m.matchNode(op, m.pattern.Root) {
-						if !hasMatch {
-							newOperands = append(newOperands, m.cloneNode(m.replacement.Root))
-							hasMatch = true
-						} else {
-							newOperands = append(newOperands, m.replaceNode(op))
-						}
-					} else {
-						newOperands = append(newOperands, m.replaceNode(op))
-					}
-				}
-				return &ast.TermGroup{
-					Operands: newOperands,
-					Relation: tg.Relation,
-				}
-			}
-			// Otherwise, replace the entire TermGroup
-			return m.cloneNode(m.replacement.Root)
-		}
-		// For other nodes, return the replacement
-		return m.cloneNode(m.replacement.Root)
-	}
-
-	// Otherwise recursively process children
-	switch n := node.(type) {
-	case *ast.TermGroup:
-		// Check if any operand matches the pattern exactly
-		hasExactMatch := false
-		for _, op := range n.Operands {
-			if m.matchNode(op, m.pattern.Root) {
-				hasExactMatch = true
-				break
+	// Handle TermGroup nodes
+	if tg, ok := node.(*ast.TermGroup); ok {
+		// Check if any operand matches the pattern
+		hasMatch := false
+		newOperands := make([]ast.Node, 0, len(tg.Operands))
+		for _, op := range tg.Operands {
+			if !hasMatch && m.matchNode(op, m.pattern.Root) {
+				newOperands = append(newOperands, m.cloneNode(m.replacement.Root))
+				hasMatch = true
+			} else {
+				newOperands = append(newOperands, m.replaceNode(op))
 			}
 		}
-
-		// If we have an exact match, replace matching operands
-		if hasExactMatch {
-			hasMatch := false
-			newOperands := make([]ast.Node, 0, len(n.Operands))
-			for _, op := range n.Operands {
-				if m.matchNode(op, m.pattern.Root) {
-					if !hasMatch {
-						newOperands = append(newOperands, m.cloneNode(m.replacement.Root))
-						hasMatch = true
-					} else {
-						newOperands = append(newOperands, m.replaceNode(op))
-					}
-				} else {
-					newOperands = append(newOperands, m.replaceNode(op))
-				}
-			}
+		// If we found a match, return the modified TermGroup
+		if hasMatch {
 			return &ast.TermGroup{
 				Operands: newOperands,
-				Relation: n.Relation,
+				Relation: tg.Relation,
 			}
 		}
-		// Otherwise, recursively process operands
-		newOperands := make([]ast.Node, len(n.Operands))
-		for i, op := range n.Operands {
-			newOperands[i] = m.replaceNode(op)
+		// If this TermGroup matches the pattern exactly, replace it
+		if m.matchNode(node, m.pattern.Root) {
+			return m.cloneNode(m.replacement.Root)
 		}
+		// Otherwise, return the modified TermGroup
 		return &ast.TermGroup{
 			Operands: newOperands,
-			Relation: n.Relation,
+			Relation: tg.Relation,
 		}
+	}
 
-	case *ast.CatchallNode:
+	// Handle CatchallNode nodes
+	if c, ok := node.(*ast.CatchallNode); ok {
 		newNode := &ast.CatchallNode{
-			NodeType:   n.NodeType,
-			RawContent: n.RawContent,
+			NodeType:   c.NodeType,
+			RawContent: c.RawContent,
 		}
-		if n.Wrap != nil {
-			newNode.Wrap = m.replaceNode(n.Wrap)
+		if c.Wrap != nil {
+			newNode.Wrap = m.replaceNode(c.Wrap)
 		}
-		if len(n.Operands) > 0 {
-			newNode.Operands = make([]ast.Node, len(n.Operands))
-			for i, op := range n.Operands {
+		if len(c.Operands) > 0 {
+			newNode.Operands = make([]ast.Node, len(c.Operands))
+			for i, op := range c.Operands {
 				newNode.Operands[i] = m.replaceNode(op)
 			}
 		}
 		return newNode
-
-	default:
-		return node
 	}
+
+	// If this node matches the pattern exactly, replace it
+	if m.matchNode(node, m.pattern.Root) {
+		return m.cloneNode(m.replacement.Root)
+	}
+
+	return node
 }
 
 // simplifyNode removes unnecessary wrappers and empty nodes
@@ -276,120 +228,97 @@
 		return false
 	}
 
-	// Handle pattern being a Token
-	if pToken, ok := pattern.(*ast.Token); ok {
-		if nToken, ok := node.(*ast.Token); ok {
-			return m.matchNode(nToken.Wrap, pToken.Wrap)
-		}
-		return false
+	// Handle wrapped nodes (Token and CatchallNode)
+	if m.tryMatchWrapped(node, pattern) {
+		return true
 	}
 
-	// Handle pattern being a Term
-	if pTerm, ok := pattern.(*ast.Term); ok {
-		// Direct term to term matching
-		if t, ok := node.(*ast.Term); ok {
-			return t.Foundry == pTerm.Foundry &&
-				t.Key == pTerm.Key &&
-				t.Layer == pTerm.Layer &&
-				t.Match == pTerm.Match &&
-				(pTerm.Value == "" || t.Value == pTerm.Value)
+	switch p := pattern.(type) {
+	case *ast.Token:
+		if n, ok := node.(*ast.Token); ok {
+			return m.matchNode(n.Wrap, p.Wrap)
 		}
-		// If node is a Token, check its wrap
-		if tkn, ok := node.(*ast.Token); ok {
-			if tkn.Wrap == nil {
-				return false
-			}
-			return m.matchNode(tkn.Wrap, pattern)
-		}
-		// If node is a TermGroup, check its operands
-		if tg, ok := node.(*ast.TermGroup); ok {
-			for _, op := range tg.Operands {
-				if m.matchNode(op, pattern) {
-					return true
-				}
-			}
-			return false
-		}
-		// If node is a CatchallNode, check its wrap and operands
-		if c, ok := node.(*ast.CatchallNode); ok {
-			if c.Wrap != nil && m.matchNode(c.Wrap, pattern) {
-				return true
-			}
-			for _, op := range c.Operands {
-				if m.matchNode(op, pattern) {
-					return true
-				}
-			}
-			return false
-		}
-		return false
-	}
 
-	// Handle pattern being a TermGroup
-	if pGroup, ok := pattern.(*ast.TermGroup); ok {
-		// For OR relations, check if any operand matches the node
-		if pGroup.Relation == ast.OrRelation {
-			for _, pOp := range pGroup.Operands {
+	case *ast.Term:
+		return m.matchTerm(node, p)
+
+	case *ast.TermGroup:
+		if p.Relation == ast.OrRelation {
+			// For OR relations, check if any operand matches
+			for _, pOp := range p.Operands {
 				if m.matchNode(node, pOp) {
 					return true
 				}
 			}
-			return false
+		} else if tg, ok := node.(*ast.TermGroup); ok && tg.Relation == p.Relation {
+			// For AND relations, all pattern operands must match in any order
+			return m.matchAndTermGroup(tg, p)
 		}
-
-		// For AND relations, node must be a TermGroup with matching relation
-		if tg, ok := node.(*ast.TermGroup); ok {
-			if tg.Relation != pGroup.Relation {
-				return false
-			}
-			// Check that all pattern operands match in any order
-			if len(tg.Operands) < len(pGroup.Operands) {
-				return false
-			}
-			matched := make([]bool, len(tg.Operands))
-			for _, pOp := range pGroup.Operands {
-				found := false
-				for j, tOp := range tg.Operands {
-					if !matched[j] && m.matchNode(tOp, pOp) {
-						matched[j] = true
-						found = true
-						break
-					}
-				}
-				if !found {
-					return false
-				}
-			}
-			return true
-		}
-
-		// If node is a Token, check its wrap
-		if tkn, ok := node.(*ast.Token); ok {
-			if tkn.Wrap == nil {
-				return false
-			}
-			return m.matchNode(tkn.Wrap, pattern)
-		}
-
-		// If node is a CatchallNode, check its wrap and operands
-		if c, ok := node.(*ast.CatchallNode); ok {
-			if c.Wrap != nil && m.matchNode(c.Wrap, pattern) {
-				return true
-			}
-			for _, op := range c.Operands {
-				if m.matchNode(op, pattern) {
-					return true
-				}
-			}
-			return false
-		}
-
-		return false
 	}
 
 	return false
 }
 
+// tryMatchWrapped attempts to match a node that might wrap other nodes
+func (m *Matcher) tryMatchWrapped(node, pattern ast.Node) bool {
+	switch n := node.(type) {
+	case *ast.Token:
+		if n.Wrap != nil {
+			return m.matchNode(n.Wrap, pattern)
+		}
+	case *ast.CatchallNode:
+		if n.Wrap != nil && m.matchNode(n.Wrap, pattern) {
+			return true
+		}
+		for _, op := range n.Operands {
+			if m.matchNode(op, pattern) {
+				return true
+			}
+		}
+	case *ast.TermGroup:
+		for _, op := range n.Operands {
+			if m.matchNode(op, pattern) {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+// matchTerm checks if a node matches a term pattern
+func (m *Matcher) matchTerm(node ast.Node, pattern *ast.Term) bool {
+	if t, ok := node.(*ast.Term); ok {
+		return t.Foundry == pattern.Foundry &&
+			t.Key == pattern.Key &&
+			t.Layer == pattern.Layer &&
+			t.Match == pattern.Match &&
+			(pattern.Value == "" || t.Value == pattern.Value)
+	}
+	return m.tryMatchWrapped(node, pattern)
+}
+
+// matchAndTermGroup checks if a TermGroup matches an AND pattern
+func (m *Matcher) matchAndTermGroup(node *ast.TermGroup, pattern *ast.TermGroup) bool {
+	if len(node.Operands) < len(pattern.Operands) {
+		return false
+	}
+	matched := make([]bool, len(node.Operands))
+	for _, pOp := range pattern.Operands {
+		found := false
+		for j, tOp := range node.Operands {
+			if !matched[j] && m.matchNode(tOp, pOp) {
+				matched[j] = true
+				found = true
+				break
+			}
+		}
+		if !found {
+			return false
+		}
+	}
+	return true
+}
+
 // cloneNode creates a deep copy of a node
 func (m *Matcher) cloneNode(node ast.Node) ast.Node {
 	if node == nil {
