Merge remote-tracking branch 'origin/devel' into 563991-improve-checker-manager
diff --git a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/Checker.java b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/Checker.java
index 99e1cba..ad11960 100644
--- a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/Checker.java
+++ b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/Checker.java
@@ -1,10 +1,10 @@
-/*******************************************************************************

- * Copyright (C) 2020 Fondazione Bruno Kessler.

- * All rights reserved. This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License v2.0

- * which accompanies this distribution, and is available at

- * http://www.eclipse.org/legal/epl-v20.html

- ******************************************************************************/

+/*******************************************************************************
+ * Copyright (C) 2020 Fondazione Bruno Kessler.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ ******************************************************************************/
 
 package org.polarsys.chess.checkers.core.checkerManager;
 
@@ -50,10 +50,35 @@
 		checkerManager.getCheckersContainter().register(this);
 	}
 
+	/**
+	 * This contains the core of the processing. 
+	 * @param monitor
+	 * @return
+	 * @throws Exception
+	 */
 	public abstract List<CheckerMessage> check(IProgressMonitor monitor) throws Exception;
 
+	/**
+	 * This init is used when the checker runs in tests or in a synchronous way.
+	 * Checkers should use the provided package and not trying to detect the current
+	 * active project.
+	 * @param systemViewPackage the SystemView package
+	 * @throws Exception
+	 */
+	public abstract void initSync(Package systemViewPackage) throws Exception;
+
+	/**
+	 * This init is used when the checker runs in an asynchronous way. It is used
+	 * to setup variables that cannot be detected in a running environment.
+	 * @throws Exception
+	 */
 	public abstract void init() throws Exception;
 
+	/**
+	 * Runs the checker in an asynchronous way. Both init() and check() are called.
+	 * @param isFirstChecker
+	 * @throws Exception
+	 */
 	public void asyncCheck(boolean isFirstChecker) throws Exception {
 		CheckerManager checkerManager = org.polarsys.chess.checkers.Activator.getCheckerManager();
 		org.eclipse.uml2.uml.Package pack = EntityUtil.getInstance().getCurrentSystemView();
@@ -97,7 +122,7 @@
 	}
 	
 	/**
-	 * Just runs the check() method and returns the scheduled job.
+	 * Only runs the check() method and returns the scheduled job.
 	 * @param pack
 	 * @return
 	 */
@@ -191,5 +216,4 @@
 	public void addError(Exception e){
 		errors.add(e);
 	}
-}
-
+}
\ No newline at end of file
diff --git a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckerManager.java b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckerManager.java
index abd4284..46a7932 100644
--- a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckerManager.java
+++ b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckerManager.java
@@ -1,10 +1,10 @@
-/*******************************************************************************

- * Copyright (C) 2020 Fondazione Bruno Kessler.

- * All rights reserved. This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License v2.0

- * which accompanies this distribution, and is available at

- * http://www.eclipse.org/legal/epl-v20.html

- ******************************************************************************/

+/*******************************************************************************
+ * Copyright (C) 2020 Fondazione Bruno Kessler.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ ******************************************************************************/
 package org.polarsys.chess.checkers.core.checkerManager;
 
 import java.util.ArrayList;
@@ -45,6 +45,7 @@
 
 	private static final String CHECKER_NAME = "checkerName";
 	List<CheckersContainer> checkersContainers;
+	
 	List<CheckerMessage> messages;
 	HashMap<String, Boolean> checkerStatus;
 
@@ -58,6 +59,11 @@
 		// checkersContainers.add(checkersContainer);
 	}
 
+	/**
+	 * Runs the checkers in an asynchronous way.
+	 * @param selectedCheckersTags
+	 * @throws Exception
+	 */
 	public void run(Set<String> selectedCheckersTags) throws Exception {
 		logger.debug("run");
 		checkerStatus = new HashMap<String, Boolean>();
@@ -72,15 +78,16 @@
 	}
 
 	/**
-	 * Launches the init() of the various checkerContainers.
+	 * Launches the initSync() of the various CheckerContainers.
 	 * @param selectedCheckersTags
+	 * @param systemViewPackage the SystemViewPackage
 	 * @throws Exception
 	 */
-	public void initSync(Set<String> selectedCheckersTags) throws Exception {
+	public void initSync(Set<String> selectedCheckersTags, Package systemViewPackage) throws Exception {
 		logger.debug("initSync");
 		for (CheckersContainer checkersContainer : checkersContainers) {
-			logger.debug("init checkersContainer");
-			checkersContainer.initSync(selectedCheckersTags);
+			logger.debug("initSync checkersContainer");
+			checkersContainer.initSync(selectedCheckersTags, systemViewPackage);
 		}
 	}
 
@@ -136,6 +143,10 @@
 		return checkersContainers.get(0);
 	}
 
+	public List<CheckersContainer> getCheckersContainers() {
+		return checkersContainers;
+	}
+
 	public void addMessages(String unifiedName, List<CheckerMessage> newMessages) throws Exception {
 		// this.messages.addAll(newMessages);
 		checkerStatus.put(unifiedName, true);
@@ -276,4 +287,3 @@
 	}
 
 }
-
diff --git a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckerMessage.java b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckerMessage.java
index bce10f3..924ff5d 100644
--- a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckerMessage.java
+++ b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckerMessage.java
@@ -1,40 +1,56 @@
-/*******************************************************************************

- * Copyright (C) 2020 Fondazione Bruno Kessler.

- * All rights reserved. This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License v2.0

- * which accompanies this distribution, and is available at

- * http://www.eclipse.org/legal/epl-v20.html

- ******************************************************************************/

-package org.polarsys.chess.checkers.core.checkerManager;

-

-import org.eclipse.core.resources.IFile;

-import org.eclipse.emf.ecore.EObject;

-import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;

-

-public class CheckerMessage {

-

-	protected IFile file;

-	protected int severity;

-	protected String message;

-	protected Object object;

-	protected String checkerName;

-	

-	public CheckerMessage(String message, int severity ,Object object, String checkerName ) {

-			this((object instanceof EObject) ? WorkspaceSynchronizer.getFile(((EObject) object).eResource()) : null, 

-					severity, message, object, checkerName);

-	}

-

-	public CheckerMessage(IFile file, int severity, String message, Object object, String checkerName) {

-		super();

-		this.file = file;

-		this.severity = severity;

-		this.message = message;

-		this.object = object;

-		this.checkerName = checkerName;

-	}

-

-	public String getMessage() {

-		return message;

-	}

-	

-}

+/*******************************************************************************
+ * Copyright (C) 2020 Fondazione Bruno Kessler.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ ******************************************************************************/
+package org.polarsys.chess.checkers.core.checkerManager;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
+
+public class CheckerMessage {
+
+	protected IFile file;
+	protected int severity;
+	protected String message;
+	protected Object object;
+	protected String checkerName;
+	
+	public CheckerMessage(String message, int severity ,Object object, String checkerName ) {
+			this((object instanceof EObject) ? WorkspaceSynchronizer.getFile(((EObject) object).eResource()) : null, 
+					severity, message, object, checkerName);
+	}
+
+	public CheckerMessage(IFile file, int severity, String message, Object object, String checkerName) {
+		super();
+		this.file = file;
+		this.severity = severity;
+		this.message = message;
+		this.object = object;
+		this.checkerName = checkerName;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+	
+	public IFile getFile() {
+		return file;
+	}
+
+	public int getSeverity() {
+		return severity;
+	}
+
+	public Object getObject() {
+		return object;
+	}
+
+	public String getCheckerName() {
+		return checkerName;
+	}
+
+}
\ No newline at end of file
diff --git a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckersContainer.java b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckersContainer.java
index 4628cb3..59ee46c 100644
--- a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckersContainer.java
+++ b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/checkerManager/CheckersContainer.java
@@ -1,10 +1,10 @@
-/*******************************************************************************

- * Copyright (C) 2020 Fondazione Bruno Kessler.

- * All rights reserved. This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License v2.0

- * which accompanies this distribution, and is available at

- * http://www.eclipse.org/legal/epl-v20.html

- ******************************************************************************/

+/*******************************************************************************
+ * Copyright (C) 2020 Fondazione Bruno Kessler.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ ******************************************************************************/
 package org.polarsys.chess.checkers.core.checkerManager;
 
 import java.util.ArrayList;
@@ -31,6 +31,11 @@
 		checkerManager.register(this);
 	}
 
+	/**
+	 * Runs the selected checkers in an asynchronous way.
+	 * @param checkersTags
+	 * @throws Exception
+	 */
 	public void run(Set<String> checkersTags) throws Exception {
 		boolean isFirstChecker = true;
 
@@ -45,15 +50,16 @@
 	}
 
 	/**
-	 * Runs the init() of the selected checkers.
+	 * Launches the initSync() of the selected checkers.
 	 * @param checkersTags
+	 * @param systemViewPackage the SystemViewPackage
 	 * @throws Exception
 	 */
