Index: src/org/topcased/java/reverse/internal/wizards/Java2UMLWizard.java
===================================================================
RCS file: /cvsroot/java2uml/plugins/org.topcased.java.reverse/src/org/topcased/java/reverse/internal/wizards/Java2UMLWizard.java,v
retrieving revision 1.1
diff -u -r1.1 Java2UMLWizard.java
--- src/org/topcased/java/reverse/internal/wizards/Java2UMLWizard.java	23 Jul 2006 09:26:55 -0000	1.1
+++ src/org/topcased/java/reverse/internal/wizards/Java2UMLWizard.java	27 Aug 2008 21:15:39 -0000
@@ -38,17 +38,17 @@
 import org.eclipse.ui.INewWizard;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchWizard;
-import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.Package;
+import org.topcased.java.reverse.AbstractJava2UMLConverter;
 import org.topcased.java.reverse.Java2UMLConverter;
+import org.topcased.java.reverse.JavaAnnotaions2UMLConverter;
 import org.topcased.java.reverse.internal.ReversePlugin;
 
 /**
- * This is a sample new wizard. Its role is to create a new file resource in the
- * provided container. If the container resource (a folder or a project) is
- * selected in the workspace when the wizard is opened, it will accept it as the
- * target container. The wizard creates one file with the extension "uml2". If a
- * sample multi-page editor (also available as a template) is registered for the
- * same extension, it will be able to open it.
+ * This is a sample new wizard. Its role is to create a new file resource in the provided container. If the container
+ * resource (a folder or a project) is selected in the workspace when the wizard is opened, it will accept it as the
+ * target container. The wizard creates one file with the extension "uml2". If a sample multi-page editor (also
+ * available as a template) is registered for the same extension, it will be able to open it.
  */
 
 public class Java2UMLWizard extends Wizard implements INewWizard
@@ -79,20 +79,22 @@
     }
 
     /**
-     * This method is called when 'Finish' button is pressed in the wizard. We
-     * will create an operation and run it using wizard as execution context.
+     * This method is called when 'Finish' button is pressed in the wizard. We will create an operation and run it using
+     * wizard as execution context.
      */
     public boolean performFinish()
     {
         final String containerName = page.getContainerName();
         final String fileName = page.getFileName();
+        final String[] importList = page.getImportList();
+        final String modelName = page.getModelName();
         IRunnableWithProgress op = new IRunnableWithProgress()
         {
             public void run(IProgressMonitor monitor) throws InvocationTargetException
             {
                 try
                 {
-                    doFinish(containerName, fileName, monitor);
+                    doFinish(containerName, fileName, importList, monitor, modelName);
                 }
                 catch (CoreException e)
                 {
@@ -122,12 +124,14 @@
     }
 
     /**
-     * The worker method. It will find the container, create the file if missing
-     * or just replace its contents, and open the editor on the newly created
-     * file.
+     * The worker method. It will find the container, create the file if missing or just replace its contents, and open
+     * the editor on the newly created file.
+     * 
+     * @param importList
+     * @param modelName
      */
 
-    private void doFinish(String containerName, String fileName, IProgressMonitor monitor) throws CoreException
+    private void doFinish(String containerName, String fileName, String[] importList, IProgressMonitor monitor, String modelName) throws CoreException
     {
         // create a sample file
         monitor.beginTask("Creating " + fileName, 2);
@@ -144,11 +148,17 @@
         {
             throwCoreException("No java element selected.");
         }
-        
-        Java2UMLConverter converter = new Java2UMLConverter();
-        Model model = null;
-        model = converter.convert(javaElement);
 
+        AbstractJava2UMLConverter converter = null;
+
+        if (page.getImportProfile())
+            converter = new JavaAnnotaions2UMLConverter();
+        else
+            converter = new Java2UMLConverter();
+
+        Package model = null;
+        converter.setImportList(importList);
+        converter.setModelName(modelName);
         // Create a resource set
         //
         ResourceSet resourceSet = new ResourceSetImpl();
@@ -165,8 +175,9 @@
         //
         if (model != null)
         {
-            emfResource.getContents().add(model);
+            // emfResource.getContents().add(model);
         }
+        model = converter.convert(javaElement, emfResource);
 
         // Save the contents of the resource to the file
         // system.
@@ -178,15 +189,13 @@
         }
         catch (IOException ioe)
         {
-            IStatus status = new Status(IStatus.ERROR, ReversePlugin.getId(), IStatus.OK,
-                    "An error occured during saving resource", ioe);
+            IStatus status = new Status(IStatus.ERROR, ReversePlugin.getId(), IStatus.OK, "An error occured during saving resource", ioe);
             throw new CoreException(status);
         }
     }
 
     /**
-     * We will accept the selection in the workbench to see if we can initialize
-     * from it.
+     * We will accept the selection in the workbench to see if we can initialize from it.
      * 
      * @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
      */
Index: src/org/topcased/java/reverse/internal/wizards/Java2UMLWizardPage.java
===================================================================
RCS file: /cvsroot/java2uml/plugins/org.topcased.java.reverse/src/org/topcased/java/reverse/internal/wizards/Java2UMLWizardPage.java,v
retrieving revision 1.1
diff -u -r1.1 Java2UMLWizardPage.java
--- src/org/topcased/java/reverse/internal/wizards/Java2UMLWizardPage.java	23 Jul 2006 09:26:55 -0000	1.1
+++ src/org/topcased/java/reverse/internal/wizards/Java2UMLWizardPage.java	27 Aug 2008 21:15:41 -0000
@@ -14,6 +14,7 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.IDialogPage;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
@@ -26,172 +27,391 @@
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
 import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.dialogs.ContainerSelectionDialog;
+import org.eclipse.ui.dialogs.ResourceSelectionDialog;
 
 /**
- * The "New" wizard page allows setting the container for the new file as well
- * as the file name. The page will only accept file name without the extension
- * OR with the extension that matches the expected one (uml2).
+ * The "New" wizard page allows setting the container for the new file as well as the file name. The page will only
+ * accept file name without the extension OR with the extension that matches the expected one (uml2).
  */
 
-public class Java2UMLWizardPage extends WizardPage {
-	private Text containerText;
-
-	private Text fileText;
-
-	private ISelection selection;
-
-	/**
-	 * Constructor for SampleNewWizardPage.
-	 * 
-	 * @param pageName
-	 */
-	public Java2UMLWizardPage(ISelection selection) {
-		super("wizardPage");
-		setTitle("UML Model File");
-		setDescription("This wizard creates a new file with *.uml extension from a Java Reverse Engineering process.");
-		this.selection = selection;
-	}
-
-	/**
-	 * @see IDialogPage#createControl(Composite)
-	 */
-	public void createControl(Composite parent) {
-		Composite container = new Composite(parent, SWT.NULL);
-		GridLayout layout = new GridLayout();
-		container.setLayout(layout);
-		layout.numColumns = 3;
-		layout.verticalSpacing = 9;
-		Label label = new Label(container, SWT.NULL);
-		label.setText("&Container:");
-
-		containerText = new Text(container, SWT.BORDER | SWT.SINGLE);
-		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-		containerText.setLayoutData(gd);
-		containerText.addModifyListener(new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				dialogChanged();
-			}
-		});
-
-		Button button = new Button(container, SWT.PUSH);
-		button.setText("Browse...");
-		button.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleBrowse();
-			}
-		});
-		label = new Label(container, SWT.NULL);
-		label.setText("&File name:");
-
-		fileText = new Text(container, SWT.BORDER | SWT.SINGLE);
-		gd = new GridData(GridData.FILL_HORIZONTAL);
-		fileText.setLayoutData(gd);
-		fileText.addModifyListener(new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				dialogChanged();
-			}
-		});
-		initialize();
-		dialogChanged();
-		setControl(container);
-	}
-
-	/**
-	 * Tests if the current workbench selection is a suitable container to use.
-	 */
-
-	private void initialize() {
-		if (selection != null && selection.isEmpty() == false
-				&& selection instanceof IStructuredSelection) {
-			IStructuredSelection ssel = (IStructuredSelection) selection;
-			if (ssel.size() > 1)
-				return;
-			Object obj = ssel.getFirstElement();
-			if (obj instanceof IResource) {
-				IContainer container;
-				if (obj instanceof IContainer)
-					container = (IContainer) obj;
-				else
-					container = ((IResource) obj).getParent();
-				containerText.setText(container.getFullPath().toString());
-			}
-		}
-		fileText.setText("model.uml");
-	}
-
-	/**
-	 * Uses the standard container selection dialog to choose the new value for
-	 * the container field.
-	 */
-
-	private void handleBrowse() {
-		ContainerSelectionDialog dialog = new ContainerSelectionDialog(
-				getShell(), ResourcesPlugin.getWorkspace().getRoot(), false,
-				"Select new file container");
-		if (dialog.open() == Window.OK) {
-			Object[] result = dialog.getResult();
-			if (result.length == 1) {
-				containerText.setText(((Path) result[0]).toString());
-			}
-		}
-	}
-
-	/**
-	 * Ensures that both text fields are set.
-	 */
-
-	private void dialogChanged() {
-		IResource container = ResourcesPlugin.getWorkspace().getRoot()
-				.findMember(new Path(getContainerName()));
-		String fileName = getFileName();
-
-		if (getContainerName().length() == 0) {
-			updateStatus("File container must be specified");
-			return;
-		}
-		if (container == null
-				|| (container.getType() & (IResource.PROJECT | IResource.FOLDER)) == 0) {
-			updateStatus("File container must exist");
-			return;
-		}
-		if (!container.isAccessible()) {
-			updateStatus("Project must be writable");
-			return;
-		}
-		if (fileName.length() == 0) {
-			updateStatus("File name must be specified");
-			return;
-		}
-		if (fileName.replace('\\', '/').indexOf('/', 1) > 0) {
-			updateStatus("File name must be valid");
-			return;
-		}
-		int dotLoc = fileName.lastIndexOf('.');
-		if (dotLoc != -1) {
-			String ext = fileName.substring(dotLoc + 1);
-			if (ext.equalsIgnoreCase("uml") == false) {
-				updateStatus("File extension must be \"uml\"");
-				return;
-			}
-		}
-		updateStatus(null);
-	}
-
-	private void updateStatus(String message) {
-		setErrorMessage(message);
-		setPageComplete(message == null);
-	}
-
-	public String getContainerName() {
-		return containerText.getText();
-	}
-
-	public String getFileName() {
-		return fileText.getText();
-	}
+public class Java2UMLWizardPage extends WizardPage
+{
+    private Text containerText;
+
+    private Text fileText;
+
+    private Text modelText;
+
+    private ISelection selection;
+
+    private Group groupModel;
+
+    private List listModelImports;
+
+    private Composite compositebtn;
+
+    private Button buttonadd;
+
+    private Button buttondel;
+
+    private Button buttonclear;
+
+    private boolean importProfile = false;
+
+    /**
+     * Constructor for SampleNewWizardPage.
+     * 
+     * @param pageName
+     */
+    public Java2UMLWizardPage(ISelection selection)
+    {
+        super("wizardPage");
+        setTitle("UML Model File");
+        setDescription("This wizard creates a new file with *.uml extension from a Java Reverse Engineering process.");
+        this.selection = selection;
+    }
+
+    /**
+     * @see IDialogPage#createControl(Composite)
+     */
+    public void createControl(Composite parent)
+    {
+        Composite container = new Composite(parent, SWT.NULL);
+        GridLayout layout = new GridLayout();
+        container.setLayout(layout);
+        layout.numColumns = 3;
+        layout.verticalSpacing = 9;
+        Label label = new Label(container, SWT.NULL);
+        label.setText("&Container:");
+
+        containerText = new Text(container, SWT.BORDER | SWT.SINGLE);
+        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+        containerText.setLayoutData(gd);
+        containerText.addModifyListener(new ModifyListener()
+        {
+            public void modifyText(ModifyEvent e)
+            {
+                dialogChanged();
+            }
+        });
+
+        Button button = new Button(container, SWT.PUSH);
+        button.setText("Browse...");
+        button.addSelectionListener(new SelectionAdapter()
+        {
+            public void widgetSelected(SelectionEvent e)
+            {
+                handleBrowse();
+            }
+        });
+        label = new Label(container, SWT.NULL);
+        label.setText("&File name:");
+
+        fileText = new Text(container, SWT.BORDER | SWT.SINGLE);
+        gd = new GridData(GridData.FILL_HORIZONTAL);
+        fileText.setLayoutData(gd);
+        fileText.addModifyListener(new ModifyListener()
+        {
+            public void modifyText(ModifyEvent e)
+            {
+                dialogChanged();
+            }
+        });
+        label = new Label(container, SWT.NULL);
+
+        label = new Label(container, SWT.NULL);
+        label.setText("&Model name:");
+        modelText = new Text(container, SWT.BORDER | SWT.SINGLE);
+        gd = new GridData(GridData.FILL_HORIZONTAL);
+        modelText.setLayoutData(gd);
+        modelText.addModifyListener(new ModifyListener()
+        {
+            public void modifyText(ModifyEvent e)
+            {
+                dialogChanged();
+            }
+        });
+        label = new Label(container, SWT.NULL);
+
+        Button button2 = new Button(container, SWT.RADIO);
+        button2.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+        button2.setText("import profile");
+        button2.addSelectionListener(new SelectionAdapter()
+        {
+            public void widgetSelected(SelectionEvent e)
+            {
+                importProfile = true;
+            }
+        });
+
+        Button button3 = new Button(container, SWT.RADIO);
+        button3.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
+        button3.setText("import model");
+        button3.setSelection(true);
+        button3.addSelectionListener(new SelectionAdapter()
+        {
+            public void widgetSelected(SelectionEvent e)
+            {
+                importProfile = false;
+            }
+        });
+        label = new Label(container, SWT.NULL);
+
+        GridLayout gridLayout1 = new GridLayout();
+        gridLayout1.numColumns = 2; // Generated
+        GridData gridData5 = new GridData();
+        gridData5.grabExcessHorizontalSpace = false; // Generated
+        gridData5.grabExcessVerticalSpace = true;
+        gridData5.verticalSpan = 20; // Generated
+        gridData5.horizontalAlignment = GridData.FILL; // Generated
+        gridData5.verticalAlignment = GridData.FILL; // Generated
+        gridData5.horizontalSpan = 10; // Generated
+        groupModel = new Group(container, SWT.NONE);
+        groupModel.setText("Model imports"); // Generated
+        groupModel.setLayoutData(gridData5); // Generated
+        groupModel.setLayout(gridLayout1); // Generated
+
+        GridData gridData7 = new GridData();
+        gridData7.grabExcessHorizontalSpace = true; // Generated
+        gridData7.grabExcessVerticalSpace = true;
+        gridData7.verticalSpan = 20; // Generated
+        gridData7.horizontalAlignment = GridData.FILL; // Generated
+        gridData7.verticalAlignment = GridData.FILL; // Generated
+        gridData7.horizontalSpan = 10; // Generated
+        listModelImports = new List(groupModel, SWT.MULTI | SWT.BORDER);
+        listModelImports.setLayoutData(gridData7); // Generated
+
+        RowLayout rowLayout = new RowLayout();
+        rowLayout.type = SWT.HORIZONTAL; // Generated
+        rowLayout.justify = false; // Generated
+        rowLayout.pack = false; // Generated
+        rowLayout.fill = false; // Generated
+        GridData gridData10 = new GridData();
+        gridData10.horizontalAlignment = GridData.FILL; // Generated
+        gridData10.horizontalSpan = 2; // Generated
+        // gridData10.verticalAlignment = GridData.CENTER; // Generated
+        compositebtn = new Composite(groupModel, SWT.NONE);
+        compositebtn.setLayoutData(gridData10); // Generated
+        compositebtn.setLayout(rowLayout); // Generated
+        buttonadd = new Button(compositebtn, SWT.NONE);
+        buttonadd.setText("add"); // Generated
+        buttonadd.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter()
+        {
+            public void widgetSelected(org.eclipse.swt.events.SelectionEvent e)
+            {
+                handleAddImport();
+            }
+        });
+        buttondel = new Button(compositebtn, SWT.NONE);
+        buttondel.setText("del"); // Generated
+        buttondel.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter()
+        {
+            public void widgetSelected(org.eclipse.swt.events.SelectionEvent e)
+            {
+                String[] selection2 = listModelImports.getSelection();
+                for (String string : selection2)
+                {
+                    listModelImports.remove(string);
+                }
+            }
+        });
+
+        buttonclear = new Button(compositebtn, SWT.NONE);
+        buttonclear.setText("clear"); // Generated
+        buttonclear.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter()
+        {
+            public void widgetSelected(org.eclipse.swt.events.SelectionEvent e)
+            {
+                listModelImports.setItems(new String[] {});
+            }
+        });
+
+        initialize();
+        dialogChanged();
+        setControl(container);
+    }
+
+    /**
+     * Tests if the current workbench selection is a suitable container to use.
+     */
+
+    private void initialize()
+    {
+        if (selection != null && selection.isEmpty() == false && selection instanceof IStructuredSelection)
+        {
+            IStructuredSelection ssel = (IStructuredSelection) selection;
+            if (ssel.size() > 1)
+                return;
+            Object obj = ssel.getFirstElement();
+            if (obj instanceof IResource)
+            {
+                IContainer container;
+                if (obj instanceof IContainer)
+                    container = (IContainer) obj;
+                else
+                    container = ((IResource) obj).getParent();
+                containerText.setText(container.getFullPath().toString());
+            }
+        }
+        fileText.setText("model.uml");
+    }
+
+    private void handleAddImport()
+    {
+        IContainer cont = ResourcesPlugin.getWorkspace().getRoot();
+
+        ResourceSelectionDialog dialog = new ResourceSelectionDialog(getShell(), cont, "select Model to Import");
+
+        // ResourceListSelectionDialog dialog = new ResourceListSelectionDialog(
+        // getShell(), cont, 1);
+        // dialog.open();
+
+        if (dialog.open() == IDialogConstants.OK_ID)
+        {
+            // dialog.setBlockOnOpen(true);
+            Object[] obj = dialog.getResult();
+            if (obj == null || obj.length < 1)
+                return;
+
+            for (int i = 0; i < obj.length; i++)
+            {
+                Object object = obj[i];
+                if (object instanceof IResource)
+                {
+                    String filename = ((IResource) obj[i]).getFullPath().toString();
+                    listModelImports.add(filename);
+
+                }
+
+            }
+        }
+    }
+
+    /**
+     * Uses the standard container selection dialog to choose the new value for the container field.
+     */
+
+    private void handleBrowse()
+    {
+        ContainerSelectionDialog dialog = new ContainerSelectionDialog(getShell(), ResourcesPlugin.getWorkspace().getRoot(), false, "Select new file container");
+        if (dialog.open() == Window.OK)
+        {
+            Object[] result = dialog.getResult();
+            if (result.length == 1)
+            {
+                containerText.setText(((Path) result[0]).toString());
+            }
+        }
+    }
+
+    /**
+     * Ensures that both text fields are set.
+     */
+
+    private void dialogChanged()
+    {
+        IResource container = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(getContainerName()));
+        String fileName = getFileName();
+
+        if (getContainerName().length() == 0)
+        {
+            updateStatus("File container must be specified");
+            return;
+        }
+        if (container == null || (container.getType() & (IResource.PROJECT | IResource.FOLDER)) == 0)
+        {
+            updateStatus("File container must exist");
+            return;
+        }
+        if (!container.isAccessible())
+        {
+            updateStatus("Project must be writable");
+            return;
+        }
+        if (fileName.length() == 0)
+        {
+            updateStatus("File name must be specified");
+            return;
+        }
+        if (fileName.replace('\\', '/').indexOf('/', 1) > 0)
+        {
+            updateStatus("File name must be valid");
+            return;
+        }
+        int dotLoc = fileName.lastIndexOf('.');
+        if (dotLoc != -1)
+        {
+            String ext = fileName.substring(dotLoc + 1);
+            if (ext.equalsIgnoreCase("uml") == false)
+            {
+                updateStatus("File extension must be \"uml\"");
+                return;
+            }
+        }
+        updateStatus(null);
+    }
+
+    private void updateStatus(String message)
+    {
+        setErrorMessage(message);
+        setPageComplete(message == null);
+    }
+
+    /**
+     * returns the container text
+     * 
+     * @return
+     */
+    public String getContainerName()
+    {
+        return containerText.getText();
+    }
+
+    /**
+     * returns the filename
+     * 
+     * @return
+     */
+    public String getFileName()
+    {
+        return fileText.getText();
+    }
+
+    /**
+     * returns the list of imports
+     * 
+     * @return
+     */
+    public String[] getImportList()
+    {
+        return listModelImports.getItems();
+    }
+
+    /**
+     * return if a profile should be imported
+     * 
+     * @return
+     */
+    public boolean getImportProfile()
+    {
+        return importProfile;
+    }
+
+    /**
+     * returns the model names
+     * 
+     * @return
+     */
+    public String getModelName()
+    {
+        return modelText.getText();
+    }
 }
