                filepath = os.path.join(dirpath, filename)
                    
                    # Read file content
                    content = self._read_file_content(filepath)
                    if not content:
                        continue
                        
                    # Parse AST (Abstract Syntax Tree)
                    try:
                        tree = ast.parse(content)
                    except SyntaxError as e:
                        self.logger.error(f"Syntax error in {filepath}: {e}")
                        continue
                        
                    # Analyze the AST for smells
                    self._analyze_ast(tree, filepath)
                    
        except Exception as e:
            self.logger.error(f"An error occurred during analysis: {str(e)}")
            
    def _read_file_content(self, filename: str) -> Optional[str]:
        """
        Reads and returns file content, handles errors.
        
        Args:
            filename: Path to read
        Returns:
            File content or None on failure
        """
        try:
            with open(filename, 'r', encoding='utf-8') as f:
                return f.read()
        except (IOError, UnicodeDecodeError):
            self.logger.error(f"Failed to read {filename}")
            return None
            
    def _analyze_ast(self, tree: ast.Module, filepath: str) -> None:
        """
        Analyzes AST for code smells and populates detection lists.
        
        Args:
            tree: AST to analyze
            filepath: File path for results
        Returns:
            None
        """
        # Track classes and their methods
        current_class = None
        class_methods: Dict[str, int] = {}
        
        for node in ast.walk(tree):
            if isinstance(node, ast.ClassDef):
                # New class detected
                current_class = node.name
                class_methods[current_class] = 0
                
            elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
                # Function definition found
                func_name = node.name
                
                # Skip __init__ and __str__ as they are expected
                if func_name in ('__init__', '__str__', '__repr__'):
                    continue
                    
                # Check if inside a class (god classes)
                if current_class:
                    class_methods[current_class] += 1
                    
                    # Long methods within classes
                    if len(ast.get_source_code(node)) > self.max_method_length:
                        self.long_methods.append({
                            'file': filepath,
                            'class': current_class,
                            'method': func_name,
                            'lines_of_code': len(ast.get_source_code(node)),
                            'smell_type': 'long_method'
                        })
                        
                else:
                  