// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/controller/InterruptibleProcessController.java
// public abstract class InterruptibleProcessController {
//     public static final String PROCESS_INTERRUPTED_MESSAGE = "Process interrupted";
// 
//     protected abstract ResourceBundle getResourceBundle();
// 
//     /**
//      * Default handling of the exception, displays information in an alert dialog.
//      *
//      * @param e the exception
//      */
//     public void handleInterruption(ProcessInterruptedException e) {
//         if (Platform.isFxApplicationThread()) {
//             showAlert(e);
//         } else {
//             Platform.runLater(() -> showAlert(e));
//         }
//     }
// 
//     private void showAlert(ProcessInterruptedException e) {
//         Alert alert = new Alert(Alert.AlertType.ERROR);
//         ResourceBundle resources = getResourceBundle();
//         alert.setTitle(resources.getString("exception_alert.title"));
//         alert.setHeaderText(resources.getString("exception_alert.header"));
//         alert.setContentText(e.getMessage());
// 
//         StringWriter sw = new StringWriter();
//         PrintWriter pw = new PrintWriter(sw);
//         e.printStackTrace(pw);
//         String exceptionText = sw.toString();
// 
//         Label stackTraceLabel = new Label(resources.getString("exception_alert.label"));
//         TextArea stackTraceTextArea = new TextArea(exceptionText);
//         stackTraceTextArea.setEditable(false);
//         stackTraceTextArea.setWrapText(true);
//         GridPane.setVgrow(stackTraceTextArea, Priority.ALWAYS);
//         GridPane.setHgrow(stackTraceTextArea, Priority.ALWAYS);
// 
//         GridPane expandableContent = new GridPane();
//         expandableContent.setPrefSize(400, 400);
//         expandableContent.setMaxWidth(Double.MAX_VALUE);
//         expandableContent.add(stackTraceLabel, 0, 0);
//         expandableContent.add(stackTraceTextArea, 0, 1);
// 
//         alert.getDialogPane().setExpandableContent(expandableContent);
//         // Dirty Linux only fix...
//         // Expandable zones cause the dialog not to resize correctly
//         if (System.getProperty("os.name").matches(".*[Ll]inux.*")) {
//             alert.getDialogPane().setPrefSize(600, 400);
//             alert.setResizable(true);
//             alert.getDialogPane().setExpanded(true);
//         }
// 
//         alert.showAndWait();
//     }
// }
// 
// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/exception/ProcessInterruptedException.java
// public class ProcessInterruptedException extends Exception {
//     /**
//      * Constructor usually used when the interruption was caused by a user action
//      *
//      * @param message the message explaining the interruption
//      */
//     public ProcessInterruptedException(String message) {
//         super(message);
//     }
// 
//     /**
//      * Contructor used when the interruption is caused by a previous exception
//      *
//      * @param message the message explaining the interruption
//      * @param cause   the cause of the interruption
//      */
//     public ProcessInterruptedException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }
// 
// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/util/SecurityConstants.java
// public static final String PROPERTIES_LOG4J = "log4j.properties";