\ No newline at end of file
Index: src/org/topcased/java/reverse/Java2UMLConverter.java
===================================================================
RCS file: /cvsroot/java2uml/plugins/org.topcased.java.reverse/src/org/topcased/java/reverse/Java2UMLConverter.java,v
retrieving revision 1.4
diff -u -r1.4 Java2UMLConverter.java
--- src/org/topcased/java/reverse/Java2UMLConverter.java	1 Aug 2006 09:44:08 -0000	1.4
+++ src/org/topcased/java/reverse/Java2UMLConverter.java	27 Aug 2008 21:15:39 -0000
@@ -6,41 +6,50 @@
  * 
  * Contributors:
  *   David Sciamma - initial API and implementation 
+ *   Urs Zeidler   - added generics, enumerations, importing of other types
+ *                   applying of stereotypes         
  ******************************************************************************/
 
 package org.topcased.java.reverse;
 
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import org.eclipse.jdt.core.Flags;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.common.util.WrappedException;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.jdt.core.IAnnotatable;
+import org.eclipse.jdt.core.IAnnotation;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IField;
 import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMemberValuePair;
 import org.eclipse.jdt.core.IMethod;
 import org.eclipse.jdt.core.IPackageFragment;
 import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
-import org.eclipse.uml2.uml.Association;
 import org.eclipse.uml2.uml.Class;
 import org.eclipse.uml2.uml.Classifier;
-import org.eclipse.uml2.uml.DataType;
 import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Enumeration;
 import org.eclipse.uml2.uml.Interface;
 import org.eclipse.uml2.uml.Model;
 import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Namespace;
 import org.eclipse.uml2.uml.Operation;
 import org.eclipse.uml2.uml.Package;
-import org.eclipse.uml2.uml.PackageableElement;
 import org.eclipse.uml2.uml.Parameter;
+import org.eclipse.uml2.uml.Profile;
 import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Stereotype;
 import org.eclipse.uml2.uml.StructuredClassifier;
 import org.eclipse.uml2.uml.Type;
 import org.eclipse.uml2.uml.UMLFactory;
+import org.eclipse.uml2.uml.UMLPackage;
 import org.eclipse.uml2.uml.VisibilityKind;
 
 /**
@@ -48,9 +57,13 @@
  * 
  * @author <a href="david.sciamma@anyware-tech.com">David Sciamma</a>
  */