-	public void initSync(Set<String> checkersTags) throws Exception {
+	public void initSync(Set<String> checkersTags, Package systemViewPackage) throws Exception {
 		for (Checker checker : checkers) {
 			if (checker.belongsTo(checkersTags)) {
 				logger.debug("init " + checker.getUnifiedName());
-				checker.init();
+				checker.initSync(systemViewPackage);
 			}
 		}
 	}
@@ -103,6 +109,8 @@
 		return tags;
 	}
 
-	
+	public List<Checker> getCheckers() {
+		return checkers;
+	}
 
 }
\ No newline at end of file
diff --git a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/IdentifiersChecker.java b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/IdentifiersChecker.java
index 9dcd2f5..c082cb4 100644
--- a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/IdentifiersChecker.java
+++ b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/IdentifiersChecker.java
@@ -1,161 +1,165 @@
-/*******************************************************************************

- * Copyright (C) 2020 Fondazione Bruno Kessler.

- * All rights reserved. This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License v2.0

- * which accompanies this distribution, and is available at

- * http://www.eclipse.org/legal/epl-v20.html

- ******************************************************************************/

-package org.polarsys.chess.checkers.core.impl;

-

-import java.util.ArrayList;

-import java.util.Collection;

-import java.util.HashSet;

-import java.util.List;

-import java.util.Set;

-

-import org.apache.log4j.Logger;

-import org.eclipse.core.resources.IMarker;

-import org.eclipse.core.runtime.IProgressMonitor;

-import org.eclipse.emf.common.util.BasicEList;

-import org.eclipse.emf.common.util.EList;

-import org.eclipse.emf.ecore.EObject;

-import org.eclipse.uml2.uml.Behavior;

-import org.eclipse.uml2.uml.Class;

-import org.eclipse.uml2.uml.NamedElement;

-import org.eclipse.uml2.uml.Operation;

-import org.eclipse.uml2.uml.Package;

-import org.eclipse.uml2.uml.Port;

-import org.eclipse.uml2.uml.Property;

-import org.polarsys.chess.checkers.core.checkerManager.Checker;

-import org.polarsys.chess.checkers.core.checkerManager.CheckerMessage;

-import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;

-

-public class IdentifiersChecker extends Checker {

-	protected Package systemViewPackage;

-	private static final Logger logger = Logger.getLogger(IdentifiersChecker.class);

-	private static final String checkerName = "IdentifierChecker";

-

-	/**

-	 * Default constructor

-	 */

-	public IdentifiersChecker() {

-		super(checkerName, getTags());

-	}

-

-	/**

-	 * Creates the checker with the given priority.

-	 * @param priority the priority

-	 */

-	public IdentifiersChecker(int priority) {

-		super(checkerName, getTags(), priority);

-	}

-

-	/**

-	 * Constructor with explicit tags.

-	 * @param tags the tags identifying this checker

-	 */

-	public IdentifiersChecker(Set<String> tags) {

-		super(checkerName, tags);

-	}

-

-	/**

-	 * Constructor with explicit tags and priority.

-	 * @param tags the tags identifying this checker

-	 * @param priority the priority

-	 */

-	public IdentifiersChecker(Set<String> tags, int priority) {

-		super(checkerName, tags, priority);

-	}

-

-	@Override

-	public List<CheckerMessage> check(IProgressMonitor monitor) throws Exception {

-		List<CheckerMessage> messages = new ArrayList<CheckerMessage>();

-		Collection<Class> blocks = null;

-		try {

-			blocks = (Collection<Class>) EntityUtil.getInstance().getAllClasses(systemViewPackage);

-		} catch (Exception e) {

-			e.printStackTrace();

-		}

-

-		monitor.beginTask(checkerName, blocks.size());

-		for (Class block : blocks) {

-			messages.addAll(processBlock(block));

-			if (monitor.isCanceled())

-				throw new Exception("Checker interrupted");

-			monitor.worked(1);

-		}

-		return messages;

-	}

-

-	/**

-	 * Processes the given block.

-	 * 

-	 * @param block

-	 *            the block to process

-	 * @return a list of messages

-	 */

-	protected List<CheckerMessage> processBlock(Class block) {

-		final EList<NamedElement> elements = filterElements(block);

-		return processElements(elements);

-	}

-

-	/**

-	 * Processes the given list of elements.

-	 * 

-	 * @param block

-	 *            the list to process

-	 * @return a list of warnings

-	 */

-	protected List<CheckerMessage> processElements(EList<NamedElement> elements) {

-		List<CheckerMessage> messages = new ArrayList<CheckerMessage>();

-

-		for (NamedElement element : elements) {

-			final String name = element.getName();

-			logger.debug("Processing " + name);

-			if (!isValidId(name)) {

-				logger.debug("The element name is not a valid identifier: " + name);

-				final String msg = "The element name is not a valid identifier: " + name;

-				messages.add(new CheckerMessage(msg, IMarker.SEVERITY_WARNING, element, checkerName));

-			}

-		}

-		return messages;

-	}

-

-	protected boolean isValidId(String id) {

-		return javax.lang.model.SourceVersion.isIdentifier(id) && (!javax.lang.model.SourceVersion.isKeyword(id));

-	}

-	

-	/**

-	 * Creates the list of elements to be analized (incuding the block itself). Can be overridden if necessary.

-	 * @param elements

-	 * @return the filtered elements

-	 */

-	protected EList<NamedElement> filterElements(Class block) {

-		final EList<Property> attributes = block.getOwnedAttributes();

-		final EList<Operation> operations = block.getOwnedOperations();

-		final EList<Behavior> behaviors = block.getOwnedBehaviors();

-		final EList<Port> ports = block.getOwnedPorts();

-

-		final EList<NamedElement> elements = new BasicEList<NamedElement>(attributes.size() + 

-				operations.size() + behaviors.size() + ports.size() + 1);

-		elements.addAll(attributes);

-		elements.addAll(operations);

-		elements.addAll(behaviors);

-		elements.addAll(ports);

-		elements.add(block);

-		return elements;

-	}

-

-	private static Set<String> getTags() {

-		Set<String> tags = new HashSet<String>();

-		tags.add("fast");

-		tags.add("warnings");

-		tags.add("sysml");

-		return tags;

-	}

-	

-	@Override

-	public void init() throws Exception {

-		systemViewPackage = EntityUtil.getInstance().getCurrentSystemView();

-	}

-}

