From 3e9fa75023cc4c918e4547997e6579e01a6e551d Mon Sep 17 00:00:00 2001
From: Moncef STITI <moncef.stiti@etu.u-pec.fr>
Date: Fri, 7 Mar 2025 22:13:57 +0100
Subject: [PATCH] =?UTF-8?q?Am=C3=A9lioration=20de=20la=20javadoc?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 bakefile.jar                                  | Bin 12101 -> 0 bytes
 src/fr/monlouyan/bakefile/BakeCLI.java        |   4 +-
 src/fr/monlouyan/bakefile/BakeEngine.java     |  49 +-
 src/fr/monlouyan/bakefile/BakefileParser.java |  42 +
 .../monlouyan/bakefile/CommandExecutor.java   |  38 +-
 .../bakefile/DependencyResolver.java          |  44 +-
 src/fr/monlouyan/bakefile/Main.java           |   9 +-
 src/fr/monlouyan/bakefile/Rule.java           |  52 +-
 .../monlouyan/bakefile/TimestampManager.java  |  11 +-
 .../bakefile/tests/BakeTestRunner.java        | 884 ------------------
 tests/bakefile.jar                            | Bin 12101 -> 0 bytes
 11 files changed, 234 insertions(+), 899 deletions(-)
 delete mode 100644 bakefile.jar
 delete mode 100644 src/fr/monlouyan/bakefile/tests/BakeTestRunner.java
 delete mode 100644 tests/bakefile.jar