-public class Java2UMLConverter
+public class Java2UMLConverter extends AbstractJava2UMLConverter
 {
 
+    // boolean converProfile = false;
+
+    // private Model umlMetamodel;
+
     /**
      * Constructor
      */
@@ -60,244 +73,99 @@
     }
 
     /**
-     * Convert an Package or a Java project into a UML2 model
-     * 
-     * @param javaElement the JavaElement
-     * @return The UML2 model or <code>null</code> if the IJavaElement is not
-     *         a Package or a Java Project.
-     * @throws JavaModelException A error occured during Java Model analysis
-     */
-    public Model convert(IJavaElement javaElement) throws JavaModelException
-    {
-        switch (javaElement.getElementType())
-        {
-            case IJavaElement.JAVA_PROJECT:
-                return doConvertion((IJavaProject) javaElement);
-            case IJavaElement.PACKAGE_FRAGMENT:
-                return doConvertion((IPackageFragment) javaElement);
-            default:
-                return null;
-        }
-    }
-
-    /**
-     * Convert a Java project into a UML2 model
-     * 
-     * @param project the Java Project
-     * @return The UML2 model.
-     * @throws JavaModelException A error occured during Java Model analysis
-     */
-    private Model doConvertion(IJavaProject project) throws JavaModelException
-    {
-        Model model = UMLFactory.eINSTANCE.createModel();
-
-        initializeModel(model);
-
-        IPackageFragment[] children = project.getPackageFragments();
-        for (int i = 0; i < children.length; i++)
-        {
-            IPackageFragment fragment = children[i];
-            if (fragment.getCompilationUnits().length > 0)
-            {
-                Package packageObject = findOrCreatePackage(model, fragment);
-
-                createTypes(packageObject, fragment);
-            }
-        }
-
-        for (int i = 0; i < children.length; i++)
-        {
-            IPackageFragment fragment = children[i];
-            if (fragment.getCompilationUnits().length > 0)
-            {
-                Package packageObject = findOrCreatePackage(model, fragment);
-
-                initializeTypes(packageObject, fragment);
-            }
-        }
-
-        for (int i = 0; i < children.length; i++)
-        {
-            IPackageFragment fragment = children[i];
-            if (fragment.getCompilationUnits().length > 0)
-            {
-                Package packageObject = findOrCreatePackage(model, fragment);
-
-                createAssociations(packageObject);
-            }
-        }
-
-        return model;
-
-    }
-
-    /**
-     * Convert a Java project into a UML2 model
-     * 
-     * @param packageModel the Java Package
-     * @return The UML2 model.
-     * @throws JavaModelException A error occured during Java Model analysis
-     */
-    private Model doConvertion(IPackageFragment packageModel) throws JavaModelException
-    {
-        Model model = UMLFactory.eINSTANCE.createModel();
-
-        return convert(model, packageModel);
-    }
-
-
-    /**
-     * Convert a Java Package Fragment into a UML2 PAckage and update the
-     * given UML2 Model
-     * 
-     * @param model The UML2 model where the Package must be inserted
-     * @param fragment the Package Fragment
-     * @return The updated UML2 model.
-     * @throws JavaModelException A error occured during Java Model analysis
-     */
-    public Model convert(Model model, IPackageFragment fragment) throws JavaModelException
-    {
-        initializeModel(model);
-
-        Package packageObject = findOrCreatePackage(model, fragment);
-
-        createTypes(packageObject, fragment);
-        initializeTypes(packageObject, fragment);
-        createAssociations(packageObject);
-
-        return model;
-    }
-
-    /**
      * Creates the Java Primitive Types.<br>
-     * We could also import these Primitive Types from the UML2 Java Library but
-     * this solution is lighter.
+     * or creates imports or applies profiles if the importlist is not empty We could also import these Primitive Types
+     * from the UML2 Java Library but this solution is lighter.
      * 
      * @param model the UML2 model to update
+     * @throws CoreException
      */