import org.apache.log4j.PropertyConfigurator;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.Security;
import java.util.ResourceBundle;
import static ch.ge.ve.offlineadmin.util.SecurityConstants.PROPERTIES_LOG4J;
import ch.ge.ve.offlineadmin.controller.InterruptibleProcessController;
import ch.ge.ve.offlineadmin.exception.ProcessInterruptedException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
        InterruptibleProcessController interruptibleProcessController = new InterruptibleProcessController() {
            @Override
            protected ResourceBundle getResourceBundle() {
                return resourceBundle;
            }
        };
        Thread.currentThread().setUncaughtExceptionHandler((t, e) -> {
            final ProcessInterruptedException processInterruptedException = new ProcessInterruptedException(resourceBundle.getString("exception_alert.generic-message"), e);
            interruptibleProcessController.handleInterruption(processInterruptedException);
        });
    }

    private BorderPane initRootLayout(ResourceBundle bundle) throws IOException {
        FXMLLoader loader = new FXMLLoader();
        URL resource = this.getClass().getResource("/ch/ge/ve/offlineadmin/view/RootLayout.fxml");
        loader.setLocation(resource);
        loader.setResources(bundle);

        return loader.load();
    }

    private URL getStyleSheet() {
        return this.getClass().getResource("/ch/ge/ve/offlineadmin/styles/offlineadmin.css");
    }

    private static ResourceBundle getBundle() {
        return ResourceBundle.getBundle("ch.ge.ve.offlineadmin.bundles.offlineadmin-messages");
    }

    private InputStream getLog4jProperties() throws IOException {
// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/controller/InterruptibleProcessController.java
// public abstract class InterruptibleProcessController {
//     public static final String PROCESS_INTERRUPTED_MESSAGE = "Process interrupted";
// 
//     protected abstract ResourceBundle getResourceBundle();
// 
//     /**
//      * Default handling of the exception, displays information in an alert dialog.
//      *
//      * @param e the exception
//      */
//     public void handleInterruption(ProcessInterruptedException e) {
//         if (Platform.isFxApplicationThread()) {
//             showAlert(e);
//         } else {
//             Platform.runLater(() -> showAlert(e));
//         }
//     }
// 
//     private void showAlert(ProcessInterruptedException e) {
//         Alert alert = new Alert(Alert.AlertType.ERROR);
//         ResourceBundle resources = getResourceBundle();
//         alert.setTitle(resources.getString("exception_alert.title"));
//         alert.setHeaderText(resources.getString("exception_alert.header"));
//         alert.setContentText(e.getMessage());
// 
//         StringWriter sw = new StringWriter();
//         PrintWriter pw = new PrintWriter(sw);
//         e.printStackTrace(pw);
//         String exceptionText = sw.toString();
// 
//         Label stackTraceLabel = new Label(resources.getString("exception_alert.label"));
//         TextArea stackTraceTextArea = new TextArea(exceptionText);
//         stackTraceTextArea.setEditable(false);
//         stackTraceTextArea.setWrapText(true);
//         GridPane.setVgrow(stackTraceTextArea, Priority.ALWAYS);
//         GridPane.setHgrow(stackTraceTextArea, Priority.ALWAYS);
// 
//         GridPane expandableContent = new GridPane();
//         expandableContent.setPrefSize(400, 400);
//         expandableContent.setMaxWidth(Double.MAX_VALUE);
//         expandableContent.add(stackTraceLabel, 0, 0);
//         expandableContent.add(stackTraceTextArea, 0, 1);
// 
//         alert.getDialogPane().setExpandableContent(expandableContent);
//         // Dirty Linux only fix...
//         // Expandable zones cause the dialog not to resize correctly
//         if (System.getProperty("os.name").matches(".*[Ll]inux.*")) {
//             alert.getDialogPane().setPrefSize(600, 400);
//             alert.setResizable(true);
//             alert.getDialogPane().setExpanded(true);
//         }
// 
//         alert.showAndWait();
//     }
// }
// 
// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/exception/ProcessInterruptedException.java
// public class ProcessInterruptedException extends Exception {
//     /**
//      * Constructor usually used when the interruption was caused by a user action
//      *
//      * @param message the message explaining the interruption
//      */
//     public ProcessInterruptedException(String message) {
//         super(message);
//     }
// 
//     /**
//      * Contructor used when the interruption is caused by a previous exception
//      *
//      * @param message the message explaining the interruption
//      * @param cause   the cause of the interruption
//      */
//     public ProcessInterruptedException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }
// 
// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/util/SecurityConstants.java
// public static final String PROPERTIES_LOG4J = "log4j.properties";


// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/OfflineAdminApp.java
import org.apache.log4j.PropertyConfigurator;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.Security;
import java.util.ResourceBundle;
import static ch.ge.ve.offlineadmin.util.SecurityConstants.PROPERTIES_LOG4J;
import ch.ge.ve.offlineadmin.controller.InterruptibleProcessController;
import ch.ge.ve.offlineadmin.exception.ProcessInterruptedException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

        InterruptibleProcessController interruptibleProcessController = new InterruptibleProcessController() {
            @Override
            protected ResourceBundle getResourceBundle() {
                return resourceBundle;
            }
        };
        Thread.currentThread().setUncaughtExceptionHandler((t, e) -> {
            final ProcessInterruptedException processInterruptedException = new ProcessInterruptedException(resourceBundle.getString("exception_alert.generic-message"), e);
            interruptibleProcessController.handleInterruption(processInterruptedException);
        });
    }

    private BorderPane initRootLayout(ResourceBundle bundle) throws IOException {
        FXMLLoader loader = new FXMLLoader();
        URL resource = this.getClass().getResource("/ch/ge/ve/offlineadmin/view/RootLayout.fxml");
        loader.setLocation(resource);
        loader.setResources(bundle);

        return loader.load();
    }

    private URL getStyleSheet() {
        return this.getClass().getResource("/ch/ge/ve/offlineadmin/styles/offlineadmin.css");
    }

    private static ResourceBundle getBundle() {
        return ResourceBundle.getBundle("ch.ge.ve.offlineadmin.bundles.offlineadmin-messages");
    }

    private InputStream getLog4jProperties() throws IOException {
        return OfflineAdminApp.class.getClassLoader().getResourceAsStream(PROPERTIES_LOG4J);