// Path: src/main/java/eme/EcoreMetamodelExtraction.java
// public class EcoreMetamodelExtraction {
//     private static final Logger logger = LogManager.getLogger(EcoreMetamodelExtraction.class.getName());
//     private final JavaProjectExtractor extractor;
//     private final EcoreMetamodelGenerator generator;
//     private final ExtractionProperties properties;
// 
//     /**
//      * Basic constructor. Builds {@link JavaProjectExtractor}, {@link EcoreMetamodelGenerator} and
//      * {@link GenModelGenerator}.
//      */
//     public EcoreMetamodelExtraction() {
//         logger.info("Started EME...");
//         properties = new ExtractionProperties();
//         extractor = new JavaProjectExtractor();
//         generator = new EcoreMetamodelGenerator(properties);
//     }
// 
//     /**
//      * Starts the Ecore metamodel extraction for a specific {@link IProject}. The {@link IProject} will be parsed and an
//      * Ecore metamodel will be build.
//      * @param project is the specific {@link IProject} for the extraction.
//      * @return the Ecore metamodel.
//      */
//     public GeneratedEcoreMetamodel extract(IProject project) {
//         logger.info("Started extraction of project " + project.getName());
//         check(project); // check if valid.
//         IJavaProject javaProject = JavaCore.create(project); // create java project
//         IntermediateModel model = extractor.buildIntermediateModel(javaProject);
//         selectExtractionScope(model); // select scope if enabled in properties
//         GeneratedEcoreMetamodel metamodel = generator.generateMetamodel(model);
//         generator.saveMetamodel(); // save metamodel
//         return metamodel;
//     }
// 
//     /**
//      * Grants access to the {@link ExtractionProperties}.
//      * @return the {@link ExtractionProperties}.
//      */
//     public ExtractionProperties getProperties() {
//         return properties;
//     }
// 
//     /**
//      * Checks whether a specific {@link IProject} is valid (neither null nor nonexistent)
//      * @param project is the specific {@link IProject}.
//      */
//     private void check(IProject project) {
//         if (project == null) {
//             throw new IllegalArgumentException("Project can't be null!");
//         } else if (!project.exists()) {
//             throw new IllegalArgumentException("Project " + project.toString() + "does not exist!");
//         }
//     }
// 
//     /**
//      * Opens a window for specifying a custom extraction scope. The scope is manifested in the correlating
//      * {@link IntermediateModel} through enabling and disabling specific model elements.
//      * @param model is the {@link IntermediateModel} for which the extraction scope is specified.
//      */
//     private void selectExtractionScope(IntermediateModel model) {
//         if (properties.get(CUSTOM_EXTRACTION_SCOPE)) {
//             new SelectionWindow().open(model);
//         }
//     }
// }
// 
// Path: src/main/java/eme/properties/ExtractionProperties.java
// public class ExtractionProperties extends AbstractProperties<TextProperty, BinaryProperty> {
//     /**
//      * Basic constructor, sets the file name, file description and symbolic bundle name.
//      */
//     public ExtractionProperties() {
//         super("user.properties", "Use this file to configure the Ecore metamodel extraction.", "EcoreMetamodelExtraction");
//     }
// }


import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;
import eme.EcoreMetamodelExtraction;
import eme.properties.ExtractionProperties;
            Object element = ((IStructuredSelection) selection).getFirstElement();
            if (element instanceof IProject) {
                IProject project = (IProject) element;
                if (isJavaProject(project)) {
                    startExtraction((IProject) element);
                } else {
                    projectMessage(event);
                }
            } else if (element instanceof IJavaProject) {
                startExtraction(((IJavaProject) element).getProject());
            } else {
                throw new IllegalStateException("Invalid selection: " + element + " is not a project.");
            }
        }
        return null;
    }

    /**
     * Warning message in case of a non-Java project.
     */
    private void projectMessage(ExecutionEvent event) throws ExecutionException {
        String message = "This project is not a Java project. Therefore, a metamodel cannot be extracted.";
        IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
        MessageDialog.openInformation(window.getShell(), title, message);
    }

    /**
     * Allows the configuration of the {@link ExtractionProperties} of the {@link EcoreMetamodelExtraction}.
     * @param properties are the {@link ExtractionProperties}.
     */