-    protected void initializeModel(Model model)
+    protected void initializeModel(Package model) throws CoreException
     {
-        if (model.getOwnedType("boolean") == null)
-        {
-            model.createOwnedPrimitiveType("boolean");
-        }
-        if (model.getOwnedType("byte") == null)
-        {
-            model.createOwnedPrimitiveType("byte");
-        }
-        if (model.getOwnedType("char") == null)
-        {
-            model.createOwnedPrimitiveType("char");
-        }
-        if (model.getOwnedType("double") == null)
-        {
-            model.createOwnedPrimitiveType("double");
-        }
-        if (model.getOwnedType("float") == null)
-        {
-            model.createOwnedPrimitiveType("float");
-        }
-        if (model.getOwnedType("int") == null)
-        {
-            model.createOwnedPrimitiveType("int");
-        }
-        if (model.getOwnedType("long") == null)
-        {
-            model.createOwnedPrimitiveType("long");
-        }
-        if (model.getOwnedType("short") == null)
-        {
-            model.createOwnedPrimitiveType("short");
-        }
-    }
+        if (importList != null)
+            if (importList.length > 0)
+            {
+                for (int i = 0; i < importList.length; i++)
+                {
+                    String im = importList[i];
+                    try
+                    {
 
-    protected Package findOrCreatePackage(Model model, IPackageFragment fragment)
-    {
-        String qualifiedName = fragment.getElementName();
+                        URI uri = URI.createFileURI(im);
+                        uri = URI.createPlatformResourceURI(im);
+                        ResourceSet RESOURCE_SET = new ResourceSetImpl();
 
-        // Creates recursively the hierarchy of packages
-        StringTokenizer tokenizer = new StringTokenizer(qualifiedName, ".");
-        Package parent = model;
-        Package packageObject = model;
-        while (tokenizer.hasMoreTokens())
-        {
-            String packageName = tokenizer.nextToken();
-            packageObject = parent.getNestedPackage(packageName);
-            if (packageObject == null)
-            {
-                packageObject = parent.createNestedPackage(packageName);
-            }
-            parent = packageObject;
-        }
+                        Package package1 = null;
 
-        return packageObject;
-    }
+                        try
+                        {
+                            Resource resource = RESOURCE_SET.getResource(uri, true);
 
-    protected Type findType(Package packageObject, String typeName)
-    {
-        Type type = null;
-        if (typeName != null)
-        {
-            NamedElement element = packageObject.getMember(typeName);
-            if (element instanceof Type)
-            {
-                type = (Type) element;
-            }
+                            package1 = (org.eclipse.uml2.uml.Package) EcoreUtil.getObjectByType(resource.getContents(), UMLPackage.eINSTANCE.getPackage());
 
-            if (type == null)
-            {
-                type = findType(packageObject.getModel(), typeName, true);
-            }
-        }
-        return type;
-    }
+                        }
+                        catch (WrappedException we)
+                        {
+                            throwCoreException(we.getMessage());
+                        }
 
-    protected Type findType(Package packageObject, String typeName, boolean deep)
-    {
-        Type type = null;
-        if (typeName != null)
-        {
-            NamedElement element = packageObject.getMember(typeName);
-            if (element instanceof Type)
-            {
-                type = (Type) element;
-            }
+                        if (package1 instanceof Profile)
+                        {
+                            Profile profile = (Profile) package1;
+                            model.applyProfile(profile);
+                        }
+                        else
+                            model.createPackageImport(package1, VisibilityKind.PUBLIC_LITERAL);
 
-            if (type == null && deep)
-            {
-                Iterator it = packageObject.getPackagedElements().iterator();
-                while (it.hasNext() && type == null)
-                {
-                    PackageableElement child = (PackageableElement) it.next();
-                    if (child instanceof Package)
+                    }
+                    catch (Exception e)
                     {
-                        type = findType((Package) child, typeName, true);
+                        throwCoreException(e.getMessage());
                     }
                 }
-            }
-        }
-        return type;
-    }
-
-    protected Type findOrCreateType(Package packageObject, String typeName)
-    {
-        Type type = findType(packageObject, typeName);
 
-        if (typeName != null && !"void".equals(typeName))
-        {
-            if (type == null)
+            }
+            else
             {
-                DataType dataType = UMLFactory.eINSTANCE.createDataType();
-                dataType.setName(typeName);
-
-                packageObject.getPackagedElements().add(dataType);
-
-                type = dataType;
+                // we create only the primitive types
+                if (model.getOwnedType("boolean") == null)
+                {
+                    model.createOwnedPrimitiveType("boolean");
+                }
+                if (model.getOwnedType("byte") == null)
+                {
+                    model.createOwnedPrimitiveType("byte");
+                }
+                if (model.getOwnedType("char") == null)
+                {
+                    model.createOwnedPrimitiveType("char");
+                }
+                if (model.getOwnedType("double") == null)
+                {
+                    model.createOwnedPrimitiveType("double");
+                }
+                if (model.getOwnedType("float") == null)
+                {
+                    model.createOwnedPrimitiveType("float");
+                }
+                if (model.getOwnedType("int") == null)
+                {
+                    model.createOwnedPrimitiveType("int");
+                }
+                if (model.getOwnedType("long") == null)
+                {
+                    model.createOwnedPrimitiveType("long");
+                }
+                if (model.getOwnedType("short") == null)
+                {
+                    model.createOwnedPrimitiveType("short");
+                }
             }
-        }
-        return type;
     }
 
+    /**
+     * Initalise the created types and populated them with operation properties and inner types.
+     */
     protected void initializeTypes(Package packageObject, IPackageFragment fragment) throws JavaModelException
     {
         // For all the package member
@@ -325,7 +193,6 @@
         // ////// update return type
         // ////// for all parameters
         // //////// update type
-
         IJavaElement[] children = fragment.getChildren();
         for (int i = 0; i < children.length; i++)
         {
@@ -338,6 +205,8 @@
                     IType type = types[j];
                     String typeName = type.getElementName();
                     NamedElement element = packageObject.getOwnedMember(typeName);
+                    if (element == null && type.getParent() != null)
+                        element = findInnerType(packageObject, type, typeName);
 
                     if (element instanceof Interface)
                     {
@@ -349,6 +218,9 @@
                         {
                             String interfaceName = superInterfaces[k];
                             Type interfaceType = findType(packageObject, interfaceName);
+                            if (interfaceType == null && type.getParent() != null)
+                                interfaceType = findInnerType(packageObject, type, typeName);
+
                             if (interfaceType != null && interfaceType instanceof Classifier)
                             {
                                 interfaceObject.createGeneralization((Classifier) interfaceType);
@@ -359,16 +231,46 @@
                         createProperties(type, interfaceObject);
                         createOperations(type, interfaceObject);
                     }
-                    if (element instanceof Class)
+                    if (element instanceof Enumeration)
                     {
-                        Class classObject = (Class) element;
+                        Enumeration enumeration = (Enumeration) element;
+
+                        String[] superInterfaces = type.getSuperInterfaceNames();
+                        for (int k = 0; k < superInterfaces.length; k++)
+                        {
+                            String interfaceName = superInterfaces[k];
+                            Type interfaceType = findType(packageObject, interfaceName);
+                            if (interfaceType == null)
+                                interfaceType = findGenericType(packageObject, interfaceName);
+
+                            if (interfaceType == null && type.getParent() != null)
+                                interfaceType = findInnerType(packageObject, type, typeName);
 
+                            if (interfaceType != null && interfaceType instanceof Interface)
+                            {
+                                enumeration.createGeneralization((Classifier) interfaceType);
+                            }
+                        }
+                        // Inner objects
+                        createProperties(type, enumeration);
+                        createOperations(type, enumeration);
+
+                    }
+                    else if (element instanceof Class)
+                    {
+                        Class classObject = (Class) element;
                         // Super Interfaces
                         String[] superInterfaces = type.getSuperInterfaceNames();
                         for (int k = 0; k < superInterfaces.length; k++)
                         {
                             String interfaceName = superInterfaces[k];
                             Type interfaceType = findType(packageObject, interfaceName);
+                            if (interfaceType == null)
+                                interfaceType = findGenericType(packageObject, interfaceName);
+
+                            if (interfaceType == null && type.getParent() != null)
+                                interfaceType = findInnerType(packageObject, type, typeName);
+
                             if (interfaceType != null && interfaceType instanceof Interface)
                             {
                                 classObject.createInterfaceRealization(interfaceName, (Interface) interfaceType);
@@ -377,7 +279,13 @@
 
                         // Generalization
                         String superClassName = type.getSuperclassName();
-                        Type classType = findOrCreateType(packageObject, superClassName);
+                        Type classType = findType(packageObject, superClassName);
+                        if (classType == null && type.getParent() != null)
+                            classType = findInnerType(packageObject, type, typeName);
+
+                        if (classType == null)
+                            classType = findOrCreateType(packageObject, superClassName);
+
                         if (classType != null && classType instanceof Classifier)
                         {
                             classObject.createGeneralization((Classifier) classType);
@@ -392,185 +300,98 @@
         }
     }
 
-    protected void createAssociations(Package packageObject) throws JavaModelException
+    /**
+     * 
+     * Process all types in the array.
+     * 
+     * @param packageObject
+     * @param types
+     * @throws JavaModelException
+     */
+    protected void processTypes(Namespace packageObject, IType[] types) throws JavaModelException
     {
-        List workingCopy = new ArrayList(packageObject.getPackagedElements());
-        Iterator itType = workingCopy.iterator();
-        while (itType.hasNext())
+        for (int j = 0; j < types.length; j++)
         {
-            PackageableElement element = (PackageableElement) itType.next();
-            if (element instanceof Interface)
-            {
-                Interface interfaceObject = (Interface) element;
-                Iterator itProp = interfaceObject.getOwnedAttributes().iterator();
-                while (itProp.hasNext())
-                {
-                    Property property = (Property) itProp.next();
-                    Type targetType = property.getType();
-                    if (targetType instanceof StructuredClassifier || targetType instanceof Interface)
-                    {
-                        createAssociation(property);
-                    }
-                }
-            }
-            if (element instanceof StructuredClassifier)
-            {
-                StructuredClassifier classifierObject = (StructuredClassifier) element;
-                Iterator itProp = classifierObject.getOwnedAttributes().iterator();
-                while (itProp.hasNext())
-                {
-                    Property property = (Property) itProp.next();
-                    Type targetType = property.getType();
-                    if (targetType instanceof StructuredClassifier || targetType instanceof Interface)
-                    {
-                        createAssociation(property);
-                    }
-                }
-            }
-        }
-    }
+            IType type = types[j];
 
-    protected void createAssociation(Property property)
-    {
-        if (property.getAssociation() == null)
-        {
-            Property opposite = foundOpposite(property);
-            Element propOwner = property.getOwner();
-            if (opposite != null)
+            IType[] innerTypes = type.getTypes();
+            if (innerTypes.length == 0)
             {
-                Association association = UMLFactory.eINSTANCE.createAssociation();
-                association.getMemberEnds().add(property);
-                association.getMemberEnds().add(opposite);
-
-                property.getNearestPackage().getPackagedElements().add(association);
+                Classifier createTypeInPackage = createTypeInPackage(packageObject, type);
+                processAnnotations(packageObject, type, createTypeInPackage);
             }
             else
             {
-                Association association = UMLFactory.eINSTANCE.createAssociation();
-                association.getMemberEnds().add(property);
-                Property createdOpposite = association.createOwnedEnd("target", (Type) propOwner);
-
-                property.getNearestPackage().getPackagedElements().add(association);
-            }
-        }
-    }
+                Classifier classifier = null;// createTypeInPackage(packageObject
+                // , type);
+                classifier = createTypeInPackage(packageObject, type);
 
-    protected Property foundOpposite(Property source)
-    {
-        Property target = null;
-
-        Type propType = source.getType();
-        Element propOwner = source.getOwner();
-        if (propType instanceof StructuredClassifier || propType instanceof Interface)
-        {
-            // Search if the property type has a property of the type of
-            // propOwner
-            List properties = null;
-            if (propType instanceof StructuredClassifier)
-            {
-                properties = ((StructuredClassifier) propType).getOwnedAttributes();
-            }
-            if (propType instanceof Interface)
-            {
-                properties = ((Interface) propType).getOwnedAttributes();
-            }
-
-            Iterator it = properties.iterator();
-            while (it.hasNext() && target == null)
-            {
-                Property prop = (Property) it.next();
-                // Check that is a different property
-                if (prop != source && propOwner.equals(prop.getType()))
-                {
-                    target = prop;
-                }
+                if (classifier != null)
+                    processTypes(classifier, innerTypes);
             }
         }
-
-        return target;
     }
 
-    protected void createTypes(Package packageObject, IPackageFragment fragment) throws JavaModelException
+    /**
+     * process the annotation and applies them as stereotypes if available
+     * 
+     * @param packageObject
+     * @param annotatable
+     * @param element
+     * @throws JavaModelException
+     */
+    private void processAnnotations(Namespace packageObject, IAnnotatable annotatable, Element element) throws JavaModelException
     {
-        IJavaElement[] children = fragment.getChildren();
-        for (int i = 0; i < children.length; i++)
+        IAnnotation[] annotations = annotatable.getAnnotations();
+        for (IAnnotation annotation : annotations)
         {
-            if (children[i] instanceof ICompilationUnit)
-            {
-                ICompilationUnit unit = (ICompilationUnit) children[i];
-                IType[] types = unit.getAllTypes();
-                for (int j = 0; j < types.length; j++)
+            String elementName = annotation.getElementName();
+            Stereotype stereotype = findStereotypeInProfile(packageObject, elementName);
+            if (stereotype != null)
+                if (element.isStereotypeApplicable(stereotype))
                 {
-                    IType type = types[j];
+                    element.applyStereotype(stereotype);
+                    IMemberValuePair[] valuePairs = annotation.getMemberValuePairs();
 
-                    if (type.isInterface())
+                    for (IMemberValuePair valuePair : valuePairs)
                     {
-                        Interface interfaceObject = UMLFactory.eINSTANCE.createInterface();
-                        interfaceObject.setName(type.getElementName());
-
-                        update(interfaceObject, type.getFlags());
-
-                        packageObject.getPackagedElements().add(interfaceObject);
-                    }
-                    else
-                    {
-                        Class classObject = UMLFactory.eINSTANCE.createClass();
-                        classObject.setName(type.getElementName());
-
-                        update(classObject, type.getFlags());
+                        String name = valuePair.getMemberName();
+                        EList<Property> attributes = stereotype.getAllAttributes();
+                        for (Property property : attributes)
+                        {
+                            if (property.getName().equals(name))
+                            {
+                                Object[] values;
+                                if (valuePair.getValue() instanceof String)
+                                {
+                                    values = new Object[] {valuePair.getValue()};
+                                }
+                                else
+                                    values = (Object[]) valuePair.getValue();
+
+                                if (property.getUpper() == 1)
+                                    element.setValue(stereotype, name, values[0]);
+                                else
+                                    for (Object object : values)
+                                    {
+                                        // TODO : here we need to check for array values
+                                    }
 
-                        packageObject.getPackagedElements().add(classObject);
+                                break;
+                            }
+                        }
                     }
                 }
-            }
-        }
-    }
 
-    protected void createOperations(IType type, Class classifier) throws JavaModelException
-    {
-        IMethod[] methods = type.getMethods();
-        for (int k = 0; k < methods.length; k++)
-        {
-            IMethod method = methods[k];
-            if (!method.isConstructor())
-            {
-                Operation operationObject = createOperation(classifier, method);
-                classifier.getOwnedOperations().add(operationObject);
-            }
         }
     }
 
-    protected Operation createOperation(Element element, IMethod method) throws JavaModelException
-    {
-        String methodName = method.getElementName();
-
-        Operation operationObject = UMLFactory.eINSTANCE.createOperation();
-        operationObject.setName(methodName);
-
-        update(operationObject, method.getFlags());
-
-        int flags = method.getFlags();
-        operationObject.setIsAbstract(Flags.isAbstract(flags));
-        operationObject.setIsStatic(Flags.isStatic(flags));
-
-        createParameters(element, operationObject, method);
-
-        if (method.exists() && !method.isConstructor())
-        {
-            String returnTypeSig = method.getReturnType();
-
-            String returnTypeWithoutArray = Signature.getElementType(returnTypeSig);
-            String returnTypeName = Signature.toString(Signature.getTypeErasure(returnTypeWithoutArray));
-            Type returnType = findOrCreateType(element.getNearestPackage(), returnTypeName);
-            if (returnType != null)
-            {
-                operationObject.createReturnResult("return", returnType);
-            }
-        }
-
-        return operationObject;
-    }
-
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.topcased.java.reverse.AbstractJava2UMLConverter#createParameters(org.eclipse.uml2.uml.Element,
+     * org.eclipse.uml2.uml.Operation, org.eclipse.jdt.core.IMethod)
+     */
     protected void createParameters(Element element, Operation operation, IMethod method) throws JavaModelException
     {
         String[] paramNames = method.getParameterNames();
@@ -585,104 +406,158 @@
 
             String typeWithoutArray = Signature.getElementType(typeSig);
             String typeName = Signature.toString(Signature.getTypeErasure(typeWithoutArray));
-            Type paramType = findOrCreateType(element.getNearestPackage(), typeName);
+
+            Type paramType = findTemplateParameter(element, typeName);
+            if (paramType == null)
+                paramType = findOrCreateType(element.getNearestPackage(), typeName);
+
             if (paramType != null)
             {
                 parameter.setType(paramType);
             }
 
             operation.getOwnedParameters().add(parameter);
+            ITypeParameter typeParameter = method.getTypeParameter(name);
+
+            processAnnotations(element.getNearestPackage(), method, parameter);
         }
     }
 
-    protected void createOperations(IType type, Interface interfaceObject) throws JavaModelException
+    /**
+     * Looks up the stereotype, makes only a simple name check.
+     * 
+     * @param packageObject
+     * @param elementName
+     * @return
+     */
+    private Stereotype findStereotypeInProfile(Namespace packageObject, String elementName)
     {
-        IMethod[] methods = type.getMethods();
-        for (int k = 0; k < methods.length; k++)
+        Model model = packageObject.getModel();
+        EList<Profile> appliedProfiles = model.getAppliedProfiles();
+        for (Profile profile : appliedProfiles)
         {
-            IMethod method = methods[k];
-            if (!method.isConstructor())
-            {
-                Operation operationObject = createOperation(interfaceObject, method);
-                interfaceObject.getOwnedOperations().add(operationObject);
-            }
+            Type type = findType(profile, elementName);
+            if (type instanceof Stereotype)
+                return (Stereotype) type;
         }
+        return null;
     }
 
-    protected void createProperties(IType type, StructuredClassifier classifier) throws JavaModelException
+    /**
+     * Creates the type in the package.
+     * 
+     * @param packageObject
+     * @param type
+     * @return
+     * @throws JavaModelException
+     */
+    protected Classifier createTypeInPackage(Namespace packageObject, IType type) throws JavaModelException
     {
-        IField[] fields = type.getFields();
-        for (int k = 0; k < fields.length; k++)
-        {
-            IField field = fields[k];
 
-            Property propertyObject = createProperty(classifier, field);
+        if (type.isInterface())
+        {
+            Interface interfaceObject = UMLFactory.eINSTANCE.createInterface();
+            if (type.isAnnotation())
+            {
+                interfaceObject.setName("@" + type.getElementName());
 
-            classifier.getOwnedAttributes().add(propertyObject);
+            }
+            else
+                interfaceObject.setName(type.getElementName());
 
-        }
-    }
+            createTemplateParameters(type, interfaceObject);
 
-    protected Property createProperty(Element element, IField field) throws JavaModelException
-    {
-        String fieldName = field.getElementName();
-        String fieldTypeSig = field.getTypeSignature();
+            update(interfaceObject, type.getFlags());
+            addToContainment(packageObject, interfaceObject);
+            return interfaceObject;
 
-        String fieldTypeWithoutArray = Signature.getElementType(fieldTypeSig);
-        String fieldTypeName = Signature.toString(Signature.getTypeErasure(fieldTypeWithoutArray));
-        Type fieldType = findOrCreateType(element.getNearestPackage(), fieldTypeName);
-
-        Property propertyObject = UMLFactory.eINSTANCE.createProperty();
-        propertyObject.setName(fieldName);
-        if (fieldType != null)
+        }
+        if (type.isEnum())
         {
-            propertyObject.setType(fieldType);
+            Enumeration enumeration = UMLFactory.eINSTANCE.createEnumeration();
+            enumeration.setName(type.getElementName());
+            update(enumeration, type.getFlags());
+            addToContainment(packageObject, enumeration);
+            return enumeration;
         }
 
-        update(propertyObject, field.getFlags());
+        Class classObject = UMLFactory.eINSTANCE.createClass();
+        classObject.setName(type.getElementName());
+        createTemplateParameters(type, classObject);
+
+        update(classObject, type.getFlags());
+        addToContainment(packageObject, classObject);
+
+        return classObject;
 
-        return propertyObject;
     }
 
-    protected void createProperties(IType type, Interface interfaceObject) throws JavaModelException
+    /**
+     * Creates the properties for a classifier, and process the annotations.
+     * 
+     * @param type
+     * @param classifier
+     * @throws JavaModelException
+     */
+    protected void createProperties(IType type, StructuredClassifier classifier) throws JavaModelException
     {
         IField[] fields = type.getFields();
         for (int k = 0; k < fields.length; k++)
         {
             IField field = fields[k];
 
-            Property propertyObject = createProperty(interfaceObject, field);
+            Property propertyObject = createProperty(classifier, field);
+            classifier.getOwnedAttributes().add(propertyObject);
+            processAnnotations(classifier.getNamespace(), type, propertyObject);
 
-            interfaceObject.getOwnedAttributes().add(propertyObject);
         }
     }
 
-    protected void update(NamedElement element, int flags) throws JavaModelException
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.topcased.java.reverse.AbstractJava2UMLConverter#createOperations(org.eclipse.jdt.core.IType,
+     * org.eclipse.uml2.uml.Class)
+     */
+    protected void createOperations(IType type, Class classifier) throws JavaModelException
     {
-        if (Flags.isPrivate(flags))
-        {
-            element.setVisibility(VisibilityKind.PRIVATE_LITERAL);
-        }
-        else if (Flags.isProtected(flags))
-        {
-            element.setVisibility(VisibilityKind.PROTECTED_LITERAL);
-        }
-        else if (Flags.isPublic(flags))
+        IMethod[] methods = type.getMethods();
+        for (int k = 0; k < methods.length; k++)
         {
-            element.setVisibility(VisibilityKind.PUBLIC_LITERAL);
+            IMethod method = methods[k];
+            if (!method.isConstructor())
+            {
+                Operation operationObject = createOperation(classifier, method);
+                classifier.getOwnedOperations().add(operationObject);
+                processAnnotations(classifier.getNamespace(), method, operationObject);
+            }
         }
     }
 
-    protected String getName(IPackageFragment fragment)
+    /**
+     * Creates a model and add it to the emfResource.
+     */
+    @Override
+    protected Package createRootPackage()
     {
-        String name = "";
-        String fullName = fragment.getElementName();
-        int dotIndex = fullName.lastIndexOf('.');
-        if (dotIndex > 0)
         {
-            name = fullName.substring(dotIndex + 1);
+            Package model;
+            model = UMLFactory.eINSTANCE.createModel();
+            emfResource.getContents().add(model);
+            model.setName(modelName);
+            return model;
         }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.topcased.java.reverse.AbstractJava2UMLConverter#postProcess(org.eclipse.uml2.uml.Package)
+     */
+    @Override
+    protected void postProcess(Package model)
+    {
+        // do nothing
 
-        return name;
     }
 }
Index: src/org/topcased/java/reverse/JavaAnnotaions2UMLConverter.java
===================================================================
RCS file: src/org/topcased/java/reverse/JavaAnnotaions2UMLConverter.java
diff -N src/org/topcased/java/reverse/JavaAnnotaions2UMLConverter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/topcased/java/reverse/JavaAnnotaions2UMLConverter.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,525 @@
+/*******************************************************************************
+ * Copyright (c) 2006 David Sciamma. All rights reserved. This program and the
+ * accompanying materials are made available under the terms of the Eclipse
+ * Public License v1.0 which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *   David Sciamma - initial API and implementation 
+ *   Urs Zeidler   - annotations to stereotypes introduced     
+ ******************************************************************************/
+package org.topcased.java.reverse;
+
+import java.lang.annotation.ElementType;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.common.util.WrappedException;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMemberValuePair;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.EnumerationLiteral;
+import org.eclipse.uml2.uml.InstanceValue;
+import org.eclipse.uml2.uml.Interface;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Namespace;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.Profile;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Stereotype;
+import org.eclipse.uml2.uml.Type;
+import org.eclipse.uml2.uml.UMLFactory;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.eclipse.uml2.uml.VisibilityKind;
+import org.eclipse.uml2.uml.resource.UMLResource;
+
+/**
+ * 
+ * JavaAnnotaions2UMLConverter, creates a profile from the annotations defined in the java code.
+ * 
+ */
+public class JavaAnnotaions2UMLConverter extends AbstractJava2UMLConverter
+{
+    private Model umlMetamodel;
+
+    private Profile profile;
+
+    /**
+     * a hard coded flag to use the simple names(because it is set to false), not an other mechanism (which dosen't
+     * exist) to locate the stereotype
+     */
+    private boolean useQualifiedName = false;
+
+    /**
+     * 
+     * process all types
+     * 
+     * @param packageObject
+     * @param types
+     * @throws JavaModelException
+     */
+    protected void processTypes(Namespace packageObject, IType[] types) throws JavaModelException
+    {
+        for (int j = 0; j < types.length; j++)
+        {
+            IType type = types[j];
+
+            IType[] innerTypes = type.getTypes();
+            if (innerTypes.length == 0)
+            {
+                createTypeInProfile(packageObject, type);
+            }
+            else
+            {
+                Classifier classifier = null;
+                classifier = createTypeInProfile(packageObject, type);
+
+                if (classifier != null)
+                    processTypes(classifier, innerTypes);
+            }
+        }
+    }
+
+    /**
+     * Creates a stereotype or an enumeration.
+     * 
+     * @param packageObject
+     * @param type
+     * @return
+     * @throws JavaModelException
+     */
+    private Classifier createTypeInProfile(Namespace packageObject, IType type) throws JavaModelException
+    {
+        if (type.isInterface() && type.isAnnotation())
+        {
+            Stereotype stereotype = UMLFactory.eINSTANCE.createStereotype();
+            stereotype.setName(type.getElementName());
+            update(stereotype, type.getFlags());
+            addToContainment(packageObject, stereotype);
+            return stereotype;
+
+        }
+        else if (type.isEnum())
+        {
+            Enumeration enumeration = UMLFactory.eINSTANCE.createEnumeration();
+            enumeration.setName(type.getElementName());
+            update(enumeration, type.getFlags());
+            addToContainment(packageObject, enumeration);
+            return enumeration;
+        }
+
+        return null;
+
+    }
+
+    /**
+     * Create the extension for a stereotype.
+     * 
+     * @param annotation
+     * @param stereotype
+     * @throws JavaModelException
+     */
+    private void createExtension(IAnnotation annotation, Stereotype stereotype) throws JavaModelException
+    {
+        if (annotation.getElementName().equals("Target") || annotation.getElementName().equals("java.lang.annotation.Target"))
+        {
+            IMemberValuePair[] memberValuePairs = annotation.getMemberValuePairs();
+
+            for (int i = 0; i < memberValuePairs.length; i++)
+            {
+                IMemberValuePair memberValuePair = memberValuePairs[i];
+                Object[] values;
+                if (memberValuePair.getValue() instanceof String)
+                {
+                    values = new Object[] {memberValuePair.getValue()};
+                }
+                else
+                    values = (Object[]) memberValuePair.getValue();
+
+                for (int j = 0; j < values.length; j++)
+                {
+
+                    String value = (String) values[j];
+                    ElementType elementType = ElementType.valueOf(value.substring(value.indexOf('.') + 1, value.length()));
+                    Class metaclass = null;
+                    switch (elementType)
+                    {
+                        case TYPE:
+                            metaclass = createClassifierReference("Classifier");
+                            break;
+                        case FIELD:
+                            metaclass = createClassifierReference("Property");
+                            break;
+                        case METHOD:
+                            metaclass = createClassifierReference("Operation");
+                            break;
+                        case PARAMETER:
+                            metaclass = createClassifierReference("Parameter");
+                            break;
+                        case PACKAGE:
+                            metaclass = createClassifierReference("Package");
+                            break;
+                        default:
+                            break;
+                    }
+
+                    if (metaclass != null)
+                        stereotype.createExtension(metaclass, false);
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Creates a metaclassreference in the profile.
+     * 
+     * @param metaClassName
+     * @return
+     */
+    private Class createClassifierReference(String metaClassName)
+    {
+        Class metaclass = (Class) umlMetamodel.getOwnedType(metaClassName);
+
+        profile.getMetaclassReference(metaclass, true);
+        return metaclass;
+    }
+
+    private void createSteteotypeProperties(IType type, Stereotype stereotype) throws JavaModelException
+    {
+        IMethod[] methods = type.getMethods();
+
+        for (int k = 0; k < methods.length; k++)
+        {
+            IMethod method = methods[k];
+            if (!method.isConstructor())
+            {
+                Property propertyObject = createProperty(stereotype, method);
+                stereotype.getOwnedAttributes().add(propertyObject);
+            }
+        }
+    }
+
+    /**
+     * Create the properties of the stereotypes, they are methods in the IType, because the annotation is an interface.
+     * 
+     * @param element
+     * @param method
+     * @return
+     * @throws JavaModelException
+     */
+    protected Property createProperty(Stereotype element, IMethod method) throws JavaModelException
+    {
+        String fieldName = method.getElementName();
+        String fieldTypeSig = method.getReturnType();
+        IMemberValuePair defaultValue = method.getDefaultValue();
+
+        int arrayCount = Signature.getArrayCount(fieldTypeSig);
+        String fieldTypeWithoutArray = Signature.getElementType(fieldTypeSig);
+        String fieldTypeName = Signature.toString(Signature.getTypeErasure(fieldTypeWithoutArray));
+        Type fieldType = findTemplateParameter(element, fieldTypeName);
+        if (fieldType == null)
+            fieldType = findOrCreateType(element.getNearestPackage(), fieldTypeName);
+
+        Property propertyObject = UMLFactory.eINSTANCE.createProperty();
+        propertyObject.setName(fieldName);
+        if (fieldType != null)
+        {
+            propertyObject.setType(fieldType);
+        }
+
+        if (defaultValue != null)
+        {
+            InstanceValue value;
+            switch (defaultValue.getValueKind())
+            {
+                case IMemberValuePair.K_STRING:
+                    propertyObject.setDefault((String) defaultValue.getValue());
+                    break;
+                case IMemberValuePair.K_CLASS:
+                    propertyObject.setDefault((String) defaultValue.getValue());
+                    break;
+                case IMemberValuePair.K_BOOLEAN:
+                    propertyObject.setBooleanDefaultValue((Boolean) defaultValue.getValue());
+                    break;
+                case IMemberValuePair.K_INT:
+                    propertyObject.setIntegerDefaultValue((Integer) defaultValue.getValue());
+                    break;
+                case IMemberValuePair.K_QUALIFIED_NAME:
+                    String qname = (String) defaultValue.getValue();
+                    String name = qname.substring(0, qname.indexOf('.'));
+                    Type type = findType(element.getNearestPackage(), name);
+                    Enumeration enu = (Enumeration) type;
+                    String lit = qname.substring(qname.indexOf('.') + 1);
+                    EnumerationLiteral ownedLiteral = enu.getOwnedLiteral(lit, true, true);
+                    value = UMLFactory.eINSTANCE.createInstanceValue();
+                    value.setInstance(ownedLiteral);
+                    propertyObject.setDefaultValue(value);
+                    break;
+                case IMemberValuePair.K_SIMPLE_NAME:
+                    // String qname = (String) defaultValue.getValue();
+                    // String name = qname.substring(0,qname.indexOf('.'));
+                    // Type type = findType(element.getNearestPackage(), name);
+                    // Enumeration enu = (Enumeration)type;
+                    // String lit = qname.substring(qname.indexOf('.')+1);
+                    // EnumerationLiteral ownedLiteral = enu.getOwnedLiteral(lit, true, true);
+                    // value = UMLFactory.eINSTANCE.createInstanceValue();
+                    // value.setInstance(ownedLiteral);
+                    // propertyObject.setDefaultValue(value );
+
+                    // TODO : handle enums by name
+                    // propertyObject.setIntegerDefaultValue((Integer)
+                    // defaultValue.getValue());
+                    break;
+                case IMemberValuePair.K_UNKNOWN:
+                    // TODO : this could be an array of the type so need to check
+                    // the type
+                    // propertyObject.setIntegerDefaultValue((Integer)
+                    // defaultValue.getValue());
+                    break;
+
+                default:
+                    break;
+            }
+        }
+
+        // TODO : we need to handle multi dim arrays but how define them in UML ?
+        if (arrayCount == 1)
+        {
+            propertyObject.setLower(0);
+            propertyObject.setUpper(-1);
+        }
+        update(propertyObject, method.getFlags());
+
+        return propertyObject;
+    }
+
+    /**
+     * Creates the Java Primitive Types.<br>
+     * We could also import these Primitive Types from the UML2 Java Library but this solution is lighter. Loads the
+     * umlMetamodel.
+     * 
+     * @param model the UML2 model to update
+     * @throws CoreException
+     */
+    protected void initializeModel(Package model) throws CoreException
+    {
+        try
+        {
+            umlMetamodel = (Model) loadUML2Model(URI.createURI(UMLResource.UML_METAMODEL_URI));
+        }
+        catch (Exception e)
+        {
+            throwCoreException(e.getMessage());
+        }
+
+        if (importList != null)
+            if (importList.length > 0)
+            {
+                for (int i = 0; i < importList.length; i++)
+                {
+                    String im = importList[i];
+                    try
+                    {
+
+                        URI uri = URI.createFileURI(im);
+                        uri = URI.createPlatformResourceURI(im);
+                        ResourceSet RESOURCE_SET = new ResourceSetImpl();
+
+                        Package package1 = null;
+
+                        try
+                        {
+                            Resource resource = RESOURCE_SET.getResource(uri, true);
+
+                            package1 = (org.eclipse.uml2.uml.Package) EcoreUtil.getObjectByType(resource.getContents(), UMLPackage.eINSTANCE.getPackage());
+
+                        }
+                        catch (WrappedException we)
+                        {
+                            throwCoreException(we.getMessage());
+                        }
+
+                        model.createPackageImport(package1, VisibilityKind.PUBLIC_LITERAL);
+
+                    }
+                    catch (Exception e)
+                    {
+                        throwCoreException(e.getMessage());
+                    }
+                }
+
+            }
+            else
+            {
+                // we create only the primitive types
+                if (model.getOwnedType("boolean") == null)
+                {
+                    model.createOwnedPrimitiveType("boolean");
+                }
+                if (model.getOwnedType("byte") == null)
+                {
+                    model.createOwnedPrimitiveType("byte");
+                }
+                if (model.getOwnedType("char") == null)
+                {
+                    model.createOwnedPrimitiveType("char");
+                }
+                if (model.getOwnedType("double") == null)
+                {
+                    model.createOwnedPrimitiveType("double");
+                }
+                if (model.getOwnedType("float") == null)
+                {
+                    model.createOwnedPrimitiveType("float");
+                }
+                if (model.getOwnedType("int") == null)
+                {
+                    model.createOwnedPrimitiveType("int");
+                }
+                if (model.getOwnedType("long") == null)
+                {
+                    model.createOwnedPrimitiveType("long");
+                }
+                if (model.getOwnedType("short") == null)
+                {
+                    model.createOwnedPrimitiveType("short");
+                }
+            }
+    }
+
+    /**
+     * Creates a profile and at it to the resource.
+     * 
+     * @see org.topcased.java.reverse.AbstractJava2UMLConverter#createRootPackage()
+     */
+    @Override
+    protected Package createRootPackage()
+    {
+        {
+            profile = UMLFactory.eINSTANCE.createProfile();
+            profile.setName(modelName);
+            emfResource.getContents().add(profile);
+            return profile;
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.topcased.java.reverse.AbstractJava2UMLConverter#initializeTypes(org.eclipse.uml2.uml.Package,
+     * org.eclipse.jdt.core.IPackageFragment)
+     */
+    protected void initializeTypes(Package packageObject, IPackageFragment fragment) throws JavaModelException
+    {
+        IJavaElement[] children = fragment.getChildren();
+        for (int i = 0; i < children.length; i++)
+        {
+            if (children[i] instanceof ICompilationUnit)
+            {
+                ICompilationUnit unit = (ICompilationUnit) children[i];
+                IType[] types = unit.getAllTypes();
+                for (int j = 0; j < types.length; j++)
+                {
+                    IType type = types[j];
+                    String typeName = type.getElementName();
+                    NamedElement element = packageObject.getOwnedMember(typeName);
+                    if (element == null && type.getParent() != null)
+                        element = findInnerType(packageObject, type, typeName);
+
+                    if (element instanceof Enumeration)
+                    {
+                        Enumeration enumeration = (Enumeration) element;
+
+                        String[] superInterfaces = type.getSuperInterfaceNames();
+                        for (int k = 0; k < superInterfaces.length; k++)
+                        {
+                            String interfaceName = superInterfaces[k];
+                            Type interfaceType = findType(packageObject, interfaceName);
+                            if (interfaceType == null)
+                                interfaceType = findGenericType(packageObject, interfaceName);
+
+                            if (interfaceType == null && type.getParent() != null)
+                                interfaceType = findInnerType(packageObject, type, typeName);
+
+                            if (interfaceType != null && interfaceType instanceof Interface)
+                            {
+                                enumeration.createGeneralization((Classifier) interfaceType);
+                            }
+                        }
+                        // Inner objects
+                        createProperties(type, enumeration);
+                        createOperations(type, enumeration);
+
+                    }
+                    if (element instanceof Stereotype)
+                    {
+                        System.out.println(fragment.getElementName() + "." + typeName);
+                        Stereotype stereotype = (Stereotype) element;
+                        // createProperties(type, stereotype);
+                        IAnnotation[] annotations = type.getAnnotations();
+                        for (IAnnotation annotation : annotations)
+                        {
+                            // System.out.println();
+                            String qualifiedName = fragment.getElementName();
+                            if (useQualifiedName)
+                                stereotype.setName(fragment.getElementName() + "." + typeName);
+
+                            createExtension(annotation, stereotype);
+                            String elementName = annotation.getElementName();
+                        }
+                        createSteteotypeProperties(type, stereotype);
+
+                        // Generalization
+                        String superClassName = type.getSuperclassName();
+                        Type classType = findType(packageObject, superClassName);
+                        if (classType == null && type.getParent() != null)
+                            classType = findInnerType(packageObject, type, typeName);
+
+                        if (classType == null)
+                            classType = findOrCreateType(packageObject, superClassName);
+
+                        if (classType != null && classType instanceof Classifier)
+                        {
+                            stereotype.createGeneralization((Classifier) classType);
+                        }
+
+                    }// end of if (element instanceof Stereotype)
+                }
+            }
+        }
+    }
+
+    /**
+     * because the profile import is not package aware, we return it self.
+     */
+    protected Package findOrCreatePackage(Package model, IPackageFragment fragment)
+    {
+        return model;
+    }
+
+    /**
+     * Refines the profile.
+     */
+    @Override
+    protected void postProcess(Package model)
+    {
+        profile.define();
+
+    }
+
+}
Index: src/org/topcased/java/reverse/AbstractJava2UMLConverter.java
===================================================================
RCS file: src/org/topcased/java/reverse/AbstractJava2UMLConverter.java
diff -N src/org/topcased/java/reverse/AbstractJava2UMLConverter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/topcased/java/reverse/AbstractJava2UMLConverter.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,1120 @@
+/*******************************************************************************
+ * Copyright (c) 2008 David Sciamma. All rights reserved. This program and the
+ * accompanying materials are made available under the terms of the Eclipse
+ * Public License v1.0 which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *   David Sciamma - initial API and implementation 
+ *   Urs Zeidler   - refactored and and added some basic methods
+ ******************************************************************************/
+
+package org.topcased.java.reverse;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.common.util.WrappedException;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.uml2.uml.Association;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.ClassifierTemplateParameter;
+import org.eclipse.uml2.uml.DataType;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.Interface;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Namespace;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.PackageableElement;
+import org.eclipse.uml2.uml.Parameter;
+import org.eclipse.uml2.uml.ParameterableElement;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.StructuredClassifier;
+import org.eclipse.uml2.uml.TemplateParameter;
+import org.eclipse.uml2.uml.TemplateSignature;
+import org.eclipse.uml2.uml.Type;
+import org.eclipse.uml2.uml.UMLFactory;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.eclipse.uml2.uml.VisibilityKind;
+import org.topcased.java.reverse.internal.ReversePlugin;
+
+/**
+ * the basic converter class defines a basic converting flow and provides support methods
+ */
+public abstract class AbstractJava2UMLConverter
+{
+    /**
+     * a list of model uris
+     */
+    protected String[] importList;
+
+    protected Resource emfResource;
+
+    protected String modelName;
+
+    public AbstractJava2UMLConverter()
+    {
+        super();
+    }
+
+    /**
+     * set the list of uris to import
+     * 
+     * @param importList
+     */
+    public void setImportList(String[] importList)
+    {
+        this.importList = importList;
+
+    }
+
+    /**
+     * Convert an Package or a Java project into a UML2 model
+     * 
+     * @param javaElement the JavaElement
+     * @return The UML2 model or <code>null</code> if the IJavaElement is not a Package or a Java Project.
+     * @throws CoreException, if the resource is null or some critical error occur while importing.
+     */
+    protected Package convert(IJavaElement javaElement) throws CoreException
+    {
+        if (emfResource == null)
+            throwCoreException("The resource can't be null.");
+
+        switch (javaElement.getElementType())
+        {
+            case IJavaElement.JAVA_PROJECT:
+                return doConvertion((IJavaProject) javaElement);
+            case IJavaElement.PACKAGE_FRAGMENT:
+                return doConvertion((IPackageFragment) javaElement);
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Convert an Package or a Java project into a UML2 profile
+     * 
+     * @param javaElement the JavaElement
+     * @return The UML2 model or <code>null</code> if the IJavaElement is not a Package or a Java Project.
+     * @throws CoreException
+     */
+    protected Package convert2Profile(IJavaElement javaElement) throws CoreException
+    {
+        return convert(javaElement);
+    }
+
+    /**
+     * Convert a Java Package Fragment into a UML2 PAckage and update the given UML2 Model
+     * 
+     * @param model The UML2 model where the Package must be inserted
+     * @param fragment the Package Fragment
+     * @return The updated UML2 model.
+     * @throws CoreException
+     */
+    protected Model convert(Model model, IPackageFragment fragment) throws CoreException
+    {
+        initializeModel(model);
+
+        Package packageObject = findOrCreatePackage(model, fragment);
+
+        createTypes(packageObject, fragment);
+        initializeTypes(packageObject, fragment);
+        createAssociations(packageObject);
+
+        return model;
+    }
+
+    protected abstract void initializeTypes(Package packageObject, IPackageFragment fragment) throws JavaModelException;
+
+    /**
+     * 
+     * process all types
+     * 
+     * @param packageObject
+     * @param types
+     * @throws JavaModelException
+     */
+    protected abstract void processTypes(Namespace packageObject, IType[] types) throws JavaModelException;
+
+    /**
+     * creates the root package
+     * 
+     * @return
+     */
+    protected abstract Package createRootPackage();
+
+    /**
+     * Creates the necessary resources to process the import, like creating of imports or loading the UML metamodel.
+     * 
+     * @param model
+     * @throws CoreException
+     */
+    protected abstract void initializeModel(Package model) throws CoreException;
+
+    /**
+     * Convert a Java project into a UML2 model
+     * 
+     * @param project the Java Project
+     * @return The UML2 model.
+     * @throws CoreException
+     */
+    private Package doConvertion(IJavaProject project) throws CoreException
+    {
+        Package model = createRootPackage();
+
+        initializeModel(model);
+
+        IPackageFragment[] children = project.getPackageFragments();
+        for (int i = 0; i < children.length; i++)
+        {
+            IPackageFragment fragment = children[i];
+            if (fragment.getCompilationUnits().length > 0)
+            {
+                Package packageObject = findOrCreatePackage(model, fragment);
+                createTypes(packageObject, fragment);
+            }
+        }
+
+        for (int i = 0; i < children.length; i++)
+        {
+            IPackageFragment fragment = children[i];
+            if (fragment.getCompilationUnits().length > 0)
+            {
+                Package packageObject = findOrCreatePackage(model, fragment);
+                initializeTypes(packageObject, fragment);
+            }
+        }
+
+        for (int i = 0; i < children.length; i++)
+        {
+            IPackageFragment fragment = children[i];
+            if (fragment.getCompilationUnits().length > 0)
+            {
+                Package packageObject = findOrCreatePackage(model, fragment);
+                createAssociations(packageObject);
+            }
+        }
+
+        postProcess(model);
+        return model;
+
+    }
+
+    /**
+     * Convert a Java project into a UML2 model
+     * 
+     * @param packageModel the Java Package
+     * @return The UML2 model.
+     * @throws CoreException
+     */
+    private Model doConvertion(IPackageFragment packageModel) throws CoreException
+    {
+        Model model = UMLFactory.eINSTANCE.createModel();
+        convert(model, packageModel);
+        postProcess(model);
+        return model;
+    }
+
+    /**
+     * After the import is finished, some things need to be done, like define the profile.
+     * 
+     * @param model
+     */
+    protected abstract void postProcess(Package model);
+
+    /**
+     * finds or create a package in the model for the fragment
+     * 
+     * @param model
+     * @param fragment
+     * @return
+     */
+    protected Package findOrCreatePackage(Package model, IPackageFragment fragment)
+    {
+        String qualifiedName = fragment.getElementName();
+
+        // Creates recursively the hierarchy of packages
+        StringTokenizer tokenizer = new StringTokenizer(qualifiedName, ".");
+        Package parent = model;
+        Package packageObject = model;
+        while (tokenizer.hasMoreTokens())
+        {
+            String packageName = tokenizer.nextToken();
+            packageObject = parent.getNestedPackage(packageName);
+            if (packageObject == null)
+            {
+                packageObject = parent.createNestedPackage(packageName);
+            }
+            parent = packageObject;
+        }
+
+        return packageObject;
+    }
+
+    /**
+     * loads an uml model from the uri
+     * 
+     * @param uri
+     * @return
+     */
+    protected org.eclipse.uml2.uml.Package loadUML2Model(URI uri)
+    {
+
+        ResourceSet RESOURCE_SET = new ResourceSetImpl();
+
+        org.eclipse.uml2.uml.Package package_ = null;
+
+        try
+        {
+            Resource resource = RESOURCE_SET.getResource(uri, true);
+
+            package_ = (org.eclipse.uml2.uml.Package) EcoreUtil.getObjectByType(resource.getContents(), UMLPackage.eINSTANCE.getPackage());
+
+        }
+        catch (WrappedException we)
+        {
+            // LOGGER.error(we);
+        }
+        return package_;
+    }
+
+    /**
+     * Find a type in a package, checks the package, in all other packages, in all imported packages. Finally test if it
+     * is a generic type.
+     * 
+     * @param packageObject
+     * @param typeName
+     * @return can return null, if nothing is found
+     */
+    protected Type findType(Package packageObject, String typeName)
+    {
+        Type type = null;
+        if (typeName != null)
+        {
+            NamedElement element = packageObject.getMember(typeName);
+            if (element instanceof Type)
+            {
+                type = (Type) element;
+            }
+
+            // TODO : another way to get the root package
+            Package model = packageObject.getModel();
+            if (model == null)
+                model = (Package) findRootPackage(packageObject);
+            if (model == null)
+                return null;
+
+            if (type == null)
+            {
+                type = findType(model, typeName, true);
+            }
+            if (type == null)
+            {
+                type = findinImportPackages(model, typeName);
+            }
+            if (type == null)
+            {
+                type = findGenericType(model, typeName);
+            }
+
+        }
+        return type;
+    }
+
+    /**
+     * A lookup for the root package.
+     * 
+     * @param packageObject
+     * @return
+     */
+    protected Package findRootPackage(Package packageObject)
+    {
+        Package parentPackage = (Package) packageObject.getOwner();
+        // it is the root package so we return it
+        if (parentPackage == null)
+            return packageObject;
+
+        while (parentPackage.getOwner() != null)
+            parentPackage = (Package) parentPackage.getOwner();
+
+        return parentPackage;
+    }
+
+    /**
+     * Checks the model imports for a type.
+     * 
+     * @param model
+     * @param typeName
+     * @return
+     */
+    private Type findinImportPackages(Package model, String typeName)
+    {
+        if ("void".equals(typeName))
+            return null;
+
+        PackageableElement importedMember = model.getImportedMember(typeName);
+        if (importedMember instanceof Type)
+        {
+            Type type = (Type) importedMember;
+            return type;
+        }// end of if (importedMember instanceof Type)
+
+        EList<Package> importedPackages = model.getImportedPackages();
+        for (Package package1 : importedPackages)
+        {
+            Type type = findType(package1, typeName, true);
+            if (type != null)
+                return type;
+        }
+        // model.getImportedMembers();
+
+        return null;
+    }
+
+    /**
+     * Find a type in the package or a subpackage.
+     * 
+     * @param packageObject
+     * @param typeName
+     * @param deep - proceed subpackages
+     * @return
+     */
+    protected Type findType(Package packageObject, String typeName, boolean deep)
+    {
+        Type type = null;
+        if (typeName != null)
+        {
+            NamedElement element = packageObject.getMember(typeName);
+            if (element instanceof Type)
+            {
+                type = (Type) element;
+            }
+
+            if (type == null && deep)
+            {
+                Iterator<PackageableElement> it = packageObject.getPackagedElements().iterator();
+                while (it.hasNext() && type == null)
+                {
+                    PackageableElement child = it.next();
+                    if (child instanceof Package)
+                    {
+                        type = findType((Package) child, typeName, true);
+                    }
+                }
+            }
+        }
+        return type;
+    }
+
+    /**
+     * Finds a type or creates it.
+     * 
+     * @param packageObject
+     * @param typeName
+     * @return
+     */
+    protected Type findOrCreateType(Package packageObject, String typeName)
+    {
+        Type type = findType(packageObject, typeName);
+
+        if (typeName != null && !"void".equals(typeName))
+        {
+            if (type == null)
+            {
+                DataType dataType = UMLFactory.eINSTANCE.createDataType();
+                dataType.setName(typeName);
+
+                packageObject.getPackagedElements().add(dataType);
+
+                type = dataType;
+            }
+        }
+        return type;
+    }
+
+    /**
+     * Looks up an inner type.
+     * 
+     * @param packageObject
+     * @param type
+     * @param typeName
+     * @param element
+     * @return - can return null
+     */
+    protected Type findInnerType(Package packageObject, IType type, String typeName)
+    {
+        Type dataType = null;
+        if (type.getParent().getElementType() == IJavaElement.TYPE)
+        {
+            NamedElement member = packageObject.getOwnedMember(type.getParent().getElementName());
+            if (member instanceof Classifier)
+            {
+                Classifier classifier = (Classifier) member;
+                NamedElement element = classifier.getOwnedMember(typeName);
+                if (element instanceof Type)
+                {
+                    dataType = (Type) element;
+                }// end of if (element instanceof )
+
+            }// end of if (member instanceof Classifier)
+        }
+        return dataType;
+    }
+
+    /**
+     * looks for a generic type
+     * 
+     * @param packageObject
+     * @param interfaceName
+     * @return
+     */
+    protected Type findGenericType(Package packageObject, String interfaceName)
+    {
+        int indexOf = interfaceName.indexOf('<');
+        if (indexOf > 0)
+        {
+            String name = interfaceName.substring(0, indexOf);
+            return findType(packageObject, name, true);
+        }
+        return null;
+    }
+
+    /**
+     * Creates the associations for the types in the package.
+     * 
+     * @param packageObject
+     * @throws JavaModelException
+     */
+    protected void createAssociations(Package packageObject) throws JavaModelException
+    {
+        List workingCopy = new ArrayList(packageObject.getPackagedElements());
+        Iterator itType = workingCopy.iterator();
+        while (itType.hasNext())
+        {
+            PackageableElement element = (PackageableElement) itType.next();
+            if (element instanceof Interface)
+            {
+                Interface interfaceObject = (Interface) element;
+                Iterator<Property> itProp = interfaceObject.getOwnedAttributes().iterator();
+                while (itProp.hasNext())
+                {
+                    Property property = itProp.next();
+                    Type targetType = property.getType();
+                    if (targetType instanceof StructuredClassifier || targetType instanceof Interface)
+                        if (!(targetType.getOwner() instanceof TemplateParameter))
+                        {
+                            createAssociation(property);
+                        }
+                }
+            }
+            if (element instanceof StructuredClassifier)
+            {
+                StructuredClassifier classifierObject = (StructuredClassifier) element;
+                Iterator itProp = classifierObject.getOwnedAttributes().iterator();
+                while (itProp.hasNext())
+                {
+                    Property property = (Property) itProp.next();
+                    Type targetType = property.getType();
+                    if ((targetType instanceof StructuredClassifier || targetType instanceof Interface))
+                        if (!(targetType.getOwner() instanceof TemplateParameter))
+                        {
+                            createAssociation(property);
+                        }
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates an association between the owner of the property and the type.
+     * 
+     * @param property
+     */
+    protected void createAssociation(Property property)
+    {
+        if (property.getAssociation() == null)
+        {
+            Property opposite = foundOpposite(property);
+            Element propOwner = property.getOwner();
+            if (opposite != null)
+            {
+                Association association = UMLFactory.eINSTANCE.createAssociation();
+                association.getMemberEnds().add(property);
+                association.getMemberEnds().add(opposite);
+
+                property.getNearestPackage().getPackagedElements().add(association);
+            }
+            else
+            {
+                Association association = UMLFactory.eINSTANCE.createAssociation();
+                association.getMemberEnds().add(property);
+                Property createdOpposite = association.createOwnedEnd("target", (Type) propOwner);
+
+                property.getNearestPackage().getPackagedElements().add(association);
+            }
+        }
+    }
+
+    protected Property foundOpposite(Property source)
+    {
+        Property target = null;
+
+        Type propType = source.getType();
+        Element propOwner = source.getOwner();
+        if (propType instanceof StructuredClassifier || propType instanceof Interface)
+        {
+            // Search if the property type has a property of the type of
+            // propOwner
+            List properties = null;
+            if (propType instanceof StructuredClassifier)
+            {
+                properties = ((StructuredClassifier) propType).getOwnedAttributes();
+            }
+            if (propType instanceof Interface)
+            {
+                properties = ((Interface) propType).getOwnedAttributes();
+            }
+
+            Iterator it = properties.iterator();
+            while (it.hasNext() && target == null)
+            {
+                Property prop = (Property) it.next();
+                // Check that is a different property
+                if (prop != source && propOwner.equals(prop.getType()))
+                {
+                    target = prop;
+                }
+            }
+        }
+
+        return target;
+    }
+
+    /**
+     * Creates the types of the fragment in the package.
+     * 
+     * @param packageObject
+     * @param fragment
+     * @throws JavaModelException
+     */
+    protected void createTypes(Package packageObject, IPackageFragment fragment) throws JavaModelException
+    {
+        IJavaElement[] children = fragment.getChildren();
+        for (int i = 0; i < children.length; i++)
+        {
+            if (children[i] instanceof ICompilationUnit)
+            {
+                ICompilationUnit unit = (ICompilationUnit) children[i];
+                IType[] types = unit.getTypes();
+
+                processTypes(packageObject, types);
+            }
+        }
+    }
+
+    /**
+     * Creates a type (class, enumeration, interface) in the package.
+     * 
+     * @param packageObject
+     * @param type
+     * @return
+     * @throws JavaModelException
+     */
+    protected Classifier createTypeInPackage(Namespace packageObject, IType type) throws JavaModelException
+    {
+
+        if (type.isInterface())
+        {
+            Interface interfaceObject = UMLFactory.eINSTANCE.createInterface();
+            if (type.isAnnotation())
+            {
+                interfaceObject.setName("@" + type.getElementName());
+
+            }
+            else
+                interfaceObject.setName(type.getElementName());
+
+            createTemplateParameters(type, interfaceObject);
+
+            update(interfaceObject, type.getFlags());
+            addToContainment(packageObject, interfaceObject);
+            return interfaceObject;
+
+        }
+        if (type.isEnum())
+        {
+            Enumeration enumeration = UMLFactory.eINSTANCE.createEnumeration();
+            enumeration.setName(type.getElementName());
+            update(enumeration, type.getFlags());
+            addToContainment(packageObject, enumeration);
+            return enumeration;
+        }
+
+        Class classObject = UMLFactory.eINSTANCE.createClass();
+        classObject.setName(type.getElementName());
+        createTemplateParameters(type, classObject);
+
+        update(classObject, type.getFlags());
+        addToContainment(packageObject, classObject);
+        // packageObject.getMembers().add(classObject);
+        return classObject;
+
+    }
+
+    /**
+     * Creates a template parameter for a classifier (a generic).
+     * 
+     * @param type
+     * @param classObject
+     * @throws JavaModelException
+     */
+    protected void createTemplateParameters(IType type, Classifier classObject) throws JavaModelException
+    {
+        ITypeParameter[] typeParameters = type.getTypeParameters();
+        if (typeParameters.length > 0)
+        {
+            TemplateSignature templateSignature = classObject.createOwnedTemplateSignature();
+
+            for (int i = 0; i < typeParameters.length; i++)
+            {
+                ITypeParameter typeParameter = typeParameters[i];
+                ClassifierTemplateParameter classifierTemplateParameter = UMLFactory.eINSTANCE.createClassifierTemplateParameter();
+                templateSignature.getOwnedParameters().add(classifierTemplateParameter);
+
+                ParameterableElement parameteredElement = classifierTemplateParameter.createOwnedParameteredElement(UMLPackage.Literals.CLASS);
+                if (parameteredElement instanceof Class)
+                {
+                    Class clazz = (Class) parameteredElement;
+                    clazz.setName(typeParameter.getElementName());
+                }// end of if (parameteredElement instanceof Class)
+            }
+        }
+    }
+
+    /**
+     * Adds a classifier to it containment feature.
+     * 
+     * @param packageObject
+     * @param classifierObject
+     */
+    protected void addToContainment(Namespace packageObject, Classifier classifierObject)
+    {
+        if (packageObject instanceof Package)
+        {
+            Package po = (Package) packageObject;
+            po.getPackagedElements().add(classifierObject);
+            return;
+        }// end of if (packageObject instanceof Package)
+        if (packageObject instanceof Class)
+        {
+            Class clazz = (Class) packageObject;
+            clazz.getNestedClassifiers().add(classifierObject);
+            return;
+        }// end of if (packageObject instanceof Class)
+        if (packageObject instanceof Interface)
+        {
+            Interface i = (Interface) packageObject;
+            i.getNestedClassifiers().add(classifierObject);
+            return;
+        }// end of if (packageObject instanceof Class)
+
+    }
+
+    /**
+     * Looks up a template parameter in an element.
+     * 
+     * @param element
+     * @param fieldName
+     * @return
+     */
+    protected Type findTemplateParameter(Element element, String fieldName)
+    {
+        EList<Element> ownedElements = element.allOwnedElements();
+        for (Element element2 : ownedElements)
+        {
+
+            if (element2 instanceof Classifier)
+            {
+                Classifier classifier = (Classifier) element2;
+                if (classifier.getName().equals(fieldName))
+                    return classifier;
+            }// end of if (element2 instanceof Classifier)
+
+            if (element2 instanceof Operation)
+            {
+                Operation operation = (Operation) element2;
+
+            }// end of if (element2 instanceof Operation)
+        }
+        return null;
+    }
+
+    /**
+     * Update the visiblilty.
+     * 
+     * @param element
+     * @param flags
+     * @throws JavaModelException
+     */
+    protected void update(NamedElement element, int flags) throws JavaModelException
+    {
+        // TODO : the java spec stated that interfaces methods has the same visiblity as the interface if not specified
+        if (Flags.isPrivate(flags))
+        {
+            element.setVisibility(VisibilityKind.PRIVATE_LITERAL);
+        }
+        else if (Flags.isProtected(flags))
+        {
+            element.setVisibility(VisibilityKind.PROTECTED_LITERAL);
+        }
+        else if (Flags.isPublic(flags))
+        {
+            element.setVisibility(VisibilityKind.PUBLIC_LITERAL);
+        }
+        else if (Flags.isPackageDefault(flags))
+        {
+            element.setVisibility(VisibilityKind.PACKAGE_LITERAL);
+        }
+    }
+
+    /**
+     * Returns the simple name of a fragment.
+     * 
+     * @param fragment
+     * @return
+     */
+    protected String getName(IPackageFragment fragment)
+    {
+        String name = "";
+        String fullName = fragment.getElementName();
+        int dotIndex = fullName.lastIndexOf('.');
+        if (dotIndex > 0)
+        {
+            name = fullName.substring(dotIndex + 1);
+        }
+
+        return name;
+    }
+
+    /**
+     * Creates operations for enumerations.
+     * 
+     * @param type
+     * @param enumeration
+     * @throws JavaModelException
+     */
+    protected void createOperations(IType type, Enumeration enumeration) throws JavaModelException
+    {
+        IMethod[] methods = type.getMethods();
+        for (int k = 0; k < methods.length; k++)
+        {
+            IMethod method = methods[k];
+            if (!method.isConstructor())
+            {
+                Operation operationObject = createOperation(enumeration, method);
+                enumeration.getOwnedOperations().add(operationObject);
+            }
+        }
+
+    }
+
+    /**
+     * Creates the properties for an enumeration.
+     * 
+     * @param type
+     * @param enumeration
+     * @throws JavaModelException
+     */
+    protected void createProperties(IType type, Enumeration enumeration) throws JavaModelException
+    {
+        IField[] fields = type.getFields();
+        for (int k = 0; k < fields.length; k++)
+        {
+            IField field = fields[k];
+            String typename = Signature.toString(Signature.getTypeErasure(Signature.getElementType(field.getTypeSignature())));
+            if (typename.equals(type.getElementName()))
+            {
+                enumeration.createOwnedLiteral(field.getElementName());
+            }
+            else
+            {
+                Property propertyObject = createProperty(enumeration, field);
+                enumeration.getOwnedAttributes().add(propertyObject);
+            }
+
+        }
+
+    }
+
+    /**
+     * Creates the methods for the classifier.
+     * 
+     * @param type
+     * @param classifier
+     * @throws JavaModelException
+     */
+    protected void createOperations(IType type, Class classifier) throws JavaModelException
+    {
+        IMethod[] methods = type.getMethods();
+        for (int k = 0; k < methods.length; k++)
+        {
+            IMethod method = methods[k];
+            if (!method.isConstructor())
+            {
+                Operation operationObject = createOperation(classifier, method);
+                classifier.getOwnedOperations().add(operationObject);
+            }
+        }
+    }
+
+    /**
+     * Create and return an operation for a type.
+     * 
+     * @param element
+     * @param method
+     * @return
+     * @throws JavaModelException
+     */
+    protected Operation createOperation(Element element, IMethod method) throws JavaModelException
+    {
+        String methodName = method.getElementName();
+
+        Operation operationObject = UMLFactory.eINSTANCE.createOperation();
+        operationObject.setName(methodName);
+
+        update(operationObject, method.getFlags());
+
+        int flags = method.getFlags();
+        operationObject.setIsAbstract(Flags.isAbstract(flags));
+        operationObject.setIsStatic(Flags.isStatic(flags));
+
+        createParameters(element, operationObject, method);
+
+        if (method.exists() && !method.isConstructor())
+        {
+            createTemplateParameters(method, operationObject);
+
+            String returnTypeSig = method.getReturnType();
+
+            String returnTypeWithoutArray = Signature.getElementType(returnTypeSig);
+            String returnTypeName = Signature.toString(Signature.getTypeErasure(returnTypeWithoutArray));
+            Type returnType = findTemplateParameter(element, returnTypeName);
+            if (returnType == null)
+                returnType = findTemplateParameter(operationObject, returnTypeName);
+
+            if (returnType == null)
+                returnType = findOrCreateType(element.getNearestPackage(), returnTypeName);
+
+            // Type returnType = findOrCreateType(element.getNearestPackage(),
+            // returnTypeName);
+            if (returnType != null)
+            {
+                operationObject.createReturnResult("return", returnType);
+            }
+        }
+
+        return operationObject;
+    }
+
+    /**
+     * Creates a template parameter for a method.
+     * 
+     * @param method
+     * @param operationObject
+     */
+    private void createTemplateParameters(IMethod method, Operation operationObject)
+    {
+        try
+        {
+            ITypeParameter[] typeParameters = method.getTypeParameters();
+            for (ITypeParameter typeParameter : typeParameters)
+            {
+                TemplateSignature templateSignature = operationObject.createOwnedTemplateSignature();
+                ClassifierTemplateParameter classifierTemplateParameter = UMLFactory.eINSTANCE.createClassifierTemplateParameter();
+                templateSignature.getOwnedParameters().add(classifierTemplateParameter);
+                ParameterableElement parameteredElement = classifierTemplateParameter.createOwnedParameteredElement(UMLPackage.Literals.CLASS);
+                if (parameteredElement instanceof Class)
+                {
+                    Class clazz = (Class) parameteredElement;
+                    clazz.setName(typeParameter.getElementName());
+                }// end of if (parameteredElement instanceof Class)
+
+            }
+
+        }
+        catch (JavaModelException e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Creates the parameters for a method.
+     * 
+     * @param element
+     * @param operation
+     * @param method
+     * @throws JavaModelException
+     */
+    protected void createParameters(Element element, Operation operation, IMethod method) throws JavaModelException
+    {
+        String[] paramNames = method.getParameterNames();
+        String[] paramTypeSigs = method.getParameterTypes();
+        for (int i = 0; i < paramNames.length; i++)
+        {
+            String name = paramNames[i];
+            String typeSig = paramTypeSigs[i];
+
+            Parameter parameter = UMLFactory.eINSTANCE.createParameter();
+            parameter.setName(name);
+
+            String typeWithoutArray = Signature.getElementType(typeSig);
+            String typeName = Signature.toString(Signature.getTypeErasure(typeWithoutArray));
+
+            Type paramType = findTemplateParameter(element, typeName);
+            if (paramType == null)
+                paramType = findOrCreateType(element.getNearestPackage(), typeName);
+
+            if (paramType != null)
+            {
+                parameter.setType(paramType);
+            }
+
+            operation.getOwnedParameters().add(parameter);
+        }
+    }
+
+    /**
+     * Creates the operations for a interface.
+     * 
+     * @param type
+     * @param interfaceObject
+     * @throws JavaModelException
+     */
+    protected void createOperations(IType type, Interface interfaceObject) throws JavaModelException
+    {
+        IMethod[] methods = type.getMethods();
+        for (int k = 0; k < methods.length; k++)
+        {
+            IMethod method = methods[k];
+            if (!method.isConstructor())
+            {
+                Operation operationObject = createOperation(interfaceObject, method);
+                interfaceObject.getOwnedOperations().add(operationObject);
+            }
+        }
+    }
+
+    /**
+     * Creates and returns a property.
+     * 
+     * @param element
+     * @param field
+     * @return
+     * @throws JavaModelException
+     */
+    protected Property createProperty(Element element, IField field) throws JavaModelException
+    {
+        String fieldName = field.getElementName();
+        String fieldTypeSig = field.getTypeSignature();
+
+        String fieldTypeWithoutArray = Signature.getElementType(fieldTypeSig);
+        String fieldTypeName = Signature.toString(Signature.getTypeErasure(fieldTypeWithoutArray));
+        Type fieldType = findTemplateParameter(element, fieldTypeName);
+        if (fieldType == null)
+            fieldType = findOrCreateType(element.getNearestPackage(), fieldTypeName);
+
+        Property propertyObject = UMLFactory.eINSTANCE.createProperty();
+        propertyObject.setName(fieldName);
+        if (fieldType != null)
+        {
+            propertyObject.setType(fieldType);
+        }
+
+        update(propertyObject, field.getFlags());
+
+        return propertyObject;
+    }
+
+    /**
+     * Creates properties in an interface.
+     * 
+     * @param type
+     * @param interfaceObject
+     * @throws JavaModelException
+     */
+    protected void createProperties(IType type, Interface interfaceObject) throws JavaModelException
+    {
+        IField[] fields = type.getFields();
+        for (int k = 0; k < fields.length; k++)
+        {
+            IField field = fields[k];
+
+            Property propertyObject = createProperty(interfaceObject, field);
+
+            interfaceObject.getOwnedAttributes().add(propertyObject);
+        }
+    }
+
+    /**
+     * Convenient method to throw a core exception.
+     * 
+     * @param message
+     * @throws CoreException
+     */
+    protected void throwCoreException(String message) throws CoreException
+    {
+        IStatus status = new Status(IStatus.ERROR, ReversePlugin.getId(), IStatus.OK, message, null);
+        throw new CoreException(status);
+    }
+
+    /**
+     * The convert method will convert all processable java elements to uml elements and store them in the resource.
+     * 
+     * @param javaElement
+     * @param emfResource
+     * @return
+     * @throws CoreException
+     */
+    public Package convert(IJavaElement javaElement, Resource emfResource) throws CoreException
+    {
+        this.emfResource = emfResource;
+        return convert(javaElement);
+    }
+
+    /**
+     * Set the model name, to the model, quite important for a profile model.
+     * 
+     * @param modelName
+     */
+    public void setModelName(String modelName)
+    {
+        this.modelName = modelName;
+
+    }
+}

