From 5757dc63a32e7d1e4a38ba98393fed659daf4ba2 Mon Sep 17 00:00:00 2001
From: "Dr. Gos" <niculescu.dragos@yahoo.com>
Date: Sat, 28 Dec 2024 20:45:44 +0200
Subject: [PATCH] Chore increase test coverage (#36)

* chore: increased test coverage and removed accidental commit of test file

* chore: increased test coverage for csharp cleaner

* chore: fixed tests failing on ci
---
 filefusion.xml                                | 6320 -----------------
 .../core/cleaner/handlers/csharp_handler.go   |   44 +-
 .../cleaner/handlers/csharp_handler_test.go   |  408 +-
 internal/core/finder.go                       |   72 +-
 internal/core/finder_test.go                  |  368 +
 internal/core/manager_test.go                 |  320 +
 6 files changed, 1057 insertions(+), 6475 deletions(-)
 delete mode 100644 filefusion.xml
 create mode 100644 internal/core/finder_test.go
 create mode 100644 internal/core/manager_test.go

diff --git a/filefusion.xml b/filefusion.xml
deleted file mode 100644
index 8922a9d..0000000
--- a/filefusion.xml
+++ /dev/null
@@ -1,6320 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<documents>
-<document index="1">
-<source>filefusion/internal/core/cleaner/handlers/bash_handler.go</source>
-<document_content>package handlers
-import (
-	"strings"
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type BashHandler struct {
-	BaseHandler
-}
-func (h *BashHandler) GetCommentTypes() []string {
-	return []string{"comment"}
-}
-func (h *BashHandler) GetImportTypes() []string {
-	return []string{"source_command", "command"}
-}
-func (h *BashHandler) GetDocCommentPrefix() string {
-	return "#"
-}
-func (h *BashHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-	if node == nil {
-		return false
-	}
-	nodeType := node.Type()
-	if nodeType == "redirected_statement" {
-		return true
-	}
-	if nodeType != "command" {
-		return false
-	}
-	if node.StartByte() >= uint32(len(content)) || node.EndByte() > uint32(len(content)) {
-		return false
-	}
-	cmdText := string(content[node.StartByte():node.EndByte()])
-	return strings.Contains(cmdText, "logger") ||
-		strings.Contains(cmdText, "echo \"Debug") ||
-		strings.Contains(cmdText, "printf \"Debug")
-}
-func (h *BashHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-	return false
-}
-</document_content>
-</document>
-<document index="2">
-<source>filefusion/internal/core/cleaner/handlers/base_handler.go</source>
-<document_content>package handlers
-import (
-	"strings"
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type LanguageHandler interface {
-	GetCommentTypes() []string
-	GetImportTypes() []string
-	GetDocCommentPrefix() string
-	IsLoggingCall(node *sitter.Node, content []byte) bool
-	IsGetterSetter(node *sitter.Node, content []byte) bool
-}
-type BaseHandler struct{}
-func (h *BaseHandler) IsMethodNamed(node *sitter.Node, content []byte, prefix string) bool {
-	if node.Type() != "method_declaration" &&
-		node.Type() != "function_declaration" &&
-		node.Type() != "getter_declaration" &&
-		node.Type() != "method_definition" {
-		return false
-	}
-	nameNode := node.ChildByFieldName("name")
-	if nameNode == nil {
-		return false
-	}
-	name := string(content[nameNode.StartByte():nameNode.EndByte()])
-	return strings.HasPrefix(strings.ToLower(name), strings.ToLower(prefix))
-}
-func stringSliceEqual(a, b []string) bool {
-	if len(a) != len(b) {
-		return false
-	}
-	for i, v := range a {
-		if v != b[i] {
-			return false
-		}
-	}
-	return true
-}
-</document_content>
-</document>
-<document index="3">
-<source>filefusion/internal/core/cleaner/handlers/base_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/golang"
-)
-func TestBaseHandler(t *testing.T) {
-	handler := &BaseHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(golang.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		prefix   string
-		expected bool
-	}{
-		{
-			name:     "get method",
-			input:    "package main\nfunc GetName() string { return name }",
-			prefix:   "Get",
-			expected: true,
-		},
-		{
-			name:     "set method",
-			input:    "package main\nfunc SetName(name string) { this.name = name }",
-			prefix:   "Set",
-			expected: true,
-		},
-		{
-			name:     "non-matching method",
-			input:    "package main\nfunc Process() error { return nil }",
-			prefix:   "Get",
-			expected: false,
-		},
-		{
-			name:     "case insensitive match",
-			input:    "package main\nfunc getName() string { return name }",
-			prefix:   "Get",
-			expected: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			var funcNode *sitter.Node
-			cursor := sitter.NewTreeCursor(tree.RootNode())
-			defer cursor.Close()
-			ok := cursor.GoToFirstChild()
-			for ok {
-				if cursor.CurrentNode().Type() == "function_declaration" {
-					funcNode = cursor.CurrentNode()
-					break
-				}
-				ok = cursor.GoToNextSibling()
-			}
-			if funcNode == nil {
-				t.Fatal("No function declaration found")
-			}
-			if got := handler.IsMethodNamed(funcNode, []byte(tt.input), tt.prefix); got != tt.expected {
-				t.Errorf("IsMethodNamed() = %v, want %v", got, tt.expected)
-			}
-		})
-	}
-}
-</document_content>
-</document>
-<document index="4">
-<source>filefusion/internal/core/cleaner/handlers/css_handler.go</source>
-<document_content>package handlers
-import (
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type CSSHandler struct {
-	BaseHandler
-}
-func (h *CSSHandler) GetCommentTypes() []string {
-	return []string{"comment"}
-}
-func (h *CSSHandler) GetImportTypes() []string {
-	return []string{"import_statement", "@import"}
-}
-func (h *CSSHandler) GetDocCommentPrefix() string {
-	return "/*"
-}
-func (h *CSSHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-	return false
-}
-func (h *CSSHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-	return false
-}
-</document_content>
-</document>
-<document index="5">
-<source>filefusion/internal/core/cleaner/handlers/cpp_handler.go</source>
-<document_content>package handlers
-import (
-	"bytes"
-	"strings"
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type CPPHandler struct {
-	BaseHandler
-}
-func (h *CPPHandler) GetCommentTypes() []string {
-	return []string{"comment", "multiline_comment"}
-}
-func (h *CPPHandler) GetImportTypes() []string {
-	return []string{"preproc_include", "using_declaration"}
-}
-func (h *CPPHandler) GetDocCommentPrefix() string {
-	return "///"
-}
-func (h *CPPHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-	if node == nil || (node.Type() != "call_expression" && node.Type() != "binary_expression") {
-		return false
-	}
-	if node.StartByte() >= uint32(len(content)) || node.EndByte() > uint32(len(content)) {
-		return false
-	}
-	callText := content[node.StartByte():node.EndByte()]
-	return bytes.Contains(callText, []byte("cout")) ||
-		bytes.Contains(callText, []byte("cerr")) ||
-		bytes.Contains(callText, []byte("clog")) ||
-		bytes.Contains(callText, []byte("printf")) ||
-		bytes.Contains(callText, []byte("fprintf")) ||
-		bytes.Contains(callText, []byte("log"))
-}
-func (h *CPPHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-	if node == nil || (node.Type() != "function_definition" && node.Type() != "function_declarator") {
-		return false
-	}
-	if node.StartByte() >= uint32(len(content)) || node.EndByte() > uint32(len(content)) {
-		return false
-	}
-	funcText := string(content[node.StartByte():node.EndByte()])
-	isGetter := (strings.Contains(strings.ToLower(funcText), "get") && !strings.Contains(strings.ToLower(funcText), "getvalue")) ||
-		(strings.Contains(strings.ToLower(funcText), "is") && !strings.Contains(strings.ToLower(funcText), "isvalue"))
-	isSetter := strings.Contains(funcText, "set") ||
-		strings.Contains(funcText, "Set")
-	if isGetter {
-		return !strings.Contains(funcText, "void") &&
-			strings.Count(funcText, ",") == 0
-	}
-	if isSetter {
-		return strings.Contains(funcText, "void") &&
-			strings.Count(funcText, ",") <= 1
-	}
-	return false
-}
-</document_content>
-</document>
-<document index="6">
-<source>filefusion/internal/core/cleaner/handlers/css_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/css"
-)
-func TestCSSHandlerBasics(t *testing.T) {
-	handler := &CSSHandler{}
-	commentTypes := handler.GetCommentTypes()
-	expected := []string{"comment"}
-	if !stringSliceEqual(commentTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	expected = []string{"import_statement", "@import"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != "/*" {
-		t.Errorf("Expected '/*', got %s", prefix)
-	}
-}
-func TestCSSLoggingCalls(t *testing.T) {
-	handler := &CSSHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(css.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "regular rule",
-			input:    ".class { color: red; }",
-			expected: false,
-		},
-		{
-			name:     "import statement",
-			input:    "@import 'styles.css';",
-			expected: false,
-		},
-		{
-			name:     "media query",
-			input:    "@media screen { body { color: blue; } }",
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			result := handler.IsLoggingCall(node, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsLoggingCall() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-	if handler.IsLoggingCall(nil, []byte("")) {
-		t.Error("Expected IsLoggingCall to return false for nil node")
-	}
-}
-func TestCSSGetterSetter(t *testing.T) {
-	handler := &CSSHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(css.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "regular rule",
-			input:    ".class { color: red; }",
-			expected: false,
-		},
-		{
-			name:     "pseudo class",
-			input:    ".class:hover { color: blue; }",
-			expected: false,
-		},
-		{
-			name:     "variable declaration",
-			input:    ":root { --main-color: blue; }",
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			result := handler.IsGetterSetter(node, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsGetterSetter() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-	if handler.IsGetterSetter(nil, []byte("")) {
-		t.Error("Expected IsGetterSetter to return false for nil node")
-	}
-}
-</document_content>
-</document>
-<document index="7">
-<source>filefusion/internal/core/cleaner/handlers/go_handler.go</source>
-<document_content>package handlers
-import (
-	"bytes"
-	"strings"
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type GoHandler struct {
-	BaseHandler
-}
-func (h *GoHandler) GetCommentTypes() []string {
-	return []string{"comment"}
-}
-func (h *GoHandler) GetImportTypes() []string {
-	return []string{"import_declaration", "import_spec"}
-}
-func (h *GoHandler) GetDocCommentPrefix() string {
-	return "///"
-}
-func (h *GoHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-	if node.Type() != "call_expression" {
-		return false
-	}
-	callText := content[node.StartByte():node.EndByte()]
-	return  ||
-		 ||
-		 ||
-}
-func (h *GoHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-	if node.Type() != "function_declaration" {
-		return false
-	}
-	nameNode := node.ChildByFieldName("name")
-	if nameNode == nil {
-		return false
-	}
-	name := string(content[nameNode.StartByte():nameNode.EndByte()])
-	return strings.HasPrefix(strings.ToLower(name), "get") ||
-		strings.HasPrefix(strings.ToLower(name), "set")
-}
-</document_content>
-</document>
-<document index="8">
-<source>filefusion/internal/core/cleaner/handlers/bash_handler_test.go</source>
-<document_content>package handlers
-import (
-	"strings"
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/bash"
-)
-func TestBashHandlerBasics(t *testing.T) {
-	handler := &BashHandler{}
-	commentTypes := handler.GetCommentTypes()
-	if len(commentTypes) != 1 || commentTypes[0] != "comment" {
-		t.Errorf("Expected ['comment'], got %v", commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	if len(importTypes) != 2 || importTypes[0] != "source_command" || importTypes[1] != "command" {
-		t.Errorf("Expected ['source_command', 'command'], got %v", importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != "#" {
-		t.Errorf("Expected '#', got %s", prefix)
-	}
-}
-func TestBashLoggingCalls(t *testing.T) {
-	handler := &BashHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(bash.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "stderr redirection",
-			input:    "echo 'Error' >&2",
-			expected: true,
-		},
-		{
-			name:     "logger command",
-			input:    "logger 'System startup complete'",
-			expected: true,
-		},
-		{
-			name:     "debug echo",
-			input:    "echo \"Debug: process started\"",
-			expected: true,
-		},
-		{
-			name:     "debug printf",
-			input:    "printf \"Debug: %s\\n\" \"$var\"",
-			expected: true,
-		},
-		{
-			name:     "regular echo",
-			input:    "echo 'Hello world'",
-			expected: false,
-		},
-		{
-			name:     "regular command",
-			input:    "ls -l",
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			if node == nil {
-				t.Fatal("Failed to get root node")
-			}
-			var printNode func(*sitter.Node, int)
-			printNode = func(n *sitter.Node, depth int) {
-				if n == nil {
-					return
-				}
-				indent := strings.Repeat("  ", depth)
-				content := ""
-				if n.StartByte() < uint32(len(tt.input)) && n.EndByte() <= uint32(len(tt.input)) {
-					content = string([]byte(tt.input)[n.StartByte():n.EndByte()])
-				}
-				t.Logf("%sNode type: %s, Content: %q", indent, n.Type(), content)
-				for i := 0; i < int(n.ChildCount()); i++ {
-					printNode(n.Child(i), depth+1)
-				}
-			}
-			printNode(node, 0)
-			var cmdNode *sitter.Node
-			var findCommand func(*sitter.Node)
-			findCommand = func(n *sitter.Node) {
-				if n.Type() == "command" || n.Type() == "redirected_statement" {
-					cmdNode = n
-					return
-				}
-				for i := 0; i < int(n.NamedChildCount()); i++ {
-					findCommand(n.NamedChild(i))
-				}
-			}
-			findCommand(node)
-			if cmdNode == nil {
-				t.Fatal("No command node found")
-			}
-			result := handler.IsLoggingCall(cmdNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsLoggingCall() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-}
-func TestBashGetterSetter(t *testing.T) {
-	handler := &BashHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(bash.GetLanguage())
-	input := `function get_value() { echo "$value"; }`
-	tree := parser.Parse(nil, []byte(input))
-	defer tree.Close()
-	node := tree.RootNode()
-	if handler.IsGetterSetter(node, []byte(input)) {
-		t.Error("Expected IsGetterSetter to always return false for Bash")
-	}
-}
-</document_content>
-</document>
-<document index="9">
-<source>filefusion/internal/core/cleaner/handlers/csharp_handler.go</source>
-<document_content>package handlers
-import (
-	"bytes"
-	"fmt"
-	"strings"
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type CSharpHandler struct {
-	BaseHandler
-}
-func (h *CSharpHandler) GetCommentTypes() []string {
-	return []string{"comment", "multiline_comment"}
-}
-func (h *CSharpHandler) GetImportTypes() []string {
-	return []string{"using_directive"}
-}
-func (h *CSharpHandler) GetDocCommentPrefix() string {
-	return "///"
-}
-func (h *CSharpHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-	if node == nil {
-		return false
-	}
-	if node.Type() != "invocation_expression" {
-		return false
-	}
-	memberAccess := node.Child(0)
-	if memberAccess == nil {
-		return false
-	}
-	if memberAccess.Type() != "member_access_expression" {
-		return false
-	}
-	callText := content[memberAccess.StartByte():memberAccess.EndByte()]
-	return bytes.Contains(callText, []byte("Console.")) ||
-		bytes.Contains(callText, []byte("Debug.")) ||
-		bytes.Contains(callText, []byte("Logger.")) ||
-		bytes.Contains(callText, []byte("Trace."))
-}
-func (h *CSharpHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-	if node == nil {
-		return false
-	}
-	switch node.Type() {
-	case "property_declaration":
-		accessorList := node.ChildByFieldName("accessors")
-		if accessorList != nil {
-			hasGetter := false
-			hasSetter := false
-			for i := 0; i < int(accessorList.ChildCount()); i++ {
-				accessor := accessorList.Child(i)
-				if accessor.Type() != "accessor_declaration" {
-					continue
-				}
-				text := string(content[accessor.StartByte():accessor.EndByte()])
-				if strings.Contains(text, "get") {
-					hasGetter = true
-				}
-				if strings.Contains(text, "set") {
-					hasSetter = true
-				}
-			}
-			return hasGetter || hasSetter
-		}
-		return false
-	case "method_declaration":
-		nameNode := node.ChildByFieldName("name")
-		bodyNode := node.ChildByFieldName("body")
-		if nameNode != nil && bodyNode != nil {
-			name := string(content[nameNode.StartByte():nameNode.EndByte()])
-			bodyText := string(content[bodyNode.StartByte():bodyNode.EndByte()])
-			if strings.HasPrefix(name, "Get") && strings.Contains(bodyText, "return") {
-				return true
-			}
-			if strings.HasPrefix(name, "Set") && strings.Contains(bodyText, "=") {
-				return true
-			}
-		}
-		return false
-	default:
-		return false
-	}
-}
-func hasAccessor(block *sitter.Node, content []byte) bool {
-	hasGetter := false
-	hasSetter := false
-	for i := 0; i < int(block.ChildCount()); i++ {
-		child := block.Child(i)
-		if child.Type() == "ERROR" {
-			text := string(content[child.StartByte():child.EndByte()])
-			if text == "get" {
-				hasGetter = true
-			} else if text == "set" {
-				hasSetter = true
-			}
-		}
-	}
-	return hasGetter || hasSetter
-}
-func findNextSibling(node *sitter.Node, nodeType string) *sitter.Node {
-	if node == nil || node.Parent() == nil {
-		return nil
-	}
-	parent := node.Parent()
-	for i := 0; i < int(parent.ChildCount()); i++ {
-		child := parent.Child(i)
-		if child == node {
-			for j := i + 1; j < int(parent.ChildCount()); j++ {
-				sibling := parent.Child(j)
-				if sibling.Type() == nodeType {
-					return sibling
-				}
-			}
-			break
-		}
-	}
-	return nil
-}
-</document_content>
-</document>
-<document index="10">
-<source>filefusion/internal/core/cleaner/handlers/html_handler.go</source>
-<document_content>package handlers
-import (
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type HTMLHandler struct {
-	BaseHandler
-}
-func (h *HTMLHandler) GetCommentTypes() []string {
-	return []string{"comment"}
-}
-func (h *HTMLHandler) GetImportTypes() []string {
-	return []string{"link_element", "script_element"}
-}
-func (h *HTMLHandler) GetDocCommentPrefix() string {
-	return "<!--"
-}
-func (h *HTMLHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-	return false
-}
-func (h *HTMLHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-	return false
-}
-</document_content>
-</document>
-<document index="11">
-<source>filefusion/internal/core/cleaner/cleaner.go</source>
-<document_content>package cleaner
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"strings"
-	"github.com/drgsn/filefusion/internal/core/cleaner/handlers"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/bash"
-	"github.com/smacker/go-tree-sitter/cpp"
-	"github.com/smacker/go-tree-sitter/csharp"
-	"github.com/smacker/go-tree-sitter/css"
-	"github.com/smacker/go-tree-sitter/golang"
-	"github.com/smacker/go-tree-sitter/html"
-	"github.com/smacker/go-tree-sitter/java"
-	"github.com/smacker/go-tree-sitter/javascript"
-	"github.com/smacker/go-tree-sitter/kotlin"
-	"github.com/smacker/go-tree-sitter/php"
-	"github.com/smacker/go-tree-sitter/python"
-	"github.com/smacker/go-tree-sitter/ruby"
-	"github.com/smacker/go-tree-sitter/sql"
-	"github.com/smacker/go-tree-sitter/swift"
-	"github.com/smacker/go-tree-sitter/typescript/typescript"
-)
-type Cleaner struct {
-	options  *CleanerOptions
-	language Language
-	handler  handlers.LanguageHandler
-}
-func NewCleaner(lang Language, options *CleanerOptions) (*Cleaner, error) {
-	if options == nil {
-		return nil, fmt.Errorf("cleaner options cannot be nil")
-	}
-	_, handler, err := getLanguageAndHandler(lang)
-	if err != nil {
-		return nil, err
-	}
-	return &Cleaner{
-		options:  options,
-		language: lang,
-		handler:  handler,
-	}, nil
-}
-func (c *Cleaner) Clean(input []byte) ([]byte, error) {
-	if len(input) == 0 {
-		return nil, fmt.Errorf("empty input")
-	}
-	parser := sitter.NewParser()
-	language, _, err := getLanguageAndHandler(c.language)
-	if err != nil {
-		return nil, fmt.Errorf("failed to get language handler: %w", err)
-	}
-	parser.SetLanguage(language)
-	tree := parser.Parse(nil, input)
-	if tree == nil {
-		return nil, fmt.Errorf("parsing error: failed to create syntax tree")
-	}
-	defer tree.Close()
-	root := tree.RootNode()
-	if root == nil {
-		return nil, fmt.Errorf("parsing error: empty syntax tree")
-	}
-	if root.HasError() {
-		return nil, fmt.Errorf("parsing error: invalid syntax")
-	}
-	output := make([]byte, len(input))
-	copy(output, input)
-	if err := c.processNode(root, &output); err != nil {
-		return nil, fmt.Errorf("processing error: %w", err)
-	}
-	if c.options.OptimizeWhitespace {
-		output = c.optimizeWhitespace(output)
-	}
-	return output, nil
-}
-func (c *Cleaner) processNode(node *sitter.Node, content *[]byte) error {
-	if !c.shouldProcessNode(node, content) {
-		return nil
-	}
-	for i := int(node.NamedChildCount()) - 1; i >= 0; i-- {
-		child := node.NamedChild(i)
-		if err := c.processNode(child, content); err != nil {
-			return err
-		}
-	}
-	shouldRemove := false
-	for _, commentType := range c.handler.GetCommentTypes() {
-		if node.Type() == commentType && c.shouldRemoveComment(node, *content) {
-			shouldRemove = true
-			break
-		}
-	}
-	if c.options.RemoveLogging && c.handler.IsLoggingCall(node, *content) {
-		shouldRemove = true
-	}
-	if c.options.RemoveGettersSetters && c.handler.IsGetterSetter(node, *content) {
-		shouldRemove = true
-	}
-	if shouldRemove {
-		*content = c.removeNode(node, *content)
-	}
-	return nil
-}
-func (c *Cleaner) shouldProcessNode(node *sitter.Node, content *[]byte) bool {
-	if node == nil || len(*content) == 0 {
-		return false
-	}
-	if node.StartByte() >= uint32(len(*content)) || node.EndByte() > uint32(len(*content)) {
-		return false
-	}
-	return true
-}
-func (c *Cleaner) shouldRemoveComment(node *sitter.Node, content []byte) bool {
-	if !c.options.RemoveComments {
-		return false
-	}
-	if c.options.PreserveDocComments {
-		commentText := content[node.StartByte():node.EndByte()]
-		docPrefix := c.handler.GetDocCommentPrefix()
-		if bytes.HasPrefix(bytes.TrimSpace(commentText), []byte(docPrefix)) {
-			return false
-		}
-		if bytes.HasPrefix(bytes.TrimSpace(commentText), []byte("// ")) {
-			text := string(bytes.TrimSpace(commentText))
-			if strings.HasPrefix(text, "// Doc ") {
-				return false
-			}
-		}
-	}
-	return true
-}
-func (c *Cleaner) removeNode(node *sitter.Node, content []byte) []byte {
-	start := node.StartByte()
-	end := node.EndByte()
-	lineStart := int(start)
-	for lineStart > 0 && content[lineStart-1] != '\n' {
-		lineStart--
-	}
-	lineEnd := int(end)
-	for lineEnd < len(content) && content[lineEnd] != '\n' {
-		lineEnd++
-	}
-	line := bytes.TrimSpace(content[lineStart:lineEnd])
-	nodeContent := bytes.TrimSpace(content[start:end])
-	if bytes.Equal(line, nodeContent) {
-		return append(content[:lineStart], content[lineEnd:]...)
-	}
-	return append(content[:start], content[end:]...)
-}
-func (c *Cleaner) optimizeWhitespace(content []byte) []byte {
-	if !c.options.OptimizeWhitespace {
-		return content
-	}
-	lines := bytes.Split(content, []byte("\n"))
-	var result [][]byte
-	var previousLineEmpty bool
-	for i := range lines {
-		line := bytes.TrimRight(lines[i], " \t")
-		isEmpty := len(bytes.TrimSpace(line)) == 0
-		if !isEmpty || (!c.options.RemoveEmptyLines && !previousLineEmpty) {
-			result = append(result, line)
-		}
-		previousLineEmpty = isEmpty
-	}
-	return append(bytes.Join(result, []byte("\n")), '\n')
-}
-func (c *Cleaner) CleanFile(r io.Reader, w io.Writer) error {
-	input, err := io.ReadAll(r)
-	if err != nil {
-		return fmt.Errorf("reading error: %w", err)
-	}
-	cleaned, err := c.Clean(input)
-	if err != nil {
-		return err
-	}
-	_, err = w.Write(cleaned)
-	return err
-}
-</document_content>
-</document>
-<document index="12">
-<source>filefusion/internal/core/cleaner/handlers/java_handler.go</source>
-<document_content>package handlers
-import (
-	"bytes"
-	"strings"
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type JavaHandler struct {
-	BaseHandler
-}
-func (h *JavaHandler) GetCommentTypes() []string {
-	return []string{"line_comment", "block_comment", "javadoc_comment"}
-}
-func (h *JavaHandler) GetImportTypes() []string {
-	return []string{"import_declaration"}
-}
-func (h *JavaHandler) GetDocCommentPrefix() string {
-	return "/**"
-}
-func (h *JavaHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-	nodeType := node.Type()
-	if nodeType != "method_invocation" {
-		return false
-	}
-	callText := content[node.StartByte():node.EndByte()]
-	loggingPatterns := []string{
-		"Logger",
-		"System.out",
-		"System.err",
-		"log.",
-		"logger.",
-	}
-	for _, pattern := range loggingPatterns {
-		if bytes.Contains(callText, []byte(pattern)) {
-			return true
-		}
-	}
-	return false
-}
-func (h *JavaHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-	if node.Type() != "method_declaration" {
-		return false
-	}
-	methodText := string(content[node.StartByte():node.EndByte()])
-	nameNode := node.ChildByFieldName("name")
-	if nameNode == nil {
-		return false
-	}
-	name := string(content[nameNode.StartByte():nameNode.EndByte()])
-	nameLower := strings.ToLower(name)
-	isGetter := (strings.HasPrefix(nameLower, "get") || strings.HasPrefix(nameLower, "is")) &&
-		strings.Contains(methodText, "return")
-	isSetter := strings.HasPrefix(nameLower, "set") &&
-		strings.Contains(methodText, "void")
-	return isGetter || isSetter
-}
-</document_content>
-</document>
-<document index="13">
-<source>filefusion/internal/core/cleaner/handlers/cpp_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/cpp"
-)
-func TestCPPHandlerBasics(t *testing.T) {
-	handler := &CPPHandler{}
-	commentTypes := handler.GetCommentTypes()
-	expected := []string{"comment", "multiline_comment"}
-	if !stringSliceEqual(commentTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	expected = []string{"preproc_include", "using_declaration"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != "///" {
-		t.Errorf("Expected '///', got %s", prefix)
-	}
-}
-func TestCPPLoggingCalls(t *testing.T) {
-	handler := &CPPHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(cpp.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "cout logging",
-			input:    "cout << \"Log message\" << endl;",
-			expected: true,
-		},
-		{
-			name:     "cerr logging",
-			input:    "cerr << \"Error message\" << endl;",
-			expected: true,
-		},
-		{
-			name:     "clog logging",
-			input:    "clog << \"Debug info\" << endl;",
-			expected: true,
-		},
-		{
-			name:     "printf logging",
-			input:    "printf(\"Debug: %s\\n\", message);",
-			expected: true,
-		},
-		{
-			name:     "fprintf logging",
-			input:    "fprintf(stderr, \"Error: %s\\n\", error);",
-			expected: true,
-		},
-		{
-			name:     "custom log call",
-			input:    "log(\"Message\");",
-			expected: true,
-		},
-		{
-			name:     "regular function call",
-			input:    "process(\"data\");",
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			var callNode *sitter.Node
-			cursor := sitter.NewTreeCursor(node)
-			defer cursor.Close()
-			var findCall func(*sitter.Node)
-			findCall = func(n *sitter.Node) {
-				if n.Type() == "call_expression" || n.Type() == "binary_expression" {
-					callNode = n
-					return
-				}
-				for i := 0; i < int(n.NamedChildCount()); i++ {
-					findCall(n.NamedChild(i))
-				}
-			}
-			findCall(node)
-			if callNode == nil {
-				t.Fatal("No call/binary expression node found")
-			}
-			result := handler.IsLoggingCall(callNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsLoggingCall() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-}
-func TestCPPGetterSetter(t *testing.T) {
-	handler := &CPPHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(cpp.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name: "getter method",
-			input: `string getName() const {
-                return name;
-            }`,
-			expected: true,
-		},
-		{
-			name: "setter method",
-			input: `void setName(string value) {
-                name = value;
-            }`,
-			expected: true,
-		},
-		{
-			name: "is getter",
-			input: `bool isValid() const {
-                return valid;
-            }`,
-			expected: true,
-		},
-		{
-			name: "regular method",
-			input: `void process() {
-                doWork();
-            }`,
-			expected: false,
-		},
-		{
-			name: "complex getter",
-			input: `int getValue(int index) {
-                return values[index];
-            }`,
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			var funcNode *sitter.Node
-			cursor := sitter.NewTreeCursor(node)
-			defer cursor.Close()
-			var findFunc func(*sitter.Node)
-			findFunc = func(n *sitter.Node) {
-				if n.Type() == "function_definition" {
-					funcNode = n
-					return
-				}
-				for i := 0; i < int(n.NamedChildCount()); i++ {
-					findFunc(n.NamedChild(i))
-				}
-			}
-			findFunc(node)
-			if funcNode == nil {
-				t.Fatal("No function definition node found")
-			}
-			result := handler.IsGetterSetter(funcNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsGetterSetter() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-}
-</document_content>
-</document>
-<document index="14">
-<source>filefusion/internal/core/cleaner/handlers/javascript_handler.go</source>
-<document_content>package handlers
-import (
-	"bytes"
-	"strings"
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type JavaScriptHandler struct {
-	BaseHandler
-}
-func (h *JavaScriptHandler) GetCommentTypes() []string {
-	return []string{"comment", "multiline_comment"}
-}
-func (h *JavaScriptHandler) GetImportTypes() []string {
-	return []string{"import_statement", "import_specifier"}
-}
-func (h *JavaScriptHandler) GetDocCommentPrefix() string {
-	return "/**"
-}
-func (h *JavaScriptHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-	if node.Type() != "call_expression" {
-		return false
-	}
-	callText := content[node.StartByte():node.EndByte()]
-	return bytes.HasPrefix(callText, []byte("console.")) ||
-}
-func (h *JavaScriptHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-	nodeType := node.Type()
-	if nodeType != "method_definition" &&
-		nodeType != "getter_declaration" &&
-		nodeType != "setter_declaration" {
-		return false
-	}
-	methodText := string(content[node.StartByte():node.EndByte()])
-	return strings.HasPrefix(methodText, "get ") ||
-		strings.HasPrefix(methodText, "set ") ||
-		nodeType == "getter_declaration" ||
-		nodeType == "setter_declaration"
-}
-</document_content>
-</document>
-<document index="15">
-<source>filefusion/internal/core/cleaner/handlers/javascript_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/javascript"
-)
-func TestJavaScriptHandlerBasics(t *testing.T) {
-	handler := &JavaScriptHandler{}
-	commentTypes := handler.GetCommentTypes()
-	expected := []string{"comment", "multiline_comment"}
-	if !stringSliceEqual(commentTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	expected = []string{"import_statement", "import_specifier"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != "/**" {
-		t.Errorf("Expected '/**', got %s", prefix)
-	}
-}
-func TestJavaScriptHandlerLoggingAndGetterSetter(t *testing.T) {
-	handler := &JavaScriptHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(javascript.GetLanguage())
-	tests := []struct {
-		name      string
-		input     string
-		isLogging bool
-		isGetter  bool
-	}{
-		{
-			name:      "console log",
-			input:     "console.log('test');",
-			isLogging: true,
-			isGetter:  false,
-		},
-		{
-			name:      "logger debug",
-			input:     "logger.debug('test');",
-			isLogging: true,
-			isGetter:  false,
-		},
-		{
-			name:      "getter method",
-			input:     "class Test { get name() { return this._name; } }",
-			isLogging: false,
-			isGetter:  true,
-		},
-		{
-			name:      "setter method",
-			input:     "class Test { set name(value) { this._name = value; } }",
-			isLogging: false,
-			isGetter:  true,
-		},
-		{
-			name:      "regular method",
-			input:     "function test() { return true; }",
-			isLogging: false,
-			isGetter:  false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			root := tree.RootNode()
-			if root == nil {
-				t.Fatal("Failed to get root node")
-			}
-			var checkNode func(*sitter.Node)
-			checkNode = func(n *sitter.Node) {
-				if n == nil {
-					return
-				}
-				nodeType := n.Type()
-				if nodeType == "call_expression" ||
-					nodeType == "method_definition" ||
-					nodeType == "getter_declaration" ||
-					nodeType == "setter_declaration" {
-					if got := handler.IsLoggingCall(n, []byte(tt.input)); got != tt.isLogging {
-						t.Errorf("IsLoggingCall() = %v, want %v for %s", got, tt.isLogging, nodeType)
-					}
-					if got := handler.IsGetterSetter(n, []byte(tt.input)); got != tt.isGetter {
-						t.Errorf("IsGetterSetter() = %v, want %v for %s", got, tt.isGetter, nodeType)
-					}
-				}
-				for i := 0; i < int(n.ChildCount()); i++ {
-					checkNode(n.Child(i))
-				}
-			}
-			checkNode(root)
-		})
-	}
-}
-</document_content>
-</document>
-<document index="16">
-<source>filefusion/internal/core/cleaner/handlers/php_handler.go</source>
-<document_content>package handlers
-import (
-	"strings"
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type PHPHandler struct {
-	BaseHandler
-}
-func (h *PHPHandler) GetCommentTypes() []string {
-	return []string{"comment", "doc_comment"}
-}
-func (h *PHPHandler) GetImportTypes() []string {
-	return []string{"namespace_use_declaration", "require", "require_once", "include", "include_once"}
-}
-func (h *PHPHandler) GetDocCommentPrefix() string {
-	return "/**"
-}
-func findNodeOfType(node *sitter.Node, nodeType string) *sitter.Node {
-	if node == nil {
-		return nil
-	}
-	if node.Type() == nodeType {
-		return node
-	}
-	for i := 0; i < int(node.NamedChildCount()); i++ {
-		if found := findNodeOfType(node.NamedChild(i), nodeType); found != nil {
-			return found
-		}
-	}
-	return nil
-}
-func (h *PHPHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-	if node == nil {
-		return false
-	}
-	var funcName string
-	nodeType := node.Type()
-	if nodeType == "function_call_expression" {
-		nameNode := node.ChildByFieldName("function")
-		if nameNode != nil && nameNode.StartByte() < uint32(len(content)) && nameNode.EndByte() <= uint32(len(content)) {
-			funcName = string(content[nameNode.StartByte():nameNode.EndByte()])
-		}
-	} else if nodeType == "echo_statement" {
-		return false
-	}
-	if funcName == "" {
-		return false
-	}
-	return funcName == "error_log" ||
-		funcName == "print_r" ||
-		funcName == "var_dump"
-}
-func (h *PHPHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-	if node == nil {
-		return false
-	}
-	methodNode := findNodeOfType(node, "method_declaration")
-	if methodNode == nil {
-		return false
-	}
-	if methodNode.StartByte() >= uint32(len(content)) || methodNode.EndByte() > uint32(len(content)) {
-		return false
-	}
-	methodText := string(content[methodNode.StartByte():methodNode.EndByte()])
-	return strings.Contains(methodText, "public function get") ||
-		strings.Contains(methodText, "public function set")
-}
-</document_content>
-</document>
-<document index="17">
-<source>filefusion/internal/core/cleaner/handlers/java_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/java"
-)
-func TestJavaHandlerBasics(t *testing.T) {
-	handler := &JavaHandler{}
-	commentTypes := handler.GetCommentTypes()
-	expected := []string{"line_comment", "block_comment", "javadoc_comment"}
-	if !stringSliceEqual(commentTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	expected = []string{"import_declaration"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != "/**" {
-		t.Errorf("Expected '/**', got %s", prefix)
-	}
-}
-func TestJavaHandlerLoggingAndGetterSetter(t *testing.T) {
-	handler := &JavaHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(java.GetLanguage())
-	tests := []struct {
-		name      string
-		input     string
-		isLogging bool
-		isGetter  bool
-	}{
-		{
-			name:      "logger field",
-			input:     "class Test { void test() { logger.info(\"test\"); } }",
-			isLogging: true,
-			isGetter:  false,
-		},
-		{
-			name:      "system out",
-			input:     "class Test { void test() { System.out.println(\"test\"); } }",
-			isLogging: true,
-			isGetter:  false,
-		},
-		{
-			name:      "system err",
-			input:     "class Test { void test() { System.err.println(\"error\"); } }",
-			isLogging: true,
-			isGetter:  false,
-		},
-		{
-			name:      "log call",
-			input:     "class Test { void test() { log.debug(\"debug\"); } }",
-			isLogging: true,
-			isGetter:  false,
-		},
-		{
-			name:      "Logger static call",
-			input:     "class Test { void test() { Logger.getLogger(Test.class).info(\"test\"); } }",
-			isLogging: true,
-			isGetter:  false,
-		},
-		{
-			name:      "regular method call",
-			input:     "class Test { void test() { process(\"data\"); } }",
-			isLogging: false,
-			isGetter:  false,
-		},
-		{
-			name:      "getter method",
-			input:     "class Test { public String getName() { return name; } }",
-			isLogging: false,
-			isGetter:  true,
-		},
-		{
-			name:      "setter method",
-			input:     "class Test { public void setName(String name) { this.name = name; } }",
-			isLogging: false,
-			isGetter:  true,
-		},
-		{
-			name:      "boolean getter with is prefix",
-			input:     "class Test { public boolean isValid() { return valid; } }",
-			isLogging: false,
-			isGetter:  true,
-		},
-		{
-			name:      "getter with javadoc",
-			input:     "class Test { /** Gets the name */ public String getName() { return name; } }",
-			isLogging: false,
-			isGetter:  true,
-		},
-		{
-			name:      "regular method",
-			input:     "class Test { public void process() { doWork(); } }",
-			isLogging: false,
-			isGetter:  false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			var cursor = sitter.NewTreeCursor(tree.RootNode())
-			defer cursor.Close()
-			var processNode func(*sitter.Node)
-			processNode = func(node *sitter.Node) {
-				if node == nil {
-					return
-				}
-				nodeType := node.Type()
-				if nodeType == "method_invocation" {
-					if got := handler.IsLoggingCall(node, []byte(tt.input)); got != tt.isLogging {
-						t.Errorf("IsLoggingCall() = %v, want %v for %s", got, tt.isLogging, nodeType)
-					}
-				} else if nodeType == "method_declaration" {
-					if got := handler.IsGetterSetter(node, []byte(tt.input)); got != tt.isGetter {
-						t.Errorf("IsGetterSetter() = %v, want %v for %s", got, tt.isGetter, nodeType)
-					}
-				}
-				for i := 0; i < int(node.NamedChildCount()); i++ {
-					child := node.NamedChild(i)
-					processNode(child)
-				}
-			}
-			processNode(tree.RootNode())
-		})
-	}
-}
-</document_content>
-</document>
-<document index="18">
-<source>filefusion/internal/core/cleaner/handlers/html_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/html"
-)
-func TestHTMLHandlerBasics(t *testing.T) {
-	handler := &HTMLHandler{}
-	commentTypes := handler.GetCommentTypes()
-	expected := []string{"comment"}
-	if !stringSliceEqual(commentTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	expected = []string{"link_element", "script_element"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != "<!--" {
-		t.Errorf("Expected '<!--', got %s", prefix)
-	}
-}
-func TestHTMLLoggingCalls(t *testing.T) {
-	handler := &HTMLHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(html.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "regular element",
-			input:    "<div>Test</div>",
-			expected: false,
-		},
-		{
-			name:     "script tag with console.log",
-			input:    "<script>console.log('test');</script>",
-			expected: false,
-		},
-		{
-			name:     "empty element",
-			input:    "<br/>",
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			result := handler.IsLoggingCall(node, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsLoggingCall() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-	if handler.IsLoggingCall(nil, []byte("")) {
-		t.Error("Expected IsLoggingCall to return false for nil node")
-	}
-	tree := parser.Parse(nil, []byte(""))
-	if tree == nil {
-		t.Fatal("Failed to parse empty input")
-	}
-	defer tree.Close()
-	if handler.IsLoggingCall(tree.RootNode(), []byte("")) {
-		t.Error("Expected IsLoggingCall to return false for empty content")
-	}
-}
-func TestHTMLGetterSetter(t *testing.T) {
-	handler := &HTMLHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(html.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "regular element",
-			input:    "<div>Test</div>",
-			expected: false,
-		},
-		{
-			name:     "input element",
-			input:    "<input type=\"text\" value=\"test\">",
-			expected: false,
-		},
-		{
-			name:     "script tag with getter",
-			input:    "<script>get value() { return this._value; }</script>",
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			result := handler.IsGetterSetter(node, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsGetterSetter() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-	if handler.IsGetterSetter(nil, []byte("")) {
-		t.Error("Expected IsGetterSetter to return false for nil node")
-	}
-	tree := parser.Parse(nil, []byte(""))
-	if tree == nil {
-		t.Fatal("Failed to parse empty input")
-	}
-	defer tree.Close()
-	if handler.IsGetterSetter(tree.RootNode(), []byte("")) {
-		t.Error("Expected IsGetterSetter to return false for empty content")
-	}
-}
-</document_content>
-</document>
-<document index="19">
-<source>filefusion/internal/core/cleaner/handlers/csharp_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/csharp"
-)
-func findFirstNodeOfType(root *sitter.Node, nodeType string) *sitter.Node {
-	if root == nil {
-		return nil
-	}
-	cursor := sitter.NewTreeCursor(root)
-	defer cursor.Close()
-	ok := cursor.GoToFirstChild()
-	for ok {
-		if cursor.CurrentNode().Type() == nodeType {
-			return cursor.CurrentNode()
-		}
-		if node := findFirstNodeOfType(cursor.CurrentNode(), nodeType); node != nil {
-			return node
-		}
-		ok = cursor.GoToNextSibling()
-	}
-	return nil
-}
-func TestCSharpHandlerBasics(t *testing.T) {
-	handler := &CSharpHandler{}
-	commentTypes := handler.GetCommentTypes()
-	expected := []string{"comment", "multiline_comment"}
-	if !stringSliceEqual(commentTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	expected = []string{"using_directive"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != "///" {
-		t.Errorf("Expected '///', got %s", prefix)
-	}
-}
-func TestCSharpLoggingCalls(t *testing.T) {
-	handler := &CSharpHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(csharp.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "console write",
-			input:    "Console.WriteLine(\"test\");",
-			expected: true,
-		},
-		{
-			name:     "debug log",
-			input:    "Debug.Log(\"test\");",
-			expected: true,
-		},
-		{
-			name:     "logger info",
-			input:    "Logger.Info(\"test\");",
-			expected: true,
-		},
-		{
-			name:     "trace write",
-			input:    "Trace.WriteLine(\"test\");",
-			expected: true,
-		},
-		{
-			name:     "regular method call",
-			input:    "Process(\"test\");",
-			expected: false,
-		},
-		{
-			name:     "string method",
-			input:    "\"test\".ToString();",
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			invocationNode := findFirstNodeOfType(tree.RootNode(), "invocation_expression")
-			if invocationNode == nil {
-				t.Fatal("Failed to find invocation_expression node")
-			}
-			result := handler.IsLoggingCall(invocationNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsLoggingCall() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-	if handler.IsLoggingCall(nil, []byte("")) {
-		t.Error("Expected IsLoggingCall to return false for nil node")
-	}
-}
-func TestCSharpGetterSetter(t *testing.T) {
-	handler := &CSharpHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(csharp.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{"auto_property", "public string Name { get; set; }", true},
-		{"getter_only_property", "public string Name { get; }", true},
-		{"setter_only_property", "public string Name { private set; }", true},
-		{"property_with_access_modifiers", "public string Name { private set; get; }", true},
-		{"getter_method", "public string GetName() { return name; }", true},
-		{"setter_method", "public void SetName(string value) { name = value; }", true},
-		{"regular_method", "public void Process() { }", false},
-		{"regular_property", "public string Name;", false},
-		{"invalid_property_syntax", "public string Name { get set; }", false},
-		{"empty_accessor_blocks", "public string Name { get; }", true},
-		{"invalid_accessor_body", "public string Name { get {} set; }", true},
-		{"missing_getter", "public string Name { set; }", true},
-		{"missing_setter", "public string Name { get; }", true},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			rootNode := tree.RootNode()
-			if rootNode == nil {
-				t.Fatal("Failed to get root node")
-			}
-			node := findRelevantNode(rootNode, []byte(tt.input), []string{"property_declaration", "method_declaration"})
-			if node == nil || node.Type() == "ERROR" {
-				t.Skip("Skipping unsupported syntax")
-			}
-			result := handler.IsGetterSetter(node, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsGetterSetter() = %v for input %q, got %v", tt.expected, tt.input, result)
-			}
-		})
-	}
-}
-func findRelevantNode(node *sitter.Node, content []byte, types []string) *sitter.Node {
-	if node == nil {
-		return nil
-	}
-	for _, nodeType := range types {
-		if node.Type() == nodeType || node.Type() == "ERROR" {
-			return node
-		}
-	}
-	for i := 0; i < int(node.ChildCount()); i++ {
-		child := node.Child(i)
-		if found := findRelevantNode(child, content, types); found != nil {
-			return found
-		}
-	}
-	return nil
-}
-</document_content>
-</document>
-<document index="20">
-<source>filefusion/cmd/filefusion/main.go</source>
-<document_content>package main
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-	"strings"
-	"github.com/drgsn/filefusion/internal/core"
-	"github.com/drgsn/filefusion/internal/core/cleaner"
-	"github.com/spf13/cobra"
-)
-var (
-	outputPath     string
-	pattern        string
-	exclude        string
-	maxFileSize    string
-	maxOutputSize  string
-	dryRun         bool
-	ignoreSymlinks bool
-	cleanEnabled         bool
-	removeComments       bool
-	preserveDocComments  bool
-	removeImports        bool
-	removeLogging        bool
-	removeGettersSetters bool
-	optimizeWhitespace   bool
-	removeEmptyLines     bool
-)
-var rootCmd = &cobra.Command{
-	Use:   "filefusion [paths...]",
-	Short: "Filefusion - File concatenation tool optimized for LLM usage",
-	Long: `Filefusion concatenates files into a format optimized for Large Language Models (LLMs).
-It preserves file metadata and structures the output in an XML-like or JSON format.
-Complete documentation is available at https://github.com/drgsn/filefusion`,
-	RunE: runMix,
-}
-func init() {
-	initCoreFlags()
-	initCleanerFlags()
-}
-func initCoreFlags() {
-	rootCmd.PersistentFlags().StringVarP(&outputPath, "output", "o", "", "output file path")
-	rootCmd.PersistentFlags().StringVarP(&pattern, "pattern", "p", "*.go,*.json,*.yaml,*.yml", "file patterns")
-	rootCmd.PersistentFlags().StringVarP(&exclude, "exclude", "e", "", "exclude patterns")
-	rootCmd.PersistentFlags().StringVar(&maxFileSize, "max-file-size", "10MB", "maximum size for individual input files")
-	rootCmd.PersistentFlags().StringVar(&maxOutputSize, "max-output-size", "50MB", "maximum size for output file")
-	rootCmd.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "Show the list of files that will be processed")
-	rootCmd.PersistentFlags().BoolVar(&ignoreSymlinks, "ignore-symlinks", false, "Ignore symbolic links when processing files")
-}
-func initCleanerFlags() {
-	rootCmd.PersistentFlags().BoolVar(&cleanEnabled, "clean", false, "enable code cleaning")
-	rootCmd.PersistentFlags().BoolVar(&removeComments, "clean-remove-comments", true, "remove comments during cleaning")
-	rootCmd.PersistentFlags().BoolVar(&preserveDocComments, "clean-preserve-doc-comments", true, "preserve documentation comments")
-	rootCmd.PersistentFlags().BoolVar(&removeImports, "clean-remove-imports", false, "remove import statements")
-	rootCmd.PersistentFlags().BoolVar(&removeLogging, "clean-remove-logging", true, "remove logging statements")
-	rootCmd.PersistentFlags().BoolVar(&removeGettersSetters, "clean-remove-getters-setters", true, "remove getter/setter methods")
-	rootCmd.PersistentFlags().BoolVar(&optimizeWhitespace, "clean-optimize-whitespace", true, "optimize whitespace")
-	rootCmd.PersistentFlags().BoolVar(&removeEmptyLines, "clean-remove-empty-lines", true, "remove empty lines")
-}
-func main() {
-	if err := rootCmd.Execute(); err != nil {
-		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
-		os.Exit(1)
-	}
-}
-func runMix(cmd *cobra.Command, args []string) error {
-	config, err := validateAndGetConfig(args)
-	if err != nil {
-		return err
-	}
-	if len(args) == 0 {
-		currentDir, err := os.Getwd()
-		if err != nil {
-			return fmt.Errorf("error getting current working directory: %w", err)
-		}
-		args = []string{currentDir}
-	}
-	fileManager := core.NewFileManager(config.MaxFileSize, config.MaxOutputSize, config.OutputType)
-	finder := core.NewFileFinder(config.IncludePatterns, config.ExcludePatterns, !ignoreSymlinks)
-	files, err := finder.FindMatchingFiles(args)
-	if err != nil {
-		return fmt.Errorf("error finding files: %w", err)
-	}
-	validFiles, err := fileManager.ValidateFiles(files)
-	if err != nil {
-		return err
-	}
-	if dryRun {
-		return nil
-	}
-	outputPaths, err := fileManager.DeriveOutputPaths(args, outputPath)
-	if err != nil {
-		return err
-	}
-	fileGroups, err := fileManager.GroupFilesByOutput(validFiles, outputPaths)
-	if err != nil {
-		return err
-	}
-	for _, group := range fileGroups {
-		processor := core.NewFileProcessor(&core.MixOptions{
-			MaxFileSize:    config.MaxFileSize,
-			MaxOutputSize:  config.MaxOutputSize,
-			OutputType:     config.OutputType,
-			CleanerOptions: config.CleanerOptions,
-		})
-		contents, err := processor.ProcessFiles(group.Files)
-		if err != nil {
-			return fmt.Errorf("error processing files for %s: %w", group.OutputPath, err)
-		}
-		generator, err := core.NewOutputGenerator(&core.MixOptions{
-			OutputPath:    group.OutputPath,
-			OutputType:    config.OutputType,
-			MaxOutputSize: config.MaxOutputSize,
-		})
-		if err != nil {
-			return fmt.Errorf("error creating output: %w", err)
-		}
-		if err := generator.Generate(contents); err != nil {
-			return fmt.Errorf("error generating output for %s: %w", group.OutputPath, err)
-		}
-	}
-	return nil
-}
-type Config struct {
-	IncludePatterns []string
-	ExcludePatterns []string
-	MaxFileSize     int64
-	MaxOutputSize   int64
-	OutputType      core.OutputType
-	CleanerOptions  *cleaner.CleanerOptions
-}
-func validateAndGetConfig(args []string) (*Config, error) {
-	if pattern == "" {
-		return nil, fmt.Errorf("pattern cannot be empty")
-	}
-	validator := core.NewPatternValidator()
-	includePatterns, err := validator.ExpandPattern(pattern)
-	if err != nil {
-		return nil, fmt.Errorf("invalid include pattern: %w", err)
-	}
-	var excludePatterns []string
-	if exclude != "" {
-		excludePatterns, err = validator.ExpandPattern(exclude)
-		if err != nil {
-			return nil, fmt.Errorf("invalid exclude pattern: %w", err)
-		}
-	}
-	fileManager := core.NewFileManager(0, 0, core.OutputTypeXML)
-	maxFileSizeBytes, err := fileManager.ParseSize(maxFileSize)
-	if err != nil {
-		return nil, fmt.Errorf("invalid max-file-size value: %w", err)
-	}
-	maxOutputSizeBytes, err := fileManager.ParseSize(maxOutputSize)
-	if err != nil {
-		return nil, fmt.Errorf("invalid max-output-size value: %w", err)
-	}
-	outputType, err := validateAndGetOutputType(outputPath)
-	if err != nil {
-		return nil, err
-	}
-	cleanerOpts := getCleanerOptions()
-	return &Config{
-		IncludePatterns: includePatterns,
-		ExcludePatterns: excludePatterns,
-		MaxFileSize:     maxFileSizeBytes,
-		MaxOutputSize:   maxOutputSizeBytes,
-		OutputType:      outputType,
-		CleanerOptions:  cleanerOpts,
-	}, nil
-}
-func validateAndGetOutputType(outputPath string) (core.OutputType, error) {
-	if outputPath == "" {
-		return core.OutputTypeXML, nil
-	}
-	ext := strings.ToLower(filepath.Ext(outputPath))
-	switch ext {
-	case ".json":
-		return core.OutputTypeJSON, nil
-	case ".yaml", ".yml":
-		return core.OutputTypeYAML, nil
-	case ".xml":
-		return core.OutputTypeXML, nil
-	default:
-		return "", fmt.Errorf("invalid output file extension: must be .xml, .json, .yaml, or .yml")
-	}
-}
-</document_content>
-</document>
-<document index="21">
-<source>filefusion/internal/core/cleaner/handlers/python_handler.go</source>
-<document_content>package handlers
-import (
-	"bytes"
-	"strings"
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type PythonHandler struct {
-	BaseHandler
-}
-func (h *PythonHandler) GetCommentTypes() []string {
-	return []string{"comment"}
-}
-func (h *PythonHandler) GetImportTypes() []string {
-	return []string{"import_statement", "import_from_statement"}
-}
-func (h *PythonHandler) GetDocCommentPrefix() string {
-	return "\"\"\""
-}
-func (h *PythonHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-	if node == nil || node.Type() != "call" {
-		return false
-	}
-	if node.StartByte() >= uint32(len(content)) || node.EndByte() > uint32(len(content)) {
-		return false
-	}
-	callText := content[node.StartByte():node.EndByte()]
-	return bytes.HasPrefix(callText, []byte("print(")) ||
-		bytes.HasPrefix(callText, []byte("logging.")) ||
-}
-func (h *PythonHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-	if node == nil || node.Type() != "function_definition" {
-		return false
-	}
-	if node.StartByte() >= uint32(len(content)) || node.EndByte() > uint32(len(content)) {
-		return false
-	}
-	parent := node.Parent()
-	if parent != nil {
-		parentText := string(content[parent.StartByte():parent.EndByte()])
-		if strings.Contains(parentText, "@property") {
-			return true
-		}
-	}
-	nameNode := node.ChildByFieldName("name")
-	if nameNode == nil {
-		return false
-	}
-	name := string(content[nameNode.StartByte():nameNode.EndByte()])
-	return strings.HasPrefix(name, "get_") ||
-		strings.HasPrefix(name, "set_")
-}
-</document_content>
-</document>
-<document index="22">
-<source>filefusion/internal/core/cleaner/handlers/sql_handler.go</source>
-<document_content>package handlers
-import (
-    sitter "github.com/smacker/go-tree-sitter"
-)
-type SQLHandler struct {
-    BaseHandler
-}
-func (h *SQLHandler) GetCommentTypes() []string {
-    return []string{"comment", "block_comment"}
-}
-func (h *SQLHandler) GetImportTypes() []string {
-    return []string{"create_extension_statement", "use_statement"}
-}
-func (h *SQLHandler) GetDocCommentPrefix() string {
-    return "--"
-}
-func (h *SQLHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-    return false
-}
-func (h *SQLHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-    return false
-}
-</document_content>
-</document>
-<document index="23">
-<source>filefusion/internal/core/cleaner/handlers/ruby_handler.go</source>
-<document_content>package handlers
-import (
-	"bytes"
-	"strings"
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type RubyHandler struct {
-	BaseHandler
-}
-func (h *RubyHandler) GetCommentTypes() []string {
-	return []string{"comment"}
-}
-func (h *RubyHandler) GetImportTypes() []string {
-	return []string{"require", "include", "require_relative"}
-}
-func (h *RubyHandler) GetDocCommentPrefix() string {
-	return "#"
-}
-func (h *RubyHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-	if node == nil || len(content) == 0 {
-		return false
-	}
-	nodeType := node.Type()
-	if nodeType != "call" && nodeType != "method_call" && nodeType != "command" {
-		return false
-	}
-	callText := content[node.StartByte():node.EndByte()]
-	return bytes.HasPrefix(callText, []byte("puts ")) ||
-		bytes.HasPrefix(callText, []byte("print ")) ||
-		bytes.HasPrefix(callText, []byte("p ")) ||
-}
-func (h *RubyHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-	if node == nil || len(content) == 0 {
-		return false
-	}
-	nodeType := node.Type()
-	if nodeType != "call" && nodeType != "method" && nodeType != "method_definition" {
-		return false
-	}
-	methodText := string(content[node.StartByte():node.EndByte()])
-	return strings.Contains(methodText, "attr_reader") ||
-		strings.Contains(methodText, "attr_writer") ||
-		strings.Contains(methodText, "attr_accessor") ||
-		strings.HasPrefix(methodText, "def get_") ||
-		strings.HasPrefix(methodText, "def set_")
-}
-</document_content>
-</document>
-<document index="24">
-<source>filefusion/internal/core/cleaner/handlers/go_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/golang"
-)
-func TestGoHandlerBasics(t *testing.T) {
-	handler := &GoHandler{}
-	commentTypes := handler.GetCommentTypes()
-	expected := []string{"comment"}
-	if !stringSliceEqual(commentTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	expected = []string{"import_declaration", "import_spec"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != "///" {
-		t.Errorf("Expected '///', got %s", prefix)
-	}
-}
-func TestGoHandlerLoggingAndGetterSetter(t *testing.T) {
-	handler := &GoHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(golang.GetLanguage())
-	tests := []struct {
-		name      string
-		input     string
-		isLogging bool
-		isGetter  bool
-	}{
-		{
-			name:      "log print",
-			input:     "package main\nfunc main() { log.Println(\"test\") }",
-			isLogging: true,
-			isGetter:  false,
-		},
-		{
-			name:      "logger debug",
-			input:     "package main\nfunc main() { logger.Debug(\"test\") }",
-			isLogging: true,
-			isGetter:  false,
-		},
-		{
-			name:      "getter method",
-			input:     "package main\nfunc GetName() string { return name }",
-			isLogging: false,
-			isGetter:  true,
-		},
-		{
-			name:      "setter method",
-			input:     "package main\nfunc SetName(name string) { this.name = name }",
-			isLogging: false,
-			isGetter:  true,
-		},
-		{
-			name:      "regular function",
-			input:     "package main\nfunc Process() error { return nil }",
-			isLogging: false,
-			isGetter:  false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			var processNode func(*sitter.Node)
-			processNode = func(node *sitter.Node) {
-				if node == nil {
-					return
-				}
-				nodeType := node.Type()
-				if nodeType == "call_expression" {
-					if got := handler.IsLoggingCall(node, []byte(tt.input)); got != tt.isLogging {
-						t.Errorf("IsLoggingCall() = %v, want %v for %s", got, tt.isLogging, nodeType)
-					}
-				} else if nodeType == "function_declaration" {
-					if got := handler.IsGetterSetter(node, []byte(tt.input)); got != tt.isGetter {
-						t.Errorf("IsGetterSetter() = %v, want %v for %s", got, tt.isGetter, nodeType)
-					}
-				}
-				for i := 0; i < int(node.NamedChildCount()); i++ {
-					processNode(node.NamedChild(i))
-				}
-			}
-			processNode(tree.RootNode())
-		})
-	}
-}
-</document_content>
-</document>
-<document index="25">
-<source>filefusion/internal/core/cleaner/handlers/typescript_handler.go</source>
-<document_content>package handlers
-type TypeScriptHandler struct {
-	JavaScriptHandler
-}
-func (h *TypeScriptHandler) GetImportTypes() []string {
-	baseTypes := h.JavaScriptHandler.GetImportTypes()
-	return append(baseTypes, "import_require_clause", "import_alias")
-}
-</document_content>
-</document>
-<document index="26">
-<source>filefusion/internal/core/cleaner/handlers/kotlin_handler.go</source>
-<document_content>package handlers
-import (
-	"bytes"
-	"strings"
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type KotlinHandler struct {
-	BaseHandler
-}
-func (h *KotlinHandler) GetCommentTypes() []string {
-	return []string{"comment", "multiline_comment", "kdoc"}
-}
-func (h *KotlinHandler) GetImportTypes() []string {
-	return []string{"import_header"}
-}
-func (h *KotlinHandler) GetDocCommentPrefix() string {
-	return "/**"
-}
-func (h *KotlinHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-	if node == nil || node.Type() != "call_expression" {
-		return false
-	}
-	if node.StartByte() >= uint32(len(content)) || node.EndByte() > uint32(len(content)) {
-		return false
-	}
-	callText := content[node.StartByte():node.EndByte()]
-	return bytes.Contains(bytes.ToLower(callText), []byte("println(")) ||
-		bytes.Contains(bytes.ToLower(callText), []byte("print(")) ||
-		bytes.Contains(callText, []byte("Logger.")) ||
-		 ||
-}
-func findFirstChild(node *sitter.Node, nodeType string) *sitter.Node {
-	if node == nil {
-		return nil
-	}
-	if node.Type() == nodeType {
-		return node
-	}
-	for i := 0; i < int(node.NamedChildCount()); i++ {
-		if found := findFirstChild(node.NamedChild(i), nodeType); found != nil {
-			return found
-		}
-	}
-	return nil
-}
-func (h *KotlinHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-	if node == nil {
-		return false
-	}
-	if node.Type() == "source_file" {
-		var propertyFound bool
-		for i := 0; i < int(node.NamedChildCount()); i++ {
-			child := node.NamedChild(i)
-			if child.Type() == "property_declaration" {
-				propertyFound = true
-				break
-			}
-		}
-		if propertyFound {
-			for i := 0; i < int(node.NamedChildCount()); i++ {
-				child := node.NamedChild(i)
-				if child.Type() == "getter" || child.Type() == "setter" {
-					return true
-				}
-			}
-		}
-		for i := 0; i < int(node.NamedChildCount()); i++ {
-			child := node.NamedChild(i)
-			if child.Type() == "function_declaration" {
-				for j := 0; j < int(child.NamedChildCount()); j++ {
-					nameNode := child.NamedChild(j)
-					if nameNode.Type() == "simple_identifier" {
-						name := string(content[nameNode.StartByte():nameNode.EndByte()])
-						if strings.HasPrefix(strings.ToLower(name), "get") || strings.HasPrefix(strings.ToLower(name), "set") {
-							return true
-						}
-						break
-					}
-				}
-			}
-		}
-		return false
-	}
-	switch node.Type() {
-	case "property_declaration":
-		if parent := node.Parent(); parent != nil {
-			for i := 0; i < int(parent.NamedChildCount()); i++ {
-				child := parent.NamedChild(i)
-				if child.Type() == "getter" || child.Type() == "setter" {
-					return true
-				}
-			}
-		}
-	case "getter", "setter":
-		return true
-	case "function_declaration":
-		for i := 0; i < int(node.NamedChildCount()); i++ {
-			nameNode := node.NamedChild(i)
-			if nameNode.Type() == "simple_identifier" {
-				name := string(content[nameNode.StartByte():nameNode.EndByte()])
-				if strings.HasPrefix(strings.ToLower(name), "get") || strings.HasPrefix(strings.ToLower(name), "set") {
-					return true
-				}
-				break
-			}
-		}
-	}
-	return false
-}
-</document_content>
-</document>
-<document index="27">
-<source>filefusion/internal/core/cleaner/options.go</source>
-<document_content>package cleaner
-type CleanerOptions struct {
-	RemoveComments bool
-	PreserveDocComments bool
-	RemoveImports bool
-	RemoveLogging bool
-	RemoveGettersSetters bool
-	OptimizeWhitespace bool
-	RemoveEmptyLines bool
-	LoggingPrefixes map[Language][]string
-}
-func DefaultOptions() *CleanerOptions {
-	return &CleanerOptions{
-		RemoveComments:       true,
-		PreserveDocComments:  true,
-		RemoveImports:        false,
-		RemoveLogging:        true,
-		RemoveGettersSetters: true,
-		OptimizeWhitespace:   true,
-		RemoveEmptyLines:     true,
-		LoggingPrefixes: map[Language][]string{
-			LangGo:         {"log.", "logger."},
-			LangJava:       {"Logger.", "System.out.", "System.err."},
-			LangPython:     {"logging.", "logger.", "print(", "print ("},
-			LangJavaScript: {"console.", "logger."},
-			LangTypeScript: {"console.", "logger."},
-			LangPHP:        {"error_log(", "print_r(", "var_dump("},
-			LangRuby:       {"puts ", "print ", "p ", "logger."},
-			LangCSharp:     {"Console.", "Debug.", "Logger."},
-			LangSwift:      {"print(", "debugPrint(", "NSLog("},
-			LangKotlin:     {"println(", "print(", "Logger."},
-		},
-	}
-}
-</document_content>
-</document>
-<document index="28">
-<source>filefusion/internal/core/cleaner/handlers/php_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/php"
-)
-func TestPHPHandlerBasics(t *testing.T) {
-	handler := &PHPHandler{}
-	commentTypes := handler.GetCommentTypes()
-	expected := []string{"comment", "doc_comment"}
-	if !stringSliceEqual(commentTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	expected = []string{"namespace_use_declaration", "require", "require_once", "include", "include_once"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != "/**" {
-		t.Errorf("Expected '/**', got %s", prefix)
-	}
-}
-func TestPHPLoggingCalls(t *testing.T) {
-	handler := &PHPHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(php.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "error_log call",
-			input:    "<?php error_log('Error message'); ?>",
-			expected: true,
-		},
-		{
-			name:     "print_r call",
-			input:    "<?php print_r($data); ?>",
-			expected: true,
-		},
-		{
-			name:     "var_dump call",
-			input:    "<?php var_dump($variable); ?>",
-			expected: true,
-		},
-		{
-			name:     "regular echo",
-			input:    "<?php echo 'Hello'; ?>",
-			expected: false,
-		},
-		{
-			name:     "regular function call",
-			input:    "<?php process($data); ?>",
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			var callNode *sitter.Node
-			var findCall func(*sitter.Node)
-			findCall = func(n *sitter.Node) {
-				if n == nil {
-					return
-				}
-				t.Logf("Node type: %s", n.Type())
-				nodeType := n.Type()
-				if nodeType == "function_call_expression" {
-					callNode = n
-					return
-				}
-				if nodeType == "echo_statement" {
-					callNode = n
-					return
-				}
-				for i := 0; i < int(n.ChildCount()); i++ {
-					findCall(n.Child(i))
-				}
-			}
-			findCall(node)
-			if callNode == nil {
-				t.Fatalf("No function call node found in input: %s\nAST structure: %s", tt.input, node.String())
-			}
-			result := handler.IsLoggingCall(callNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsLoggingCall() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-}
-func TestPHPGetterSetter(t *testing.T) {
-	handler := &PHPHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(php.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name: "getter method",
-			input: `<?php
-                class Test {
-                    public function getName() {
-                        return $this->name;
-                    }
-                }
-            ?>`,
-			expected: true,
-		},
-		{
-			name: "setter method",
-			input: `<?php
-                class Test {
-                    public function setName($value) {
-                        $this->name = $value;
-                    }
-                }
-            ?>`,
-			expected: true,
-		},
-		{
-			name: "regular method",
-			input: `<?php
-                class Test {
-                    public function process() {
-                        return $this->doWork();
-                    }
-                }
-            ?>`,
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			var methodNode *sitter.Node
-			var findMethod func(*sitter.Node)
-			findMethod = func(n *sitter.Node) {
-				if n == nil {
-					return
-				}
-				if n.Type() == "method_declaration" {
-					methodNode = n
-					return
-				}
-				for i := 0; i < int(n.NamedChildCount()); i++ {
-					findMethod(n.NamedChild(i))
-				}
-			}
-			findMethod(node)
-			if methodNode == nil {
-				t.Fatal("No method declaration node found")
-			}
-			result := handler.IsGetterSetter(methodNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsGetterSetter() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-}
-</document_content>
-</document>
-<document index="29">
-<source>filefusion/internal/core/cleaner/handlers/typescript_handler_test.go</source>
-<document_content>package handlers
-import "testing"
-func TestTypeScriptHandler(t *testing.T) {
-	handler := &TypeScriptHandler{}
-	importTypes := handler.GetImportTypes()
-	baseImportTypes := handler.JavaScriptHandler.GetImportTypes()
-	for _, baseType := range baseImportTypes {
-		found := false
-		for _, importType := range importTypes {
-			if importType == baseType {
-				found = true
-				break
-			}
-		}
-		if !found {
-			t.Errorf("TypeScript handler missing base import type: %s", baseType)
-		}
-	}
-	if len(importTypes) <= len(baseImportTypes) {
-		t.Error("TypeScript handler should have additional import types")
-	}
-	extraTypes := []string{"import_require_clause", "import_alias"}
-	for _, extraType := range extraTypes {
-		found := false
-		for _, importType := range importTypes {
-			if importType == extraType {
-				found = true
-				break
-			}
-		}
-		if !found {
-			t.Errorf("TypeScript handler missing import type: %s", extraType)
-		}
-	}
-}
-</document_content>
-</document>
-<document index="30">
-<source>filefusion/internal/core/cleaner/types.go</source>
-<document_content>package cleaner
-type Language string
-const (
-	LangGo         Language = "go"
-	LangJava       Language = "java"
-	LangPython     Language = "python"
-	LangSwift      Language = "swift"
-	LangKotlin     Language = "kotlin"
-	LangSQL        Language = "sql"
-	LangHTML       Language = "html"
-	LangJavaScript Language = "javascript"
-	LangTypeScript Language = "typescript"
-	LangCSS        Language = "css"
-	LangCPP        Language = "cpp"
-	LangCSharp     Language = "csharp"
-	LangPHP        Language = "php"
-	LangRuby       Language = "ruby"
-	LangBash       Language = "bash"
-)
-</document_content>
-</document>
-<document index="31">
-<source>filefusion/internal/core/cleaner/cleaner_test.go</source>
-<document_content>package cleaner
-import (
-	"bytes"
-	"context"
-	"fmt"
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/golang"
-)
-type errorReader struct {
-	err error
-}
-func (r *errorReader) Read(p []byte) (n int, err error) {
-	return 0, r.err
-}
-func TestNewCleaner(t *testing.T) {
-	tests := []struct {
-		name        string
-		lang        Language
-		options     *CleanerOptions
-		shouldError bool
-	}{
-		{
-			name:        "valid Go cleaner",
-			lang:        LangGo,
-			options:     DefaultOptions(),
-			shouldError: false,
-		},
-		{
-			name:        "nil options",
-			lang:        LangGo,
-			options:     nil,
-			shouldError: true,
-		},
-		{
-			name:        "unsupported language",
-			lang:        "invalid",
-			options:     DefaultOptions(),
-			shouldError: true,
-		},
-		{
-			name:        "valid Java cleaner",
-			lang:        LangJava,
-			options:     DefaultOptions(),
-			shouldError: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			cleaner, err := NewCleaner(tt.lang, tt.options)
-			if tt.shouldError {
-				if err == nil {
-					t.Error("Expected error but got none")
-				}
-				return
-			}
-			if err != nil {
-				t.Errorf("Unexpected error: %v", err)
-				return
-			}
-			if cleaner == nil {
-				t.Error("Expected non-nil cleaner")
-			}
-		})
-	}
-}
-func TestClean(t *testing.T) {
-	tests := []struct {
-		name           string
-		lang           Language
-		input          string
-		options        *CleanerOptions
-		expected       string
-		shouldContain  []string
-		shouldNotMatch []string
-		shouldError    bool
-	}{
-		{
-			name:  "remove Go comments",
-			lang:  LangGo,
-			input: "package main\n// This is a comment\nfunc main() {}\n/* Block comment */\n",
-			options: &CleanerOptions{
-				RemoveComments:      true,
-				PreserveDocComments: false,
-				OptimizeWhitespace:  true,
-				RemoveEmptyLines:    true,
-			},
-			expected: "package main\nfunc main() {}\n",
-		},
-		{
-			name:  "preserve Go doc comments",
-			lang:  LangGo,
-			input: "package main\n// Regular comment\n/// Doc comment\nfunc main() {}\n",
-			options: &CleanerOptions{
-				RemoveComments:      true,
-				PreserveDocComments: true,
-			},
-			shouldContain:  []string{"/// Doc comment"},
-			shouldNotMatch: []string{"// Regular comment"},
-		},
-		{
-			name:  "remove Java logging",
-			lang:  LangJava,
-			input: "class Test {\nvoid test() {\nlog.info(\"test\");\nSystem.out.println(\"debug\");\n}\n}",
-			options: &CleanerOptions{
-				RemoveLogging: true,
-			},
-			shouldNotMatch: []string{"log.info", "System.out.println"},
-		},
-		{
-			name:  "remove getters",
-			lang:  LangJava,
-			input: "public class Test {\n    public String getName() { return name; }\n    void otherMethod() {}\n}",
-			options: &CleanerOptions{
-				RemoveGettersSetters: true,
-			},
-			shouldContain:  []string{"otherMethod"},
-			shouldNotMatch: []string{"getName"},
-		},
-		{
-			name:  "optimize whitespace",
-			lang:  LangGo,
-			input: "package main\n\n\nfunc main() {\n\n\n}\n\n",
-			options: &CleanerOptions{
-				OptimizeWhitespace: true,
-				RemoveEmptyLines:   true,
-			},
-			expected: "package main\nfunc main() {\n}\n",
-		},
-		{
-			name:  "invalid syntax",
-			lang:  LangGo,
-			input: "package main\nfunc main() {",
-			options: &CleanerOptions{
-				RemoveComments: true,
-			},
-			shouldError: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			cleaner, err := NewCleaner(tt.lang, tt.options)
-			if err != nil {
-				t.Fatalf("Failed to create cleaner: %v", err)
-			}
-			output, err := cleaner.Clean([]byte(tt.input))
-			if tt.shouldError {
-				if err == nil {
-					t.Error("Expected error but got none")
-				}
-				return
-			}
-			if err != nil {
-				t.Errorf("Unexpected error: %v", err)
-				return
-			}
-			if tt.expected != "" && string(output) != tt.expected {
-				t.Errorf("Expected:\n%s\nGot:\n%s", tt.expected, string(output))
-			}
-			for _, s := range tt.shouldContain {
-				if !bytes.Contains(output, []byte(s)) {
-					t.Errorf("Expected output to contain %q", s)
-				}
-			}
-			for _, s := range tt.shouldNotMatch {
-				if bytes.Contains(output, []byte(s)) {
-					t.Errorf("Expected output to not contain %q", s)
-				}
-			}
-		})
-	}
-}
-func TestCleanFile(t *testing.T) {
-	tests := []struct {
-		name        string
-		input       string
-		options     *CleanerOptions
-		shouldError bool
-	}{
-		{
-			name:        "valid input",
-			input:       "package main\nfunc main() {}\n",
-			shouldError: false,
-		},
-		{
-			name:        "invalid reader",
-			input:       "",
-			shouldError: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			cleaner, err := NewCleaner(LangGo, DefaultOptions())
-			if err != nil {
-				t.Fatalf("Failed to create cleaner: %v", err)
-			}
-			var input bytes.Buffer
-			if tt.name == "invalid reader" {
-				r := &errorReader{err: fmt.Errorf("read error")}
-				var output bytes.Buffer
-				err = cleaner.CleanFile(r, &output)
-			} else {
-				input.WriteString(tt.input)
-				var output bytes.Buffer
-				err = cleaner.CleanFile(&input, &output)
-			}
-			if tt.shouldError {
-				if err == nil {
-					t.Error("Expected error but got none")
-				}
-				return
-			}
-			if err != nil {
-				t.Errorf("Unexpected error: %v", err)
-				return
-			}
-		})
-	}
-}
-func TestProcessNode(t *testing.T) {
-	parser := sitter.NewParser()
-	parser.SetLanguage(golang.GetLanguage())
-	input := []byte("package main\n// Comment\nfunc main() {}\n")
-	tree, err := parser.ParseCtx(context.Background(), nil, input)
-	if err != nil {
-		t.Fatalf("Failed to parse input: %v", err)
-	}
-	defer tree.Close()
-	tests := []struct {
-		name           string
-		options        *CleanerOptions
-		shouldContain  []string
-		shouldNotMatch []string
-	}{
-		{
-			name: "remove comments",
-			options: &CleanerOptions{
-				RemoveComments:      true,
-				PreserveDocComments: false,
-			},
-			shouldNotMatch: []string{"// Comment"},
-		},
-		{
-			name: "preserve structure",
-			options: &CleanerOptions{
-				RemoveComments: true,
-			},
-			shouldContain: []string{"package main", "func main()"},
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			cleaner, err := NewCleaner(LangGo, tt.options)
-			if err != nil {
-				t.Fatalf("Failed to create cleaner: %v", err)
-			}
-			content := make([]byte, len(input))
-			copy(content, input)
-			err = cleaner.processNode(tree.RootNode(), &content)
-			if err != nil {
-				t.Fatalf("Failed to process node: %v", err)
-			}
-			for _, s := range tt.shouldContain {
-				if !bytes.Contains(content, []byte(s)) {
-					t.Errorf("Expected output to contain %q", s)
-				}
-			}
-			for _, s := range tt.shouldNotMatch {
-				if bytes.Contains(content, []byte(s)) {
-					t.Errorf("Expected output to not contain %q", s)
-				}
-			}
-		})
-	}
-}
-func TestShouldRemoveComment(t *testing.T) {
-	parser := sitter.NewParser()
-	parser.SetLanguage(golang.GetLanguage())
-	tests := []struct {
-		name        string
-		options     *CleanerOptions
-		commentText string
-		shouldKeep  bool
-	}{
-		{
-			name: "regular comment with removal enabled",
-			options: &CleanerOptions{
-				RemoveComments:      true,
-				PreserveDocComments: false,
-			},
-			commentText: "// Regular comment",
-			shouldKeep:  false,
-		},
-		{
-			name: "doc comment with preservation enabled",
-			options: &CleanerOptions{
-				RemoveComments:      true,
-				PreserveDocComments: true,
-			},
-			commentText: "// Doc comment",
-			shouldKeep:  true,
-		},
-		{
-			name: "comment with removal disabled",
-			options: &CleanerOptions{
-				RemoveComments:      false,
-				PreserveDocComments: true,
-			},
-			commentText: "// Any comment",
-			shouldKeep:  true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			cleaner, err := NewCleaner(LangGo, tt.options)
-			if err != nil {
-				t.Fatalf("Failed to create cleaner: %v", err)
-			}
-			tree, err := parser.ParseCtx(context.Background(), nil, []byte(tt.commentText))
-			if err != nil {
-				t.Fatalf("Failed to parse input: %v", err)
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			shouldRemove := cleaner.shouldRemoveComment(node, []byte(tt.commentText))
-			if shouldRemove == tt.shouldKeep {
-				t.Errorf("Expected shouldRemove=%v for comment %q", !tt.shouldKeep, tt.commentText)
-			}
-		})
-	}
-}
-</document_content>
-</document>
-<document index="32">
-<source>filefusion/internal/core/cleaner/handlers/sql_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/sql"
-)
-func TestSQLHandlerBasics(t *testing.T) {
-	handler := &SQLHandler{}
-	commentTypes := handler.GetCommentTypes()
-	expected := []string{"comment", "block_comment"}
-	if !stringSliceEqual(commentTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	expected = []string{"create_extension_statement", "use_statement"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != "--" {
-		t.Errorf("Expected '--', got %s", prefix)
-	}
-}
-func TestSQLLoggingCalls(t *testing.T) {
-	handler := &SQLHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(sql.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "select statement",
-			input:    "SELECT * FROM users;",
-			expected: false,
-		},
-		{
-			name:     "insert statement",
-			input:    "INSERT INTO logs (message) VALUES ('test');",
-			expected: false,
-		},
-		{
-			name:     "create table",
-			input:    "CREATE TABLE logs (id INT, message TEXT);",
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			result := handler.IsLoggingCall(node, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsLoggingCall() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-	if handler.IsLoggingCall(nil, []byte("")) {
-		t.Error("Expected IsLoggingCall to return false for nil node")
-	}
-	tree := parser.Parse(nil, []byte(""))
-	if tree == nil {
-		t.Fatal("Failed to parse empty input")
-	}
-	defer tree.Close()
-	if handler.IsLoggingCall(tree.RootNode(), []byte("")) {
-		t.Error("Expected IsLoggingCall to return false for empty content")
-	}
-	malformed := "SELECT * FROM"
-	tree = parser.Parse(nil, []byte(malformed))
-	if tree == nil {
-		t.Fatal("Failed to parse malformed input")
-	}
-	defer tree.Close()
-	if handler.IsLoggingCall(tree.RootNode(), []byte(malformed)) {
-		t.Error("Expected IsLoggingCall to return false for malformed input")
-	}
-}
-func TestSQLGetterSetter(t *testing.T) {
-	handler := &SQLHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(sql.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "select statement",
-			input:    "SELECT value FROM settings WHERE key = 'name';",
-			expected: false,
-		},
-		{
-			name:     "update statement",
-			input:    "UPDATE settings SET value = 'new' WHERE key = 'name';",
-			expected: false,
-		},
-		{
-			name:     "create function",
-			input:    "CREATE FUNCTION get_setting(p_key TEXT) RETURNS TEXT AS $$ SELECT value FROM settings WHERE key = p_key; $$ LANGUAGE SQL;",
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			result := handler.IsGetterSetter(node, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsGetterSetter() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-	if handler.IsGetterSetter(nil, []byte("")) {
-		t.Error("Expected IsGetterSetter to return false for nil node")
-	}
-	tree := parser.Parse(nil, []byte(""))
-	if tree == nil {
-		t.Fatal("Failed to parse empty input")
-	}
-	defer tree.Close()
-	if handler.IsGetterSetter(tree.RootNode(), []byte("")) {
-		t.Error("Expected IsGetterSetter to return false for empty content")
-	}
-	malformed := "CREATE FUNCTION get_value"
-	tree = parser.Parse(nil, []byte(malformed))
-	if tree == nil {
-		t.Fatal("Failed to parse malformed input")
-	}
-	defer tree.Close()
-	if handler.IsGetterSetter(tree.RootNode(), []byte(malformed)) {
-		t.Error("Expected IsGetterSetter to return false for malformed input")
-	}
-}
-</document_content>
-</document>
-<document index="33">
-<source>filefusion/internal/core/cleaner/handlers/swift_handler.go</source>
-<document_content>package handlers
-import (
-	"bytes"
-	"strings"
-	sitter "github.com/smacker/go-tree-sitter"
-)
-type SwiftHandler struct {
-	BaseHandler
-}
-func (h *SwiftHandler) GetCommentTypes() []string {
-	return []string{"comment", "multiline_comment", "documentation_comment"}
-}
-func (h *SwiftHandler) GetImportTypes() []string {
-	return []string{"import_declaration"}
-}
-func (h *SwiftHandler) GetDocCommentPrefix() string {
-	return "///"
-}
-func (h *SwiftHandler) IsLoggingCall(node *sitter.Node, content []byte) bool {
-	if node.Type() != "call_expression" {
-		return false
-	}
-	callText := content[node.StartByte():node.EndByte()]
-	return bytes.HasPrefix(callText, []byte("print(")) ||
-		bytes.HasPrefix(callText, []byte("debugPrint(")) ||
-		bytes.HasPrefix(callText, []byte("NSLog(")) ||
-}
-func (h *SwiftHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
-	nodeType := node.Type()
-	if nodeType == "variable_declaration" || nodeType == "getter_specifier" || nodeType == "setter_specifier" {
-		var findAccessor func(*sitter.Node) bool
-		findAccessor = func(n *sitter.Node) bool {
-			if n == nil {
-				return false
-			}
-			nType := n.Type()
-			if nType == "getter_specifier" || nType == "setter_specifier" {
-				return true
-			}
-			for i := 0; i < int(n.NamedChildCount()); i++ {
-				if findAccessor(n.NamedChild(i)) {
-					return true
-				}
-			}
-			return false
-		}
-		return findAccessor(node)
-	}
-	if nodeType == "function_declaration" {
-		funcText := string(content[node.StartByte():node.EndByte()])
-		funcName := ""
-		for i := 0; i < int(node.NamedChildCount()); i++ {
-			child := node.NamedChild(i)
-			if child.Type() == "simple_identifier" {
-				funcName = string(content[child.StartByte():child.EndByte()])
-				break
-			}
-		}
-		return (strings.HasPrefix(funcName, "get") && strings.Contains(funcText, "return")) ||
-			(strings.HasPrefix(funcName, "set") && strings.Contains(funcText, "="))
-	}
-	return false
-}
-</document_content>
-</document>
-<document index="34">
-<source>filefusion/internal/core/cleaner/handlers/swift_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/swift"
-)
-func TestSwiftHandlerBasics(t *testing.T) {
-	handler := &SwiftHandler{}
-	commentTypes := handler.GetCommentTypes()
-	expected := []string{"comment", "multiline_comment", "documentation_comment"}
-	if !stringSliceEqual(commentTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	expected = []string{"import_declaration"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != "///" {
-		t.Errorf("Expected '///', got %s", prefix)
-	}
-}
-func TestSwiftLoggingCalls(t *testing.T) {
-	handler := &SwiftHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(swift.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "print call",
-			input:    "print(\"Debug message\")",
-			expected: true,
-		},
-		{
-			name:     "debugPrint call",
-			input:    "debugPrint(\"Debug info\")",
-			expected: true,
-		},
-		{
-			name:     "NSLog call",
-			input:    "NSLog(\"Log message\")",
-			expected: true,
-		},
-		{
-			name:     "logger call",
-			input:    "logger.debug(\"Debug info\")",
-			expected: true,
-		},
-		{
-			name:     "regular function call",
-			input:    "process(\"data\")",
-			expected: false,
-		},
-		{
-			name:     "method call",
-			input:    "obj.process()",
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			var callNode *sitter.Node
-			var findCall func(*sitter.Node)
-			findCall = func(n *sitter.Node) {
-				if n.Type() == "call_expression" {
-					callNode = n
-					return
-				}
-				for i := 0; i < int(n.NamedChildCount()); i++ {
-					findCall(n.NamedChild(i))
-				}
-			}
-			findCall(node)
-			if callNode == nil {
-				t.Fatal("No call node found")
-			}
-			result := handler.IsLoggingCall(callNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsLoggingCall() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-}
-func TestSwiftGetterSetter(t *testing.T) {
-	handler := &SwiftHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(swift.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name: "computed property getter",
-			input: `var name: String {
-				get { return _name }
-			}`,
-			expected: true,
-		},
-		{
-			name: "computed property getter and setter",
-			input: `var name: String {
-				get { return _name }
-				set { _name = newValue }
-			}`,
-			expected: true,
-		},
-		{
-			name: "regular method",
-			input: `func process() {
-				doWork()
-			}`,
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			var propNode *sitter.Node
-			var findProp func(*sitter.Node)
-			findProp = func(n *sitter.Node) {
-				if n == nil {
-					return
-				}
-				if n.Type() == "variable_declaration" || n.Type() == "function_declaration" || n.Type() == "getter_specifier" || n.Type() == "setter_specifier" {
-					propNode = n
-					return
-				}
-				for i := 0; i < int(n.NamedChildCount()); i++ {
-					child := n.NamedChild(i)
-					findProp(child)
-					if propNode != nil {
-						return
-					}
-				}
-			}
-			findProp(node)
-			if propNode == nil {
-				t.Fatal("No property or function declaration node found")
-			}
-			result := handler.IsGetterSetter(propNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsGetterSetter() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-}
-</document_content>
-</document>
-<document index="35">
-<source>filefusion/internal/core/cleaner/handlers/kotlin_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/kotlin"
-)
-func TestKotlinHandlerBasics(t *testing.T) {
-	handler := &KotlinHandler{}
-	commentTypes := handler.GetCommentTypes()
-	expected := []string{"comment", "multiline_comment", "kdoc"}
-	if !stringSliceEqual(commentTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	expected = []string{"import_header"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != "/**" {
-		t.Errorf("Expected '/**', got %s", prefix)
-	}
-}
-func TestKotlinLoggingCalls(t *testing.T) {
-	handler := &KotlinHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(kotlin.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "println call",
-			input:    "println(\"Debug message\")",
-			expected: true,
-		},
-		{
-			name:     "print call",
-			input:    "print(\"Debug info\")",
-			expected: true,
-		},
-		{
-			name:     "Logger call",
-			input:    "Logger.debug(\"Debug info\")",
-			expected: true,
-		},
-		{
-			name:     "logger instance call",
-			input:    "logger.info(\"message\")",
-			expected: true,
-		},
-		{
-			name:     "log call",
-			input:    "log.info(\"Info message\")",
-			expected: true,
-		},
-		{
-			name:     "regular function call",
-			input:    "process(\"data\")",
-			expected: false,
-		},
-		{
-			name:     "method call",
-			input:    "obj.process()",
-			expected: false,
-		},
-		{
-			name:     "nested logging call",
-			input:    "logger.info(getData().toString())",
-			expected: true,
-		},
-		{
-			name:     "logging with string template",
-			input:    "println(\"Value: ${value}\")",
-			expected: true,
-		},
-		{
-			name:     "logging with multiple arguments",
-			input:    "logger.info(\"Message: {}\", value)",
-			expected: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			var callNode *sitter.Node
-			var findCall func(*sitter.Node)
-			findCall = func(n *sitter.Node) {
-				if n.Type() == "call_expression" {
-					callNode = n
-					return
-				}
-				for i := 0; i < int(n.NamedChildCount()); i++ {
-					findCall(n.NamedChild(i))
-				}
-			}
-			findCall(node)
-			if callNode == nil {
-				t.Fatal("No call node found")
-			}
-			result := handler.IsLoggingCall(callNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsLoggingCall() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-	if handler.IsLoggingCall(nil, []byte("")) {
-		t.Error("Expected IsLoggingCall to return false for nil node")
-	}
-	tree := parser.Parse(nil, []byte(""))
-	if tree == nil {
-		t.Fatal("Failed to parse empty input")
-	}
-	defer tree.Close()
-	if handler.IsLoggingCall(tree.RootNode(), []byte("")) {
-		t.Error("Expected IsLoggingCall to return false for empty content")
-	}
-	malformed := "println(\"unclosed string"
-	tree = parser.Parse(nil, []byte(malformed))
-	if tree == nil {
-		t.Fatal("Failed to parse malformed input")
-	}
-	defer tree.Close()
-	if handler.IsLoggingCall(tree.RootNode(), []byte(malformed)) {
-		t.Error("Expected IsLoggingCall to return false for malformed input")
-	}
-}
-func TestKotlinGetterSetter(t *testing.T) {
-	handler := &KotlinHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(kotlin.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name: "property with getter",
-			input: `var name: String
-				get() = field`,
-			expected: true,
-		},
-		{
-			name: "property with getter and setter",
-			input: `var name: String
-				get() = field
-				set(value) { field = value }`,
-			expected: true,
-		},
-		{
-			name: "getter function",
-			input: `fun getName(): String {
-				return name
-			}`,
-			expected: true,
-		},
-		{
-			name: "setter function",
-			input: `fun setName(value: String) {
-				this.name = value
-			}`,
-			expected: true,
-		},
-		{
-			name: "regular method",
-			input: `fun process() {
-				doWork()
-			}`,
-			expected: false,
-		},
-		{
-			name: "property with annotations",
-			input: `@JsonProperty
-				var name: String
-				get() = field`,
-			expected: true,
-		},
-		{
-			name: "property with complex type",
-			input: `var items: List<Map<String, Int>>
-				get() = field`,
-			expected: true,
-		},
-		{
-			name: "nested property",
-			input: `class Outer {
-				inner class Inner {
-					var name: String
-					get() = field
-				}
-			}`,
-			expected: true,
-		},
-		{
-			name: "property with custom getter logic",
-			input: `var fullName: String
-				get() = "$firstName $lastName"`,
-			expected: true,
-		},
-		{
-			name: "property with visibility modifiers",
-			input: `private var _name: String = ""
-				public var name: String
-					get() = _name
-					set(value) { _name = value }`,
-			expected: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			var targetNode *sitter.Node
-			var findNode func(*sitter.Node)
-			findNode = func(n *sitter.Node) {
-				if n == nil {
-					return
-				}
-				if n.Type() == "property_declaration" || n.Type() == "function_declaration" {
-					targetNode = n
-					return
-				}
-				for i := 0; i < int(n.NamedChildCount()); i++ {
-					findNode(n.NamedChild(i))
-				}
-			}
-			findNode(node)
-			if targetNode == nil {
-				t.Fatal("No property or function declaration node found")
-			}
-			result := handler.IsGetterSetter(targetNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsGetterSetter() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-	if handler.IsGetterSetter(nil, []byte("")) {
-		t.Error("Expected IsGetterSetter to return false for nil node")
-	}
-	tree := parser.Parse(nil, []byte(""))
-	if tree == nil {
-		t.Fatal("Failed to parse empty input")
-	}
-	defer tree.Close()
-	if handler.IsGetterSetter(tree.RootNode(), []byte("")) {
-		t.Error("Expected IsGetterSetter to return false for empty content")
-	}
-	malformed := "var name: String get("
-	tree = parser.Parse(nil, []byte(malformed))
-	if tree == nil {
-		t.Fatal("Failed to parse malformed input")
-	}
-	defer tree.Close()
-	if handler.IsGetterSetter(tree.RootNode(), []byte(malformed)) {
-		t.Error("Expected IsGetterSetter to return false for malformed input")
-	}
-}
-func TestKotlinFindFirstChild(t *testing.T) {
-	parser := sitter.NewParser()
-	parser.SetLanguage(kotlin.GetLanguage())
-	tests := []struct {
-		name         string
-		input        string
-		searchType   string
-		shouldFind   bool
-		expectedText string
-	}{
-		{
-			name: "find simple identifier",
-			input: `fun test() {
-				val name = "test"
-			}`,
-			searchType:   "simple_identifier",
-			shouldFind:   true,
-			expectedText: "test",
-		},
-		{
-			name: "find in nested structure",
-			input: `class Test {
-				fun method() {
-					val x = 1
-				}
-			}`,
-			searchType:   "property_declaration",
-			shouldFind:   true,
-			expectedText: "val x = 1",
-		},
-		{
-			name:       "non-existent type",
-			input:      "val x = 1",
-			searchType: "non_existent_type",
-			shouldFind: false,
-		},
-		{
-			name:       "empty input",
-			input:      "",
-			searchType: "simple_identifier",
-			shouldFind: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			found := findFirstChild(tree.RootNode(), tt.searchType)
-			if tt.shouldFind {
-				if found == nil {
-					t.Errorf("Expected to find node of type %s, but found nil", tt.searchType)
-				} else if string([]byte(tt.input)[found.StartByte():found.EndByte()]) != tt.expectedText {
-					t.Errorf("Expected node text %q, got %q", tt.expectedText, string([]byte(tt.input)[found.StartByte():found.EndByte()]))
-				}
-			} else if found != nil {
-				t.Errorf("Expected not to find node of type %s, but found one", tt.searchType)
-			}
-		})
-	}
-	if found := findFirstChild(nil, "any_type"); found != nil {
-		t.Error("Expected findFirstChild to return nil for nil node")
-	}
-}
-</document_content>
-</document>
-<document index="36">
-<source>filefusion/internal/core/cleaner/handlers/ruby_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/ruby"
-)
-func TestRubyHandlerBasics(t *testing.T) {
-	handler := &RubyHandler{}
-	commentTypes := handler.GetCommentTypes()
-	expected := []string{"comment"}
-	if !stringSliceEqual(commentTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	expected = []string{"require", "include", "require_relative"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != "#" {
-		t.Errorf("Expected '#', got %s", prefix)
-	}
-}
-func TestRubyLoggingCalls(t *testing.T) {
-	handler := &RubyHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(ruby.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "puts call",
-			input:    "puts 'Debug message'",
-			expected: true,
-		},
-		{
-			name:     "print call",
-			input:    "print 'Debug info'",
-			expected: true,
-		},
-		{
-			name:     "p call",
-			input:    "p object",
-			expected: true,
-		},
-		{
-			name:     "logger call",
-			input:    "logger.info('Log message')",
-			expected: true,
-		},
-		{
-			name:     "logger with block",
-			input:    "logger.debug { 'Debug info' }",
-			expected: true,
-		},
-		{
-			name:     "regular method call",
-			input:    "process_data('input')",
-			expected: false,
-		},
-		{
-			name:     "method with puts in name",
-			input:    "outputs('test')",
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			var callNode *sitter.Node
-			var findCall func(*sitter.Node)
-			findCall = func(n *sitter.Node) {
-				if n == nil {
-					return
-				}
-				nodeType := n.Type()
-				if nodeType == "call" || nodeType == "method_call" || nodeType == "command" {
-					callNode = n
-					return
-				}
-				for i := 0; i < int(n.NamedChildCount()); i++ {
-					findCall(n.NamedChild(i))
-				}
-			}
-			findCall(node)
-			if callNode == nil {
-				t.Logf("AST: %s", node.String())
-				t.Fatal("No call node found")
-			}
-			result := handler.IsLoggingCall(callNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsLoggingCall() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-	if handler.IsLoggingCall(nil, []byte("")) {
-		t.Error("Expected IsLoggingCall to return false for nil node")
-	}
-	tree := parser.Parse(nil, []byte(""))
-	if tree == nil {
-		t.Fatal("Failed to parse empty input")
-	}
-	defer tree.Close()
-	if handler.IsLoggingCall(tree.RootNode(), []byte("")) {
-		t.Error("Expected IsLoggingCall to return false for empty content")
-	}
-	malformed := "puts 'unclosed string"
-	tree = parser.Parse(nil, []byte(malformed))
-	if tree == nil {
-		t.Fatal("Failed to parse malformed input")
-	}
-	defer tree.Close()
-	node := tree.RootNode()
-	if node == nil {
-		t.Fatal("Failed to get root node")
-	}
-	if handler.IsLoggingCall(node, []byte(malformed)) {
-		t.Error("Expected IsLoggingCall to return false for malformed input")
-	}
-}
-func TestRubyGetterSetter(t *testing.T) {
-	handler := &RubyHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(ruby.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "attr_reader",
-			input:    "attr_reader :name",
-			expected: true,
-		},
-		{
-			name:     "attr_writer",
-			input:    "attr_writer :name",
-			expected: true,
-		},
-		{
-			name:     "attr_accessor",
-			input:    "attr_accessor :name, :age",
-			expected: true,
-		},
-		{
-			name:     "getter method",
-			input:    "def get_name\n  @name\nend",
-			expected: true,
-		},
-		{
-			name:     "setter method",
-			input:    "def set_name(value)\n  @name = value\nend",
-			expected: true,
-		},
-		{
-			name:     "regular method",
-			input:    "def process\n  do_work\nend",
-			expected: false,
-		},
-		{
-			name:     "method with get in name",
-			input:    "def forget\n  clear_memory\nend",
-			expected: false,
-		},
-		{
-			name:     "multiple attr_readers",
-			input:    "attr_reader :name, :age, :email",
-			expected: true,
-		},
-		{
-			name:     "attr_accessor with symbols",
-			input:    "attr_accessor :first_name, :last_name",
-			expected: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			var targetNode *sitter.Node
-			var findNode func(*sitter.Node)
-			findNode = func(n *sitter.Node) {
-				if n == nil {
-					return
-				}
-				nodeType := n.Type()
-				if nodeType == "call" || nodeType == "method" || nodeType == "method_definition" {
-					targetNode = n
-					return
-				}
-				for i := 0; i < int(n.NamedChildCount()); i++ {
-					findNode(n.NamedChild(i))
-				}
-			}
-			findNode(node)
-			if targetNode == nil {
-				t.Logf("AST: %s", node.String())
-				t.Fatal("No call or method node found")
-			}
-			result := handler.IsGetterSetter(targetNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsGetterSetter() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-	if handler.IsGetterSetter(nil, []byte("")) {
-		t.Error("Expected IsGetterSetter to return false for nil node")
-	}
-	tree := parser.Parse(nil, []byte(""))
-	if tree == nil {
-		t.Fatal("Failed to parse empty input")
-	}
-	defer tree.Close()
-	node := tree.RootNode()
-	if node == nil {
-		t.Fatal("Failed to get root node")
-	}
-	if handler.IsGetterSetter(node, []byte("")) {
-		t.Error("Expected IsGetterSetter to return false for empty content")
-	}
-	malformed := "def get_name"
-	tree = parser.Parse(nil, []byte(malformed))
-	if tree == nil {
-		t.Fatal("Failed to parse malformed input")
-	}
-	defer tree.Close()
-	node = tree.RootNode()
-	if node == nil {
-		t.Fatal("Failed to get root node")
-	}
-	if handler.IsGetterSetter(node, []byte(malformed)) {
-		t.Error("Expected IsGetterSetter to return false for malformed input")
-	}
-}
-</document_content>
-</document>
-<document index="37">
-<source>filefusion/internal/core/cleaner/utility_test.go</source>
-<document_content>package cleaner
-import (
-	"testing"
-)
-func TestDefaultOptions(t *testing.T) {
-	options := DefaultOptions()
-	if options == nil {
-		t.Error("DefaultOptions() returned nil")
-	}
-	if !options.RemoveComments {
-		t.Error("RemoveComments should be true by default")
-	}
-	if !options.PreserveDocComments {
-		t.Error("PreserveDocComments should be true by default")
-	}
-	if options.RemoveImports {
-		t.Error("RemoveImports should be false by default")
-	}
-	if !options.RemoveLogging {
-		t.Error("RemoveLogging should be true by default")
-	}
-	if !options.RemoveGettersSetters {
-		t.Error("RemoveGettersSetters should be true by default")
-	}
-	if !options.OptimizeWhitespace {
-		t.Error("OptimizeWhitespace should be true by default")
-	}
-	if !options.RemoveEmptyLines {
-		t.Error("RemoveEmptyLines should be true by default")
-	}
-	if options.LoggingPrefixes == nil {
-		t.Error("LoggingPrefixes should not be nil")
-	}
-	expectedLanguages := []Language{
-		LangGo, LangJava, LangPython, LangJavaScript,
-		LangPHP, LangRuby, LangCSharp, LangSwift,
-		LangKotlin,
-	}
-	for _, lang := range expectedLanguages {
-		if prefixes, exists := options.LoggingPrefixes[lang]; !exists {
-			t.Errorf("Missing logging prefixes for language: %s", lang)
-		} else if len(prefixes) == 0 {
-			t.Errorf("Empty logging prefixes for language: %s", lang)
-		}
-	}
-}
-func TestGetSupportedLanguages(t *testing.T) {
-	langs := GetSupportedLanguages()
-	if len(langs) == 0 {
-		t.Error("GetSupportedLanguages() returned empty list")
-	}
-	required := map[Language]bool{
-		LangGo:         false,
-		LangJava:       false,
-		LangPython:     false,
-		LangJavaScript: false,
-		LangTypeScript: false,
-		LangPHP:        false,
-		LangRuby:       false,
-		LangCSharp:     false,
-	}
-	for _, lang := range langs {
-		if _, ok := required[lang]; ok {
-			required[lang] = true
-		}
-	}
-	for lang, found := range required {
-		if !found {
-			t.Errorf("Required language %s not found in supported languages", lang)
-		}
-	}
-}
-func TestNewCleanerValidation(t *testing.T) {
-	tests := []struct {
-		name        string
-		lang        Language
-		options     *CleanerOptions
-		shouldError bool
-	}{
-		{
-			name:        "nil options",
-			lang:        LangGo,
-			options:     nil,
-			shouldError: true,
-		},
-		{
-			name:        "invalid language",
-			lang:        "invalid",
-			options:     DefaultOptions(),
-			shouldError: true,
-		},
-		{
-			name:        "valid configuration",
-			lang:        LangGo,
-			options:     DefaultOptions(),
-			shouldError: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			_, err := NewCleaner(tt.lang, tt.options)
-			if tt.shouldError {
-				if err == nil {
-					t.Error("Expected error but got none")
-				}
-			} else {
-				if err != nil {
-					t.Errorf("Unexpected error: %v", err)
-				}
-			}
-		})
-	}
-}
-</document_content>
-</document>
-<document index="38">
-<source>filefusion/internal/core/cleaner/handlers/python_handler_test.go</source>
-<document_content>package handlers
-import (
-	"testing"
-	sitter "github.com/smacker/go-tree-sitter"
-	"github.com/smacker/go-tree-sitter/python"
-)
-func TestPythonHandlerBasics(t *testing.T) {
-	handler := &PythonHandler{}
-	commentTypes := handler.GetCommentTypes()
-	if len(commentTypes) != 1 || commentTypes[0] != "comment" {
-		t.Errorf("Expected ['comment'], got %v", commentTypes)
-	}
-	importTypes := handler.GetImportTypes()
-	expected := []string{"import_statement", "import_from_statement"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
-	}
-	if prefix := handler.GetDocCommentPrefix(); prefix != `"""` {
-		t.Errorf("Expected '\"\"\"', got %s", prefix)
-	}
-}
-func TestPythonHandlerLogging(t *testing.T) {
-	handler := &PythonHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(python.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name:     "simple print call",
-			input:    "print('Debug message')",
-			expected: true,
-		},
-		{
-			name:     "print with formatting",
-			input:    "print(f'Value is {value}')",
-			expected: true,
-		},
-		{
-			name:     "logging module info",
-			input:    "logging.info('Info message')",
-			expected: true,
-		},
-		{
-			name:     "logging module debug",
-			input:    "logging.debug('Debug info')",
-			expected: true,
-		},
-		{
-			name:     "logging module error",
-			input:    "logging.error('Error occurred')",
-			expected: true,
-		},
-		{
-			name:     "logger instance debug",
-			input:    "logger.debug('Debug info')",
-			expected: true,
-		},
-		{
-			name:     "logger instance info",
-			input:    "logger.info('Info message')",
-			expected: true,
-		},
-		{
-			name:     "regular function call",
-			input:    "process_data('input')",
-			expected: false,
-		},
-		{
-			name:     "method call",
-			input:    "obj.process()",
-			expected: false,
-		},
-		{
-			name:     "print-like method",
-			input:    "printer.execute('message')",
-			expected: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			var callNode *sitter.Node
-			var findCall func(*sitter.Node)
-			findCall = func(n *sitter.Node) {
-				if n.Type() == "call" {
-					callNode = n
-					return
-				}
-				for i := 0; i < int(n.NamedChildCount()); i++ {
-					findCall(n.NamedChild(i))
-				}
-			}
-			findCall(node)
-			if callNode == nil {
-				t.Fatal("No call node found")
-			}
-			result := handler.IsLoggingCall(callNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsLoggingCall() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-}
-func TestPythonHandlerGetterSetter(t *testing.T) {
-	handler := &PythonHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(python.GetLanguage())
-	tests := []struct {
-		name     string
-		input    string
-		expected bool
-	}{
-		{
-			name: "property getter",
-			input: `@property
-def name(self):
-    return self._name`,
-			expected: true,
-		},
-		{
-			name: "property with decorator and docstring",
-			input: `@property
-def name(self):
-    """Get the name value."""
-    return self._name`,
-			expected: true,
-		},
-		{
-			name: "traditional getter",
-			input: `def get_name(self):
-    return self._name`,
-			expected: true,
-		},
-		{
-			name: "traditional setter",
-			input: `def set_name(self, value):
-    self._name = value`,
-			expected: true,
-		},
-		{
-			name: "get method with validation",
-			input: `def get_value(self):
-    if self._value is None:
-        raise ValueError("Value not set")
-    return self._value`,
-			expected: true,
-		},
-		{
-			name: "set method with validation",
-			input: `def set_value(self, value):
-    if value < 0:
-        raise ValueError("Value must be positive")
-    self._value = value`,
-			expected: true,
-		},
-		{
-			name: "regular method",
-			input: `def process_data(self):
-    return self.data.process()`,
-			expected: false,
-		},
-		{
-			name: "get method with args",
-			input: `def get_item(self, index):
-    return self._items[index]`,
-			expected: true,
-		},
-		{
-			name: "method with get prefix",
-			input: `def getting_started():
-    print("Tutorial")`,
-			expected: false,
-		},
-		{
-			name: "non-property decorated method",
-			input: `@staticmethod
-def get_version():
-    return "1.0.0"`,
-			expected: true,
-		},
-		{
-			name: "unrelated decorator method",
-			input: `@deprecated
-def get_legacy_value():
-    return old_value`,
-			expected: true,
-		},
-		{
-			name: "complex getter",
-			input: `def get_calculated_value(self):
-    return sum(self._values) / len(self._values)`,
-			expected: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			node := tree.RootNode()
-			var funcNode *sitter.Node
-			var findFunc func(*sitter.Node)
-			findFunc = func(n *sitter.Node) {
-				if n.Type() == "function_definition" {
-					funcNode = n
-					return
-				}
-				for i := 0; i < int(n.NamedChildCount()); i++ {
-					findFunc(n.NamedChild(i))
-				}
-			}
-			findFunc(node)
-			if funcNode == nil {
-				t.Fatal("No function definition node found")
-			}
-			result := handler.IsGetterSetter(funcNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsGetterSetter() = %v for input %q", tt.expected, tt.input)
-			}
-		})
-	}
-}
-func TestPythonHandlerEdgeCases(t *testing.T) {
-	handler := &PythonHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(python.GetLanguage())
-	if handler.IsLoggingCall(nil, []byte("")) {
-		t.Error("Expected IsLoggingCall to return false for nil node")
-	}
-	if handler.IsGetterSetter(nil, []byte("")) {
-		t.Error("Expected IsGetterSetter to return false for nil node")
-	}
-	tree := parser.Parse(nil, []byte(""))
-	if tree == nil {
-		t.Fatal("Failed to parse empty input")
-	}
-	defer tree.Close()
-	node := tree.RootNode()
-	if handler.IsLoggingCall(node, []byte("")) {
-		t.Error("Expected IsLoggingCall to return false for empty content")
-	}
-	if handler.IsGetterSetter(node, []byte("")) {
-		t.Error("Expected IsGetterSetter to return false for empty content")
-	}
-	malformed := "def get_value(self:"
-	tree = parser.Parse(nil, []byte(malformed))
-	if tree == nil {
-		t.Fatal("Failed to parse malformed input")
-	}
-	defer tree.Close()
-	node = tree.RootNode()
-	if handler.IsGetterSetter(node, []byte(malformed)) {
-		t.Error("Expected IsGetterSetter to return false for malformed input")
-	}
-}
-</document_content>
-</document>
-<document index="39">
-<source>filefusion/internal/core/types.go</source>
-<document_content>package core
-import (
-	"fmt"
-	"path/filepath"
-	"strings"
-	"github.com/drgsn/filefusion/internal/core/cleaner"
-)
-type FileContent struct {
-	Path      string `json:"path"`
-	Name      string `json:"name"`
-	Content   string `json:"content"`
-	Extension string `json:"extension"`
-	Size      int64  `json:"size"`
-}
-type OutputType string
-const (
-	ColorRed   = "\033[1;31m"
-	ColorGreen = "\033[0;32m"
-	ColorReset = "\033[0m"
-)
-const (
-	OutputTypeXML  OutputType = "XML"
-	OutputTypeJSON OutputType = "JSON"
-	OutputTypeYAML OutputType = "YAML"
-)
-type MixOptions struct {
-	InputPath      string
-	OutputPath     string
-	Pattern        string
-	Exclude        string
-	MaxFileSize    int64
-	MaxOutputSize  int64
-	OutputType     OutputType
-	CleanerOptions *cleaner.CleanerOptions
-	IgnoreSymlinks bool
-}
-func validatePattern(pattern string) error {
-	if pattern == "" {
-		return fmt.Errorf("pattern cannot be empty")
-	}
-	patterns := strings.Split(pattern, ",")
-	for _, p := range patterns {
-		p = strings.TrimSpace(p)
-		if p == "" {
-			continue
-		}
-		if _, err := filepath.Match(p, "test"); err != nil {
-			return fmt.Errorf("syntax error in pattern %q: %w", p, err)
-		}
-	}
-	return nil
-}
-func validateExcludePatterns(exclude string) error {
-	if exclude == "" {
-		return nil
-	}
-	patterns := strings.Split(exclude, ",")
-	for _, p := range patterns {
-		p = strings.TrimSpace(p)
-		if p == "" {
-			continue
-		}
-		if strings.Contains(p, "**") {
-			continue
-		}
-		if _, err := filepath.Match(p, "test"); err != nil {
-			return fmt.Errorf("invalid exclusion pattern %q: %w", p, err)
-		}
-	}
-	return nil
-}
-func (m *MixOptions) Validate() error {
-	if m.InputPath == "" {
-		return &MixError{Message: "input path is required"}
-	}
-	if m.OutputPath == "" {
-		return &MixError{Message: "output path is required"}
-	}
-	if err := validatePattern(m.Pattern); err != nil {
-		return err
-	}
-	if err := validateExcludePatterns(m.Exclude); err != nil {
-		return err
-	}
-	if m.MaxFileSize <= 0 {
-		return &MixError{Message: "max file size must be greater than 0"}
-	}
-	if m.MaxOutputSize <= 0 {
-		return &MixError{Message: "max output size must be greater than 0"}
-	}
-	switch m.OutputType {
-	case OutputTypeXML, OutputTypeJSON, OutputTypeYAML:
-	default:
-		return &MixError{Message: fmt.Sprintf("unsupported output type: %s", m.OutputType)}
-	}
-	return nil
-}
-type MixError struct {
-	File    string
-	Message string
-}
-func (e *MixError) Error() string {
-	if e.File != "" {
-		return "file " + e.File + ": " + e.Message
-	}
-	return e.Message
-}
-</document_content>
-</document>
-<document index="40">
-<source>filefusion/internal/core/output.go</source>
-<document_content>package core
-import (
-	"encoding/json"
-	"fmt"
-	"os"
-	"path/filepath"
-	"strings"
-	"text/template"
-	"gopkg.in/yaml.v3"
-)
-type OutputGenerator struct {
-	options *MixOptions
-	workDir string
-}
-func NewOutputGenerator(options *MixOptions) (*OutputGenerator, error) {
-	workDir, err := os.Getwd()
-	if err != nil {
-		return nil, fmt.Errorf("failed to get working directory: %w", err)
-	}
-	return &OutputGenerator{
-		options: options,
-		workDir: workDir,
-	}, nil
-}
-func (g *OutputGenerator) normalizePath(path string) string {
-	path = filepath.ToSlash(path)
-	workDir := filepath.ToSlash(g.workDir)
-	lastDir := filepath.Base(workDir)
-	workDirComponents := strings.Split(workDir, "/")
-	if len(workDirComponents) > 1 {
-		parentDir := strings.Join(workDirComponents[:len(workDirComponents)-1], "/")
-		if strings.HasPrefix(path, parentDir) {
-			path = strings.TrimPrefix(path, parentDir)
-			path = strings.TrimPrefix(path, "/")
-		}
-	}
-	if !strings.HasPrefix(path, lastDir+"/") && !strings.HasPrefix(path, lastDir) {
-		path = filepath.Join(lastDir, path)
-	}
-	return filepath.ToSlash(path)
-}
-func (g *OutputGenerator) Generate(contents []FileContent) error {
-	tempFile, err := os.CreateTemp("", "filefusion-*")
-	if err != nil {
-		return &MixError{
-			File:    g.options.OutputPath,
-			Message: fmt.Sprintf("error creating temporary file: %v", err),
-		}
-	}
-	tempPath := tempFile.Name()
-	defer os.Remove(tempPath)
-	normalizedContents := make([]FileContent, len(contents))
-	for i, content := range contents {
-		normalizedContents[i] = FileContent{
-			Path:      g.normalizePath(content.Path),
-			Name:      content.Name,
-			Content:   content.Content,
-			Extension: content.Extension,
-			Size:      content.Size,
-		}
-	}
-	switch g.options.OutputType {
-	case OutputTypeJSON:
-		err = g.generateJSON(tempFile, normalizedContents)
-	case OutputTypeYAML:
-		err = g.generateYAML(tempFile, normalizedContents)
-	case OutputTypeXML:
-		err = g.generateXML(tempFile, normalizedContents)
-	default:
-		return &MixError{Message: fmt.Sprintf("unsupported output type: %s", g.options.OutputType)}
-	}
-	if err != nil {
-		return err
-	}
-	tempFile.Close()
-	info, err := os.Stat(tempPath)
-	if err != nil {
-		return &MixError{Message: fmt.Sprintf("error checking output file size: %v", err)}
-	}
-	if info.Size() > g.options.MaxOutputSize {
-		return &MixError{
-			Message: fmt.Sprintf("output size (%d bytes) exceeds maximum allowed size (%d bytes)",
-				info.Size(), g.options.MaxOutputSize),
-		}
-	}
-	return os.Rename(tempPath, g.options.OutputPath)
-}
-func (g *OutputGenerator) generateJSON(file *os.File, contents []FileContent) error {
-	output := struct {
-		Documents []struct {
-			Index           int    `json:"index"`
-			Source          string `json:"source"`
-			DocumentContent string `json:"document_content"`
-		} `json:"documents"`
-	}{
-		Documents: make([]struct {
-			Index           int    `json:"index"`
-			Source          string `json:"source"`
-			DocumentContent string `json:"document_content"`
-		}, len(contents)),
-	}
-	for i, content := range contents {
-		output.Documents[i] = struct {
-			Index           int    `json:"index"`
-			Source          string `json:"source"`
-			DocumentContent string `json:"document_content"`
-		}{
-			Index:           i + 1,
-			Source:          content.Path,
-			DocumentContent: content.Content,
-		}
-	}
-	encoder := json.NewEncoder(file)
-	encoder.SetIndent("", "  ")
-	if err := encoder.Encode(output); err != nil {
-		return &MixError{Message: fmt.Sprintf("error encoding JSON: %v", err)}
-	}
-	return nil
-}
-func (g *OutputGenerator) generateYAML(file *os.File, contents []FileContent) error {
-	docs := struct {
-		Documents []struct {
-			Index           int    `yaml:"index"`
-			Source          string `yaml:"source"`
-			DocumentContent string `yaml:"document_content"`
-		} `yaml:"documents"`
-	}{
-		Documents: make([]struct {
-			Index           int    `yaml:"index"`
-			Source          string `yaml:"source"`
-			DocumentContent string `yaml:"document_content"`
-		}, len(contents)),
-	}
-	for i, content := range contents {
-		docs.Documents[i] = struct {
-			Index           int    `yaml:"index"`
-			Source          string `yaml:"source"`
-			DocumentContent string `yaml:"document_content"`
-		}{
-			Index:           i + 1,
-			Source:          content.Path,
-			DocumentContent: content.Content,
-		}
-	}
-	encoder := yaml.NewEncoder(file)
-	encoder.SetIndent(2)
-	if err := encoder.Encode(docs); err != nil {
-		return &MixError{Message: fmt.Sprintf("error encoding YAML: %v", err)}
-	}
-	return nil
-}
-func (g *OutputGenerator) generateXML(file *os.File, contents []FileContent) error {
-	const xmlTemplate = `<?xml version="1.0" encoding="UTF-8"?>
-<documents>{{range $index, $file := .}}
-<document index="{{add $index 1}}">
-<source>{{.Path}}</source>
-<document_content>{{.Content}}</document_content>
-</document>{{end}}
-</documents>`
-	t, err := template.New("llm").Funcs(template.FuncMap{
-		"add": func(a, b int) int { return a + b },
-	}).Parse(xmlTemplate)
-	if err != nil {
-		return &MixError{Message: fmt.Sprintf("error parsing template: %v", err)}
-	}
-	if err := t.Execute(file, contents); err != nil {
-		return &MixError{Message: fmt.Sprintf("error executing template: %v", err)}
-	}
-	return nil
-}
-</document_content>
-</document>
-<document index="41">
-<source>filefusion/internal/core/processor.go</source>
-<document_content>package core
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-	"strings"
-	"sync"
-	"github.com/drgsn/filefusion/internal/core/cleaner"
-)
-type FileResult struct {
-	Content FileContent
-	Error   error
-}
-type FileProcessor struct {
-	options  *MixOptions
-	cleaners map[cleaner.Language]*cleaner.Cleaner
-	mu       sync.RWMutex
-}
-func NewFileProcessor(options *MixOptions) *FileProcessor {
-	return &FileProcessor{
-		options:  options,
-		cleaners: make(map[cleaner.Language]*cleaner.Cleaner),
-	}
-}
-func (p *FileProcessor) ProcessFiles(paths []string) ([]FileContent, error) {
-	numWorkers := min(len(paths), 10)
-	results := make(chan FileResult, len(paths))
-	var wg sync.WaitGroup
-	jobs := make(chan string, len(paths))
-	for _, path := range paths {
-		jobs <- path
-	}
-	close(jobs)
-	for i := 0; i < numWorkers; i++ {
-		wg.Add(1)
-		go func() {
-			defer wg.Done()
-			for path := range jobs {
-				result := p.processFile(path)
-				results <- result
-			}
-		}()
-	}
-	go func() {
-		wg.Wait()
-		close(results)
-	}()
-	var contents []FileContent
-	var errors []error
-	for result := range results {
-		if result.Error != nil {
-			errors = append(errors, result.Error)
-			continue
-		}
-		if result.Content.Size > 0 {
-			contents = append(contents, result.Content)
-		}
-	}
-	var firstError error
-	if len(errors) > 0 {
-		firstError = errors[0]
-	}
-	return contents, firstError
-}
-func (p *FileProcessor) processFile(path string) FileResult {
-	info, err := os.Stat(path)
-	if err != nil {
-		return FileResult{
-			Error: &MixError{
-				File:    path,
-				Message: fmt.Sprintf("error getting file info: %v", err),
-			},
-		}
-	}
-	if info.IsDir() {
-		return FileResult{
-			Error: &MixError{
-				File:    path,
-				Message: "is a directory",
-			},
-		}
-	}
-	if info.Size() > p.options.MaxFileSize {
-		fmt.Fprintf(os.Stderr, "Warning: Skipping %s (size %d bytes exceeds limit %d bytes)\n",
-			path, info.Size(), p.options.MaxFileSize)
-		return FileResult{}
-	}
-	content, err := os.ReadFile(path)
-	if err != nil {
-		return FileResult{
-			Error: &MixError{
-				File:    path,
-				Message: fmt.Sprintf("error reading file: %v", err),
-			},
-		}
-	}
-	if p.options.CleanerOptions != nil {
-		cleaned, err := p.cleanContent(path, content)
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "Warning: Failed to clean %s: %v\n", path, err)
-		} else {
-			content = cleaned
-		}
-	}
-	relPath, err := p.createRelativePath(path)
-	if err != nil {
-		relPath = path
-	}
-	return FileResult{
-		Content: FileContent{
-			Path:      filepath.ToSlash(relPath),
-			Name:      filepath.Base(path),
-			Extension: strings.TrimPrefix(filepath.Ext(path), "."),
-			Content:   string(content),
-			Size:      int64(len(content)),
-		},
-	}
-}
-func (p *FileProcessor) cleanContent(path string, content []byte) ([]byte, error) {
-	defer func() {
-		if r := recover(); r != nil {
-			fmt.Fprintf(os.Stderr, "Recovered from panic in cleanContent for %s: %v\n", path, r)
-		}
-	}()
-	lang := p.detectLanguage(path)
-	if lang == "" {
-		return content, nil
-	}
-	c, err := p.getOrCreateCleaner(lang)
-	if err != nil {
-		return nil, fmt.Errorf("failed to create cleaner: %w", err)
-	}
-	cleaned, err := c.Clean(content)
-	if err != nil {
-		return nil, fmt.Errorf("failed to clean content: %w", err)
-	}
-	return cleaned, nil
-}
-func (p *FileProcessor) getOrCreateCleaner(lang cleaner.Language) (*cleaner.Cleaner, error) {
-	p.mu.RLock()
-	c, exists := p.cleaners[lang]
-	p.mu.RUnlock()
-	if exists {
-		return c, nil
-	}
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	if c, exists = p.cleaners[lang]; exists {
-		return c, nil
-	}
-	c, err := cleaner.NewCleaner(lang, p.options.CleanerOptions)
-	if err != nil {
-		return nil, err
-	}
-	p.cleaners[lang] = c
-	return c, nil
-}
-func (p *FileProcessor) createRelativePath(path string) (string, error) {
-	baseDir := filepath.Clean(p.options.InputPath)
-	cleanPath := filepath.Clean(path)
-	baseDir = filepath.ToSlash(baseDir)
-	cleanPath = filepath.ToSlash(cleanPath)
-	relPath := cleanPath
-	if strings.HasPrefix(cleanPath, baseDir) {
-		relPath = cleanPath[len(baseDir):]
-		relPath = strings.TrimPrefix(relPath, "/")
-	}
-	return relPath, nil
-}
-func (p *FileProcessor) detectLanguage(path string) cleaner.Language {
-	ext := strings.ToLower(filepath.Ext(path))
-	switch ext {
-	case ".go":
-		return cleaner.LangGo
-	case ".java":
-		return cleaner.LangJava
-	case ".py":
-		return cleaner.LangPython
-	case ".js":
-		return cleaner.LangJavaScript
-	case ".ts":
-		return cleaner.LangTypeScript
-	case ".html":
-		return cleaner.LangHTML
-	case ".css":
-		return cleaner.LangCSS
-	case ".cpp", ".cc", ".h":
-		return cleaner.LangCPP
-	case ".cs":
-		return cleaner.LangCSharp
-	case ".php":
-		return cleaner.LangPHP
-	case ".rb":
-		return cleaner.LangRuby
-	case ".sh", ".bash":
-		return cleaner.LangBash
-	case ".swift":
-		return cleaner.LangSwift
-	case ".kt":
-		return cleaner.LangKotlin
-	case ".sql":
-		return cleaner.LangSQL
-	}
-	return ""
-}
-func min(a, b int) int {
-	if a < b {
-		return a
-	}
-	return b
-}
-</document_content>
-</document>
-<document index="42">
-<source>filefusion/internal/core/finder.go</source>
-<document_content>package core
-import (
-	"fmt"
-	"io/fs"
-	"os"
-	"path/filepath"
-	"runtime"
-	"strings"
-	"sync"
-	"github.com/bmatcuk/doublestar/v4"
-)
-type FileFinder struct {
-	includes       []string
-	excludes       []string
-	followSymlinks bool
-	seenPaths      map[string]bool
-	seenLinks      map[string]bool
-	mu             sync.Mutex
-}
-type Result struct {
-	Path string
-	Err  error
-}
-func NewFileFinder(includes, excludes []string, followSymlinks bool) *FileFinder {
-	return &FileFinder{
-		includes:       includes,
-		excludes:       excludes,
-		followSymlinks: followSymlinks,
-		seenPaths:      make(map[string]bool),
-		seenLinks:      make(map[string]bool),
-	}
-}
-func (ff *FileFinder) FindMatchingFiles(basePaths []string) ([]string, error) {
-	resultChan := make(chan Result)
-	var wg sync.WaitGroup
-	numWorkers := runtime.GOMAXPROCS(0)
-	pathChan := make(chan string, len(basePaths))
-	for i := 0; i < numWorkers; i++ {
-		wg.Add(1)
-		go ff.worker(pathChan, resultChan, &wg)
-	}
-	go func() {
-		for _, path := range basePaths {
-			pathChan <- path
-		}
-		close(pathChan)
-	}()
-	go func() {
-		wg.Wait()
-		close(resultChan)
-	}()
-	var matches []string
-	seen := make(map[string]bool)
-	var firstErr error
-	for result := range resultChan {
-		if result.Err != nil {
-			if firstErr == nil {
-				firstErr = result.Err
-			}
-			continue
-		}
-		if !seen[result.Path] {
-			matches = append(matches, result.Path)
-			seen[result.Path] = true
-		}
-	}
-	if firstErr != nil {
-		return matches, fmt.Errorf("errors occurred while finding files: %w", firstErr)
-	}
-	return matches, nil
-}
-func (ff *FileFinder) processSymlink(path string, resultChan chan<- Result) error {
-	realPath, err := filepath.EvalSymlinks(path)
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "Warning: Could not resolve symlink %q: %v\n", path, err)
-		return nil
-	}
-	ff.mu.Lock()
-	seenBefore := ff.seenPaths[realPath]
-	ff.seenPaths[realPath] = true
-	ff.mu.Unlock()
-	if seenBefore {
-		return nil
-	}
-	realInfo, err := os.Stat(realPath)
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "Warning: Could not stat resolved symlink %q: %v\n", realPath, err)
-		return nil
-	}
-	if realInfo.IsDir() {
-		return filepath.WalkDir(realPath, func(p string, d fs.DirEntry, err error) error {
-			if err != nil {
-				return err
-			}
-			return ff.handleEntry(p, d, resultChan)
-		})
-	}
-	normalizedPath := filepath.ToSlash(path)
-	include, err := ff.shouldIncludeFile(normalizedPath)
-	if err != nil {
-		return err
-	}
-	if include {
-		resultChan <- Result{Path: path}
-	}
-	return nil
-}
-func (ff *FileFinder) processRegularFile(path string, resultChan chan<- Result) error {
-	normalizedPath := filepath.ToSlash(path)
-	ff.mu.Lock()
-	seenBefore := ff.seenPaths[path]
-	ff.seenPaths[path] = true
-	ff.mu.Unlock()
-	if seenBefore {
-		return nil
-	}
-	include, err := ff.shouldIncludeFile(normalizedPath)
-	if err != nil {
-		return err
-	}
-	if include {
-		resultChan <- Result{Path: path}
-	}
-	return nil
-}
-func (ff *FileFinder) handleEntry(path string, d fs.DirEntry, resultChan chan<- Result) error {
-	info, err := d.Info()
-	if err != nil {
-		return fmt.Errorf("error getting file info for %q: %w", path, err)
-	}
-	if info.Mode()&os.ModeSymlink != 0 {
-		ff.mu.Lock()
-		ff.seenLinks[path] = true
-		ff.mu.Unlock()
-		if !ff.followSymlinks {
-			return nil
-		}
-		return ff.processSymlink(path, resultChan)
-	}
-	if d.IsDir() {
-		return nil
-	}
-	return ff.processRegularFile(path, resultChan)
-}
-func (ff *FileFinder) worker(pathChan <-chan string, resultChan chan<- Result, wg *sync.WaitGroup) {
-	defer wg.Done()
-	for basePath := range pathChan {
-		absPath, err := filepath.Abs(basePath)
-		if err != nil {
-			resultChan <- Result{Err: fmt.Errorf("error resolving path %q: %w", basePath, err)}
-			continue
-		}
-		err = filepath.WalkDir(absPath, func(path string, d fs.DirEntry, err error) error {
-			if err != nil {
-				if os.IsNotExist(err) || os.IsPermission(err) {
-					fmt.Fprintf(os.Stderr, "Warning: Skipping %s: %v\n", path, err)
-					return nil
-				}
-				return err
-			}
-			return ff.handleEntry(path, d, resultChan)
-		})
-		if err != nil {
-			resultChan <- Result{Err: fmt.Errorf("error walking path %q: %w", basePath, err)}
-		}
-	}
-}
-func (ff *FileFinder) GetRealPath(path string) (string, error) {
-	realPath, err := filepath.EvalSymlinks(path)
-	if err != nil {
-		return "", fmt.Errorf("error resolving symlink %q: %w", path, err)
-	}
-	if runtime.GOOS == "darwin" && strings.HasPrefix(realPath, "/private") {
-		realPath = realPath[8:]
-	}
-	return realPath, nil
-}
-func (ff *FileFinder) IsSymlink(path string) (bool, error) {
-	ff.mu.Lock()
-	defer ff.mu.Unlock()
-	return ff.seenLinks[path], nil
-}
-func (ff *FileFinder) matchPattern(pattern, path, basename string) (bool, error) {
-	if !strings.Contains(pattern, "/") {
-		return doublestar.Match(pattern, basename)
-	}
-	return doublestar.Match(pattern, path)
-}
-func (ff *FileFinder) shouldIncludeFile(path string) (bool, error) {
-	basename := filepath.Base(path)
-	for _, pattern := range ff.excludes {
-		matched, err := ff.matchPattern(pattern, path, basename)
-		if err != nil {
-			return false, fmt.Errorf("invalid exclude pattern %q: %w", pattern, err)
-		}
-		if matched {
-			return false, nil
-		}
-	}
-	if len(ff.includes) == 0 {
-		return true, nil
-	}
-	for _, pattern := range ff.includes {
-		matched, err := ff.matchPattern(pattern, path, basename)
-		if err != nil {
-			return false, fmt.Errorf("invalid include pattern %q: %w", pattern, err)
-		}
-		if matched {
-			return true, nil
-		}
-	}
-	return false, nil
-}
-</document_content>
-</document>
-<document index="43">
-<source>filefusion/internal/core/patterns.go</source>
-<document_content>package core
-import (
-	"fmt"
-	"strings"
-	"github.com/bmatcuk/doublestar/v4"
-)
-type PatternError struct {
-	Pattern string
-	Reason  string
-}
-func (e *PatternError) Error() string {
-	return fmt.Sprintf("invalid pattern %q: %s", e.Pattern, e.Reason)
-}
-type PatternValidator struct {
-	allowBraces    bool
-	allowNegation  bool
-	maxPatternLen  int
-	allowedSymbols []rune
-	bannedPatterns []string
-}
-func NewPatternValidator() *PatternValidator {
-	return &PatternValidator{
-		allowBraces:    true,
-		allowNegation:  true,
-		maxPatternLen:  1000,
-		allowedSymbols: []rune{'*', '?', '[', ']', '{', '}', ',', '!', '/'},
-		bannedPatterns: []string{
-			"../",
-			"/..",
-			"/**/../",
-			"**/.*/**",
-		},
-	}
-}
-func (v *PatternValidator) ValidatePattern(pattern string) error {
-	if strings.Contains(pattern, "\x00") {
-		return &PatternError{
-			Pattern: pattern,
-			Reason:  "pattern contains null bytes",
-		}
-	}
-	if len(pattern) > v.maxPatternLen {
-		return &PatternError{
-			Pattern: pattern,
-			Reason:  fmt.Sprintf("pattern too long (max %d chars)", v.maxPatternLen),
-		}
-	}
-	for _, banned := range v.bannedPatterns {
-		if strings.Contains(pattern, banned) {
-			return &PatternError{
-				Pattern: pattern,
-				Reason:  fmt.Sprintf("contains banned pattern: %q", banned),
-			}
-		}
-	}
-	if !v.allowNegation && strings.HasPrefix(pattern, "!") {
-		return &PatternError{
-			Pattern: pattern,
-			Reason:  "negation patterns are not allowed",
-		}
-	}
-	if !v.allowBraces && (strings.Contains(pattern, "{") || strings.Contains(pattern, "}")) {
-		return &PatternError{
-			Pattern: pattern,
-			Reason:  "brace expansion is not allowed",
-		}
-	}
-	if err := validateBraces(pattern); err != nil {
-		return err
-	}
-	if err := validateBrackets(pattern); err != nil {
-		return err
-	}
-	if !doublestar.ValidatePattern(pattern) {
-		return &PatternError{
-			Pattern: pattern,
-			Reason:  "invalid pattern syntax",
-		}
-	}
-	return nil
-}
-func validateBraces(pattern string) error {
-	stack := 0
-	for i, ch := range pattern {
-		switch ch {
-		case '{':
-			stack++
-		case '}':
-			stack--
-			if stack < 0 {
-				return &PatternError{
-					Pattern: pattern,
-					Reason:  fmt.Sprintf("unmatched closing brace at position %d", i),
-				}
-			}
-		}
-	}
-	if stack > 0 {
-		return &PatternError{
-			Pattern: pattern,
-			Reason:  "unclosed brace",
-		}
-	}
-	return nil
-}
-func validateBrackets(pattern string) error {
-	stack := 0
-	for i, ch := range pattern {
-		switch ch {
-		case '[':
-			stack++
-		case ']':
-			stack--
-			if stack < 0 {
-				return &PatternError{
-					Pattern: pattern,
-					Reason:  fmt.Sprintf("unmatched closing bracket at position %d", i),
-				}
-			}
-		}
-	}
-	if stack > 0 {
-		return &PatternError{
-			Pattern: pattern,
-			Reason:  "unclosed bracket",
-		}
-	}
-	return nil
-}
-func (v *PatternValidator) splitPatterns(pattern string) []string {
-	var patterns []string
-	var currentPattern strings.Builder
-	inBrace := 0
-	for i := 0; i < len(pattern); i++ {
-		switch pattern[i] {
-		case '{':
-			inBrace++
-			currentPattern.WriteByte(pattern[i])
-		case '}':
-			inBrace--
-			currentPattern.WriteByte(pattern[i])
-		case ',':
-			if inBrace > 0 {
-				currentPattern.WriteByte(pattern[i])
-			} else if currentPattern.Len() > 0 {
-				patterns = append(patterns, currentPattern.String())
-				currentPattern.Reset()
-			}
-		default:
-			currentPattern.WriteByte(pattern[i])
-		}
-	}
-	if currentPattern.Len() > 0 {
-		patterns = append(patterns, currentPattern.String())
-	}
-	return patterns
-}
-func (v *PatternValidator) expandBracePattern(pattern string) []string {
-	idx := strings.Index(pattern, "{")
-	if idx < 0 {
-		return []string{pattern}
-	}
-	closeIdx := strings.LastIndex(pattern, "}")
-	if closeIdx <= idx {
-		return []string{pattern}
-	}
-	prefix := pattern[:idx]
-	suffix := pattern[closeIdx+1:]
-	options := strings.Split(pattern[idx+1:closeIdx], ",")
-	result := make([]string, len(options))
-	for i, opt := range options {
-		result[i] = prefix + opt + suffix
-	}
-	return result
-}
-func (v *PatternValidator) ExpandPattern(pattern string) ([]string, error) {
-	if pattern == "" {
-		return []string{}, nil
-	}
-	if err := validateBraces(pattern); err != nil {
-		return nil, err
-	}
-	if err := validateBrackets(pattern); err != nil {
-		return nil, err
-	}
-	patterns := v.splitPatterns(pattern)
-	var result []string
-	for _, p := range patterns {
-		expanded := v.expandBracePattern(p)
-		result = append(result, expanded...)
-	}
-	return result, nil
-}
-</document_content>
-</document>
-<document index="44">
-<source>filefusion/internal/core/types_test.go</source>
-<document_content>package core
-import (
-	"testing"
-	"github.com/stretchr/testify/assert"
-)
-func TestMixOptionsValidate(t *testing.T) {
-	tests := []struct {
-		name    string
-		options MixOptions
-		wantErr bool
-		errMsg  string
-	}{
-		{
-			name: "valid options",
-			options: MixOptions{
-				InputPath:     "/input",
-				OutputPath:    "/output",
-				Pattern:       "*.txt",
-				MaxFileSize:   1024,
-				MaxOutputSize: 2048,
-				OutputType:    OutputTypeJSON,
-			},
-			wantErr: false,
-		},
-		{
-			name: "empty input path",
-			options: MixOptions{
-				OutputPath:    "/output",
-				Pattern:       "*.txt",
-				MaxFileSize:   1024,
-				MaxOutputSize: 2048,
-				OutputType:    OutputTypeJSON,
-			},
-			wantErr: true,
-			errMsg:  "input path is required",
-		},
-		{
-			name: "empty output path",
-			options: MixOptions{
-				InputPath:     "/input",
-				Pattern:       "*.txt",
-				MaxFileSize:   1024,
-				MaxOutputSize: 2048,
-				OutputType:    OutputTypeJSON,
-			},
-			wantErr: true,
-			errMsg:  "output path is required",
-		},
-		{
-			name: "invalid pattern",
-			options: MixOptions{
-				InputPath:     "/input",
-				OutputPath:    "/output",
-				Pattern:       "[",
-				MaxFileSize:   1024,
-				MaxOutputSize: 2048,
-				OutputType:    OutputTypeJSON,
-			},
-			wantErr: true,
-			errMsg:  `syntax error in pattern "["`,
-		},
-		{
-			name: "invalid exclude pattern",
-			options: MixOptions{
-				InputPath:     "/input",
-				OutputPath:    "/output",
-				Pattern:       "*.txt",
-				Exclude:       "[",
-				MaxFileSize:   1024,
-				MaxOutputSize: 2048,
-				OutputType:    OutputTypeJSON,
-			},
-			wantErr: true,
-			errMsg:  `invalid exclusion pattern "["`,
-		},
-		{
-			name: "zero max file size",
-			options: MixOptions{
-				InputPath:     "/input",
-				OutputPath:    "/output",
-				Pattern:       "*.txt",
-				MaxFileSize:   0,
-				MaxOutputSize: 2048,
-				OutputType:    OutputTypeJSON,
-			},
-			wantErr: true,
-			errMsg:  "max file size must be greater than 0",
-		},
-		{
-			name: "zero max output size",
-			options: MixOptions{
-				InputPath:     "/input",
-				OutputPath:    "/output",
-				Pattern:       "*.txt",
-				MaxFileSize:   1024,
-				MaxOutputSize: 0,
-				OutputType:    OutputTypeJSON,
-			},
-			wantErr: true,
-			errMsg:  "max output size must be greater than 0",
-		},
-		{
-			name: "unsupported output type",
-			options: MixOptions{
-				InputPath:     "/input",
-				OutputPath:    "/output",
-				Pattern:       "*.txt",
-				MaxFileSize:   1024,
-				MaxOutputSize: 2048,
-				OutputType:    "INVALID",
-			},
-			wantErr: true,
-			errMsg:  "unsupported output type: INVALID",
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			err := tt.options.Validate()
-			if tt.wantErr {
-				assert.Error(t, err)
-				assert.Contains(t, err.Error(), tt.errMsg)
-			} else {
-				assert.NoError(t, err)
-			}
-		})
-	}
-}
-func TestValidatePattern(t *testing.T) {
-	tests := []struct {
-		name    string
-		pattern string
-		wantErr bool
-	}{
-		{
-			name:    "valid single pattern",
-			pattern: "*.txt",
-			wantErr: false,
-		},
-		{
-			name:    "valid multiple patterns",
-			pattern: "*.txt,*.go,*.md",
-			wantErr: false,
-		},
-		{
-			name:    "empty pattern",
-			pattern: "",
-			wantErr: true,
-		},
-		{
-			name:    "invalid pattern",
-			pattern: "[",
-			wantErr: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			err := validatePattern(tt.pattern)
-			if tt.wantErr {
-				assert.Error(t, err)
-			} else {
-				assert.NoError(t, err)
-			}
-		})
-	}
-}
-func TestValidateExcludePatterns(t *testing.T) {
-	tests := []struct {
-		name    string
-		exclude string
-		wantErr bool
-	}{
-		{
-			name:    "empty exclude",
-			exclude: "",
-			wantErr: false,
-		},
-		{
-			name:    "valid single pattern",
-			exclude: "*.tmp",
-			wantErr: false,
-		},
-		{
-			name:    "valid multiple patterns",
-			exclude: "*.tmp,*.log,*.bak",
-			wantErr: false,
-		},
-		{
-			name:    "glob pattern with **",
-			exclude: "**/vendor/**",
-			wantErr: false,
-		},
-		{
-			name:    "invalid pattern",
-			exclude: "[",
-			wantErr: true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			err := validateExcludePatterns(tt.exclude)
-			if tt.wantErr {
-				assert.Error(t, err)
-			} else {
-				assert.NoError(t, err)
-			}
-		})
-	}
-}
-func TestMixErrorString(t *testing.T) {
-	tests := []struct {
-		name     string
-		err      MixError
-		expected string
-	}{
-		{
-			name: "error with file",
-			err: MixError{
-				File:    "test.txt",
-				Message: "file not found",
-			},
-			expected: "file test.txt: file not found",
-		},
-		{
-			name: "error without file",
-			err: MixError{
-				Message: "invalid operation",
-			},
-			expected: "invalid operation",
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			assert.Equal(t, tt.expected, tt.err.Error())
-		})
-	}
-}
-</document_content>
-</document>
-<document index="45">
-<source>filefusion/internal/core/manager.go</source>
-<document_content>package core
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-	"strconv"
-	"strings"
-)
-type FileManager struct {
-	maxFileSize   int64
-	maxOutputSize int64
-	outputType    OutputType
-}
-type FileGroup struct {
-	OutputPath string
-	Files      []string
-}
-func NewFileManager(maxFileSize, maxOutputSize int64, outputType OutputType) *FileManager {
-	return &FileManager{
-		maxFileSize:   maxFileSize,
-		maxOutputSize: maxOutputSize,
-		outputType:    outputType,
-	}
-}
-func (fm *FileManager) ValidateFiles(files []string) ([]string, error) {
-	var validFiles []string
-	var totalSize int64
-	var ignoredCount int
-	for _, file := range files {
-		info, err := os.Stat(file)
-		if err != nil {
-			return nil, fmt.Errorf("error getting file info: %w", err)
-		}
-		if info.Size() > fm.maxFileSize {
-			ignoredCount++
-			continue
-		}
-		validFiles = append(validFiles, file)
-		totalSize += info.Size()
-	}
-	if ignoredCount > 0 {
-	}
-	if len(validFiles) == 0 {
-		return nil, fmt.Errorf("no valid files found matching patterns")
-	}
-	if totalSize > fm.maxOutputSize {
-		return nil, fmt.Errorf("total size of valid files (%s) exceeds maximum output size (%s)",
-			formatSize(totalSize), formatSize(fm.maxOutputSize))
-	}
-	return validFiles, nil
-}
-func (fm *FileManager) GroupFilesByOutput(files []string, outputPaths []string) ([]FileGroup, error) {
-	if len(outputPaths) == 1 {
-		return []FileGroup{{
-			OutputPath: outputPaths[0],
-			Files:      files,
-		}}, nil
-	}
-	pathsWithoutExt := make(map[string]string)
-	for _, outPath := range outputPaths {
-		pathWithoutExt := strings.TrimSuffix(outPath, filepath.Ext(outPath))
-		pathsWithoutExt[pathWithoutExt] = outPath
-	}
-	groups := make(map[string][]string)
-	var unmatchedFiles []string
-	for _, file := range files {
-		filePathWithoutExt := strings.TrimSuffix(file, filepath.Ext(file))
-		bestMatch := fm.findBestMatchingPath(filePathWithoutExt, pathsWithoutExt)
-		if bestMatch == "" {
-			unmatchedFiles = append(unmatchedFiles, file)
-			continue
-		}
-		outputPath := pathsWithoutExt[bestMatch]
-		groups[outputPath] = append(groups[outputPath], file)
-	}
-	if len(unmatchedFiles) > 0 {
-		firstOutputWithoutExt := strings.TrimSuffix(outputPaths[0], filepath.Ext(outputPaths[0]))
-		unmatchedPath := firstOutputWithoutExt + "_unmatched.xml"
-		groups[unmatchedPath] = unmatchedFiles
-	}
-	var result []FileGroup
-	for outputPath, files := range groups {
-		result = append(result, FileGroup{
-			OutputPath: outputPath,
-			Files:      files,
-		})
-	}
-	return result, nil
-}
-func (fm *FileManager) DeriveOutputPaths(inputPaths []string, customOutputPath string) ([]string, error) {
-	currentDir, err := os.Getwd()
-	if err != nil {
-		return nil, err
-	}
-	if customOutputPath != "" {
-		return []string{filepath.Join(currentDir, customOutputPath)}, nil
-	}
-	result := make([]string, len(inputPaths))
-	for i, path := range inputPaths {
-		if path == "." {
-			dirName := filepath.Base(currentDir)
-			result[i] = filepath.Join(currentDir, fm.addDefaultExtension(dirName))
-		} else {
-			result[i] = filepath.Join(currentDir, fm.deriveOutputName(path))
-		}
-	}
-	return result, nil
-}
-func (fm *FileManager) ParseSize(size string) (int64, error) {
-	size = strings.ToUpper(strings.ReplaceAll(size, " ", ""))
-	if size == "" {
-		return 0, fmt.Errorf("size cannot be empty")
-	}
-	var multiplier int64 = 1
-	var value string
-	switch {
-	case strings.HasSuffix(size, "TB"):
-		multiplier = 1024 * 1024 * 1024 * 1024
-		value = strings.TrimSuffix(size, "TB")
-	case strings.HasSuffix(size, "GB"):
-		multiplier = 1024 * 1024 * 1024
-		value = strings.TrimSuffix(size, "GB")
-	case strings.HasSuffix(size, "MB"):
-		multiplier = 1024 * 1024
-		value = strings.TrimSuffix(size, "MB")
-	case strings.HasSuffix(size, "KB"):
-		multiplier = 1024
-		value = strings.TrimSuffix(size, "KB")
-	case strings.HasSuffix(size, "B"):
-		value = strings.TrimSuffix(size, "B")
-	default:
-		return 0, fmt.Errorf("invalid size format: must end with B, KB, MB, GB, or TB")
-	}
-	num, err := strconv.ParseInt(value, 10, 64)
-	if err != nil {
-		return 0, fmt.Errorf("invalid size number: %w", err)
-	}
-	if num <= 0 {
-		return 0, fmt.Errorf("size must be a positive number")
-	}
-	return num * multiplier, nil
-}
-func (fm *FileManager) findBestMatchingPath(filePath string, dirPaths map[string]string) string {
-	var bestMatch string
-	var maxCommonSegments int
-	fileComponents := strings.Split(filepath.Clean(filePath), string(os.PathSeparator))
-	for dirPath := range dirPaths {
-		dirComponents := strings.Split(filepath.Clean(dirPath), string(os.PathSeparator))
-		commonSegments := fm.countCommonSegments(fileComponents, dirComponents)
-		if commonSegments > maxCommonSegments || bestMatch == "" {
-			maxCommonSegments = commonSegments
-			bestMatch = dirPath
-		}
-	}
-	if maxCommonSegments > 0 {
-		return bestMatch
-	}
-	return ""
-}
-func (fm *FileManager) countCommonSegments(a, b []string) int {
-	count := 0
-	for i := 0; i < len(a) && i < len(b); i++ {
-		if a[i] != b[i] {
-			break
-		}
-		count++
-	}
-	return count
-}
-func (fm *FileManager) deriveOutputName(path string) string {
-	base := filepath.Base(strings.TrimSuffix(path, string(os.PathSeparator)))
-	return fm.addDefaultExtension(base)
-}
-func (fm *FileManager) addDefaultExtension(name string) string {
-	switch fm.outputType {
-	case OutputTypeJSON:
-		return name + ".json"
-	case OutputTypeYAML:
-		return name + ".yaml"
-	default:
-		return name + ".xml"
-	}
-}
-func formatSize(bytes int64) string {
-	const unit = 1024
-	if bytes < unit {
-		return fmt.Sprintf("%d B", bytes)
-	}
-	div, exp := int64(unit), 0
-	for n := bytes / unit; n >= unit; n /= unit {
-		div *= unit
-		exp++
-	}
-	return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
-}
-</document_content>
-</document>
-<document index="46">
-<source>filefusion/internal/core/processor_test.go</source>
-<document_content>package core
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-	"runtime"
-	"strings"
-	"sync"
-	"testing"
-	"time"
-	"unicode/utf8"
-	"github.com/drgsn/filefusion/internal/core/cleaner"
-)
-func normalizeWhitespace(s string) string {
-	s = strings.ReplaceAll(s, "\r\n", "\n")
-	s = strings.TrimSpace(s)
-	s = strings.Join(strings.Fields(strings.ReplaceAll(s, "\n", " ")), " ")
-	return s
-}
-func TestFileProcessor(t *testing.T) {
-	tmpDir, err := os.MkdirTemp("", "filefusion-test-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(tmpDir)
-	files := map[string]struct {
-		size    int64
-		content string
-	}{
-		"small.txt":     {size: 100, content: strings.Repeat("a", 100)},
-		"medium.txt":    {size: 1024, content: strings.Repeat("b", 1024)},
-		"large.txt":     {size: 2048, content: strings.Repeat("c", 2048)},
-		"test/nest.txt": {size: 100, content: strings.Repeat("d", 100)},
-	}
-	for name, info := range files {
-		path := filepath.Join(tmpDir, name)
-		err := os.MkdirAll(filepath.Dir(path), 0755)
-		if err != nil {
-			t.Fatalf("Failed to create directory for %s: %v", name, err)
-		}
-		err = os.WriteFile(path, []byte(info.content), 0644)
-		if err != nil {
-			t.Fatalf("Failed to create test file %s: %v", name, err)
-		}
-	}
-	tests := []struct {
-		name          string
-		maxSize       int64
-		expectedCount int
-	}{
-		{
-			name:          "process all files",
-			maxSize:       3000,
-			expectedCount: 4,
-		},
-		{
-			name:          "size limit excludes large file",
-			maxSize:       1500,
-			expectedCount: 3,
-		},
-		{
-			name:          "small size limit",
-			maxSize:       500,
-			expectedCount: 2,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			processor := NewFileProcessor(&MixOptions{
-				InputPath:   tmpDir,
-				MaxFileSize: tt.maxSize,
-			})
-			var paths []string
-			for name := range files {
-				paths = append(paths, filepath.Join(tmpDir, name))
-			}
-			contents, err := processor.ProcessFiles(paths)
-			if err != nil {
-				t.Fatalf("ProcessFiles failed: %v", err)
-			}
-			if len(contents) != tt.expectedCount {
-				t.Errorf("Expected %d files, got %d", tt.expectedCount, len(contents))
-			}
-			for _, content := range contents {
-				relPath, err := filepath.Rel(tmpDir, filepath.Join(tmpDir, content.Path))
-				if err != nil {
-					t.Fatalf("Failed to get relative path: %v", err)
-				}
-				expectedInfo, exists := files[relPath]
-				if !exists {
-					t.Errorf("Unexpected file in results: %s (relative path: %s)", content.Path, relPath)
-					continue
-				}
-				if content.Size != expectedInfo.size {
-					t.Errorf("Size mismatch for %s: expected %d, got %d",
-						relPath, expectedInfo.size, content.Size)
-				}
-				if content.Content != expectedInfo.content {
-					t.Errorf("Content mismatch for %s", relPath)
-				}
-			}
-		})
-	}
-}
-func TestFileProcessorErrors(t *testing.T) {
-	tmpDir, err := os.MkdirTemp("", "filefusion-error-test-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(tmpDir)
-	nestedDir := filepath.Join(tmpDir, "nested")
-	if err := os.MkdirAll(nestedDir, 0755); err != nil {
-		t.Fatalf("Failed to create nested directory: %v", err)
-	}
-	testFile := filepath.Join(nestedDir, "test.txt")
-	if err := os.WriteFile(testFile, []byte("test content"), 0644); err != nil {
-		t.Fatalf("Failed to create test file: %v", err)
-	}
-	processor := NewFileProcessor(&MixOptions{
-		InputPath:   tmpDir,
-		MaxFileSize: 1,
-	})
-	tests := []struct {
-		name        string
-		path        string
-		wantErr     bool
-		errContains string
-	}{
-		{
-			name:        "process directory as file",
-			path:        nestedDir,
-			wantErr:     true,
-			errContains: "is a directory",
-		},
-		{
-			name:        "process non-existent file",
-			path:        filepath.Join(tmpDir, "nonexistent.txt"),
-			wantErr:     true,
-			errContains: "no such file",
-		},
-		{
-			name:    "process file exceeding size limit",
-			path:    testFile,
-			wantErr: false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			result := processor.processFile(tt.path)
-			if tt.wantErr {
-				if result.Error == nil {
-					t.Errorf("Expected error for %s", tt.name)
-					return
-				}
-				if tt.errContains != "" && !strings.Contains(strings.ToLower(result.Error.Error()), strings.ToLower(tt.errContains)) {
-					t.Errorf("Expected error containing %q, got %q", tt.errContains, result.Error)
-				}
-			} else {
-				if result.Error != nil {
-					t.Errorf("Unexpected error: %v", result.Error)
-				}
-			}
-		})
-	}
-}
-func TestProcessorConcurrency(t *testing.T) {
-	tmpDir, err := os.MkdirTemp("", "filefusion-concurrent-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(tmpDir)
-	files := []struct {
-		name        string
-		content     string
-		permissions os.FileMode
-		shouldError bool
-	}{
-		{"readable.txt", "test content", 0644, false},
-		{"unreadable.txt", "test content", 0000, true},
-		{"executable.txt", "test content", 0755, false},
-	}
-	var filePaths []string
-	for _, f := range files {
-		path := filepath.Join(tmpDir, f.name)
-		if err := os.WriteFile(path, []byte(f.content), f.permissions); err != nil {
-			t.Fatalf("Failed to create test file %s: %v", f.name, err)
-		}
-		filePaths = append(filePaths, path)
-		if err := os.Chmod(path, f.permissions); err != nil {
-			t.Fatalf("Failed to set permissions for %s: %v", f.name, err)
-		}
-	}
-	processor := NewFileProcessor(&MixOptions{
-		InputPath:   tmpDir,
-		MaxFileSize: 1024 * 1024,
-	})
-	contents, err := processor.ProcessFiles(filePaths)
-	if err == nil {
-		t.Error("Expected error due to unreadable file, got none")
-	}
-	readableCount := 0
-	for _, content := range contents {
-		if !strings.Contains(content.Path, "unreadable") {
-			readableCount++
-		}
-	}
-	expectedReadable := 2
-	if readableCount != expectedReadable {
-		t.Errorf("Expected %d readable files, got %d", expectedReadable, readableCount)
-	}
-}
-func TestProcessorEdgeCases(t *testing.T) {
-	tmpDir, err := os.MkdirTemp("", "filefusion-paths-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(tmpDir)
-	edgeCases := []struct {
-		path    string
-		content string
-	}{
-		{"file with spaces.go", "content"},
-		{"file#with#hashes.go", "content"},
-		{"file_with_漢字.go", "content"},
-		{"../outside/attempt.go", "content"},
-		{"./inside/./path.go", "content"},
-	}
-	for _, ec := range edgeCases {
-		path := filepath.Join(tmpDir, ec.path)
-		if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
-			continue
-		}
-		if err := os.WriteFile(path, []byte(ec.content), 0644); err != nil {
-			continue
-		}
-	}
-	processor := NewFileProcessor(&MixOptions{
-		InputPath:   tmpDir,
-		MaxFileSize: 1024,
-	})
-	paths := []string{
-		filepath.Join(tmpDir, "file with spaces.go"),
-		filepath.Join(tmpDir, "file#with#hashes.go"),
-		filepath.Join(tmpDir, "file_with_漢字.go"),
-	}
-	contents, err := processor.ProcessFiles(paths)
-	if err != nil {
-		t.Fatalf("Failed to process edge case paths: %v", err)
-	}
-	if len(contents) != 3 {
-		t.Errorf("Expected 3 processed files, got %d", len(contents))
-	}
-}
-func TestLanguageDetection(t *testing.T) {
-	processor := NewFileProcessor(&MixOptions{})
-	tests := []struct {
-		path     string
-		expected cleaner.Language
-	}{
-		{"test.go", cleaner.LangGo},
-		{"test.java", cleaner.LangJava},
-		{"test.py", cleaner.LangPython},
-		{"test.js", cleaner.LangJavaScript},
-		{"test.ts", cleaner.LangTypeScript},
-		{"test.html", cleaner.LangHTML},
-		{"test.css", cleaner.LangCSS},
-		{"test.cpp", cleaner.LangCPP},
-		{"test.cc", cleaner.LangCPP},
-		{"test.h", cleaner.LangCPP},
-		{"test.cs", cleaner.LangCSharp},
-		{"test.php", cleaner.LangPHP},
-		{"test.rb", cleaner.LangRuby},
-		{"test.sh", cleaner.LangBash},
-		{"test.bash", cleaner.LangBash},
-		{"test.swift", cleaner.LangSwift},
-		{"test.kt", cleaner.LangKotlin},
-		{"test.sql", cleaner.LangSQL},
-		{"test.txt", ""},
-		{"test", ""},
-		{"test.JAVA", cleaner.LangJava},
-	}
-	for _, tt := range tests {
-		t.Run(tt.path, func(t *testing.T) {
-			got := processor.detectLanguage(tt.path)
-			if got != tt.expected {
-				t.Errorf("detectLanguage(%q) = %v, want %v", tt.path, got, tt.expected)
-			}
-		})
-	}
-}
-func TestCleanerCaching(t *testing.T) {
-	processor := NewFileProcessor(&MixOptions{
-		CleanerOptions: &cleaner.CleanerOptions{},
-	})
-	c1, err := processor.getOrCreateCleaner(cleaner.LangGo)
-	if err != nil {
-		t.Fatalf("Failed to create first cleaner: %v", err)
-	}
-	c2, err := processor.getOrCreateCleaner(cleaner.LangGo)
-	if err != nil {
-		t.Fatalf("Failed to get cached cleaner: %v", err)
-	}
-	if c1 != c2 {
-		t.Error("Expected same cleaner instance to be returned from cache")
-	}
-	var wg sync.WaitGroup
-	for i := 0; i < 10; i++ {
-		wg.Add(1)
-		go func() {
-			defer wg.Done()
-			c, err := processor.getOrCreateCleaner(cleaner.LangGo)
-			if err != nil {
-				t.Errorf("Concurrent cleaner access failed: %v", err)
-			}
-			if c != c1 {
-				t.Error("Got different cleaner instance in concurrent access")
-			}
-		}()
-	}
-	wg.Wait()
-}
-func TestWorkerPoolBehavior(t *testing.T) {
-	tmpDir, err := os.MkdirTemp("", "filefusion-workers-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(tmpDir)
-	fileCount := 20
-	var paths []string
-	for i := 0; i < fileCount; i++ {
-		path := filepath.Join(tmpDir, fmt.Sprintf("test%d.txt", i))
-		if err := os.WriteFile(path, []byte("test content"), 0644); err != nil {
-			t.Fatalf("Failed to create test file: %v", err)
-		}
-		paths = append(paths, path)
-	}
-	processor := NewFileProcessor(&MixOptions{
-		InputPath:   tmpDir,
-		MaxFileSize: 1024,
-	})
-	start := time.Now()
-	contents, err := processor.ProcessFiles(paths)
-	duration := time.Since(start)
-	if err != nil {
-		t.Fatalf("ProcessFiles failed: %v", err)
-	}
-	if len(contents) != fileCount {
-		t.Errorf("Expected %d processed files, got %d", fileCount, len(contents))
-	}
-	expectedMaxDuration := time.Second
-	if duration > expectedMaxDuration {
-		t.Errorf("Processing took too long (%v), suggesting lack of concurrency", duration)
-	}
-}
-func TestRelativePathCreation(t *testing.T) {
-	tests := []struct {
-		name         string
-		inputPath    string
-		filePath     string
-		expectedPath string
-		expectError  bool
-	}{
-		{
-			name:         "simple relative path",
-			inputPath:    "/base/dir",
-			filePath:     "/base/dir/file.txt",
-			expectedPath: "file.txt",
-		},
-		{
-			name:         "nested relative path",
-			inputPath:    "/base/dir",
-			filePath:     "/base/dir/nested/file.txt",
-			expectedPath: "nested/file.txt",
-		},
-		{
-			name:         "path with dots",
-			inputPath:    "/base/dir",
-			filePath:     "/base/dir/./nested/../file.txt",
-			expectedPath: "file.txt",
-		},
-		{
-			name:         "path outside input directory",
-			inputPath:    "/base/dir",
-			filePath:     "/other/dir/file.txt",
-			expectedPath: "/other/dir/file.txt",
-		},
-		{
-			name:         "input path with trailing slash",
-			inputPath:    "/base/dir/",
-			filePath:     "/base/dir/file.txt",
-			expectedPath: "file.txt",
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			processor := NewFileProcessor(&MixOptions{
-				InputPath: tt.inputPath,
-			})
-			got, err := processor.createRelativePath(tt.filePath)
-			if tt.expectError {
-				if err == nil {
-					t.Error("Expected error, got none")
-				}
-				return
-			}
-			if err != nil {
-				t.Errorf("Unexpected error: %v", err)
-				return
-			}
-			if got != tt.expectedPath {
-				t.Errorf("createRelativePath() = %v, want %v", got, tt.expectedPath)
-			}
-		})
-	}
-}
-func TestCleanerPanicRecovery(t *testing.T) {
-	tmpDir, err := os.MkdirTemp("", "filefusion-panic-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(tmpDir)
-	testFile := filepath.Join(tmpDir, "test.go")
-	testContent := "package main\n\nfunc main() {}\n"
-	if err := os.WriteFile(testFile, []byte(testContent), 0644); err != nil {
-		t.Fatalf("Failed to create test file: %v", err)
-	}
-	processor := NewFileProcessor(&MixOptions{
-		InputPath:      tmpDir,
-		CleanerOptions: cleaner.DefaultOptions(),
-		MaxFileSize:    1024,
-	})
-	result := processor.processFile(testFile)
-	if result.Error != nil {
-		t.Errorf("Expected no error, got: %v", result.Error)
-	}
-	expectedNormalized := normalizeWhitespace(testContent)
-	gotNormalized := normalizeWhitespace(result.Content.Content)
-	if expectedNormalized != gotNormalized {
-		t.Errorf("Content mismatch after normalization:\nExpected: '%s'\nGot: '%s'",
-			expectedNormalized, gotNormalized)
-	}
-}
-func TestCleanerErrorHandling(t *testing.T) {
-	tmpDir, err := os.MkdirTemp("", "filefusion-error-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(tmpDir)
-	testCases := []struct {
-		name           string
-		content        string
-		expectOriginal bool
-	}{
-		{
-			name:           "process Go file",
-			content:        "package main\n\nfunc main() {}\n",
-			expectOriginal: true,
-		},
-	}
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			testFile := filepath.Join(tmpDir, "test.go")
-			if err := os.WriteFile(testFile, []byte(tc.content), 0644); err != nil {
-				t.Fatalf("Failed to create test file: %v", err)
-			}
-			processor := NewFileProcessor(&MixOptions{
-				InputPath:      tmpDir,
-				CleanerOptions: cleaner.DefaultOptions(),
-				MaxFileSize:    1024,
-			})
-			result := processor.processFile(testFile)
-			if result.Error != nil {
-				t.Fatalf("Unexpected error: %v", result.Error)
-			}
-			if tc.expectOriginal {
-				gotNormalized := normalizeWhitespace(result.Content.Content)
-				if !strings.Contains(gotNormalized, "package main") {
-					t.Errorf("Expected content to contain 'package main', got: '%s'", gotNormalized)
-				}
-				if !strings.Contains(gotNormalized, "func main()") {
-					t.Errorf("Expected content to contain 'func main()', got: '%s'", gotNormalized)
-				}
-			}
-		})
-	}
-}
-func TestProcessFileUnknownLanguage(t *testing.T) {
-	tmpDir, err := os.MkdirTemp("", "filefusion-unknown-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(tmpDir)
-	testFile := filepath.Join(tmpDir, "test.xyz")
-	testContent := "some random content\n"
-	if err := os.WriteFile(testFile, []byte(testContent), 0644); err != nil {
-		t.Fatalf("Failed to create test file: %v", err)
-	}
-	processor := NewFileProcessor(&MixOptions{
-		InputPath:      tmpDir,
-		CleanerOptions: cleaner.DefaultOptions(),
-		MaxFileSize:    1024,
-	})
-	result := processor.processFile(testFile)
-	if result.Error != nil {
-		t.Errorf("Expected no error for unknown language, got: %v", result.Error)
-	}
-	if result.Content.Content != testContent {
-		t.Errorf("Expected content to remain unchanged for unknown language.\nExpected: %q\nGot: %q",
-			testContent, result.Content.Content)
-	}
-	if result.Content.Extension != "xyz" {
-		t.Errorf("Expected extension 'xyz', got %q", result.Content.Extension)
-	}
-	if !strings.HasSuffix(result.Content.Path, "test.xyz") {
-		t.Errorf("Expected path to end with 'test.xyz', got %q", result.Content.Path)
-	}
-}
-func TestProcessFileEdgeCases(t *testing.T) {
-	tmpDir, err := os.MkdirTemp("", "filefusion-edge-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(tmpDir)
-	tests := []struct {
-		name        string
-		setup       func(dir string) string
-		maxFileSize int64
-		wantErr     bool
-		check       func(*testing.T, FileResult)
-	}{
-		{
-			name: "empty file",
-			setup: func(dir string) string {
-				path := filepath.Join(dir, "empty.go")
-				err := os.WriteFile(path, []byte(""), 0644)
-				if err != nil {
-					t.Fatalf("Failed to create empty file: %v", err)
-				}
-				return path
-			},
-			maxFileSize: 1024,
-			wantErr:     false,
-			check: func(t *testing.T, r FileResult) {
-				if r.Content.Size != 0 {
-					t.Errorf("Expected size 0 for empty file, got %d", r.Content.Size)
-				}
-			},
-		},
-		{
-			name: "whitespace only file",
-			setup: func(dir string) string {
-				path := filepath.Join(dir, "whitespace.go")
-				err := os.WriteFile(path, []byte("   \n\t\n   "), 0644)
-				if err != nil {
-					t.Fatalf("Failed to create whitespace file: %v", err)
-				}
-				return path
-			},
-			maxFileSize: 1024,
-			wantErr:     false,
-			check: func(t *testing.T, r FileResult) {
-				if len(strings.TrimSpace(r.Content.Content)) != 0 {
-					t.Error("Expected trimmed content to be empty")
-				}
-			},
-		},
-		{
-			name: "file with null bytes",
-			setup: func(dir string) string {
-				path := filepath.Join(dir, "null.go")
-				content := []byte("package main\x00func main() {}")
-				err := os.WriteFile(path, content, 0644)
-				if err != nil {
-					t.Fatalf("Failed to create file with null bytes: %v", err)
-				}
-				return path
-			},
-			maxFileSize: 1024,
-			wantErr:     false,
-			check: func(t *testing.T, r FileResult) {
-				if !strings.Contains(r.Content.Content, "\x00") {
-					t.Error("Expected content to preserve null bytes")
-				}
-			},
-		},
-		{
-			name: "file with invalid UTF-8",
-			setup: func(dir string) string {
-				path := filepath.Join(dir, "invalid_utf8.go")
-				content := []byte("package main\xFF\xFEfunc main() {}")
-				err := os.WriteFile(path, content, 0644)
-				if err != nil {
-					t.Fatalf("Failed to create file with invalid UTF-8: %v", err)
-				}
-				return path
-			},
-			maxFileSize: 1024,
-			wantErr:     false,
-			check: func(t *testing.T, r FileResult) {
-				if utf8.ValidString(r.Content.Content) {
-					t.Error("Expected content to remain invalid UTF-8")
-				}
-			},
-		},
-		{
-			name: "file at exact size limit",
-			setup: func(dir string) string {
-				path := filepath.Join(dir, "exact.go")
-				content := make([]byte, 10)
-				err := os.WriteFile(path, content, 0644)
-				if err != nil {
-					t.Fatalf("Failed to create exact size file: %v", err)
-				}
-				return path
-			},
-			maxFileSize: 10,
-			wantErr:     false,
-			check: func(t *testing.T, r FileResult) {
-				if r.Content.Size != 10 {
-					t.Errorf("Expected size 10, got %d", r.Content.Size)
-				}
-			},
-		},
-		{
-			name: "special characters in filename",
-			setup: func(dir string) string {
-				path := filepath.Join(dir, "special!@#$%^&()_+{}.go")
-				err := os.WriteFile(path, []byte("content"), 0644)
-				if err != nil {
-					t.Fatalf("Failed to create file with special chars: %v", err)
-				}
-				return path
-			},
-			maxFileSize: 1024,
-			wantErr:     false,
-			check: func(t *testing.T, r FileResult) {
-				if !strings.Contains(r.Content.Path, "!@#$%^&()_+") {
-					t.Error("Expected special characters to be preserved in path")
-				}
-			},
-		},
-		{
-			name: "nil cleaner options",
-			setup: func(dir string) string {
-				path := filepath.Join(dir, "test.go")
-				err := os.WriteFile(path, []byte("package main"), 0644)
-				if err != nil {
-					t.Fatalf("Failed to create test file: %v", err)
-				}
-				return path
-			},
-			maxFileSize: 1024,
-			wantErr:     false,
-			check: func(t *testing.T, r FileResult) {
-				if r.Content.Content != "package main" {
-					t.Error("Expected content to remain unchanged with nil cleaner options")
-				}
-			},
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			filePath := tt.setup(tmpDir)
-			processor := NewFileProcessor(&MixOptions{
-				InputPath:      tmpDir,
-				MaxFileSize:    tt.maxFileSize,
-				CleanerOptions: nil,
-			})
-			result := processor.processFile(filePath)
-			if tt.wantErr {
-				if result.Error == nil {
-					t.Error("Expected error but got none")
-				}
-				return
-			}
-			if result.Error != nil {
-				t.Errorf("Unexpected error: %v", result.Error)
-				return
-			}
-			tt.check(t, result)
-		})
-	}
-}
-func TestProcessFileSymlinks(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		t.Skip("Skipping symlink tests on Windows")
-	}
-	tmpDir, err := os.MkdirTemp("", "filefusion-symlink-*")
-	if err != nil {
-		t.Fatalf("Failed to create temp dir: %v", err)
-	}
-	defer os.RemoveAll(tmpDir)
-	realFile := filepath.Join(tmpDir, "real.go")
-	if err := os.WriteFile(realFile, []byte("package main"), 0644); err != nil {
-		t.Fatalf("Failed to create real file: %v", err)
-	}
-	validLink := filepath.Join(tmpDir, "valid.go")
-	if err := os.Symlink(realFile, validLink); err != nil {
-		t.Fatalf("Failed to create symlink: %v", err)
-	}
-	brokenLink := filepath.Join(tmpDir, "broken.go")
-	if err := os.Symlink(filepath.Join(tmpDir, "nonexistent.go"), brokenLink); err != nil {
-		t.Fatalf("Failed to create broken symlink: %v", err)
-	}
-	processor := NewFileProcessor(&MixOptions{
-		InputPath:   tmpDir,
-		MaxFileSize: 1024,
-	})
-	result := processor.processFile(validLink)
-	if result.Error != nil {
-		t.Errorf("Expected no error for valid symlink, got: %v", result.Error)
-	}
-	if result.Content.Content != "package main" {
-		t.Error("Expected to read content through valid symlink")
-	}
-	result = processor.processFile(brokenLink)
-	if result.Error == nil {
-		t.Error("Expected error for broken symlink, got none")
-	}
-}
-</document_content>
-</document>
-</documents>
\ No newline at end of file
diff --git a/internal/core/cleaner/handlers/csharp_handler.go b/internal/core/cleaner/handlers/csharp_handler.go
index d06c84e..4085ff7 100644
--- a/internal/core/cleaner/handlers/csharp_handler.go
+++ b/internal/core/cleaner/handlers/csharp_handler.go
@@ -64,26 +64,7 @@ func (h *CSharpHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
 	case "property_declaration":
 		accessorList := node.ChildByFieldName("accessors")
 		if accessorList != nil {
-			hasGetter := false
-			hasSetter := false
-
-			for i := 0; i < int(accessorList.ChildCount()); i++ {
-				accessor := accessorList.Child(i)
-
-				if accessor.Type() != "accessor_declaration" {
-					// Skip unsupported accessor node types
-					continue
-				}
-
-				text := string(content[accessor.StartByte():accessor.EndByte()])
-				if strings.Contains(text, "get") {
-					hasGetter = true
-				}
-				if strings.Contains(text, "set") {
-					hasSetter = true
-				}
-			}
-			return hasGetter || hasSetter
+			return hasAccessor(accessorList, content)
 		}
 		return false
 
@@ -109,17 +90,24 @@ func (h *CSharpHandler) IsGetterSetter(node *sitter.Node, content []byte) bool {
 
 // Helper function to check for `get` or `set` in a block
 func hasAccessor(block *sitter.Node, content []byte) bool {
+	if block == nil {
+		return false
+	}
+
 	hasGetter := false
 	hasSetter := false
 
-	for i := 0; i < int(block.ChildCount()); i++ {
-		child := block.Child(i)
-		if child.Type() == "ERROR" {
-			// Interpret `ERROR` nodes as `get` or `set`
-			text := string(content[child.StartByte():child.EndByte()])
-			if text == "get" {
+	cursor := sitter.NewTreeCursor(block)
+	defer cursor.Close()
+
+	for ok := cursor.GoToFirstChild(); ok; ok = cursor.GoToNextSibling() {
+		node := cursor.CurrentNode()
+		if node.Type() == "accessor_declaration" {
+			text := string(content[node.StartByte():node.EndByte()])
+			if strings.Contains(text, "get") {
 				hasGetter = true
-			} else if text == "set" {
+			}
+			if strings.Contains(text, "set") {
 				hasSetter = true
 			}
 		}
@@ -149,4 +137,4 @@ func findNextSibling(node *sitter.Node, nodeType string) *sitter.Node {
 		}
 	}
 	return nil
-}
+}
\ No newline at end of file
diff --git a/internal/core/cleaner/handlers/csharp_handler_test.go b/internal/core/cleaner/handlers/csharp_handler_test.go
index cc6e74c..4e5e1a1 100644
--- a/internal/core/cleaner/handlers/csharp_handler_test.go
+++ b/internal/core/cleaner/handlers/csharp_handler_test.go
@@ -1,190 +1,386 @@
 package handlers
 
 import (
+	"strings"
 	"testing"
 
 	sitter "github.com/smacker/go-tree-sitter"
 	"github.com/smacker/go-tree-sitter/csharp"
+	"github.com/stretchr/testify/assert"
 )
 
-func findFirstNodeOfType(root *sitter.Node, nodeType string) *sitter.Node {
+func getCSharpLanguage() *sitter.Language {
+	return csharp.GetLanguage()
+}
+
+// Helper function to find node by type in the AST
+func findNodeByType(root *sitter.Node, nodeType string) *sitter.Node {
 	if root == nil {
 		return nil
 	}
+
+	if root.Type() == nodeType {
+		return root
+	}
+
 	cursor := sitter.NewTreeCursor(root)
 	defer cursor.Close()
 
-	ok := cursor.GoToFirstChild()
-	for ok {
-		if cursor.CurrentNode().Type() == nodeType {
-			return cursor.CurrentNode()
-		}
-		if node := findFirstNodeOfType(cursor.CurrentNode(), nodeType); node != nil {
+	for ok := cursor.GoToFirstChild(); ok; ok = cursor.GoToNextSibling() {
+		if node := findNodeByType(cursor.CurrentNode(), nodeType); node != nil {
 			return node
 		}
-		ok = cursor.GoToNextSibling()
 	}
+
 	return nil
 }
 
-func TestCSharpHandlerBasics(t *testing.T) {
-	handler := &CSharpHandler{}
-
-	// Test comment types
-	commentTypes := handler.GetCommentTypes()
-	expected := []string{"comment", "multiline_comment"}
-	if !stringSliceEqual(commentTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, commentTypes)
+// Helper function to debug print node structure
+func debugPrintNode(t *testing.T, node *sitter.Node, content []byte, level int) {
+	if node == nil {
+		return
 	}
 
-	// Test import types
-	importTypes := handler.GetImportTypes()
-	expected = []string{"using_directive"}
-	if !stringSliceEqual(importTypes, expected) {
-		t.Errorf("Expected %v, got %v", expected, importTypes)
+	indent := strings.Repeat("  ", level)
+	nodeText := ""
+	if content != nil {
+		nodeText = string(content[node.StartByte():node.EndByte()])
 	}
+	t.Logf("%sType: %s, Text: %s", indent, node.Type(), nodeText)
 
-	// Test doc comment prefix
-	if prefix := handler.GetDocCommentPrefix(); prefix != "///" {
-		t.Errorf("Expected '///', got %s", prefix)
+	cursor := sitter.NewTreeCursor(node)
+	defer cursor.Close()
+
+	for ok := cursor.GoToFirstChild(); ok; ok = cursor.GoToNextSibling() {
+		debugPrintNode(t, cursor.CurrentNode(), content, level+1)
 	}
 }
 
-func TestCSharpLoggingCalls(t *testing.T) {
+func TestCSharpHandler_GetCommentTypes(t *testing.T) {
 	handler := &CSharpHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(csharp.GetLanguage())
+	expected := []string{"comment", "multiline_comment"}
+	actual := handler.GetCommentTypes()
+	assert.Equal(t, expected, actual, "Comment types should match expected values")
+}
 
+func TestCSharpHandler_GetImportTypes(t *testing.T) {
+	handler := &CSharpHandler{}
+	expected := []string{"using_directive"}
+	actual := handler.GetImportTypes()
+	assert.Equal(t, expected, actual, "Import types should match expected values")
+}
+
+func TestCSharpHandler_GetDocCommentPrefix(t *testing.T) {
+	handler := &CSharpHandler{}
+	expected := "///"
+	actual := handler.GetDocCommentPrefix()
+	assert.Equal(t, expected, actual, "Doc comment prefix should be ///")
+}
+
+func TestCSharpHandler_IsLoggingCall(t *testing.T) {
+	handler := &CSharpHandler{}
+	
 	tests := []struct {
 		name     string
-		input    string
+		code     string
 		expected bool
 	}{
 		{
-			name:     "console write",
-			input:    "Console.WriteLine(\"test\");",
+			name: "Console.WriteLine call",
+			code: `namespace TestNamespace {
+				class Program {
+					void Method() {
+						Console.WriteLine("test");
+					}
+				}
+			}`,
 			expected: true,
 		},
 		{
-			name:     "debug log",
-			input:    "Debug.Log(\"test\");",
+			name: "Debug.Log call",
+			code: `namespace TestNamespace {
+				class Program {
+					void Method() {
+						Debug.Log("test");
+					}
+				}
+			}`,
 			expected: true,
 		},
 		{
-			name:     "logger info",
-			input:    "Logger.Info(\"test\");",
+			name: "Logger.Info call",
+			code: `namespace TestNamespace {
+				class Program {
+					void Method() {
+						Logger.Info("test");
+					}
+				}
+			}`,
 			expected: true,
 		},
 		{
-			name:     "trace write",
-			input:    "Trace.WriteLine(\"test\");",
+			name: "Trace.WriteLine call",
+			code: `namespace TestNamespace {
+				class Program {
+					void Method() {
+						Trace.WriteLine("test");
+					}
+				}
+			}`,
 			expected: true,
 		},
 		{
-			name:     "regular method call",
-			input:    "Process(\"test\");",
+			name: "Regular method call",
+			code: `namespace TestNamespace {
+				class Program {
+					void Method() {
+						MyMethod("test");
+					}
+				}
+			}`,
 			expected: false,
 		},
 		{
-			name:     "string method",
-			input:    "\"test\".ToString();",
+			name: "Regular property access",
+			code: `namespace TestNamespace {
+				class Program {
+					void Method() {
+						var x = myObject.Property.ToString();
+					}
+				}
+			}`,
 			expected: false,
 		},
 	}
 
+	parser := sitter.NewParser()
+	parser.SetLanguage(getCSharpLanguage())
+
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
-			}
-			defer tree.Close()
-			invocationNode := findFirstNodeOfType(tree.RootNode(), "invocation_expression")
-			if invocationNode == nil {
-				t.Fatal("Failed to find invocation_expression node")
+			tree := parser.Parse(nil, []byte(tt.code))
+			invocationNode := findNodeByType(tree.RootNode(), "invocation_expression")
+			
+			if invocationNode == nil && tt.expected {
+				t.Fatalf("Failed to find invocation_expression node in AST for test case: %s", tt.name)
 			}
 
-			result := handler.IsLoggingCall(invocationNode, []byte(tt.input))
-			if result != tt.expected {
-				t.Errorf("Expected IsLoggingCall() = %v for input %q", tt.expected, tt.input)
+			if invocationNode != nil {
+				result := handler.IsLoggingCall(invocationNode, []byte(tt.code))
+				assert.Equal(t, tt.expected, result, "IsLoggingCall result should match expected for %s", tt.name)
 			}
 		})
 	}
-
-	// Test nil node
-	if handler.IsLoggingCall(nil, []byte("")) {
-		t.Error("Expected IsLoggingCall to return false for nil node")
-	}
 }
 
-func TestCSharpGetterSetter(t *testing.T) {
+func TestCSharpHandler_IsGetterSetter(t *testing.T) {
 	handler := &CSharpHandler{}
-	parser := sitter.NewParser()
-	parser.SetLanguage(csharp.GetLanguage())
-
+	
 	tests := []struct {
 		name     string
-		input    string
+		code     string
+		nodeType string
 		expected bool
 	}{
-		{"auto_property", "public string Name { get; set; }", true},
-		{"getter_only_property", "public string Name { get; }", true},
-		{"setter_only_property", "public string Name { private set; }", true},
-		{"property_with_access_modifiers", "public string Name { private set; get; }", true},
-		{"getter_method", "public string GetName() { return name; }", true},
-		{"setter_method", "public void SetName(string value) { name = value; }", true},
-		{"regular_method", "public void Process() { }", false},
-		{"regular_property", "public string Name;", false},
-		{"invalid_property_syntax", "public string Name { get set; }", false},
-		{"empty_accessor_blocks", "public string Name { get; }", true},
-		{"invalid_accessor_body", "public string Name { get {} set; }", true},
-		{"missing_getter", "public string Name { set; }", true},
-		{"missing_setter", "public string Name { get; }", true},
+		{
+			name: "Simple property with get/set",
+			code: `namespace TestNamespace {
+				class TestClass {
+					public int MyProperty { get; set; }
+				}
+			}`,
+			nodeType: "property_declaration",
+			expected: true,
+		},
+		{
+			name: "Property with only getter",
+			code: `namespace TestNamespace {
+				class TestClass {
+					public int MyProperty { get; }
+				}
+			}`,
+			nodeType: "property_declaration",
+			expected: true,
+		},
+		{
+			name: "Property with only setter",
+			code: `namespace TestNamespace {
+				class TestClass {
+					public int MyProperty { set { value = value; } }
+				}
+			}`,
+			nodeType: "property_declaration",
+			expected: true,
+		},
+		{
+			name: "Getter method",
+			code: `namespace TestNamespace {
+				class TestClass {
+					public int GetValue() { return value; }
+				}
+			}`,
+			nodeType: "method_declaration",
+			expected: true,
+		},
+		{
+			name: "Setter method",
+			code: `namespace TestNamespace {
+				class TestClass {
+					public void SetValue(int value) { this.value = value; }
+				}
+			}`,
+			nodeType: "method_declaration",
+			expected: true,
+		},
+		{
+			name: "Regular method",
+			code: `namespace TestNamespace {
+				class TestClass {
+					public void DoSomething() { }
+				}
+			}`,
+			nodeType: "method_declaration",
+			expected: false,
+		},
+		{
+			name: "Property without accessors",
+			code: `namespace TestNamespace {
+				class TestClass {
+					public int MyProperty => 42;
+				}
+			}`,
+			nodeType: "property_declaration",
+			expected: false,
+		},
 	}
 
+	parser := sitter.NewParser()
+	parser.SetLanguage(getCSharpLanguage())
+
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			tree := parser.Parse(nil, []byte(tt.input))
-			if tree == nil {
-				t.Fatal("Failed to parse input")
+			tree := parser.Parse(nil, []byte(tt.code))
+			targetNode := findNodeByType(tree.RootNode(), tt.nodeType)
+			
+			if targetNode == nil {
+				t.Fatalf("Failed to find %s node in AST for test case: %s", tt.nodeType, tt.name)
 			}
-			defer tree.Close()
-
-			rootNode := tree.RootNode()
-			if rootNode == nil {
-				t.Fatal("Failed to get root node")
+			
+			// Debug print the node structure if needed
+			if testing.Verbose() {
+				t.Log("Node structure for:", tt.name)
+				debugPrintNode(t, targetNode, []byte(tt.code), 0)
 			}
+			
+			result := handler.IsGetterSetter(targetNode, []byte(tt.code))
+			assert.Equal(t, tt.expected, result, "IsGetterSetter result should match expected for %s", tt.name)
+		})
+	}
+}
+
+func TestHelperFunctions(t *testing.T) {
+	parser := sitter.NewParser()
+	parser.SetLanguage(getCSharpLanguage())
 
-			node := findRelevantNode(rootNode, []byte(tt.input), []string{"property_declaration", "method_declaration"})
-			if node == nil || node.Type() == "ERROR" {
-				t.Skip("Skipping unsupported syntax")
+	t.Run("hasAccessor", func(t *testing.T) {
+		code := `namespace TestNamespace {
+			class TestClass {
+				public int MyProperty { get; set; }
 			}
+		}`
+		tree := parser.Parse(nil, []byte(code))
+		propertyNode := findNodeByType(tree.RootNode(), "property_declaration")
+		
+		if propertyNode == nil {
+			t.Fatal("Failed to find property_declaration node")
+		}
+
+		accessorList := propertyNode.ChildByFieldName("accessors")
+		if accessorList == nil {
+			t.Fatal("Failed to find accessor_list node")
+		}
+
+		if testing.Verbose() {
+			t.Log("Node structure for hasAccessor test:")
+			debugPrintNode(t, accessorList, []byte(code), 0)
+		}
 
-			result := handler.IsGetterSetter(node, []byte(tt.input))
+		result := hasAccessor(accessorList, []byte(code))
+		assert.True(t, result, "hasAccessor should return true for property with get/set")
+	})
 
-			if result != tt.expected {
-				t.Errorf("Expected IsGetterSetter() = %v for input %q, got %v", tt.expected, tt.input, result)
+	t.Run("findNextSibling", func(t *testing.T) {
+		code := `namespace TestNamespace {
+			class MyClass {
+				public void Method1() {}
+				public void Method2() {}
 			}
-		})
-	}
+		}`
+		tree := parser.Parse(nil, []byte(code))
+		method1 := findNodeByType(tree.RootNode(), "method_declaration")
+		
+		if method1 == nil {
+			t.Fatal("Failed to find first method declaration")
+		}
+		
+		nextMethod := findNextSibling(method1, "method_declaration")
+		assert.NotNil(t, nextMethod, "findNextSibling should find Method2")
+		assert.Equal(t, "method_declaration", nextMethod.Type(), "Next sibling should be a method declaration")
+	})
 }
 
-func findRelevantNode(node *sitter.Node, content []byte, types []string) *sitter.Node {
-	if node == nil {
-		return nil
-	}
-
-	for _, nodeType := range types {
-		if node.Type() == nodeType || node.Type() == "ERROR" {
-			return node
+func TestCSharpHandler_EdgeCases(t *testing.T) {
+	handler := &CSharpHandler{}
+	parser := sitter.NewParser()
+	parser.SetLanguage(getCSharpLanguage())
+	
+	t.Run("IsLoggingCall with nil node", func(t *testing.T) {
+		result := handler.IsLoggingCall(nil, []byte(""))
+		assert.False(t, result, "IsLoggingCall should return false for nil node")
+	})
+	
+	t.Run("IsGetterSetter with nil node", func(t *testing.T) {
+		result := handler.IsGetterSetter(nil, []byte(""))
+		assert.False(t, result, "IsGetterSetter should return false for nil node")
+	})
+	
+	t.Run("IsLoggingCall with empty content", func(t *testing.T) {
+		code := `namespace TestNamespace {
+			class TestClass {
+				void Method() {}
+			}
+		}`
+		tree := parser.Parse(nil, []byte(code))
+		methodNode := findNodeByType(tree.RootNode(), "method_declaration")
+		
+		if methodNode == nil {
+			t.Fatal("Failed to find method declaration")
 		}
-	}
-
-	for i := 0; i < int(node.ChildCount()); i++ {
-		child := node.Child(i)
-		if found := findRelevantNode(child, content, types); found != nil {
-			return found
+		
+		result := handler.IsLoggingCall(methodNode, []byte(code))
+		assert.False(t, result, "IsLoggingCall should return false for empty method")
+	})
+	
+	t.Run("IsGetterSetter with empty content", func(t *testing.T) {
+		code := `namespace TestNamespace {
+			class TestClass {
+				public int EmptyProperty { }
+			}
+		}`
+		tree := parser.Parse(nil, []byte(code))
+		propertyNode := findNodeByType(tree.RootNode(), "property_declaration")
+		
+		if propertyNode == nil {
+			t.Fatal("Failed to find property declaration")
 		}
-	}
-	return nil
+		
+		result := handler.IsGetterSetter(propertyNode, []byte(code))
+		assert.False(t, result, "IsGetterSetter should return false for empty property")
+	})
+
+	t.Run("hasAccessor with nil node", func(t *testing.T) {
+		result := hasAccessor(nil, []byte(""))
+		assert.False(t, result, "hasAccessor should return false for nil node")
+	})
 }
+		
\ No newline at end of file
diff --git a/internal/core/finder.go b/internal/core/finder.go
index 4641c19..235d333 100644
--- a/internal/core/finder.go
+++ b/internal/core/finder.go
@@ -106,10 +106,17 @@ func (ff *FileFinder) FindMatchingFiles(basePaths []string) ([]string, error) {
 // and pattern matching for the linked file.
 func (ff *FileFinder) processSymlink(path string, resultChan chan<- Result) error {
 	// Resolve the actual file path that the symlink points to
-	realPath, err := filepath.EvalSymlinks(path)
+	realPath, err := ff.GetRealPath(path)
 	if err != nil {
-		// For broken symlinks, just log and continue rather than returning an error
-		fmt.Fprintf(os.Stderr, "Warning: Could not resolve symlink %q: %v\n", path, err)
+		// For broken symlinks, just check the symlink itself
+		normalizedPath := filepath.ToSlash(path)
+		include, err := ff.shouldIncludeFile(normalizedPath)
+		if err != nil {
+			return err
+		}
+		if include {
+			resultChan <- Result{Path: path}
+		}
 		return nil
 	}
 
@@ -117,23 +124,30 @@ func (ff *FileFinder) processSymlink(path string, resultChan chan<- Result) erro
 	ff.mu.Lock()
 	seenBefore := ff.seenPaths[realPath]
 	ff.seenPaths[realPath] = true
+	ff.seenLinks[path] = true
 	ff.mu.Unlock()
 
-	// Skip if we've seen this path before (prevents cycles)
 	if seenBefore {
+		// If we've seen the target before, still check if we should include the symlink
+		normalizedPath := filepath.ToSlash(path)
+		include, err := ff.shouldIncludeFile(normalizedPath)
+		if err != nil {
+			return err
+		}
+		if include {
+			resultChan <- Result{Path: path}
+		}
 		return nil
 	}
 
 	// Get info about the real file
-	realInfo, err := os.Stat(realPath)
+	info, err := os.Stat(realPath)
 	if err != nil {
-		// Log warning and continue for stat errors
-		fmt.Fprintf(os.Stderr, "Warning: Could not stat resolved symlink %q: %v\n", realPath, err)
 		return nil
 	}
 
-	// For directory symlinks, add the path to be processed
-	if realInfo.IsDir() {
+	// For directory symlinks, walk the directory
+	if info.IsDir() {
 		return filepath.WalkDir(realPath, func(p string, d fs.DirEntry, err error) error {
 			if err != nil {
 				return err
@@ -142,16 +156,16 @@ func (ff *FileFinder) processSymlink(path string, resultChan chan<- Result) erro
 		})
 	}
 
-	// Check if the symlink target matches our patterns
+	// For file symlinks, check the symlink path against patterns
 	normalizedPath := filepath.ToSlash(path)
 	include, err := ff.shouldIncludeFile(normalizedPath)
 	if err != nil {
 		return err
 	}
-
 	if include {
 		resultChan <- Result{Path: path}
 	}
+
 	return nil
 }
 
@@ -160,10 +174,16 @@ func (ff *FileFinder) processSymlink(path string, resultChan chan<- Result) erro
 func (ff *FileFinder) processRegularFile(path string, resultChan chan<- Result) error {
 	normalizedPath := filepath.ToSlash(path)
 
+	// Get real path for deduplication
+	realPath, err := ff.GetRealPath(path)
+	if err != nil {
+		realPath = path // If we can't resolve, use original path
+	}
+
 	// Check if we've seen this file before
 	ff.mu.Lock()
-	seenBefore := ff.seenPaths[path]
-	ff.seenPaths[path] = true
+	seenBefore := ff.seenPaths[realPath]
+	ff.seenPaths[realPath] = true
 	ff.mu.Unlock()
 
 	if seenBefore {
@@ -190,16 +210,26 @@ func (ff *FileFinder) handleEntry(path string, d fs.DirEntry, resultChan chan<-
 		return fmt.Errorf("error getting file info for %q: %w", path, err)
 	}
 
-	// Handle symlinks specially if configured to follow them
+	// Check if it's a symlink
 	if info.Mode()&os.ModeSymlink != 0 {
-		ff.mu.Lock()
-		ff.seenLinks[path] = true
-		ff.mu.Unlock()
-
-		if !ff.followSymlinks {
-			return nil
+		if ff.followSymlinks {
+			// Process symlink
+			err := ff.processSymlink(path, resultChan)
+			if err != nil {
+				return fmt.Errorf("error processing symlink %q: %w", path, err)
+			}
+		} else {
+			// Even if we don't follow symlinks, we should still check if the symlink itself matches
+			normalizedPath := filepath.ToSlash(path)
+			include, err := ff.shouldIncludeFile(normalizedPath)
+			if err != nil {
+				return err
+			}
+			if include {
+				resultChan <- Result{Path: path}
+			}
 		}
-		return ff.processSymlink(path, resultChan)
+		return nil
 	}
 
 	// Skip directories as they're handled by WalkDir
diff --git a/internal/core/finder_test.go b/internal/core/finder_test.go
new file mode 100644
index 0000000..3593b3d
--- /dev/null
+++ b/internal/core/finder_test.go
@@ -0,0 +1,368 @@
+package core
+
+import (
+	"os"
+	"path/filepath"
+	"sort"
+	"testing"
+)
+
+func TestNewFileFinder(t *testing.T) {
+	includes := []string{"*.txt"}
+	excludes := []string{"temp*"}
+	ff := NewFileFinder(includes, excludes, true)
+
+	if ff == nil {
+		t.Fatal("NewFileFinder returned nil")
+	}
+	if len(ff.includes) != 1 || ff.includes[0] != "*.txt" {
+		t.Errorf("Expected includes to be [*.txt], got %v", ff.includes)
+	}
+	if len(ff.excludes) != 1 || ff.excludes[0] != "temp*" {
+		t.Errorf("Expected excludes to be [temp*], got %v", ff.excludes)
+	}
+	if !ff.followSymlinks {
+		t.Error("Expected followSymlinks to be true")
+	}
+}
+
+func setupTestFiles(t *testing.T) (string, func()) {
+	tempDir, err := os.MkdirTemp("", "filefinder_test_*")
+	if err != nil {
+		t.Fatalf("Failed to create temp directory: %v", err)
+	}
+
+	// Create test file structure
+	files := []string{
+		"file1.txt",
+		"file2.log",
+		"temp.txt",
+		"subdir/file3.txt",
+		"subdir/file4.log",
+		"subdir/temp.log",
+	}
+
+	for _, file := range files {
+		path := filepath.Join(tempDir, file)
+		err := os.MkdirAll(filepath.Dir(path), 0755)
+		if err != nil {
+			os.RemoveAll(tempDir)
+			t.Fatalf("Failed to create directory structure: %v", err)
+		}
+		err = os.WriteFile(path, []byte("test content"), 0644)
+		if err != nil {
+			os.RemoveAll(tempDir)
+			t.Fatalf("Failed to create test file: %v", err)
+		}
+	}
+
+	// Create a symlink for testing
+	linkPath := filepath.Join(tempDir, "link1.txt")
+	targetPath := filepath.Join(tempDir, "file1.txt")
+
+	// Remove existing symlink if it exists
+	os.Remove(linkPath)
+
+	err = os.Symlink(targetPath, linkPath)
+	if err != nil {
+		t.Logf("Failed to create symlink: %v", err)
+		// Don't fail the test, but log the error
+	}
+
+	// Verify symlink creation
+	fi, err := os.Lstat(linkPath)
+	if err != nil {
+		t.Logf("Failed to stat symlink: %v", err)
+	} else {
+		t.Logf("Symlink created: %v, is symlink: %v", linkPath, fi.Mode()&os.ModeSymlink != 0)
+	}
+
+	cleanup := func() {
+		os.RemoveAll(tempDir)
+	}
+
+	return tempDir, cleanup
+}
+
+func TestFindMatchingFiles(t *testing.T) {
+	tempDir, cleanup := setupTestFiles(t)
+	defer cleanup()
+
+	// Verify the test directory structure
+	err := filepath.Walk(tempDir, func(path string, info os.FileInfo, err error) error {
+		if err != nil {
+			return err
+		}
+		isSymlink := info.Mode()&os.ModeSymlink != 0
+		t.Logf("Found file: %s (symlink: %v)", path, isSymlink)
+		if isSymlink {
+			target, err := os.Readlink(path)
+			if err != nil {
+				t.Logf("Error reading symlink: %v", err)
+			} else {
+				t.Logf("Symlink target: %s", target)
+			}
+		}
+		return nil
+	})
+	if err != nil {
+		t.Fatalf("Error walking test directory: %v", err)
+	}
+
+	tests := []struct {
+		name          string
+		includes      []string
+		excludes      []string
+		followSymlink bool
+		expectedCount int
+		expectError   bool
+	}{
+		{
+			name:          "Match all txt files",
+			includes:      []string{"**.txt"},
+			excludes:      nil,
+			followSymlink: false,
+			expectedCount: 4, // file1.txt, temp.txt, subdir/file3.txt, link1.txt
+		},
+		{
+			name:          "Match txt files excluding temp",
+			includes:      []string{"**.txt"},
+			excludes:      []string{"**/temp*"},
+			followSymlink: false,
+			expectedCount: 3, // file1.txt, subdir/file3.txt, link1.txt
+		},
+		{
+			name:          "Match with symlinks",
+			includes:      []string{"**.txt"},
+			excludes:      []string{"**/temp*"},
+			followSymlink: true,
+			expectedCount: 3, // file1.txt, subdir/file3.txt, link1.txt
+		},
+		{
+			name:          "Match only log files",
+			includes:      []string{"**.log"},
+			excludes:      nil,
+			followSymlink: false,
+			expectedCount: 3, // file2.log, subdir/file4.log, subdir/temp.log
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ff := NewFileFinder(tt.includes, tt.excludes, tt.followSymlink)
+			matches, err := ff.FindMatchingFiles([]string{tempDir})
+
+			if err != nil {
+				t.Errorf("Unexpected error: %v", err)
+				return
+			}
+
+			// Sort matches for consistent comparison
+			sort.Strings(matches)
+
+			// Print detailed information about matches
+			t.Logf("Found %d matches:", len(matches))
+			for _, match := range matches {
+				info, err := os.Lstat(match)
+				if err != nil {
+					t.Logf("Error getting info for %s: %v", match, err)
+					continue
+				}
+				isSymlink := info.Mode()&os.ModeSymlink != 0
+				t.Logf("- %s (symlink: %v)", match, isSymlink)
+				if isSymlink {
+					target, err := os.Readlink(match)
+					if err != nil {
+						t.Logf("  Error reading symlink: %v", err)
+					} else {
+						t.Logf("  Target: %s", target)
+					}
+				}
+			}
+
+			if len(matches) != tt.expectedCount {
+				t.Errorf("Expected %d matches, got %d: %v",
+					tt.expectedCount, len(matches), matches)
+			}
+		})
+	}
+}
+
+func TestProcessSymlink(t *testing.T) {
+	tempDir, cleanup := setupTestFiles(t)
+	defer cleanup()
+
+	ff := NewFileFinder([]string{"**.txt"}, nil, true)
+	resultChan := make(chan Result)
+
+	go func() {
+		err := ff.processSymlink(filepath.Join(tempDir, "link1.txt"), resultChan)
+		if err != nil {
+			t.Errorf("Unexpected error processing symlink: %v", err)
+		}
+		close(resultChan)
+	}()
+
+	results := []string{}
+	for result := range resultChan {
+		if result.Err != nil {
+			t.Errorf("Unexpected error in result: %v", result.Err)
+			continue
+		}
+		results = append(results, result.Path)
+	}
+
+	if len(results) != 1 {
+		t.Errorf("Expected 1 result, got %d: %v", len(results), results)
+	}
+}
+
+func TestShouldIncludeFile(t *testing.T) {
+	tests := []struct {
+		name     string
+		includes []string
+		excludes []string
+		path     string
+		expected bool
+	}{
+		{
+			name:     "Match include pattern",
+			includes: []string{"*.txt"},
+			excludes: nil,
+			path:     "test.txt",
+			expected: true,
+		},
+		{
+			name:     "Match exclude pattern",
+			includes: []string{"*.txt"},
+			excludes: []string{"temp*"},
+			path:     "temp.txt",
+			expected: false,
+		},
+		{
+			name:     "No include patterns",
+			includes: nil,
+			excludes: []string{"temp*"},
+			path:     "file.log",
+			expected: true,
+		},
+		{
+			name:     "Path with directories",
+			includes: []string{"**/test/*.txt"},
+			excludes: nil,
+			path:     "path/to/test/file.txt",
+			expected: true,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ff := NewFileFinder(tt.includes, tt.excludes, false)
+			result, err := ff.shouldIncludeFile(tt.path)
+			if err != nil {
+				t.Errorf("Unexpected error: %v", err)
+				return
+			}
+			if result != tt.expected {
+				t.Errorf("Expected shouldIncludeFile to return %v for path %s, got %v",
+					tt.expected, tt.path, result)
+			}
+		})
+	}
+}
+
+func TestGetRealPath(t *testing.T) {
+	tempDir, cleanup := setupTestFiles(t)
+	defer cleanup()
+
+	ff := NewFileFinder(nil, nil, true)
+	linkPath := filepath.Join(tempDir, "link1.txt")
+	realPath := filepath.Join(tempDir, "file1.txt")
+
+	got, err := ff.GetRealPath(linkPath)
+	if err != nil {
+		t.Errorf("Unexpected error: %v", err)
+		return
+	}
+
+	// Normalize paths for comparison
+	gotAbs, _ := filepath.Abs(got)
+	realAbs, _ := filepath.Abs(realPath)
+	if gotAbs != realAbs {
+		t.Errorf("Expected real path %s, got %s", realAbs, gotAbs)
+	}
+}
+
+func TestIsSymlink(t *testing.T) {
+	tempDir, cleanup := setupTestFiles(t)
+	defer cleanup()
+
+	ff := NewFileFinder([]string{"**.txt"}, nil, true)
+	linkPath := filepath.Join(tempDir, "link1.txt")
+
+	// First, find all files to populate the seenLinks map
+	_, err := ff.FindMatchingFiles([]string{tempDir})
+	if err != nil {
+		t.Fatalf("Failed to find files: %v", err)
+	}
+
+	isLink, err := ff.IsSymlink(linkPath)
+	if err != nil {
+		t.Errorf("Unexpected error: %v", err)
+		return
+	}
+	if !isLink {
+		t.Errorf("Expected %s to be recognized as symlink", linkPath)
+	}
+
+	nonLinkPath := filepath.Join(tempDir, "file1.txt")
+	isLink, err = ff.IsSymlink(nonLinkPath)
+	if err != nil {
+		t.Errorf("Unexpected error: %v", err)
+		return
+	}
+	if isLink {
+		t.Errorf("Expected %s to not be recognized as symlink", nonLinkPath)
+	}
+}
+
+func TestConcurrentFinding(t *testing.T) {
+	tempDir, cleanup := setupTestFiles(t)
+	defer cleanup()
+
+	// Create multiple base paths for testing concurrency
+	basePaths := []string{
+		filepath.Join(tempDir, "subdir"),
+		tempDir,
+	}
+
+	ff := NewFileFinder([]string{"**.txt"}, []string{"**/temp*"}, true)
+	matches, err := ff.FindMatchingFiles(basePaths)
+	if err != nil {
+		t.Fatalf("Failed to find files concurrently: %v", err)
+	}
+
+	// Sort matches for consistent comparison
+	sort.Strings(matches)
+
+	// Log matches for debugging
+	t.Logf("Found matches: %v", matches)
+
+	// Count unique matches (excluding symlinks pointing to the same file)
+	seen := make(map[string]bool)
+	for _, match := range matches {
+		realPath, err := ff.GetRealPath(match)
+		if err != nil {
+			t.Logf("Warning: Could not resolve path %s: %v", match, err)
+			seen[match] = true
+			continue
+		}
+		seen[realPath] = true
+	}
+
+	expectedCount := 3 // file1.txt, subdir/file3.txt, and link1.txt
+	if len(matches) != expectedCount {
+		t.Errorf("Expected %d matches, got %d: %v", expectedCount, len(matches), matches)
+		t.Logf("Unique paths found: %d", len(seen))
+	}
+}
diff --git a/internal/core/manager_test.go b/internal/core/manager_test.go
new file mode 100644
index 0000000..b8bcd9a
--- /dev/null
+++ b/internal/core/manager_test.go
@@ -0,0 +1,320 @@
+package core
+
+import (
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+func TestNewFileManager(t *testing.T) {
+	fm := NewFileManager(100, 1000, OutputTypeXML)
+	if fm.maxFileSize != 100 {
+		t.Errorf("Expected maxFileSize to be 100, got %d", fm.maxFileSize)
+	}
+	if fm.maxOutputSize != 1000 {
+		t.Errorf("Expected maxOutputSize to be 1000, got %d", fm.maxOutputSize)
+	}
+	if fm.outputType != OutputTypeXML {
+		t.Errorf("Expected outputType to be XML, got %v", fm.outputType)
+	}
+}
+
+func TestValidateFiles(t *testing.T) {
+	// Create temporary test files
+	tempDir := t.TempDir()
+
+	smallFile := filepath.Join(tempDir, "small.txt")
+	if err := os.WriteFile(smallFile, []byte("small"), 0644); err != nil {
+		t.Fatal(err)
+	}
+
+	largeFile := filepath.Join(tempDir, "large.txt")
+	if err := os.WriteFile(largeFile, []byte("large content here"), 0644); err != nil {
+		t.Fatal(err)
+	}
+
+	tests := []struct {
+		name          string
+		files         []string
+		maxFileSize   int64
+		maxOutputSize int64
+		wantLen       int
+		wantErr       bool
+	}{
+		{
+			name:          "valid files within limits",
+			files:         []string{smallFile},
+			maxFileSize:   100,
+			maxOutputSize: 200,
+			wantLen:       1,
+			wantErr:       false,
+		},
+		{
+			name:          "file exceeds max file size",
+			files:         []string{largeFile},
+			maxFileSize:   5,
+			maxOutputSize: 200,
+			wantLen:       0,
+			wantErr:       true,
+		},
+		{
+			name:          "total size exceeds max output size",
+			files:         []string{smallFile, largeFile},
+			maxFileSize:   100,
+			maxOutputSize: 10,
+			wantLen:       0,
+			wantErr:       true,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			fm := NewFileManager(tt.maxFileSize, tt.maxOutputSize, OutputTypeXML)
+			got, err := fm.ValidateFiles(tt.files)
+
+			if (err != nil) != tt.wantErr {
+				t.Errorf("ValidateFiles() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+
+			if !tt.wantErr && len(got) != tt.wantLen {
+				t.Errorf("ValidateFiles() got %v files, want %v", len(got), tt.wantLen)
+			}
+		})
+	}
+}
+
+func TestGroupFilesByOutput(t *testing.T) {
+	tests := []struct {
+		name        string
+		files       []string
+		outputPaths []string
+		wantGroups  int
+		wantErr     bool
+	}{
+		{
+			name:        "single output path",
+			files:       []string{"file1.txt", "file2.txt"},
+			outputPaths: []string{"output.xml"},
+			wantGroups:  1,
+			wantErr:     false,
+		},
+		{
+			name:        "multiple output paths",
+			files:       []string{"dir1/file1.txt", "dir2/file2.txt"},
+			outputPaths: []string{"dir1/out.xml", "dir2/out.xml"},
+			wantGroups:  2,
+			wantErr:     false,
+		},
+		{
+			name:        "unmatched files",
+			files:       []string{"dir1/file1.txt", "other/file2.txt"},
+			outputPaths: []string{"dir1/out.xml", "dir2/out.xml"},
+			wantGroups:  2,
+			wantErr:     false,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			fm := NewFileManager(1000, 10000, OutputTypeXML)
+			groups, err := fm.GroupFilesByOutput(tt.files, tt.outputPaths)
+
+			if (err != nil) != tt.wantErr {
+				t.Errorf("GroupFilesByOutput() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+
+			if !tt.wantErr && len(groups) != tt.wantGroups {
+				t.Errorf("GroupFilesByOutput() got %v groups, want %v", len(groups), tt.wantGroups)
+			}
+		})
+	}
+}
+
+func TestDeriveOutputPaths(t *testing.T) {
+	
+	tests := []struct {
+		name           string
+		inputPaths     []string
+		customOutput   string
+		outputType     OutputType
+		expectedSuffix string
+		wantPathsCount int
+	}{
+		{
+			name:           "current directory",
+			inputPaths:     []string{"."},
+			customOutput:   "",
+			outputType:     OutputTypeXML,
+			expectedSuffix: ".xml",
+			wantPathsCount: 1,
+		},
+		{
+			name:           "custom output path",
+			inputPaths:     []string{"file1.txt"},
+			customOutput:   "custom.json",
+			outputType:     OutputTypeJSON,
+			expectedSuffix: ".json",
+			wantPathsCount: 1,
+		},
+		{
+			name:           "multiple input paths",
+			inputPaths:     []string{"file1.txt", "file2.txt"},
+			customOutput:   "",
+			outputType:     OutputTypeYAML,
+			expectedSuffix: ".yaml",
+			wantPathsCount: 2,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			fm := NewFileManager(1000, 10000, tt.outputType)
+			paths, err := fm.DeriveOutputPaths(tt.inputPaths, tt.customOutput)
+
+			if err != nil {
+				t.Errorf("DeriveOutputPaths() error = %v", err)
+				return
+			}
+
+			if len(paths) != tt.wantPathsCount {
+				t.Errorf("DeriveOutputPaths() got %v paths, want %v", len(paths), tt.wantPathsCount)
+			}
+
+			for _, path := range paths {
+				if !filepath.IsAbs(path) {
+					t.Errorf("Expected absolute path, got %v", path)
+				}
+				if tt.customOutput == "" && !strings.HasSuffix(path, tt.expectedSuffix) {
+					t.Errorf("Expected path to end with %v, got %v", tt.expectedSuffix, path)
+				}
+			}
+		})
+	}
+}
+
+func TestParseSize(t *testing.T) {
+	tests := []struct {
+		name    string
+		size    string
+		want    int64
+		wantErr bool
+	}{
+		{
+			name:    "bytes",
+			size:    "100B",
+			want:    100,
+			wantErr: false,
+		},
+		{
+			name:    "kilobytes",
+			size:    "1KB",
+			want:    1024,
+			wantErr: false,
+		},
+		{
+			name:    "megabytes",
+			size:    "1MB",
+			want:    1024 * 1024,
+			wantErr: false,
+		},
+		{
+			name:    "gigabytes",
+			size:    "1GB",
+			want:    1024 * 1024 * 1024,
+			wantErr: false,
+		},
+		{
+			name:    "terabytes",
+			size:    "1TB",
+			want:    1024 * 1024 * 1024 * 1024,
+			wantErr: false,
+		},
+		{
+			name:    "invalid format",
+			size:    "100",
+			want:    0,
+			wantErr: true,
+		},
+		{
+			name:    "negative size",
+			size:    "-1MB",
+			want:    0,
+			wantErr: true,
+		},
+		{
+			name:    "empty string",
+			size:    "",
+			want:    0,
+			wantErr: true,
+		},
+		{
+			name:    "invalid unit",
+			size:    "100XB",
+			want:    0,
+			wantErr: true,
+		},
+	}
+
+	fm := NewFileManager(1000, 10000, OutputTypeXML)
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := fm.ParseSize(tt.size)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("ParseSize() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if got != tt.want {
+				t.Errorf("ParseSize() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestHelperMethods(t *testing.T) {
+	t.Run("findBestMatchingPath", func(t *testing.T) {
+		fm := NewFileManager(1000, 10000, OutputTypeXML)
+		dirPaths := map[string]string{
+			"dir1/subdir": "dir1/subdir/out.xml",
+			"dir2":        "dir2/out.xml",
+		}
+
+		tests := []struct {
+			filePath  string
+			wantMatch string
+		}{
+			{"dir1/subdir/file.txt", "dir1/subdir"},
+			{"dir2/file.txt", "dir2"},
+			{"dir3/file.txt", ""},
+		}
+
+		for _, tt := range tests {
+			got := fm.findBestMatchingPath(tt.filePath, dirPaths)
+			if got != tt.wantMatch {
+				t.Errorf("findBestMatchingPath(%v) = %v, want %v", tt.filePath, got, tt.wantMatch)
+			}
+		}
+	})
+
+	t.Run("countCommonSegments", func(t *testing.T) {
+		fm := NewFileManager(1000, 10000, OutputTypeXML)
+		tests := []struct {
+			a    []string
+			b    []string
+			want int
+		}{
+			{[]string{"dir1", "subdir"}, []string{"dir1", "subdir"}, 2},
+			{[]string{"dir1", "subdir"}, []string{"dir1", "other"}, 1},
+			{[]string{"dir1"}, []string{"dir2"}, 0},
+		}
+
+		for _, tt := range tests {
+			got := fm.countCommonSegments(tt.a, tt.b)
+			if got != tt.want {
+				t.Errorf("countCommonSegments(%v, %v) = %v, want %v", tt.a, tt.b, got, tt.want)
+			}
+		}
+	})
+}