// Path: src/main/java/eme/EcoreMetamodelExtraction.java
// public class EcoreMetamodelExtraction {
//     private static final Logger logger = LogManager.getLogger(EcoreMetamodelExtraction.class.getName());
//     private final JavaProjectExtractor extractor;
//     private final EcoreMetamodelGenerator generator;
//     private final ExtractionProperties properties;
// 
//     /**
//      * Basic constructor. Builds {@link JavaProjectExtractor}, {@link EcoreMetamodelGenerator} and
//      * {@link GenModelGenerator}.
//      */
//     public EcoreMetamodelExtraction() {
//         logger.info("Started EME...");
//         properties = new ExtractionProperties();
//         extractor = new JavaProjectExtractor();
//         generator = new EcoreMetamodelGenerator(properties);
//     }
// 
//     /**
//      * Starts the Ecore metamodel extraction for a specific {@link IProject}. The {@link IProject} will be parsed and an
//      * Ecore metamodel will be build.
//      * @param project is the specific {@link IProject} for the extraction.
//      * @return the Ecore metamodel.
//      */
//     public GeneratedEcoreMetamodel extract(IProject project) {
//         logger.info("Started extraction of project " + project.getName());
//         check(project); // check if valid.
//         IJavaProject javaProject = JavaCore.create(project); // create java project
//         IntermediateModel model = extractor.buildIntermediateModel(javaProject);
//         selectExtractionScope(model); // select scope if enabled in properties
//         GeneratedEcoreMetamodel metamodel = generator.generateMetamodel(model);
//         generator.saveMetamodel(); // save metamodel
//         return metamodel;
//     }
// 
//     /**
//      * Grants access to the {@link ExtractionProperties}.
//      * @return the {@link ExtractionProperties}.
//      */
//     public ExtractionProperties getProperties() {
//         return properties;
//     }
// 
//     /**
//      * Checks whether a specific {@link IProject} is valid (neither null nor nonexistent)
//      * @param project is the specific {@link IProject}.
//      */
//     private void check(IProject project) {
//         if (project == null) {
//             throw new IllegalArgumentException("Project can't be null!");
//         } else if (!project.exists()) {
//             throw new IllegalArgumentException("Project " + project.toString() + "does not exist!");
//         }
//     }
// 
//     /**
//      * Opens a window for specifying a custom extraction scope. The scope is manifested in the correlating
//      * {@link IntermediateModel} through enabling and disabling specific model elements.
//      * @param model is the {@link IntermediateModel} for which the extraction scope is specified.
//      */
//     private void selectExtractionScope(IntermediateModel model) {
//         if (properties.get(CUSTOM_EXTRACTION_SCOPE)) {
//             new SelectionWindow().open(model);
//         }
//     }
// }
// 
// Path: src/main/java/eme/properties/ExtractionProperties.java
// public class ExtractionProperties extends AbstractProperties<TextProperty, BinaryProperty> {
//     /**
//      * Basic constructor, sets the file name, file description and symbolic bundle name.
//      */
//     public ExtractionProperties() {
//         super("user.properties", "Use this file to configure the Ecore metamodel extraction.", "EcoreMetamodelExtraction");
//     }
// }


// Path: src/main/java/eme/handlers/ProjectHandler.java
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;
import eme.EcoreMetamodelExtraction;
import eme.properties.ExtractionProperties;

            Object element = ((IStructuredSelection) selection).getFirstElement();
            if (element instanceof IProject) {
                IProject project = (IProject) element;
                if (isJavaProject(project)) {
                    startExtraction((IProject) element);
                } else {
                    projectMessage(event);
                }
            } else if (element instanceof IJavaProject) {
                startExtraction(((IJavaProject) element).getProject());
            } else {
                throw new IllegalStateException("Invalid selection: " + element + " is not a project.");
            }
        }
        return null;
    }

    /**
     * Warning message in case of a non-Java project.
     */
    private void projectMessage(ExecutionEvent event) throws ExecutionException {
        String message = "This project is not a Java project. Therefore, a metamodel cannot be extracted.";
        IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
        MessageDialog.openInformation(window.getShell(), title, message);
    }

    /**
     * Allows the configuration of the {@link ExtractionProperties} of the {@link EcoreMetamodelExtraction}.
     * @param properties are the {@link ExtractionProperties}.
     */
    protected void configure(ExtractionProperties properties) {