+/*******************************************************************************
+ * Copyright (C) 2020 Fondazione Bruno Kessler.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ ******************************************************************************/
+package org.polarsys.chess.checkers.core.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.Port;
+import org.eclipse.uml2.uml.Property;
+import org.polarsys.chess.checkers.core.checkerManager.Checker;
+import org.polarsys.chess.checkers.core.checkerManager.CheckerMessage;
+import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;
+
+public class IdentifiersChecker extends Checker {
+	protected Package systemViewPackage;
+	private static final Logger logger = Logger.getLogger(IdentifiersChecker.class);
+	private static final String checkerName = "IdentifierChecker";
+
+	/**
+	 * Default constructor
+	 */
+	public IdentifiersChecker() {
+		super(checkerName, getTags());
+	}
+
+	/**
+	 * Creates the checker with the given priority.
+	 * @param priority the priority
+	 */
+	public IdentifiersChecker(int priority) {
+		super(checkerName, getTags(), priority);
+	}
+
+	/**
+	 * Constructor with explicit tags.
+	 * @param tags the tags identifying this checker
+	 */
+	public IdentifiersChecker(Set<String> tags) {
+		super(checkerName, tags);
+	}
+
+	/**
+	 * Constructor with explicit tags and priority.
+	 * @param tags the tags identifying this checker
+	 * @param priority the priority
+	 */
+	public IdentifiersChecker(Set<String> tags, int priority) {
+		super(checkerName, tags, priority);
+	}
+
+	@Override
+	public List<CheckerMessage> check(IProgressMonitor monitor) throws Exception {
+		List<CheckerMessage> messages = new ArrayList<CheckerMessage>();
+		Collection<Class> blocks = null;
+		try {
+			blocks = (Collection<Class>) EntityUtil.getInstance().getAllClasses(systemViewPackage);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		monitor.beginTask(checkerName, blocks.size());
+		for (Class block : blocks) {
+			messages.addAll(processBlock(block));
+			if (monitor.isCanceled())
+				throw new Exception("Checker interrupted");
+			monitor.worked(1);
+		}
+		return messages;
+	}
+
+	/**
+	 * Processes the given block.
+	 * 
+	 * @param block
+	 *            the block to process
+	 * @return a list of messages
+	 */
+	protected List<CheckerMessage> processBlock(Class block) {
+		final EList<NamedElement> elements = filterElements(block);
+		return processElements(elements);
+	}
+
+	/**
+	 * Processes the given list of elements.
+	 * 
+	 * @param block
+	 *            the list to process
+	 * @return a list of warnings
+	 */
+	protected List<CheckerMessage> processElements(EList<NamedElement> elements) {
+		List<CheckerMessage> messages = new ArrayList<CheckerMessage>();
+
+		for (NamedElement element : elements) {
+			final String name = element.getName();
+			logger.debug("Processing " + name);
+			if (!isValidId(name)) {
+				logger.debug("The element name is not a valid identifier: " + name);
+				final String msg = "The element name is not a valid identifier: " + name;
+				messages.add(new CheckerMessage(msg, IMarker.SEVERITY_WARNING, element, checkerName));
+			}
+		}
+		return messages;
+	}
+
+	protected boolean isValidId(String id) {
+		return javax.lang.model.SourceVersion.isIdentifier(id) && (!javax.lang.model.SourceVersion.isKeyword(id));
+	}
+	
+	/**
+	 * Creates the list of elements to be analized (incuding the block itself). Can be overridden if necessary.
+	 * @param elements
+	 * @return the filtered elements
+	 */
+	protected EList<NamedElement> filterElements(Class block) {
+		final EList<Property> attributes = block.getOwnedAttributes();
+		final EList<Operation> operations = block.getOwnedOperations();
+		final EList<Behavior> behaviors = block.getOwnedBehaviors();
+		final EList<Port> ports = block.getOwnedPorts();
+
+		final EList<NamedElement> elements = new BasicEList<NamedElement>(attributes.size() + 
+				operations.size() + behaviors.size() + ports.size() + 1);
+		elements.addAll(attributes);
+		elements.addAll(operations);
+		elements.addAll(behaviors);
+		elements.addAll(ports);
+		elements.add(block);
+		return elements;
+	}
+
+	private static Set<String> getTags() {
+		Set<String> tags = new HashSet<String>();
+		tags.add("fast");
+		tags.add("warnings");
+		tags.add("sysml");
+		return tags;
+	}
+	
+	@Override
+	public void init() throws Exception {
+		systemViewPackage = EntityUtil.getInstance().getCurrentSystemView();
+	}
+
+	@Override
+	public void initSync(Package systemViewPackage) throws Exception {
+		this.systemViewPackage = systemViewPackage;
+	}
+}
diff --git a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/NameDistance.java b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/NameDistance.java
index 8d56967..e613ac0 100644
--- a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/NameDistance.java
+++ b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/NameDistance.java
@@ -1,298 +1,303 @@
-/*******************************************************************************

- * Copyright (C) 2020 Fondazione Bruno Kessler.

- * All rights reserved. This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License v2.0

- * which accompanies this distribution, and is available at

- * http://www.eclipse.org/legal/epl-v20.html

- ******************************************************************************/

-package org.polarsys.chess.checkers.core.impl;

-

-import java.util.ArrayList;

-import java.util.Collection;

-import java.util.HashSet;

-import java.util.List;

-import java.util.Set;

-import org.apache.log4j.Logger;

-import org.eclipse.core.resources.IMarker;

-import org.eclipse.core.runtime.IProgressMonitor;

-import org.eclipse.emf.common.util.BasicEList;

-import org.eclipse.emf.common.util.EList;

-import org.eclipse.emf.ecore.EObject;

-import org.polarsys.chess.checkers.core.checkerManager.Checker;

-import org.polarsys.chess.checkers.core.checkerManager.CheckerMessage;

-import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;

-import org.eclipse.uml2.uml.Package;

-import org.eclipse.uml2.uml.Port;

-import org.eclipse.uml2.uml.Property;

-import org.eclipse.uml2.uml.Behavior;

-import org.eclipse.uml2.uml.Class;

-import org.eclipse.uml2.uml.NamedElement;

-import org.eclipse.uml2.uml.Operation;

-

-/**

- * Computes the minimum distance among properties inside SysML Blocks.

- * 

- * @author cristofo

- *

- */

-public class NameDistance extends Checker {

-

-	/** Minimum distance between two elements; below it, marks as suspect. */

-	private int threshold = 2;

-	private Package systemViewPackage;

-	private static final Logger logger = Logger.getLogger(NameDistance.class);

-	private static final String checkerName = "NameDistance";

-

-	/**

-	 * Creates a name distance checker with default threshold.

-	 */

-	public NameDistance() {

-		super(checkerName, getTags());

-	}

-

-	/**

-	 * Creates a name distance checker with the given priority.

-	 * @param priority the priority

-	 */

-	public NameDistance(int priority) {

-		super(checkerName, getTags(), priority);

-	}

-

-	/**

-	 * Creates a name distance checker with the given priority and threshold.

-	 * @param priority the priority

-	 * @param threshold the threshold to use

-	 */

-	public NameDistance(int priority, int threshold) {

-		super(checkerName, getTags(), priority);

-		setThreshold(threshold);

-	}

-

-	/**

-	 * Constructor with explicit tags.

-	 * @param tags the tags identifying this checker

-	 */

-	public NameDistance(Set<String> tags) {

-		super(checkerName, tags);

-	}

-

-	/**

-	 * Constructor with explicit tags and priority.

-	 * @param tags the tags identifying this checker

-	 * @param priority the priority

-	 */

-	public NameDistance(Set<String> tags, int priority) {

-		super(checkerName, tags, priority);

-	}

-

-	/**

-	 * Constructor with explicit tags, priority and threshold.

-	 * @param tags the tags identifying this checker

-	 * @param priority the priority

-	 * @param threshold the threshold to use

-	 */

-	public NameDistance(Set<String> tags, int priority, int threshold) {

-		super(checkerName, tags, priority);

-		setThreshold(threshold);

-	}

-	

-	private static Set<String> getTags() {

-		Set<String> tags = new HashSet<String>();

-		tags.add("fast");

-		tags.add("warnings");

-		tags.add("errors");

-		tags.add("sysml");

-		return tags;

-	}

-

-	public int getThreshold() {

-		return threshold;

-	}

-

-	public void setThreshold(int threshold) {

-		this.threshold = threshold;

-	}

-

-	@Override

-	public List<CheckerMessage> check(IProgressMonitor monitor) throws Exception {

-		List<CheckerMessage> messages = new ArrayList<CheckerMessage>();

-		Collection<Class> blocks = null;

-		try {

-			blocks = (Collection<Class>) EntityUtil.getInstance().getAllClasses(systemViewPackage);

-		} catch (Exception e) {

-			e.printStackTrace();

-		}

-

-		monitor.beginTask(unifiedName, blocks.size());

-		for (Class block : blocks) {

-			messages.addAll(processBlock(block));

-			if (monitor.isCanceled())

-				throw new Exception("Checker interrupted");

-			monitor.worked(1);

-		}

-		return messages;

-	}

-

-	/**

-	 * Processes the given block.

-	 * 

-	 * @param block

-	 *            the block to process

-	 * @return a list of warnings

-	 */

-	private List<CheckerMessage> processBlock(Class block) {

-		final EList<NamedElement> elements = filterElements(block);

-		return processElements(elements);

-	}

-

-	/**

-	 * Creates the list of elements to be analized. Can be overridden if necessary.

-	 * @param elements

-	 * @return the filtered elements

-	 */

-	protected EList<NamedElement> filterElements(Class block) {

-		final EList<Property> attributes = block.getOwnedAttributes();

-		final EList<Operation> operations = block.getOwnedOperations();

-		final EList<Behavior> behaviors = block.getOwnedBehaviors();

-		final EList<Port> ports = block.getOwnedPorts();

-

-		final EList<NamedElement> elements = new BasicEList<NamedElement>(attributes.size() + 

-				operations.size() + behaviors.size() + ports.size());

-		elements.addAll(attributes);

-		elements.addAll(operations);

-		elements.addAll(behaviors);

-		elements.addAll(ports);

-		return elements;

-	}

-	

-	/**

-	 * Processes the given list of elements.

-	 * 

-	 * @param block

-	 *            the list to process

-	 * @return a list of warnings

-	 */

-	private List<CheckerMessage> processElements(EList<NamedElement> elements) {

-		List<CheckerMessage> messages = new ArrayList<CheckerMessage>();

-

-		for (int i = 0; i < elements.size(); i++) {

-			final NamedElement first = elements.get(i);

-			final String firstName = normalizeName(first.getName());

-			ArrayList<String> similarNames = new ArrayList<String>(2);

-			for (int j = 0; j < elements.size(); j++) {

-				if (j == i)

-					continue;

-				final NamedElement second = elements.get(j);

-

-				final String secondName = normalizeName(second.getName());

-				final int distance = levenshteinDistance(firstName, secondName);

-				logger.debug(firstName + " and " + secondName + " distance = " + distance);

-

-				if (distance == 0) {

-					final String msg = equalsMsg(first, second);

-					messages.add(createMessage(msg, IMarker.SEVERITY_ERROR, first, unifiedName));

-				}

-				if (distance <= threshold) {

-					similarNames.add(second.getName());

-				}

-			}

-

-			// If some similarities are found, store the entry in the warnings

-			if (similarNames.size() > 0) {

-				final String msg = similarMsg(first, similarNames);

-				messages.add(createMessage(msg, IMarker.SEVERITY_WARNING, first, unifiedName));

-			}

-		}

-		return messages;

-	}

-	

-	protected String equalsMsg(NamedElement first, NamedElement second) {

-		return "The term '" + first.getName() + "' is equal to '" + second.getName()  + 

-				"' in block '" + ((Class) first.getOwner()).getName() + "'";

-	}

-

-	protected String similarMsg(NamedElement first, ArrayList<String> similarNames) {

-		return "The term '" + first.getName() + "' is very similar to '"

-				+ String.join("' and '", similarNames) + "' in block '" + ((Class) first.getOwner()).getName() + "'";

-	}

-	

-	/**

-	 * Removes macro and event prefixes from the name, and put it in lowercase.

-	 * 

-	 * @param name

-	 * @return

-	 */

-	private String normalizeName(String name) {

-		// if (name.startsWith(RfiAccEntityUtil.MACRO_PREFIX) &&

-		// Character.isUpperCase(name.charAt(RfiAccEntityUtil.MACRO_PREFIX.length())))

-		// {

-		// name = name.substring(RfiAccEntityUtil.MACRO_PREFIX.length());

-		// } else if (name.startsWith(RfiAccEntityUtil.EVENT_PREFIX) &&

-		// Character.isUpperCase(name.charAt(RfiAccEntityUtil.EVENT_PREFIX.length())))

-		// {

-		// name = name.substring(RfiAccEntityUtil.EVENT_PREFIX.length());

-		// }

-

-		return name.toLowerCase();

-	}

-

-	/**

-	 * Computes the Levenshtein distance. Code taken from

-	 * https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#Java

-	 * 

-	 * @param lhs

-	 * @param rhs

-	 * @return the distance

-	 */

-	private static int levenshteinDistance(CharSequence lhs, CharSequence rhs) {

-		int len0 = lhs.length() + 1;

-		int len1 = rhs.length() + 1;

-

-		// the array of distances

-		int[] cost = new int[len0];

-		int[] newcost = new int[len0];

-

-		// initial cost of skipping prefix in String s0

-		for (int i = 0; i < len0; i++)

-			cost[i] = i;

-

-		// dynamically computing the array of distances

-

-		// transformation cost for each letter in s1

-		for (int j = 1; j < len1; j++) {

-			// initial cost of skipping prefix in String s1

-			newcost[0] = j;

-

-			// transformation cost for each letter in s0

-			for (int i = 1; i < len0; i++) {

-				// matching current letters in both strings

-				int match = (lhs.charAt(i - 1) == rhs.charAt(j - 1)) ? 0 : 1;

-

-				// computing cost for each transformation

-				int cost_replace = cost[i - 1] + match;

-				int cost_insert = cost[i] + 1;

-				int cost_delete = newcost[i - 1] + 1;

-

-				// keep minimum cost

-				newcost[i] = Math.min(Math.min(cost_insert, cost_delete), cost_replace);

-			}

-

-			// swap cost/newcost arrays

-			int[] swap = cost;

-			cost = newcost;

-			newcost = swap;

-		}

-

-		// the distance is the cost for transforming all letters in both strings

-		return cost[len0 - 1];

-	}

-

-	protected CheckerMessage createMessage(String msg, int severity, EObject element, String unifiedName) {

-		return new CheckerMessage(msg, severity, element, unifiedName);

-	}

-	

-	@Override

-	public void init() throws Exception {

-		systemViewPackage = EntityUtil.getInstance().getCurrentSystemView();

-	}

-}

+/*******************************************************************************
+ * Copyright (C) 2020 Fondazione Bruno Kessler.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ ******************************************************************************/
+package org.polarsys.chess.checkers.core.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.log4j.Logger;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.polarsys.chess.checkers.core.checkerManager.Checker;
+import org.polarsys.chess.checkers.core.checkerManager.CheckerMessage;
+import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.Port;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Operation;
+
+/**
+ * Computes the minimum distance among properties inside SysML Blocks.
+ * 
+ * @author cristofo
+ *
+ */
+public class NameDistance extends Checker {
+
+	/** Minimum distance between two elements; below it, marks as suspect. */
+	private int threshold = 2;
+	private Package systemViewPackage;
+	private static final Logger logger = Logger.getLogger(NameDistance.class);
+	private static final String checkerName = "NameDistance";
+
+	/**
+	 * Creates a name distance checker with default threshold.
+	 */
+	public NameDistance() {
+		super(checkerName, getTags());
+	}
+
+	/**
+	 * Creates a name distance checker with the given priority.
+	 * @param priority the priority
+	 */
+	public NameDistance(int priority) {
+		super(checkerName, getTags(), priority);
+	}
+
+	/**
+	 * Creates a name distance checker with the given priority and threshold.
+	 * @param priority the priority
+	 * @param threshold the threshold to use
+	 */
+	public NameDistance(int priority, int threshold) {
+		super(checkerName, getTags(), priority);
+		setThreshold(threshold);
+	}
+
+	/**
+	 * Constructor with explicit tags.
+	 * @param tags the tags identifying this checker
+	 */
+	public NameDistance(Set<String> tags) {
+		super(checkerName, tags);
+	}
+
+	/**
+	 * Constructor with explicit tags and priority.
+	 * @param tags the tags identifying this checker
+	 * @param priority the priority
+	 */
+	public NameDistance(Set<String> tags, int priority) {
+		super(checkerName, tags, priority);
+	}
+
+	/**
+	 * Constructor with explicit tags, priority and threshold.
+	 * @param tags the tags identifying this checker
+	 * @param priority the priority
+	 * @param threshold the threshold to use
+	 */
+	public NameDistance(Set<String> tags, int priority, int threshold) {
+		super(checkerName, tags, priority);
+		setThreshold(threshold);
+	}
+	
+	private static Set<String> getTags() {
+		Set<String> tags = new HashSet<String>();
+		tags.add("fast");
+		tags.add("warnings");
+		tags.add("errors");
+		tags.add("sysml");
+		return tags;
+	}
+
+	public int getThreshold() {
+		return threshold;
+	}
+
+	public void setThreshold(int threshold) {
+		this.threshold = threshold;
+	}
+
+	@Override
+	public List<CheckerMessage> check(IProgressMonitor monitor) throws Exception {
+		List<CheckerMessage> messages = new ArrayList<CheckerMessage>();
+		Collection<Class> blocks = null;
+		try {
+			blocks = (Collection<Class>) EntityUtil.getInstance().getAllClasses(systemViewPackage);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		monitor.beginTask(unifiedName, blocks.size());
+		for (Class block : blocks) {
+			messages.addAll(processBlock(block));
+			if (monitor.isCanceled())
+				throw new Exception("Checker interrupted");
+			monitor.worked(1);
+		}
+		return messages;
+	}
+
+	/**
+	 * Processes the given block.
+	 * 
+	 * @param block
+	 *            the block to process
+	 * @return a list of warnings
+	 */
+	private List<CheckerMessage> processBlock(Class block) {
+		final EList<NamedElement> elements = filterElements(block);
+		return processElements(elements);
+	}
+
+	/**
+	 * Creates the list of elements to be analized. Can be overridden if necessary.
+	 * @param elements
+	 * @return the filtered elements
+	 */
+	protected EList<NamedElement> filterElements(Class block) {
+		final EList<Property> attributes = block.getOwnedAttributes();
+		final EList<Operation> operations = block.getOwnedOperations();
+		final EList<Behavior> behaviors = block.getOwnedBehaviors();
+		final EList<Port> ports = block.getOwnedPorts();
+
+		final EList<NamedElement> elements = new BasicEList<NamedElement>(attributes.size() + 
+				operations.size() + behaviors.size() + ports.size());
+		elements.addAll(attributes);
+		elements.addAll(operations);
+		elements.addAll(behaviors);
+		elements.addAll(ports);
+		return elements;
+	}
+	
+	/**
+	 * Processes the given list of elements.
+	 * 
+	 * @param block
+	 *            the list to process
+	 * @return a list of warnings
+	 */
+	private List<CheckerMessage> processElements(EList<NamedElement> elements) {
+		List<CheckerMessage> messages = new ArrayList<CheckerMessage>();
+
+		for (int i = 0; i < elements.size(); i++) {
+			final NamedElement first = elements.get(i);
+			final String firstName = normalizeName(first.getName());
+			ArrayList<String> similarNames = new ArrayList<String>(2);
+			for (int j = 0; j < elements.size(); j++) {
+				if (j == i)
+					continue;
+				final NamedElement second = elements.get(j);
+
+				final String secondName = normalizeName(second.getName());
+				final int distance = levenshteinDistance(firstName, secondName);
+				logger.debug(firstName + " and " + secondName + " distance = " + distance);
+
+				if (distance == 0) {
+					final String msg = equalsMsg(first, second);
+					messages.add(createMessage(msg, IMarker.SEVERITY_ERROR, first, unifiedName));
+				}
+				if (distance <= threshold) {
+					similarNames.add(second.getName());
+				}
+			}
+
+			// If some similarities are found, store the entry in the warnings
+			if (similarNames.size() > 0) {
+				final String msg = similarMsg(first, similarNames);
+				messages.add(createMessage(msg, IMarker.SEVERITY_WARNING, first, unifiedName));
+			}
+		}
+		return messages;
+	}
+	
+	protected String equalsMsg(NamedElement first, NamedElement second) {
+		return "The term '" + first.getName() + "' is equal to '" + second.getName()  + 
+				"' in block '" + ((Class) first.getOwner()).getName() + "'";
+	}
+
+	protected String similarMsg(NamedElement first, ArrayList<String> similarNames) {
+		return "The term '" + first.getName() + "' is very similar to '"
+				+ String.join("' and '", similarNames) + "' in block '" + ((Class) first.getOwner()).getName() + "'";
+	}
+	
+	/**
+	 * Removes macro and event prefixes from the name, and put it in lowercase.
+	 * 
+	 * @param name
+	 * @return
+	 */
+	private String normalizeName(String name) {
+		// if (name.startsWith(RfiAccEntityUtil.MACRO_PREFIX) &&
+		// Character.isUpperCase(name.charAt(RfiAccEntityUtil.MACRO_PREFIX.length())))
+		// {
+		// name = name.substring(RfiAccEntityUtil.MACRO_PREFIX.length());
+		// } else if (name.startsWith(RfiAccEntityUtil.EVENT_PREFIX) &&
+		// Character.isUpperCase(name.charAt(RfiAccEntityUtil.EVENT_PREFIX.length())))
+		// {
+		// name = name.substring(RfiAccEntityUtil.EVENT_PREFIX.length());
+		// }
+
+		return name.toLowerCase();
+	}
+
+	/**
+	 * Computes the Levenshtein distance. Code taken from
+	 * https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#Java
+	 * 
+	 * @param lhs
+	 * @param rhs
+	 * @return the distance
+	 */
+	private static int levenshteinDistance(CharSequence lhs, CharSequence rhs) {
+		int len0 = lhs.length() + 1;
+		int len1 = rhs.length() + 1;
+
+		// the array of distances
+		int[] cost = new int[len0];
+		int[] newcost = new int[len0];
+
+		// initial cost of skipping prefix in String s0
+		for (int i = 0; i < len0; i++)
+			cost[i] = i;
+
+		// dynamically computing the array of distances
+
+		// transformation cost for each letter in s1
+		for (int j = 1; j < len1; j++) {
+			// initial cost of skipping prefix in String s1
+			newcost[0] = j;
+
+			// transformation cost for each letter in s0
+			for (int i = 1; i < len0; i++) {
+				// matching current letters in both strings
+				int match = (lhs.charAt(i - 1) == rhs.charAt(j - 1)) ? 0 : 1;
+
+				// computing cost for each transformation
+				int cost_replace = cost[i - 1] + match;
+				int cost_insert = cost[i] + 1;
+				int cost_delete = newcost[i - 1] + 1;
+
+				// keep minimum cost
+				newcost[i] = Math.min(Math.min(cost_insert, cost_delete), cost_replace);
+			}
+
+			// swap cost/newcost arrays
+			int[] swap = cost;
+			cost = newcost;
+			newcost = swap;
+		}
+
+		// the distance is the cost for transforming all letters in both strings
+		return cost[len0 - 1];
+	}
+
+	protected CheckerMessage createMessage(String msg, int severity, EObject element, String unifiedName) {
+		return new CheckerMessage(msg, severity, element, unifiedName);
+	}
+	
+	@Override
+	public void init() throws Exception {
+		systemViewPackage = EntityUtil.getInstance().getCurrentSystemView();
+	}
+
+	@Override
+	public void initSync(Package systemViewPackage) throws Exception {
+		this.systemViewPackage = systemViewPackage;
+	}
+}
diff --git a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/StateStatus.java b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/StateStatus.java
index edbe85c..db0356d 100644
--- a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/StateStatus.java
+++ b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/StateStatus.java
@@ -1,329 +1,331 @@
-/*******************************************************************************

- * Copyright (C) 2020 Fondazione Bruno Kessler.

- * All rights reserved. This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License v2.0

- * which accompanies this distribution, and is available at

- * http://www.eclipse.org/legal/epl-v20.html

- ******************************************************************************/

-package org.polarsys.chess.checkers.core.impl;

-

-import java.util.ArrayList;

-import java.util.Collection;

-import java.util.HashSet;

-import java.util.List;

-import java.util.Set;

-

-import org.apache.log4j.Logger;

-import org.eclipse.core.resources.IMarker;

-import org.eclipse.core.runtime.IProgressMonitor;

-import org.eclipse.emf.common.util.EList;

-import org.eclipse.emf.ecore.EObject;

-import org.eclipse.uml2.uml.Class;

-import org.eclipse.uml2.uml.Package;

-import org.eclipse.uml2.uml.Region;

-import org.eclipse.uml2.uml.StateMachine;

-import org.eclipse.uml2.uml.Transition;

-import org.eclipse.uml2.uml.Vertex;

-import org.polarsys.chess.checkers.core.checkerManager.Checker;

-import org.polarsys.chess.checkers.core.checkerManager.CheckerMessage;

-import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;

-

-/**

- * Two checkers that detect unreachable states and states without transitions to other 

- * states, inside a StateMachine.

- * 

- * @author cristofo

- *

- */

-public class StateStatus extends Checker {

-	private Package systemViewPackage;

-	protected static final Logger logger = Logger.getLogger(StateStatus.class);

-	private final EntityUtil entityUtil = EntityUtil.getInstance();

-	private static final String checkerName = "StateStatus";

-

-	/**

-	 * Creates a state checker

-	 */

-	public StateStatus() {

-		super(checkerName, getTags());

-	}

-

-	/**

-	 * Creates a state checker with the given priority

-	 * @param priority the priority

-	 */

-	public StateStatus(int priority) {

-		super(checkerName, getTags(), priority);

-	}

-

-	/**

-	 * Constructor with explicit tags.

-	 * @param tags the tags identifying this checker

-	 */

-	public StateStatus(Set<String> tags) {

-		super(checkerName, tags);

-	}

-

-	/**

-	 * Constructor with explicit tags and priority.

-	 * @param tags the tags identifying this checker

-	 * @param priority the priority

-	 */

-	public StateStatus(Set<String> tags, int priority) {

-		super(checkerName, tags, priority);

-	}

-

-	private static Set<String> getTags() {

-		Set<String> tags = new HashSet<String>();

-		tags.add("fast");

-		tags.add("errors");

-		tags.add("state machine");

-		return tags;

-	}

-

-	@Override

-	public List<CheckerMessage> check(IProgressMonitor monitor) throws Exception {

-		List<CheckerMessage> messages = new ArrayList<CheckerMessage>();

-		Collection<Class> blocks = null;

-		blocks = getBlocks(systemViewPackage);

-

-		monitor.beginTask(unifiedName, blocks.size());

-		for (Class block : blocks) {

-//			warnings.addAll(checkForDeadAndUnreachableStates(block));

-			messages.addAll(checkForDeadStates(block));

-			messages.addAll(checkForUnreachableStates(block));

-			if (monitor.isCanceled())

-				throw new Exception("Checker interrupted");

-			monitor.worked(1);

-		}

-		return messages;

-	}

-

-	/**

-	 * Returns the blocks that should be checked inside the model. Can be overwritter if necessary.

-	 * @param systemViewPackage

-	 * @return

-	 */

-	protected Collection<Class> getBlocks(Package systemViewPackage) {

-		try {

-			return (Collection<Class>) EntityUtil.getInstance().getAllClasses(systemViewPackage);

-		} catch (Exception e) {

-			e.printStackTrace();

-		}

-		return null;

-	}

-	

-	/**

-	 * A dead state is a state with no transitions to other states.

-	 * @param block

-	 * @return list of errors

-	 */

-	protected List<CheckerMessage> checkForDeadStates(Class block) {

-		List<CheckerMessage> errors = new ArrayList<CheckerMessage>();

-		

-		final Set<StateMachine> stateMachines = entityUtil.getNominalStateMachines(block);

-		if (stateMachines.isEmpty()) {

-			logger.error("No state machines are present in block " + block.getName());			

-		}

-		

-		for (StateMachine stateMachine : stateMachines) {

-			if (stateMachine == null) continue;

-			final String stateMachineName = stateMachine.getName();

-			final Region region = stateMachine.getRegion(null); // Assume that only one region is present

-			if (region == null) {

-				logger.error("State machine " + stateMachineName + " of block " + block.getName() + 

-						" is not valid");

-				continue;

-			}

-			

-			// If there is only one intermediate state, don't do any check

-			if (entityUtil.getIntermediateStates(stateMachine).size() <= 1) continue;

-			

-			final EList<Vertex> states = entityUtil.getStates(stateMachine);

-			final List<String> deadStates = new ArrayList<String>(1);

-			for (Vertex state : states) {

-				if (entityUtil.isFinalState(state)) continue;

-				boolean dead = true;

-				final EList<Transition> outgoingTransitions = entityUtil.getOutgoingTransitions(state);

-				for (Transition transition : outgoingTransitions) {

-					if (entityUtil.getTransitionNextState(transition) != state) {

-						dead = false;

-						break;

-					}

-				}

-				if (dead) {

-					final String msg = deadMsg(state, block);

-					errors.add(createMessage(msg, IMarker.SEVERITY_ERROR, state, unifiedName));

-

-					deadStates.add(state.getName());

-				}

-			}

-			if (deadStates.size() == 0) {

-				logger.debug("State machine " + stateMachineName + ": all states are valid");

-			} else {

-				logger.error("State machine " + stateMachineName + ": the following states are dead: " + 

-						String.join(", ", deadStates));

-			}

-		}

-		

-		return errors;

-	}

-	

-	/**

-	 * An unreachable state is a state that is no reachable from other states.

-	 * @param block

-	 * @return list of errors

-	 */

-	private List<CheckerMessage> checkForUnreachableStates(Class block) {

-		List<CheckerMessage> errors = new ArrayList<CheckerMessage>();

-		

-		final Set<StateMachine> stateMachines = entityUtil.getNominalStateMachines(block);

-		if (stateMachines.isEmpty()) {

-			logger.error("No state machines are present in block " + block.getName());			

-		}

-		

-		for (StateMachine stateMachine : stateMachines) {

-			if (stateMachine == null) continue;

-			final String stateMachineName = stateMachine.getName();

-			final Region region = stateMachine.getRegion(null); // Assume that only one region is present

-			if (region == null) {

-				logger.error("State machine " + stateMachineName + " of block " + block.getName() + 

-						" is not valid");

-				continue;

-			}

-			final EList<Vertex> states = entityUtil.getIntermediateStates(stateMachine);

-			final List<String> unreachableStates = new ArrayList<String>(1);

-			for (Vertex state : states) {

-				boolean unreachable = true;

-				final EList<Transition> incomingTransitions = entityUtil.getIncomingTransitions(state);

-				for (Transition transition : incomingTransitions) {

-					if (entityUtil.getTransitionSourceState(transition) != state) {

-						unreachable = false;

-						break;

-					}

-				}

-				if (unreachable) {

-					final String msg = unreachableMsg(state, block);

-					errors.add(createMessage(msg, IMarker.SEVERITY_ERROR, state, unifiedName));

-					unreachableStates.add(state.getName());					

-				}

-			}

-			if (unreachableStates.size() == 0) {

-				logger.debug("State machine " + stateMachineName + ": all states are valid");

-			} else {

-				logger.error("State machine " + stateMachineName + ": the following states are not reachable: " + 

-						String.join(", ", unreachableStates));

-			}

-		}

-		

-		return errors;

-	}

-

-	/**

-	 * An unreachable state is a state that is no reachable from other states.

-	 * @param block

-	 * @return list of errors

-	 */

-	private List<CheckerMessage> checkForDeadAndUnreachableStates(Class block) {		

-		List<CheckerMessage> errors = new ArrayList<CheckerMessage>();

-		

-		final Set<StateMachine> stateMachines = entityUtil.getNominalStateMachines(block);

-		if (stateMachines.isEmpty()) {

-			logger.error("No state machines are present in block " + block.getName());			

-		}

-		

-		for (StateMachine stateMachine : stateMachines) {

-			if (stateMachine == null) continue;

-			final String stateMachineName = stateMachine.getName();

-			final Region region = stateMachine.getRegion(null); // Assume that only one region is present

-			if (region == null) {

-				logger.error("State machine " + stateMachineName + " of block " + block.getName() + 

-						" is not valid");

-				continue;

-			}

-			final EList<Vertex> states = entityUtil.getStates(stateMachine);

-			final List<String> deadStates = new ArrayList<String>(1);

-			final List<String> unreachableStates = new ArrayList<String>(1);

-

-			int stateCounter = 0;

-			for (Vertex state : states) {

-				if (!entityUtil.isFinalState(state)) {

-					stateCounter++;

-				}

-			}

-			

-			for (Vertex state : states) {

-				boolean dead = false;

-				boolean unreachable = false;

-				if (!entityUtil.isFinalState(state)) {

-					dead = true;

-					final EList<Transition> outgoingTransitions = entityUtil.getOutgoingTransitions(state);

-					for (Transition transition : outgoingTransitions) {

-						if (entityUtil.getTransitionNextState(transition) != state) {

-							dead = false;

-							break;

-						}

-					}					

-				}

-

-				if (!entityUtil.isInitialState(state)) {

-					unreachable = true;

-					final EList<Transition> incomingTransitions = entityUtil.getIncomingTransitions(state);

-					for (Transition transition : incomingTransitions) {

-						if (entityUtil.getTransitionSourceState(transition) != state) {

-							unreachable = false;

-							break;

-						}

-					}

-				}

-

-				if ((dead && stateCounter > 2)) {

-					final String msg = deadMsg(state, block);

-					errors.add(createMessage(msg, IMarker.SEVERITY_ERROR, state, unifiedName));

-					deadStates.add(state.getName());

-				}

-

-				if ((unreachable)) {

-					final String msg = unreachableMsg(state, block);

-					errors.add(createMessage(msg, IMarker.SEVERITY_ERROR, state, unifiedName));

-					unreachableStates.add(state.getName());

-				}

-			}

-			if (deadStates.size() == 0) {

-				logger.debug("State machine " + stateMachineName + ": all states are valid");

-			} else {

-				logger.error("State machine " + stateMachineName + ": the following states are dead: " + 

-						String.join(", ", deadStates));

-			}

-			if (unreachableStates.size() == 0) {

-				logger.debug("State machine " + stateMachineName + ": all states are valid");

-			} else {

-				logger.error("State machine " + stateMachineName + ": the following states are not reachable: " + 

-						String.join(", ", unreachableStates));

-			}

-		}

-		return errors;

-	}

-	

-	protected CheckerMessage createMessage(String msg, int severity, EObject state, String unifiedName) {

-		return new CheckerMessage(msg, severity, state, unifiedName);

-	}

-	

-	protected String deadMsg(Vertex state, Class block) {

-		return "The state '" + state.getName() + "' of block '" + 

-				block.getName() + "' does not have any transitions to other states";

-	}

-	

-	protected String unreachableMsg(Vertex state, Class block) {

-		return "The state '" + state.getName() + "' of block '" + 

-				block.getName() + "' is never reachable";

-	}

-

-	@Override

-	public void init() throws Exception {

-		systemViewPackage = EntityUtil.getInstance().getCurrentSystemView();

-		

-		//TODO: aprire esattamente il progetto corretto, dove sono quando lancio il check? Devo essere su un progetto,

-		// e quello viene analizzato

-	}

-}

+/*******************************************************************************
+ * Copyright (C) 2020 Fondazione Bruno Kessler.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ ******************************************************************************/
+package org.polarsys.chess.checkers.core.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.Region;
+import org.eclipse.uml2.uml.StateMachine;
+import org.eclipse.uml2.uml.Transition;
+import org.eclipse.uml2.uml.Vertex;
+import org.polarsys.chess.checkers.core.checkerManager.Checker;
+import org.polarsys.chess.checkers.core.checkerManager.CheckerMessage;
+import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;
+
+/**
+ * Two checkers that detect unreachable states and states without transitions to other 
+ * states, inside a StateMachine.
+ * 
+ * @author cristofo
+ *
+ */
+public class StateStatus extends Checker {
+	private Package systemViewPackage;
+	protected static final Logger logger = Logger.getLogger(StateStatus.class);
+	private final EntityUtil entityUtil = EntityUtil.getInstance();
+	private static final String checkerName = "StateStatus";
+
+	/**
+	 * Creates a state checker
+	 */
+	public StateStatus() {
+		super(checkerName, getTags());
+	}
+
+	/**
+	 * Creates a state checker with the given priority
+	 * @param priority the priority
+	 */
+	public StateStatus(int priority) {
+		super(checkerName, getTags(), priority);
+	}
+
+	/**
+	 * Constructor with explicit tags.
+	 * @param tags the tags identifying this checker
+	 */
+	public StateStatus(Set<String> tags) {
+		super(checkerName, tags);
+	}
+
+	/**
+	 * Constructor with explicit tags and priority.
+	 * @param tags the tags identifying this checker
+	 * @param priority the priority
+	 */
+	public StateStatus(Set<String> tags, int priority) {
+		super(checkerName, tags, priority);
+	}
+
+	private static Set<String> getTags() {
+		Set<String> tags = new HashSet<String>();
+		tags.add("fast");
+		tags.add("errors");
+		tags.add("state machine");
+		return tags;
+	}
+
+	@Override
+	public List<CheckerMessage> check(IProgressMonitor monitor) throws Exception {
+		List<CheckerMessage> messages = new ArrayList<CheckerMessage>();
+		Collection<Class> blocks = null;
+		blocks = getBlocks(systemViewPackage);
+
+		monitor.beginTask(unifiedName, blocks.size());
+		for (Class block : blocks) {
+//			warnings.addAll(checkForDeadAndUnreachableStates(block));
+			messages.addAll(checkForDeadStates(block));
+			messages.addAll(checkForUnreachableStates(block));
+			if (monitor.isCanceled())
+				throw new Exception("Checker interrupted");
+			monitor.worked(1);
+		}
+		return messages;
+	}
+
+	/**
+	 * Returns the blocks that should be checked inside the model. Can be overwritter if necessary.
+	 * @param systemViewPackage
+	 * @return
+	 */
+	protected Collection<Class> getBlocks(Package systemViewPackage) {
+		try {
+			return (Collection<Class>) EntityUtil.getInstance().getAllClasses(systemViewPackage);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+	
+	/**
+	 * A dead state is a state with no transitions to other states.
+	 * @param block
+	 * @return list of errors
+	 */
+	protected List<CheckerMessage> checkForDeadStates(Class block) {
+		List<CheckerMessage> errors = new ArrayList<CheckerMessage>();
+		
+		final Set<StateMachine> stateMachines = entityUtil.getNominalStateMachines(block);
+		if (stateMachines.isEmpty()) {
+			logger.error("No state machines are present in block " + block.getName());			
+		}
+		
+		for (StateMachine stateMachine : stateMachines) {
+			if (stateMachine == null) continue;
+			final String stateMachineName = stateMachine.getName();
+			final Region region = stateMachine.getRegion(null); // Assume that only one region is present
+			if (region == null) {
+				logger.error("State machine " + stateMachineName + " of block " + block.getName() + 
+						" is not valid");
+				continue;
+			}
+			
+			// If there is only one intermediate state, don't do any check
+			if (entityUtil.getIntermediateStates(stateMachine).size() <= 1) continue;
+			
+			final EList<Vertex> states = entityUtil.getStates(stateMachine);
+			final List<String> deadStates = new ArrayList<String>(1);
+			for (Vertex state : states) {
+				if (entityUtil.isFinalState(state)) continue;
+				boolean dead = true;
+				final EList<Transition> outgoingTransitions = entityUtil.getOutgoingTransitions(state);
+				for (Transition transition : outgoingTransitions) {
+					if (entityUtil.getTransitionNextState(transition) != state) {
+						dead = false;
+						break;
+					}
+				}
+				if (dead) {
+					final String msg = deadMsg(state, block);
+					errors.add(createMessage(msg, IMarker.SEVERITY_ERROR, state, unifiedName));
+
+					deadStates.add(state.getName());
+				}
+			}
+			if (deadStates.size() == 0) {
+				logger.debug("State machine " + stateMachineName + ": all states are valid");
+			} else {
+				logger.error("State machine " + stateMachineName + ": the following states are dead: " + 
+						String.join(", ", deadStates));
+			}
+		}
+		
+		return errors;
+	}
+	
+	/**
+	 * An unreachable state is a state that is no reachable from other states.
+	 * @param block
+	 * @return list of errors
+	 */
+	private List<CheckerMessage> checkForUnreachableStates(Class block) {
+		List<CheckerMessage> errors = new ArrayList<CheckerMessage>();
+		
+		final Set<StateMachine> stateMachines = entityUtil.getNominalStateMachines(block);
+		if (stateMachines.isEmpty()) {
+			logger.error("No state machines are present in block " + block.getName());			
+		}
+		
+		for (StateMachine stateMachine : stateMachines) {
+			if (stateMachine == null) continue;
+			final String stateMachineName = stateMachine.getName();
+			final Region region = stateMachine.getRegion(null); // Assume that only one region is present
+			if (region == null) {
+				logger.error("State machine " + stateMachineName + " of block " + block.getName() + 
+						" is not valid");
+				continue;
+			}
+			final EList<Vertex> states = entityUtil.getIntermediateStates(stateMachine);
+			final List<String> unreachableStates = new ArrayList<String>(1);
+			for (Vertex state : states) {
+				boolean unreachable = true;
+				final EList<Transition> incomingTransitions = entityUtil.getIncomingTransitions(state);
+				for (Transition transition : incomingTransitions) {
+					if (entityUtil.getTransitionSourceState(transition) != state) {
+						unreachable = false;
+						break;
+					}
+				}
+				if (unreachable) {
+					final String msg = unreachableMsg(state, block);
+					errors.add(createMessage(msg, IMarker.SEVERITY_ERROR, state, unifiedName));
+					unreachableStates.add(state.getName());					
+				}
+			}
+			if (unreachableStates.size() == 0) {
+				logger.debug("State machine " + stateMachineName + ": all states are valid");
+			} else {
+				logger.error("State machine " + stateMachineName + ": the following states are not reachable: " + 
+						String.join(", ", unreachableStates));
+			}
+		}
+		
+		return errors;
+	}
+
+	/**
+	 * An unreachable state is a state that is no reachable from other states.
+	 * @param block
+	 * @return list of errors
+	 */
+	private List<CheckerMessage> checkForDeadAndUnreachableStates(Class block) {		
+		List<CheckerMessage> errors = new ArrayList<CheckerMessage>();
+		
+		final Set<StateMachine> stateMachines = entityUtil.getNominalStateMachines(block);
+		if (stateMachines.isEmpty()) {
+			logger.error("No state machines are present in block " + block.getName());			
+		}
+		
+		for (StateMachine stateMachine : stateMachines) {
+			if (stateMachine == null) continue;
+			final String stateMachineName = stateMachine.getName();
+			final Region region = stateMachine.getRegion(null); // Assume that only one region is present
+			if (region == null) {
+				logger.error("State machine " + stateMachineName + " of block " + block.getName() + 
+						" is not valid");
+				continue;
+			}
+			final EList<Vertex> states = entityUtil.getStates(stateMachine);
+			final List<String> deadStates = new ArrayList<String>(1);
+			final List<String> unreachableStates = new ArrayList<String>(1);
+
+			int stateCounter = 0;
+			for (Vertex state : states) {
+				if (!entityUtil.isFinalState(state)) {
+					stateCounter++;
+				}
+			}
+			
+			for (Vertex state : states) {
+				boolean dead = false;
+				boolean unreachable = false;
+				if (!entityUtil.isFinalState(state)) {
+					dead = true;
+					final EList<Transition> outgoingTransitions = entityUtil.getOutgoingTransitions(state);
+					for (Transition transition : outgoingTransitions) {
+						if (entityUtil.getTransitionNextState(transition) != state) {
+							dead = false;
+							break;
+						}
+					}					
+				}
+
+				if (!entityUtil.isInitialState(state)) {
+					unreachable = true;
+					final EList<Transition> incomingTransitions = entityUtil.getIncomingTransitions(state);
+					for (Transition transition : incomingTransitions) {
+						if (entityUtil.getTransitionSourceState(transition) != state) {
+							unreachable = false;
+							break;
+						}
+					}
+				}
+
+				if ((dead && stateCounter > 2)) {
+					final String msg = deadMsg(state, block);
+					errors.add(createMessage(msg, IMarker.SEVERITY_ERROR, state, unifiedName));
+					deadStates.add(state.getName());
+				}
+
+				if ((unreachable)) {
+					final String msg = unreachableMsg(state, block);
+					errors.add(createMessage(msg, IMarker.SEVERITY_ERROR, state, unifiedName));
+					unreachableStates.add(state.getName());
+				}
+			}
+			if (deadStates.size() == 0) {
+				logger.debug("State machine " + stateMachineName + ": all states are valid");
+			} else {
+				logger.error("State machine " + stateMachineName + ": the following states are dead: " + 
+						String.join(", ", deadStates));
+			}
+			if (unreachableStates.size() == 0) {
+				logger.debug("State machine " + stateMachineName + ": all states are valid");
+			} else {
+				logger.error("State machine " + stateMachineName + ": the following states are not reachable: " + 
+						String.join(", ", unreachableStates));
+			}
+		}
+		return errors;
+	}
+	
+	protected CheckerMessage createMessage(String msg, int severity, EObject state, String unifiedName) {
+		return new CheckerMessage(msg, severity, state, unifiedName);
+	}
+	
+	protected String deadMsg(Vertex state, Class block) {
+		return "The state '" + state.getName() + "' of block '" + 
+				block.getName() + "' does not have any transitions to other states";
+	}
+	
+	protected String unreachableMsg(Vertex state, Class block) {
+		return "The state '" + state.getName() + "' of block '" + 
+				block.getName() + "' is never reachable";
+	}
+
+	@Override
+	public void init() throws Exception {
+		systemViewPackage = EntityUtil.getInstance().getCurrentSystemView();
+	}
+
+	@Override
+	public void initSync(Package systemViewPackage) throws Exception {
+		this.systemViewPackage = systemViewPackage;
+	}
+}
diff --git a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/TestChecker1.java b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/TestChecker1.java
index 5259614..4c4a85e 100644
--- a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/TestChecker1.java
+++ b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/TestChecker1.java
@@ -1,84 +1,90 @@
-/*******************************************************************************

- * Copyright (C) 2020 Fondazione Bruno Kessler.

- * All rights reserved. This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License v2.0

- * which accompanies this distribution, and is available at

- * http://www.eclipse.org/legal/epl-v20.html

- ******************************************************************************/

-package org.polarsys.chess.checkers.core.impl;

-

-import java.util.ArrayList;

-import java.util.List;

-import java.util.Set;

-import java.util.concurrent.TimeUnit;

-import org.eclipse.core.runtime.Path;

-import org.eclipse.core.resources.IFile;

-import org.eclipse.core.resources.IMarker;

-import org.eclipse.core.resources.IProject;

-import org.eclipse.core.resources.IResource;

-import org.eclipse.core.resources.ResourcesPlugin;

-import org.eclipse.core.runtime.IPath;

-import org.eclipse.core.runtime.IProgressMonitor;

-import org.eclipse.emf.ecore.EObject;

-import org.eclipse.emf.ecore.util.EcoreUtil;

-import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;

-import org.polarsys.chess.checkers.core.checkerManager.Checker;

-import org.polarsys.chess.checkers.core.checkerManager.CheckerMessage;

-import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;

-

-

-public class TestChecker1 extends Checker {

-

-	org.eclipse.uml2.uml.Package systemViewPackage;

-	IResource resource;

-	IFile file;

-	public TestChecker1(String unifiedName, Set<String> checkerTags, int priority) {

-		super(unifiedName, checkerTags,priority);

-	}

-

-	@Override

-	public List<CheckerMessage> check(IProgressMonitor monitor) throws Exception {

-

-		monitor.beginTask(unifiedName, 3);

-		System.out.println("systemViewPackage: "+systemViewPackage);

-		//Resource resource = systemViewPackage.eResource();

-		

-		//IResource resource = getResourceForModel(systemViewPackage);

-		List<CheckerMessage> res = new ArrayList<CheckerMessage>();

-		long time = 0;

-		while(time<10){

-		res.add(new CheckerMessage("StateMachineChecker2 "+time+" priority "+registerPriority, IMarker.SEVERITY_ERROR, systemViewPackage,unifiedName));

-		TimeUnit.SECONDS.sleep(1);

-		time++;

-		monitor.worked(1);

-		}

-		return res;

-	}

-

-	

-	

-	public IResource getResourceForModel(EObject obj) {

-		//org.eclipse.emf.common.util.URI uri = obj.eResource().getURI();

-		org.eclipse.emf.common.util.URI uri = EcoreUtil.getURI(obj);

-		System.out.println("uri: "+uri);

-	        // assuming platform://resource/project/path/to/file

-		String projectStr = uri.segment(1);

-		IPath path = new Path(uri.path()).removeFirstSegments(2);

-		System.out.println("path: "+path);

-		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectStr);

-		System.out.println("project: "+project);

-		return project.findMember(path);

-	}

-	

-	@Override

-	public void init() throws Exception {

-		systemViewPackage = EntityUtil.getInstance().getCurrentSystemView();

-		//resource = ResourcesPlugin.getWorkspace().getRoot();

-		resource = getResourceForModel(systemViewPackage);

-		file = WorkspaceSynchronizer.getFile(systemViewPackage.eResource());

-		System.out.println("resource: "+resource);

-		

-	}

-

-

-}

+/*******************************************************************************
+ * Copyright (C) 2020 Fondazione Bruno Kessler.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ ******************************************************************************/
+package org.polarsys.chess.checkers.core.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
+import org.eclipse.uml2.uml.Package;
+import org.polarsys.chess.checkers.core.checkerManager.Checker;
+import org.polarsys.chess.checkers.core.checkerManager.CheckerMessage;
+import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;
+
+
+public class TestChecker1 extends Checker {
+
+	org.eclipse.uml2.uml.Package systemViewPackage;
+	IResource resource;
+	IFile file;
+	public TestChecker1(String unifiedName, Set<String> checkerTags, int priority) {
+		super(unifiedName, checkerTags,priority);
+	}
+
+	@Override
+	public List<CheckerMessage> check(IProgressMonitor monitor) throws Exception {
+
+		monitor.beginTask(unifiedName, 3);
+		System.out.println("systemViewPackage: "+systemViewPackage);
+		//Resource resource = systemViewPackage.eResource();
+		
+		//IResource resource = getResourceForModel(systemViewPackage);
+		List<CheckerMessage> res = new ArrayList<CheckerMessage>();
+		long time = 0;
+		while(time<10){
+		res.add(new CheckerMessage("StateMachineChecker2 "+time+" priority "+registerPriority, IMarker.SEVERITY_ERROR, systemViewPackage,unifiedName));
+		TimeUnit.SECONDS.sleep(1);
+		time++;
+		monitor.worked(1);
+		}
+		return res;
+	}
+
+	
+	
+	public IResource getResourceForModel(EObject obj) {
+		//org.eclipse.emf.common.util.URI uri = obj.eResource().getURI();
+		org.eclipse.emf.common.util.URI uri = EcoreUtil.getURI(obj);
+		System.out.println("uri: "+uri);
+	        // assuming platform://resource/project/path/to/file
+		String projectStr = uri.segment(1);
+		IPath path = new Path(uri.path()).removeFirstSegments(2);
+		System.out.println("path: "+path);
+		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectStr);
+		System.out.println("project: "+project);
+		return project.findMember(path);
+	}
+	
+	@Override
+	public void init() throws Exception {
+		systemViewPackage = EntityUtil.getInstance().getCurrentSystemView();
+		//resource = ResourcesPlugin.getWorkspace().getRoot();
+		resource = getResourceForModel(systemViewPackage);
+		file = WorkspaceSynchronizer.getFile(systemViewPackage.eResource());
+		System.out.println("resource: "+resource);
+		
+	}
+
+	@Override
+	public void initSync(Package systemViewPackage) throws Exception {
+		this.systemViewPackage = systemViewPackage;
+		resource = getResourceForModel(systemViewPackage);
+		file = WorkspaceSynchronizer.getFile(systemViewPackage.eResource());
+	}
+}
diff --git a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/TestChecker2.java b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/TestChecker2.java
index 8d9dee4..f25a3d8 100644
--- a/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/TestChecker2.java
+++ b/plugins/org.polarsys.chess.checkers/src/org/polarsys/chess/checkers/core/impl/TestChecker2.java
@@ -1,63 +1,69 @@
-/*******************************************************************************

- * Copyright (C) 2020 Fondazione Bruno Kessler.

- * All rights reserved. This program and the accompanying materials

- * are made available under the terms of the Eclipse Public License v2.0

- * which accompanies this distribution, and is available at

- * http://www.eclipse.org/legal/epl-v20.html

- ******************************************************************************/

-package org.polarsys.chess.checkers.core.impl;

-

-import java.util.ArrayList;

-import java.util.List;

-import java.util.Set;

-import java.util.concurrent.TimeUnit;

-

-import org.eclipse.core.resources.IFile;

-import org.eclipse.core.resources.IMarker;

-import org.eclipse.core.runtime.IProgressMonitor;

-import org.eclipse.core.runtime.Status;

-import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;

-import org.polarsys.chess.checkers.core.checkerManager.Checker;

-import org.polarsys.chess.checkers.core.checkerManager.CheckerMessage;

-import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;

-

-

-public class TestChecker2 extends Checker {

-

-	org.eclipse.uml2.uml.Package systemViewPackage;

-	private IFile file;

-	

-	public TestChecker2(String unifiedName, Set<String> checkerTags) {

-		super(unifiedName,  checkerTags);

-	}

-

-

-	@Override

-	public List<CheckerMessage> check(IProgressMonitor monitor) throws Exception {

-	

-		monitor.beginTask(unifiedName, 6);

-	

-		List<CheckerMessage> res = new ArrayList<CheckerMessage>();

-		long time = 0;

-		while(time<6){

-		res.add(new CheckerMessage("SysMLChecker1 "+time, IMarker.SEVERITY_ERROR,systemViewPackage,unifiedName));

-		if (monitor.isCanceled()) {

-			System.out.println("monitor.isCanceled()");

-	       throw new Exception();

-	    }

-		TimeUnit.SECONDS.sleep(1);

-		time++;

-		monitor.worked(1);

-		}

-		return res;

-	}

-

-

-	@Override

-	public void init() throws Exception {

-		systemViewPackage = EntityUtil.getInstance().getCurrentSystemView();

-		file = WorkspaceSynchronizer.getFile(systemViewPackage.eResource());

-		

-	}

-

-}

+/*******************************************************************************
+ * Copyright (C) 2020 Fondazione Bruno Kessler.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ ******************************************************************************/
+package org.polarsys.chess.checkers.core.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
+import org.eclipse.uml2.uml.Package;
+import org.polarsys.chess.checkers.core.checkerManager.Checker;
+import org.polarsys.chess.checkers.core.checkerManager.CheckerMessage;
+import org.polarsys.chess.contracts.profile.chesscontract.util.EntityUtil;
+
+
+public class TestChecker2 extends Checker {
+
+	org.eclipse.uml2.uml.Package systemViewPackage;
+	private IFile file;
+	
+	public TestChecker2(String unifiedName, Set<String> checkerTags) {
+		super(unifiedName,  checkerTags);
+	}
+
+
+	@Override
+	public List<CheckerMessage> check(IProgressMonitor monitor) throws Exception {
+	
+		monitor.beginTask(unifiedName, 6);
+	
+		List<CheckerMessage> res = new ArrayList<CheckerMessage>();
+		long time = 0;
+		while(time<6){
+		res.add(new CheckerMessage("SysMLChecker1 "+time, IMarker.SEVERITY_ERROR,systemViewPackage,unifiedName));
+		if (monitor.isCanceled()) {
+			System.out.println("monitor.isCanceled()");
+	       throw new Exception();
+	    }
+		TimeUnit.SECONDS.sleep(1);
+		time++;
+		monitor.worked(1);
+		}
+		return res;
+	}
+
+
+	@Override
+	public void init() throws Exception {
+		systemViewPackage = EntityUtil.getInstance().getCurrentSystemView();
+		file = WorkspaceSynchronizer.getFile(systemViewPackage.eResource());
+	}
+
+
+	@Override
+	public void initSync(Package systemViewPackage) throws Exception {
+		this.systemViewPackage = systemViewPackage;
+		file = WorkspaceSynchronizer.getFile(systemViewPackage.eResource());
+	}
+
+}