diff --git a/bakefile.jar b/bakefile.jar
deleted file mode 100644
index 875b1b3bdfb568a74d7ba081bfe6268d33fcb5b8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 12101
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
N*1tB+z<>Qe{|`rCu-*Uw

diff --git a/src/fr/monlouyan/bakefile/BakeCLI.java b/src/fr/monlouyan/bakefile/BakeCLI.java
index b909324..3fba9cc 100644
--- a/src/fr/monlouyan/bakefile/BakeCLI.java
+++ b/src/fr/monlouyan/bakefile/BakeCLI.java
@@ -8,7 +8,6 @@ import java.util.ArrayList;
  * 
  * @author Moncef STITI
  * @version 1.0
- * @date 03/02/2025
  * @see Main
  */
 public class BakeCLI {
@@ -26,7 +25,6 @@ public class BakeCLI {
      * Constructeur de la classe BakeCLI
      * 
      * @param args Les arguments passés en ligne de commande
-     * @return void
      * @see Main
      */
     public BakeCLI(String[] args){
@@ -58,7 +56,7 @@ public class BakeCLI {
 
     /**
      * Permet de récupérer les arguments autres que "-d" passés en ligne de commande
-     * @return
+     * @return La liste des arguments
      */
     public static List<String> getTargets(){ return targets; }
 }
diff --git a/src/fr/monlouyan/bakefile/BakeEngine.java b/src/fr/monlouyan/bakefile/BakeEngine.java
index a536064..22b5a7d 100644
--- a/src/fr/monlouyan/bakefile/BakeEngine.java
+++ b/src/fr/monlouyan/bakefile/BakeEngine.java
@@ -4,36 +4,83 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+/**
+ * Moteur principal de l'application Bake.
+ * Cette classe est responsable de l'orchestration du processus de build
+ * en utilisant les règles définies dans le fichier Bakefile.
+ * 
+ * @author Moncef STITI, Yanis HAMOUDI, Louay DARDOURI
+ * @version 1.0
+ */
 public class BakeEngine {
+
+	/** Analyseur syntaxique du fichier Bakefile */
     private BakefileParser parser;
+
+	/** Responsable de la résolution des dépendances entre règles */
     private DependencyResolver resolver;
+
+	/** Exécuteur des commandes définies dans les règles */
     private CommandExecutor executor;
+
+	/** Map qui stocke toutes les règles indexées par leur nom */
     private static Map<String, Rule> ruleMap;
     
+	/**
+     * Constructeur qui initialise le moteur Bake.
+     * Crée un parser pour le fichier "Bakefile" par défaut et initialise le résolveur de dépendances.
+     */
     public BakeEngine() {
         this.parser = new BakefileParser("Bakefile");
         this.resolver = new DependencyResolver(BakeCLI.isDebug());
         ruleMap = new HashMap<>();
     }
 
+	/**
+     * Vérifie si une règle avec le nom spécifié existe.
+     * 
+     * @param target Nom de la règle à vérifier
+     * @return true si la règle existe, false sinon
+     */
     public static boolean hasRule(String target) {
         return ruleMap.containsKey(target);
     }
 
+
+	/**
+     * Récupère une règle par son nom.
+     * 
+     * @param target Nom de la règle à récupérer
+     * @return La règle correspondante ou null si elle n'existe pas
+     */
     public static Rule getRule(String target) {
         return ruleMap.get(target);
     }
     
+	/**
+     * Exécute le processus de build complet.
+     * Cette méthode réalise les étapes suivantes :
+     * <ol>
+     *   <li>Parse le fichier Bakefile</li>
+     *   <li>Construit la carte des règles</li>
+     *   <li>Résout les dépendances entre les règles</li>
+     *   <li>Exécute les règles dans l'ordre déterminé</li>
+     * </ol>
+     */
     public void run() {
+		// Analyse le fichier Bakefile pour extraire les règles
         List<Rule> rules = parser.parse();
 
+		// Ajoute toutes les règles à la map pour référence rapide
         for (Rule rule : rules) {
             ruleMap.put(rule.getName(), rule);
         }
 
+		// Résout les dépendances pour déterminer l'ordre d'exécution
         List<Rule> rulesToBuild = resolver.resolve(rules, BakeCLI.getTargets());
         this.executor = new CommandExecutor(BakeCLI.isDebug(), resolver.isCircular());
-        
+		
+		// Exécute les règles dans l'ordre déterminé
         for (Rule rule : rulesToBuild) {
             executor.execute(rule);
         }
diff --git a/src/fr/monlouyan/bakefile/BakefileParser.java b/src/fr/monlouyan/bakefile/BakefileParser.java
index 711312a..6f6b039 100644
--- a/src/fr/monlouyan/bakefile/BakefileParser.java
+++ b/src/fr/monlouyan/bakefile/BakefileParser.java
@@ -8,6 +8,14 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
+/**
+ * Parseur de fichier Bakefile.
+ * Cette classe est responsable de l'analyse syntaxique du fichier Bakefile
+ * pour extraire les règles de build, les dépendances et les commandes associées.
+ * 
+ * @author Moncef STITI, Yanis HAMOUDI, Louay DARDOURI
+ * @version 1.0
+ */
 public class BakefileParser {
 	
 	/**
@@ -62,11 +70,21 @@ public class BakefileParser {
      */
     private Map<String, String> variables = new HashMap<>();
     
+	/**
+	 * Constructeur de la classe BakefileParser.
+	 * @param filename Nom du fichier Bakefile à parser
+	 */
     public BakefileParser(String filename) {
         this.filename = filename;
         firstTarget = null;
     }
 
+	/**
+	 * Gérer les lignes de continuation.
+	 * @param lines Liste des lignes du fichier Bakefile
+	 * @param startIndex Index de la première ligne de continuation
+	 * @return La ligne combinée
+	 */
     private String handleContinuationLines(List<String> lines, int startIndex) {
         StringBuilder combinedLine = new StringBuilder();
         int i = startIndex;
@@ -89,6 +107,11 @@ public class BakefileParser {
         return combinedLine.toString();
     }
 
+	/**
+	 * Remplacer les variables dans une chaîne.
+	 * @param input Chaîne à traiter
+	 * @return Chaîne avec les variables remplacées
+	 */
     private String replaceVariables(String input) {
         if (input == null) return null;
         
@@ -126,12 +149,22 @@ public class BakefileParser {
         return result.trim();
     }
 
+	/**
+	 * Remplacer les variables dans une liste de chaînes.
+	 * @param items Liste de chaînes à traiter
+	 * @return Liste de chaînes avec les variables remplacées
+	 */
     private List<String> replaceVariablesInList(List<String> items) {
         return items.stream()
                    .map(this::replaceVariables)
                    .collect(Collectors.toList());
     }
 
+	/**
+	 * Découper les dépendances en une liste de chaînes.
+	 * @param depStr Chaîne de dépendances
+	 * @return Liste de dépendances
+	 */
     private List<String> splitDependencies(String depStr) {
         if (depStr == null || depStr.trim().isEmpty()) {
             return new ArrayList<>();
@@ -144,6 +177,11 @@ public class BakefileParser {
                     .collect(Collectors.toList());
     }
 
+	/**
+	 * Découper les cibles en une liste de chaînes.
+	 * @param targetStr Chaîne de cibles
+	 * @return Liste de cibles
+	 */
     private List<String> splitTargets(String targetStr) {
         if (targetStr == null || targetStr.trim().isEmpty()) {
             return new ArrayList<>();
@@ -156,6 +194,10 @@ public class BakefileParser {
                     .collect(Collectors.toList());
     }
 
+	/**
+	 * Analyser le fichier Bakefile pour extraire les règles de build.
+	 * @return Liste des règles extraites
+	 */
     public List<Rule> parse() {
         List<Rule> rules = new ArrayList<>();
         Set<String> phonyTargets = new HashSet<>();
diff --git a/src/fr/monlouyan/bakefile/CommandExecutor.java b/src/fr/monlouyan/bakefile/CommandExecutor.java
index 4d1287e..5aeaa02 100644
--- a/src/fr/monlouyan/bakefile/CommandExecutor.java
+++ b/src/fr/monlouyan/bakefile/CommandExecutor.java
@@ -3,17 +3,49 @@ package fr.monlouyan.bakefile;
 import java.io.File;
 import java.io.IOException;
 
+/**
+ * Exécuteur des commandes définies dans les règles.
+ * Cette classe est responsable de l'exécution des commandes définies dans les règles
+ * du fichier Bakefile.
+ * 
+ * @author Moncef STITI, Yanis HAMOUDI, Louay DARDOURI
+ * @version 1.0
+ */
 public class CommandExecutor {
+	/**
+	 * true si le mode debug est activé, false sinon
+	 */
     private boolean debug;
-    private boolean needsUpdate = false;  // Pour tracker si quelque chose doit être mis à jour
-    private boolean isCircular = false;  // Pour tracker si un cycle a été détecté
-    private boolean futureTimestampDetected = false; // Pour détecter les timestamps dans le futur
 
+	/**
+	 * Pour tracker si quelque chose doit être mis à jour
+	 */
+    private boolean needsUpdate = false;
+
+	/**
+	 * Pour tracker si un cycle a été détecté
+	 */
+    private boolean isCircular = false;
+	
+	/**
+	 * Pour détecter les timestamps dans le futur
+	 */
+    private boolean futureTimestampDetected = false;
+
+	/**
+	 * Constructeur de la classe CommandExecutor.
+	 * @param debug true si le mode debug est activé, false sinon
+	 * @param isCircular true si on est en mode circulaire, false sinon
+	 */
     public CommandExecutor(boolean debug, boolean isCircular) {
         this.debug = debug;
         this.isCircular = isCircular;
     }
     
+	/**
+	 * Exécute les commandes d'une règle.
+	 * @param rule La règle à exécuter
+	 */
     public void execute(Rule rule) {
         // On vérifie d'abord si cette règle a besoin d'être mise à jour
         boolean ruleNeedsUpdate = rule.needsUpdate();
diff --git a/src/fr/monlouyan/bakefile/DependencyResolver.java b/src/fr/monlouyan/bakefile/DependencyResolver.java
index 26c5378..b2574b4 100644
--- a/src/fr/monlouyan/bakefile/DependencyResolver.java
+++ b/src/fr/monlouyan/bakefile/DependencyResolver.java
@@ -2,16 +2,40 @@ package fr.monlouyan.bakefile;
 
 import java.util.*;
 
+/**
+ * Résolveur de dépendances entre les règles du fichier Bakefile.
+ * Cette classe est responsable de la résolution des dépendances entre les règles
+ * pour déterminer l'ordre dans lequel les règles doivent être
+ * 
+ * @author Moncef STITI, Yanis HAMOUDI, Louay DARDOURI
+ * @version 1.0
+ */
 public class DependencyResolver {
+
+	/*** true si le mode debug est activé, false sinon */
     private boolean debug;
+
+	/*** Map des règles indexées par leur nom */
     private Map<String, Rule> ruleMap;
+
+	/*** true si une dépendance circulaire est détectée, false sinon */
     private boolean isCircular;
-    
+	
+	/**
+	 * Constructeur de la classe DependencyResolver.
+	 * @param debug true si le mode debug est activé, false sinon
+	 */
     public DependencyResolver(boolean debug) {
         this.debug = debug;
         this.isCircular = false;
     }
 
+	/**
+	 * Résout les dépendances entre les règles.
+	 * @param allRules Liste de toutes les règles
+	 * @param requestedRules Liste des règles demandées
+	 * @return Liste 
+	 */
     public List<Rule> resolve(List<Rule> allRules, List<String> requestedRules) {
         List<Rule> rulesToBuild = new ArrayList<>();
         ruleMap = new HashMap<>();
@@ -64,6 +88,12 @@ public class DependencyResolver {
         return rulesToBuild;
     }
 
+	/**
+	 * Méthode de tri topologique pour résoudre les dépendances.
+	 * @param ruleName Nom de la règle
+	 * @param processed Set des règles déjà traitées
+	 * @param buildOrder Liste des règles dans l'ordre
+	 */
     private void topologicalSort(String ruleName, Set<String> processed, List<String> buildOrder) {
         if (!ruleMap.containsKey(ruleName) || processed.contains(ruleName)) {
             return;
@@ -85,7 +115,13 @@ public class DependencyResolver {
         buildOrder.add(ruleName);
     }
 
-    // La méthode detectCycle avec une modification pour les chemins home
+    /**
+	 * Méthode de détection des cycles dans les dépendances.
+	 * @param ruleName Nom de la règle
+	 * @param visited Set des règles déjà visitées
+	 * @param stack Set des règles en cours de traitement
+	 * @param parent Nom de la règle parente
+	 */
     private void detectCycle(String ruleName, Set<String> visited, Set<String> stack, String parent) {
         if (stack.contains(ruleName)) {
             if (parent != null) { 
@@ -121,6 +157,10 @@ public class DependencyResolver {
         }
     }
 
+	/**
+	 * Vérifie si une dépendance circulaire a été détectée.
+	 * @return true si une dépendance circulaire a été détectée, false sinon
+	 */
     public boolean isCircular() {
         return isCircular;
     }
diff --git a/src/fr/monlouyan/bakefile/Main.java b/src/fr/monlouyan/bakefile/Main.java
index 3f455f1..ee4e909 100755
--- a/src/fr/monlouyan/bakefile/Main.java
+++ b/src/fr/monlouyan/bakefile/Main.java
@@ -5,15 +5,20 @@ package fr.monlouyan.bakefile;
  * 
  * @version 1.0
  * @author Moncef STITI
- * @date 03/02/2025
  */
 public class Main{
 
+	/**
+	 * Constructeur de la classe Main (privé pour empêcher l'instanciation)
+	 */
+	private Main() {
+		// Constructeur inutile
+	}
+
     /**
      * Méthode principale du programme
      * 
      * @param args Les arguments passés en ligne de commande
-     * @return void
      */
     public static void main(String[] args){
         @SuppressWarnings("unused")
diff --git a/src/fr/monlouyan/bakefile/Rule.java b/src/fr/monlouyan/bakefile/Rule.java
index 2a1d074..f2f3648 100644
--- a/src/fr/monlouyan/bakefile/Rule.java
+++ b/src/fr/monlouyan/bakefile/Rule.java
@@ -2,14 +2,36 @@ package fr.monlouyan.bakefile;
 
 import java.io.File;
 import java.util.List;
-import java.util.Date;
 
+/**
+ * Représente une règle du fichier Bakefile.
+ * Chaque règle est composée d'un nom, d'une liste de dépendances et d'une liste de commandes.
+ * Une règle peut être phony, c'est-à-dire qu'elle n'a pas de fichier cible associé.
+ * 
+ * @author Moncef STITI, Yanis HAMOUDI, Louay DARDOURI
+ * @version 1.0
+ */
 public class Rule {
+
+	/*** Nom de la règle */
     private String name;
+
+	/*** Liste des dépendances de la règle */
     private List<String> dependencies;
+	
+	/*** Liste des commandes */
     private List<String> commands;
+
+	/*** true si la règle est phony, false sinon */
     private boolean isPhony;
 
+	/**
+	 * Constructeur de la classe Rule.
+	 * @param name Nom de la règle
+	 * @param dependencies Liste des dépendances
+	 * @param commands Liste des commandes
+	 * @param isPhony true si la règle est phony, false sinon
+	 */
     public Rule(String name, List<String> dependencies, List<String> commands, boolean isPhony) {
         this.name = name;
         this.dependencies = dependencies;
@@ -17,12 +39,40 @@ public class Rule {
         this.isPhony = isPhony;
     }
 
+	/**
+	 * Récupère le nom de la règle.
+	 * @return Le nom de la règle
+	 */
     public String getName() { return name; }
+
+	/**
+	 * Récupère la liste des dépendances de la règle.
+	 * @return La liste des dépendances
+	 */
     public List<String> getDependencies() { return dependencies; }
+
+	/**
+	 * Récupère la liste des commandes de la règle.
+	 * @return La liste des commandes
+	 */
     public List<String> getCommands() { return commands; }
+
+	/**
+	 * Vérifie si la règle est phony.
+	 * @return true si la règle est phony, false sinon.
+	 */
     public boolean isPhony() { return isPhony; }
+
+	/**
+	 * Vérifie si la règle est vide (sans dépendances ni commandes).
+	 * @return true si la règle est vide, false sinon
+	 */
     public boolean isEmpty() { return dependencies.isEmpty() && commands.isEmpty(); }
 
+	/**
+	 * Vérifie si la règle doit être mise à jour.
+	 * @return true si la règle doit être mise à jour, false sinon
+	 */
     public boolean needsUpdate() {
         if (BakeCLI.isDebug()){
             System.out.println("Debug : Checking if rule " + name + " needs update");
diff --git a/src/fr/monlouyan/bakefile/TimestampManager.java b/src/fr/monlouyan/bakefile/TimestampManager.java
index 6ffac34..76f8cfc 100644
--- a/src/fr/monlouyan/bakefile/TimestampManager.java
+++ b/src/fr/monlouyan/bakefile/TimestampManager.java
@@ -6,18 +6,23 @@ import java.util.Date;
 
 /**
  * Classe utilitaire pour la gestion des timestamps des fichiers.
- * Dernière modification : 04/02/2025
  * 
  * @author Moncef STITI, Yanis HAMOUDI
  * @version 1.0
- * @date 04/02/2025
  */
 public class TimestampManager {
 
+	/**
+	 * Constructeur de TimestampManager.
+	 */
+	public TimestampManager() {
+		// Constructeur inutile
+	}
+
     /**
      * Récupère le timestamp d'un fichier.
-     * @param filePath Le chemin du fichier.
      * @return Le timestamp du fichier, ou 0 si le fichier n'existe pas.
+	 * @param file Le fichier
      */
     public static long getTimestamp(File file) {
         if (file.exists()) {
diff --git a/src/fr/monlouyan/bakefile/tests/BakeTestRunner.java b/src/fr/monlouyan/bakefile/tests/BakeTestRunner.java
deleted file mode 100644
index 2f2cfae..0000000
--- a/src/fr/monlouyan/bakefile/tests/BakeTestRunner.java
+++ /dev/null
@@ -1,884 +0,0 @@
-package fr.monlouyan.bakefile.tests;
-
-import javax.swing.*;
-import javax.swing.border.EmptyBorder;
-import javax.swing.table.DefaultTableModel;
-import javax.swing.text.DefaultCaret;
-import java.awt.*;
-import java.io.*;
-import java.nio.file.*;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-public class BakeTestRunner extends JFrame {
-    private JPanel mainPanel;
-    private JTable testTable;
-    private DefaultTableModel tableModel;
-    private JTextArea logArea;
-    private JButton runSelectedButton;
-    private JButton runAllButton;
-    private JComboBox<String> languageComboBox;
-    private JProgressBar progressBar;
-    private JButton openLogsButton;
-    private JButton compareSelectedButton;
-    
-    private final ExecutorService executor = Executors.newSingleThreadExecutor();
-    private final String baseDir = System.getProperty("user.dir");
-    private final String logsDir = baseDir + File.separator + "logs";
-    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-    
-    private final Color PASSED_COLOR = new Color(220, 255, 220);
-    private final Color FAILED_COLOR = new Color(255, 220, 220);
-    private final Color RUNNING_COLOR = new Color(220, 220, 255);
-    
-    enum TestStatus {
-        NOT_RUN, RUNNING, PASSED, FAILED
-    }
-    
-    public BakeTestRunner() {
-        setTitle("Bake Test Runner");
-        setSize(1000, 700);
-        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-        setLocationRelativeTo(null);
-        
-        setupUI();
-        loadTests();
-        createLogsDirectory();
-    }
-    
-	private void setupUI() {
-		mainPanel = new JPanel(new BorderLayout(10, 10));
-		mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
-		
-		// Panel du haut avec contrôles modernisés
-		JPanel controlPanel = new JPanel();
-		controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS));
-		
-		// Première ligne de contrôles
-		JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
-		runSelectedButton = new JButton("Run Selected Tests");
-		runAllButton = new JButton("Run All Tests");
-		compareSelectedButton = new JButton("Compare Selected Test");
-		
-		// Styliser les boutons
-		runSelectedButton.setBackground(new Color(255, 255, 255)); // Steel Blue
-		runSelectedButton.setForeground(Color.BLACK);
-		runSelectedButton.setFont(new Font("Dialog", Font.BOLD, 12));
-		
-		runAllButton.setBackground(new Color(255, 255, 255)); // Medium Sea Green
-		runAllButton.setForeground(Color.BLACK);
-		runAllButton.setFont(new Font("Dialog", Font.BOLD, 12));
-		
-		compareSelectedButton.setBackground(new Color(255, 255, 255)); // Dodger Blue
-		compareSelectedButton.setForeground(Color.BLACK);
-		compareSelectedButton.setFont(new Font("Dialog", Font.BOLD, 12));
-		
-		buttonPanel.add(runSelectedButton);
-		buttonPanel.add(runAllButton);
-		buttonPanel.add(compareSelectedButton);
-		
-		// Deuxième ligne de contrôles
-		JPanel filterPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
-		filterPanel.add(new JLabel("Language:"));
-		languageComboBox = new JComboBox<>(new String[]{"All", "C", "Java"});
-		languageComboBox.setPreferredSize(new Dimension(100, 25));
-		
-		openLogsButton = new JButton("Open Logs Directory");
-		openLogsButton.setBackground(new Color(211, 211, 211)); // Light Gray
-		openLogsButton.setFont(new Font("Dialog", Font.PLAIN, 12));
-		
-		filterPanel.add(languageComboBox);
-		filterPanel.add(Box.createHorizontalStrut(10));
-		filterPanel.add(openLogsButton);
-		
-		controlPanel.add(buttonPanel);
-		controlPanel.add(Box.createVerticalStrut(5));
-		controlPanel.add(filterPanel);
-		
-		// Tableau stylisé pour la liste des tests
-		String[] columnNames = {"#", "Language", "Test Name", "Status", "Last Run"};
-		tableModel = new DefaultTableModel(columnNames, 0) {
-			@Override
-			public boolean isCellEditable(int row, int column) {
-				return false;
-			}
-			
-			@Override
-			public Class<?> getColumnClass(int column) {
-				if (column == 0) return Integer.class;
-				return String.class;
-			}
-		};
-		
-		testTable = new JTable(tableModel) {
-			@Override
-			public Component prepareRenderer(javax.swing.table.TableCellRenderer renderer, int row, int column) {
-				Component comp = super.prepareRenderer(renderer, row, column);
-				
-				// Alterner les couleurs des lignes
-				if (!comp.getBackground().equals(getSelectionBackground())) {
-					String status = (String) getValueAt(row, 3);
-					if ("PASSED".equals(status)) {
-						comp.setBackground(PASSED_COLOR);
-					} else if ("FAILED".equals(status)) {
-						comp.setBackground(FAILED_COLOR);
-					} else if ("RUNNING".equals(status)) {
-						comp.setBackground(RUNNING_COLOR);
-					} else {
-						comp.setBackground(row % 2 == 0 ? new Color(240, 240, 250) : Color.WHITE);
-					}
-				}
-				return comp;
-			}
-		};
-		
-		testTable.getColumnModel().getColumn(0).setPreferredWidth(30);
-		testTable.getColumnModel().getColumn(0).setMaxWidth(50);
-		testTable.getColumnModel().getColumn(1).setPreferredWidth(70);
-		testTable.getColumnModel().getColumn(1).setMaxWidth(100);
-		testTable.getColumnModel().getColumn(2).setPreferredWidth(300);
-		testTable.getColumnModel().getColumn(3).setPreferredWidth(80);
-		testTable.getColumnModel().getColumn(3).setMaxWidth(120);
-		testTable.getColumnModel().getColumn(4).setPreferredWidth(150);
-		
-		testTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
-		testTable.setRowHeight(28);
-		testTable.setShowGrid(false);
-		testTable.setIntercellSpacing(new Dimension(0, 0));
-		testTable.getTableHeader().setFont(new Font("Dialog", Font.BOLD, 12));
-		testTable.getTableHeader().setOpaque(false);
-		testTable.getTableHeader().setBackground(new Color(240, 240, 240));
-		testTable.setFont(new Font("Dialog", Font.PLAIN, 12));
-		
-		// Zone de logs améliorée
-		logArea = new JTextArea();
-		logArea.setEditable(false);
-		logArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
-		logArea.setBackground(new Color(250, 250, 250));
-		logArea.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
-		DefaultCaret caret = (DefaultCaret) logArea.getCaret();
-		caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
-		
-		JPanel logPanel = new JPanel(new BorderLayout());
-		logPanel.add(new JLabel(" Test Output:"), BorderLayout.NORTH);
-		logPanel.add(new JScrollPane(logArea), BorderLayout.CENTER);
-		
-		// Barre de progression stylisée
-		progressBar = new JProgressBar(0, 100);
-		progressBar.setStringPainted(true);
-		progressBar.setString("Ready");
-		progressBar.setFont(new Font("Dialog", Font.BOLD, 11));
-		progressBar.setForeground(new Color(46, 139, 87)); // Sea Green
-		
-		// Layout
-		JSplitPane splitPane = new JSplitPane(
-			JSplitPane.VERTICAL_SPLIT,
-			new JScrollPane(testTable),
-			logPanel
-		);
-		splitPane.setDividerLocation(300);
-		splitPane.setContinuousLayout(true);
-		splitPane.setDividerSize(5);
-		
-		mainPanel.add(controlPanel, BorderLayout.NORTH);
-		mainPanel.add(splitPane, BorderLayout.CENTER);
-		
-		JPanel statusPanel = new JPanel(new BorderLayout());
-		statusPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
-		statusPanel.add(progressBar, BorderLayout.CENTER);
-		mainPanel.add(statusPanel, BorderLayout.SOUTH);
-		
-		setContentPane(mainPanel);
-		
-		// Add action listeners
-		runSelectedButton.addActionListener(e -> runSelectedTests());
-		runAllButton.addActionListener(e -> runAllTests());
-		compareSelectedButton.addActionListener(e -> compareSelectedTest());
-		openLogsButton.addActionListener(e -> openLogsDirectory());
-		languageComboBox.addActionListener(e -> filterTestsByLanguage());
-	}
-
-    private void createLogsDirectory() {
-        try {
-            Files.createDirectories(Paths.get(logsDir));
-        } catch (IOException e) {
-            logMessage("Error creating logs directory: " + e.getMessage());
-        }
-    }
-    
-    private void openLogsDirectory() {
-        try {
-            Desktop.getDesktop().open(new File(logsDir));
-        } catch (IOException e) {
-            logMessage("Error opening logs directory: " + e.getMessage());
-            JOptionPane.showMessageDialog(this, 
-                "Could not open logs directory: " + e.getMessage(), 
-                "Error", JOptionPane.ERROR_MESSAGE);
-        }
-    }
-    
-    private void compareSelectedTest() {
-        int selectedRow = testTable.getSelectedRow();
-        if (selectedRow == -1) {
-            JOptionPane.showMessageDialog(this, 
-                "Please select a test to compare", 
-                "No Test Selected", JOptionPane.WARNING_MESSAGE);
-            return;
-        }
-        
-        String language = (String) tableModel.getValueAt(selectedRow, 1);
-        String testName = (String) tableModel.getValueAt(selectedRow, 2);
-        
-        String logFilePath = logsDir + File.separator + language + "_" + testName + ".log";
-        File logFile = new File(logFilePath);
-        
-        if (!logFile.exists()) {
-            JOptionPane.showMessageDialog(this, 
-                "No log file found for this test. Please run the test first.", 
-                "Log Not Found", JOptionPane.WARNING_MESSAGE);
-            return;
-        }
-        
-        showComparisonDialog(logFile, language, testName);
-    }
-    
-	private void showComparisonDialog(File logFile, String language, String testName) {
-		JDialog dialog = new JDialog(this, "Comparison: " + language + " - " + testName, true);
-		dialog.setLayout(new BorderLayout(10, 10));
-		dialog.setSize(1000, 600);
-		dialog.setLocationRelativeTo(this);
-		
-		try {
-			List<String> lines = Files.readAllLines(logFile.toPath());
-			String content = String.join("\n", lines);
-			
-			// Split content to make and bake sections if possible
-			String makeOutput = "";
-			String bakeOutput = "";
-			String comparisonResults = "";
-			
-			// Better parsing - enhanced for clearer splitting
-			int makeIndex = content.indexOf("=== Make Output ===");
-			int bakeIndex = content.indexOf("=== Bake Output ===");
-			int comparisonIndex = content.indexOf("=== Comparison Results ===");
-			
-			if (makeIndex != -1 && bakeIndex != -1) {
-				makeOutput = content.substring(makeIndex, bakeIndex).trim();
-				if (comparisonIndex != -1) {
-					bakeOutput = content.substring(bakeIndex, comparisonIndex).trim();
-					comparisonResults = content.substring(comparisonIndex).trim();
-				} else {
-					bakeOutput = content.substring(bakeIndex).trim();
-				}
-			}
-			
-			JTextPane makeArea = createStyledTextPane(makeOutput);
-			JTextPane bakeArea = createStyledTextPane(bakeOutput);
-			JTextPane comparisonArea = createStyledTextPane(
-				comparisonIndex != -1 ? comparisonResults : "No comparison results available."
-			);
-			
-			JTabbedPane tabbedPane = new JTabbedPane();
-			tabbedPane.addTab("Make Output", new JScrollPane(makeArea));
-			tabbedPane.addTab("Bake Output", new JScrollPane(bakeArea));
-			tabbedPane.addTab("Comparison", new JScrollPane(comparisonArea));
-			tabbedPane.setFont(new Font("Dialog", Font.PLAIN, 12));
-			
-			// Détection et mise en évidence des différences
-			highlightDifferences(makeArea, bakeArea);
-			
-			dialog.add(tabbedPane, BorderLayout.CENTER);
-			
-			JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
-			JButton closeButton = new JButton("Close");
-			closeButton.setFont(new Font("Dialog", Font.BOLD, 12));
-			closeButton.addActionListener(e -> dialog.dispose());
-			buttonPanel.add(closeButton);
-			
-			dialog.add(buttonPanel, BorderLayout.SOUTH);
-			dialog.setVisible(true);
-			
-		} catch (IOException e) {
-			JOptionPane.showMessageDialog(dialog, 
-				"Error reading log file: " + e.getMessage(), 
-				"Error", JOptionPane.ERROR_MESSAGE);
-		}
-	}
-	
-	// Méthode pour créer un JTextPane stylisé
-	private JTextPane createStyledTextPane(String content) {
-		JTextPane textPane = new JTextPane();
-		textPane.setEditable(false);
-		textPane.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
-		textPane.setText(content);
-		textPane.setMargin(new Insets(10, 10, 10, 10));
-		textPane.setBackground(new Color(252, 252, 252));
-		
-		// Appliquer une coloration syntaxique basique
-		highlightKeywords(textPane);
-		
-		return textPane;
-	}
-
-// Méthode pour mettre en évidence les mots clés
-private void highlightKeywords(JTextPane textPane) {
-    // Obtenez le document et le kit de style
-    javax.swing.text.StyledDocument doc = textPane.getStyledDocument();
-    javax.swing.text.Style defaultStyle = javax.swing.text.StyleContext.getDefaultStyleContext()
-            .getStyle(javax.swing.text.StyleContext.DEFAULT_STYLE);
-    
-    // Créez différents styles pour différents types de texte
-    javax.swing.text.Style errorStyle = doc.addStyle("errorStyle", defaultStyle);
-    javax.swing.text.StyleConstants.setForeground(errorStyle, new Color(220, 0, 0));
-    javax.swing.text.StyleConstants.setBold(errorStyle, true);
-    
-    javax.swing.text.Style successStyle = doc.addStyle("successStyle", defaultStyle);
-    javax.swing.text.StyleConstants.setForeground(successStyle, new Color(0, 128, 0));
-    javax.swing.text.StyleConstants.setBold(successStyle, true);
-    
-    // Appliquez les styles aux mots-clés
-    String text = textPane.getText();
-    applyStyle(doc, text, "Error", errorStyle);
-    applyStyle(doc, text, "error", errorStyle);
-    applyStyle(doc, text, "ERROR", errorStyle);
-    applyStyle(doc, text, "failed", errorStyle);
-    applyStyle(doc, text, "FAILED", errorStyle);
-    
-    applyStyle(doc, text, "PASSED", successStyle);
-    applyStyle(doc, text, "passed", successStyle);
-    applyStyle(doc, text, "successful", successStyle);
-}
-
-// Méthode auxiliaire pour appliquer un style à un mot-clé spécifique
-private void applyStyle(javax.swing.text.StyledDocument doc, String text, String pattern, javax.swing.text.Style style) {
-    int pos = 0;
-    while ((pos = text.indexOf(pattern, pos)) >= 0) {
-        doc.setCharacterAttributes(pos, pattern.length(), style, true);
-        pos += pattern.length();
-    }
-}
-
-// Méthode pour mettre en évidence les différences entre les sorties make et bake
-private void highlightDifferences(JTextPane makeArea, JTextPane bakeArea) {
-    // Cette méthode devrait idéalement comparer les lignes et mettre en évidence les différences
-    // Pour une première implémentation simple, nous allons juste colorer les lignes contenant des erreurs
-    
-    highlightKeywords(makeArea);
-    highlightKeywords(bakeArea);
-}
-    
-    private void loadTests() {
-        tableModel.setRowCount(0);
-        
-        // Load C tests
-        loadTestsForLanguage("C");
-        
-        // Load Java tests
-        loadTestsForLanguage("Java");
-    }
-    
-    private void loadTestsForLanguage(String language) {
-        File languageDir = new File(baseDir + File.separator + "tests" + File.separator + language);
-        if (!languageDir.exists() || !languageDir.isDirectory()) {
-            logMessage("Warning: Directory not found: " + languageDir.getPath());
-            return;
-        }
-        
-        File[] testDirs = languageDir.listFiles(File::isDirectory);
-        if (testDirs == null) {
-            logMessage("Warning: No test directories found in " + languageDir.getPath());
-            return;
-        }
-        
-        Arrays.sort(testDirs, (a, b) -> {
-            // Extract test number for sorting
-            Pattern pattern = Pattern.compile("test-(\\d+)");
-            Matcher matcherA = pattern.matcher(a.getName());
-            Matcher matcherB = pattern.matcher(b.getName());
-            
-            if (matcherA.find() && matcherB.find()) {
-                try {
-                    int numA = Integer.parseInt(matcherA.group(1));
-                    int numB = Integer.parseInt(matcherB.group(1));
-                    return Integer.compare(numA, numB);
-                } catch (NumberFormatException e) {
-                    return a.getName().compareTo(b.getName());
-                }
-            }
-            return a.getName().compareTo(b.getName());
-        });
-        
-        for (File testDir : testDirs) {
-            String testName = testDir.getName();
-            if (testName.startsWith("test-")) {
-                Object[] row = {tableModel.getRowCount() + 1, language, testName, "Not Run", ""};
-                tableModel.addRow(row);
-            }
-        }
-    }
-    
-    private void filterTestsByLanguage() {
-        String selectedLanguage = (String) languageComboBox.getSelectedItem();
-        if (selectedLanguage == null || selectedLanguage.equals("All")) {
-            loadTests();
-            return;
-        }
-        
-        tableModel.setRowCount(0);
-        loadTestsForLanguage(selectedLanguage);
-    }
-    
-    private void runSelectedTests() {
-        int[] selectedRows = testTable.getSelectedRows();
-        if (selectedRows.length == 0) {
-            JOptionPane.showMessageDialog(this, 
-                "Please select at least one test to run", 
-                "No Test Selected", JOptionPane.WARNING_MESSAGE);
-            return;
-        }
-        
-        List<TestInfo> testsToRun = new ArrayList<>();
-        for (int row : selectedRows) {
-            String language = (String) tableModel.getValueAt(row, 1);
-            String testName = (String) tableModel.getValueAt(row, 2);
-            testsToRun.add(new TestInfo(row, language, testName));
-        }
-        
-        disableButtons();
-        runTests(testsToRun);
-    }
-    
-    private void runAllTests() {
-        List<TestInfo> testsToRun = new ArrayList<>();
-        for (int row = 0; row < tableModel.getRowCount(); row++) {
-            String language = (String) tableModel.getValueAt(row, 1);
-            String testName = (String) tableModel.getValueAt(row, 2);
-            testsToRun.add(new TestInfo(row, language, testName));
-        }
-        
-        disableButtons();
-        runTests(testsToRun);
-    }
-    
-    private void disableButtons() {
-        runSelectedButton.setEnabled(false);
-        runAllButton.setEnabled(false);
-        compareSelectedButton.setEnabled(false);
-        languageComboBox.setEnabled(false);
-    }
-    
-    private void enableButtons() {
-        runSelectedButton.setEnabled(true);
-        runAllButton.setEnabled(true);
-        compareSelectedButton.setEnabled(true);
-        languageComboBox.setEnabled(true);
-    }
-    
-    private void runTests(List<TestInfo> testsToRun) {
-        progressBar.setValue(0);
-        progressBar.setString("Running tests (0/" + testsToRun.size() + ")");
-        logArea.setText("");
-        
-        executor.submit(() -> {
-            try {
-                int total = testsToRun.size();
-                int current = 0;
-                
-                for (int i = 0; i < testsToRun.size(); i++) {
-                    TestInfo test = testsToRun.get(i);
-                    final int currentTest = i + 1;
-                    
-                    // Update UI to show we're running this test
-                    SwingUtilities.invokeLater(() -> {
-                        tableModel.setValueAt(TestStatus.RUNNING.name(), test.row, 3);
-                        testTable.setValueAt(TestStatus.RUNNING.name(), test.row, 3);
-                        testTable.setValueAt(dateFormat.format(new Date()), test.row, 4);
-                        
-                        // Highlight the row
-                        testTable.setRowSelectionInterval(test.row, test.row);
-                        
-                        // Update the progress bar
-                        progressBar.setValue((int)((double)currentTest / total * 100));
-                        progressBar.setString("Running tests (" + currentTest + "/" + total + ")");
-                    });
-                    
-                    // Run the test
-                    logMessage("\n========================================================");
-                    logMessage("Running Test: " + test.language + " - " + test.testName);
-                    logMessage("========================================================");
-                    
-                    boolean success = runTest(test);
-                    
-                    // Update UI with the result
-                    SwingUtilities.invokeLater(() -> {
-                        testTable.setValueAt(success ? TestStatus.PASSED.name() : TestStatus.FAILED.name(), 
-                                         test.row, 3);
-                    });
-                }
-                
-                // Test run complete
-                SwingUtilities.invokeLater(() -> {
-                    progressBar.setValue(100);
-                    progressBar.setString("All tests completed");
-                    enableButtons();
-                    logMessage("\n========================================================");
-                    logMessage("Test run completed at " + dateFormat.format(new Date()));
-                    logMessage("========================================================");
-                });
-            } catch (Exception e) {
-                SwingUtilities.invokeLater(() -> {
-                    logMessage("Error running tests: " + e.getMessage());
-                    for (StackTraceElement element : e.getStackTrace()) {
-                        logMessage("    " + element.toString());
-                    }
-                    progressBar.setString("Error running tests");
-                    enableButtons();
-                });
-            }
-        });
-    }
-    
-    private boolean runTest(TestInfo test) {
-        String testDir = baseDir + File.separator + "tests" + File.separator + 
-                         test.language + File.separator + test.testName;
-        
-        File makeDir = new File(testDir + File.separator + "make");
-        File bakeDir = new File(testDir + File.separator + "bake");
-        
-        if (!makeDir.exists() || !bakeDir.exists()) {
-            logMessage("Error: Make or Bake directory not found for test " + test.testName);
-            return false;
-        }
-        
-        String logFilePath = logsDir + File.separator + test.language + "_" + test.testName + ".log";
-        
-        try (PrintWriter writer = new PrintWriter(new FileWriter(logFilePath))) {
-            // Header information
-            writer.println("Test: " + test.language + " - " + test.testName);
-            writer.println("Date: " + dateFormat.format(new Date()));
-            writer.println("========================================================");
-            
-            // Compare initial file state
-            writer.println("\n=== Initial File Comparison ===");
-            logMessage("Comparing initial files...");
-            
-            Map<String, FileInfo> makeFiles = scanDirectory(makeDir);
-            Map<String, FileInfo> bakeFiles = scanDirectory(bakeDir);
-            
-            compareAndLogFiles(makeFiles, bakeFiles, writer);
-            
-            // Run make
-            writer.println("\n=== Make Output ===");
-            logMessage("Running make...");
-            
-            ProcessResult makeResult = runProcess("make", makeDir);
-            writer.println(makeResult.output);
-            logMessage(makeResult.output);
-            
-            // Run bake
-            writer.println("\n=== Bake Output ===");
-            logMessage("Running bake...");
-            
-            ProcessResult bakeResult = runProcess("java -cp bakefile.jar fr.monlouyan.bakefile.Main", bakeDir);
-            writer.println(bakeResult.output);
-            logMessage(bakeResult.output);
-            
-            // Compare results
-            logMessage("Comparing results...");
-            writer.println("\n=== Comparison Results ===");
-            
-            // Compare exit codes
-            boolean exitCodesMatch = makeResult.exitCode == bakeResult.exitCode;
-            writer.println("Exit codes match: " + exitCodesMatch);
-            writer.println("Make exit code: " + makeResult.exitCode);
-            writer.println("Bake exit code: " + bakeResult.exitCode);
-            
-            // Compare output patterns (ignoring the tool name differences)
-            boolean outputPatternsMatch = compareOutputPatterns(makeResult.output, bakeResult.output);
-            writer.println("Output patterns match: " + outputPatternsMatch);
-            
-            // Compare final file state
-            writer.println("\n=== Final File State Comparison ===");
-            
-            Map<String, FileInfo> makeFinalFiles = scanDirectory(makeDir);
-            Map<String, FileInfo> bakeFinalFiles = scanDirectory(bakeDir);
-            
-            compareAndLogFiles(makeFinalFiles, bakeFinalFiles, writer);
-            
-            // Check if files were created or modified as expected
-            boolean fileChangesMatch = compareFileChanges(makeFiles, makeFinalFiles, bakeFiles, bakeFinalFiles);
-            writer.println("File changes match: " + fileChangesMatch);
-            
-            // Test summary
-            boolean testPassed = exitCodesMatch && outputPatternsMatch && fileChangesMatch;
-            writer.println("\n=== Test Result ===");
-            writer.println(testPassed ? "PASSED" : "FAILED");
-            
-            logMessage(testPassed ? "Test PASSED" : "Test FAILED");
-            
-            return testPassed;
-            
-        } catch (IOException e) {
-            logMessage("Error running test: " + e.getMessage());
-            return false;
-        }
-    }
-    
-    private boolean compareFileChanges(
-            Map<String, FileInfo> makeInitial, 
-            Map<String, FileInfo> makeFinal,
-            Map<String, FileInfo> bakeInitial, 
-            Map<String, FileInfo> bakeFinal) {
-        
-        // Check if the same files were created in both directories
-        Set<String> makeCreated = new HashSet<>(makeFinal.keySet());
-        makeCreated.removeAll(makeInitial.keySet());
-        
-        Set<String> bakeCreated = new HashSet<>(bakeFinal.keySet());
-        bakeCreated.removeAll(bakeInitial.keySet());
-        
-        if (!makeCreated.equals(bakeCreated)) {
-            logMessage("Different files created:\nMake: " + makeCreated + "\nBake: " + bakeCreated);
-            return false;
-        }
-        
-        // Check if the same files were modified
-        boolean filesMatch = true;
-        for (String file : makeInitial.keySet()) {
-            if (makeFinal.containsKey(file) && bakeInitial.containsKey(file) && bakeFinal.containsKey(file)) {
-                boolean makeModified = !makeInitial.get(file).equals(makeFinal.get(file));
-                boolean bakeModified = !bakeInitial.get(file).equals(bakeFinal.get(file));
-                
-                if (makeModified != bakeModified) {
-                    logMessage("File modification mismatch for " + file + 
-                              "\nMake modified: " + makeModified + 
-                              "\nBake modified: " + bakeModified);
-                    filesMatch = false;
-                }
-            }
-        }
-        
-        return filesMatch;
-    }
-    
-    private ProcessResult runProcess(String command, File directory) throws IOException {
-        ProcessBuilder processBuilder = new ProcessBuilder("/bin/sh", "-c", command);
-        processBuilder.directory(directory);
-        Process process = processBuilder.start();
-        
-        // Capture stdout and stderr
-        StringBuilder output = new StringBuilder();
-        try (BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
-             BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
-            
-            String line;
-            while ((line = stdInput.readLine()) != null) {
-                output.append(line).append("\n");
-            }
-            
-            while ((line = stdError.readLine()) != null) {
-                output.append("ERROR: ").append(line).append("\n");
-            }
-        }
-        
-        try {
-            process.waitFor();
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-        }
-        
-        return new ProcessResult(process.exitValue(), output.toString());
-    }
-    
-    private Map<String, FileInfo> scanDirectory(File directory) throws IOException {
-        Map<String, FileInfo> files = new HashMap<>();
-        
-        if (!directory.exists() || !directory.isDirectory()) {
-            return files;
-        }
-        
-        Files.walkFileTree(directory.toPath(), new SimpleFileVisitor<Path>() {
-            @Override
-            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
-                String relativePath = directory.toPath().relativize(file).toString();
-                
-                // Skip bakefile.jar to avoid differences
-                if (relativePath.equals("bakefile.jar")) {
-                    return FileVisitResult.CONTINUE;
-                }
-                
-                FileInfo info = new FileInfo(
-                    Files.isRegularFile(file),
-                    attrs.size(),
-                    attrs.lastModifiedTime().toMillis()
-                );
-                
-                files.put(relativePath, info);
-                return FileVisitResult.CONTINUE;
-            }
-        });
-        
-        return files;
-    }
-    
-    private void compareAndLogFiles(Map<String, FileInfo> makeFiles, 
-                                   Map<String, FileInfo> bakeFiles, 
-                                   PrintWriter writer) {
-        Set<String> allFiles = new HashSet<>();
-        allFiles.addAll(makeFiles.keySet());
-        allFiles.addAll(bakeFiles.keySet());
-        
-        List<String> sortedFiles = new ArrayList<>(allFiles);
-        Collections.sort(sortedFiles);
-        
-        writer.println("File comparison:");
-        for (String file : sortedFiles) {
-            FileInfo makeInfo = makeFiles.get(file);
-            FileInfo bakeInfo = bakeFiles.get(file);
-            
-            writer.print(file + ": ");
-            if (makeInfo == null) {
-                writer.println("Only in Bake");
-            } else if (bakeInfo == null) {
-                writer.println("Only in Make");
-            } else if (makeInfo.equals(bakeInfo)) {
-                writer.println("Identical");
-            } else {
-                writer.println("Different");
-                writer.println("  Make: " + makeInfo);
-                writer.println("  Bake: " + bakeInfo);
-            }
-        }
-    }
-    
-    private boolean compareOutputPatterns(String makeOutput, String bakeOutput) {
-        // Normalize output by replacing tool-specific words
-        String normalizedMake = makeOutput.replaceAll("\\bmake\\b", "TOOL")
-                                         .replaceAll("\\bMake\\b", "TOOL");
-        String normalizedBake = bakeOutput.replaceAll("\\bbake\\b", "TOOL")
-                                         .replaceAll("\\bBake\\b", "TOOL");
-        
-        // Compare line by line, ignoring exact timestamps or specific paths
-        String[] makeLines = normalizedMake.split("\n");
-        String[] bakeLines = normalizedBake.split("\n");
-        
-        // If line counts are very different, they're probably not matching
-        if (Math.abs(makeLines.length - bakeLines.length) > 2) {
-            logMessage("Output line count mismatch: Make=" + makeLines.length + 
-                      ", Bake=" + bakeLines.length);
-            return false;
-        }
-        
-        // Compare key patterns like error messages, file operations, etc.
-        Pattern errorPattern = Pattern.compile(".*Error.*|.*\\*\\*\\*.*|.*failed.*", 
-                                             Pattern.CASE_INSENSITIVE);
-        Pattern commandPattern = Pattern.compile("^[a-z0-9_\\-]+ .*|^\\$.*");
-        
-        List<String> makeErrors = extractMatches(makeLines, errorPattern);
-        List<String> bakeErrors = extractMatches(bakeLines, errorPattern);
-        
-        List<String> makeCommands = extractMatches(makeLines, commandPattern);
-        List<String> bakeCommands = extractMatches(bakeLines, commandPattern);
-        
-        // If error counts are different, that's a significant difference
-        if (makeErrors.size() != bakeErrors.size()) {
-            logMessage("Error count mismatch: Make=" + makeErrors.size() + 
-                      ", Bake=" + bakeErrors.size());
-            return false;
-        }
-        
-        // If command counts are different, that's a significant difference
-        if (makeCommands.size() != bakeCommands.size()) {
-            logMessage("Command count mismatch: Make=" + makeCommands.size() + 
-                      ", Bake=" + bakeCommands.size());
-            return false;
-        }
-        
-        return true;
-    }
-    
-    private List<String> extractMatches(String[] lines, Pattern pattern) {
-        return Arrays.stream(lines)
-                    .filter(line -> pattern.matcher(line).matches())
-                    .collect(Collectors.toList());
-    }
-    
-    private void logMessage(String message) {
-        SwingUtilities.invokeLater(() -> {
-            logArea.append(message + "\n");
-            // Scroll to bottom
-            logArea.setCaretPosition(logArea.getDocument().getLength());
-        });
-    }
-    
-    private static class TestInfo {
-        int row;
-        String language;
-        String testName;
-        
-        TestInfo(int row, String language, String testName) {
-            this.row = row;
-            this.language = language;
-            this.testName = testName;
-        }
-    }
-    
-    private static class FileInfo {
-        boolean isFile;
-        long size;
-        long lastModified;
-        
-        FileInfo(boolean isFile, long size, long lastModified) {
-            this.isFile = isFile;
-            this.size = size;
-            this.lastModified = lastModified;
-        }
-        
-        @Override
-        public boolean equals(Object obj) {
-            if (!(obj instanceof FileInfo)) {
-                return false;
-            }
-            FileInfo other = (FileInfo) obj;
-            return isFile == other.isFile && size == other.size;
-            // We don't compare lastModified times directly
-        }
-        
-        @Override
-        public String toString() {
-            return "isFile=" + isFile + ", size=" + size + ", lastModified=" + 
-                   new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(lastModified));
-        }
-    }
-    
-    private static class ProcessResult {
-        int exitCode;
-        String output;
-        
-        ProcessResult(int exitCode, String output) {
-            this.exitCode = exitCode;
-            this.output = output;
-        }
-    }
-    
-    public static void main(String[] args) {
-        SwingUtilities.invokeLater(() -> {
-            try {
-                // Set native look and feel
-                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            
-            BakeTestRunner runner = new BakeTestRunner();
-            runner.setVisible(true);
-        });
-    }
-}
\ No newline at end of file
diff --git a/tests/bakefile.jar b/tests/bakefile.jar
deleted file mode 100644
index 875b1b3bdfb568a74d7ba081bfe6268d33fcb5b8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 12101
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
N*1tB+z<>Qe{|`rCu-*Uw