/*
 *                                                                            
 *  Copyright (c) 2011 - 2017 - Loetz GmbH & Co KG, 69115 Heidelberg, Germany 
 *                                                                            
 *  All rights reserved. This program and the accompanying materials           
 *  are made available under the terms of the Eclipse Public License 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                                                            
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Initial contribution:                                                      
 *     Loetz GmbH & Co. KG                              
 * 
 */
package org.eclipse.osbp.dsl.metadata.service;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;

import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.dsl.semantic.common.types.LTypedPackage;
import org.eclipse.osbp.dsl.semantic.dto.LDto;
import org.eclipse.osbp.dsl.semantic.entity.LEntity;
import org.eclipse.osbp.dsl.xtext.types.bundles.BundleSpaceTypeProvider;
import org.eclipse.osbp.ecview.dsl.extensions.SuperTypeCollector;
import org.eclipse.osbp.ecview.semantic.uimodel.UiBeanSlot;
import org.eclipse.osbp.ecview.semantic.uimodel.UiIDEView;
import org.eclipse.osbp.ecview.semantic.uimodel.UiModelPackage;
import org.eclipse.osbp.preferences.ProductConfiguration;
import org.eclipse.osbp.runtime.common.extender.IExtenderConstants;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.perspective.IPerspectiveProvider;
import org.eclipse.osbp.ui.api.useraccess.AbstractAuthorization.Action;
import org.eclipse.osbp.ui.api.useraccess.AbstractAuthorization.Group;
import org.eclipse.osbp.ui.api.useraccess.IUserAccessService;
import org.eclipse.osbp.xtext.action.ActionPackage;
import org.eclipse.osbp.xtext.action.ActionToolbar;
import org.eclipse.osbp.xtext.authorizationdsl.AuthorizationPackage;
import org.eclipse.osbp.xtext.authorizationdsl.Role;
import org.eclipse.osbp.xtext.blip.Blip;
import org.eclipse.osbp.xtext.blip.BlipPackage;
import org.eclipse.osbp.xtext.builder.metadata.services.AbstractBuilderParticipant;
import org.eclipse.osbp.xtext.builder.metadata.services.IBuilderParticipant;
import org.eclipse.osbp.xtext.builder.metadata.services.IMetadataBuilderService;
import org.eclipse.osbp.xtext.builder.metadata.services.IUnitOfWork;
import org.eclipse.osbp.xtext.chart.Chart;
import org.eclipse.osbp.xtext.chart.ChartDSLPackage;
import org.eclipse.osbp.xtext.chart.ChartPackage;
import org.eclipse.osbp.xtext.cubedsl.CubeDimensionUsage;
import org.eclipse.osbp.xtext.cubedsl.CubeHierarchy;
import org.eclipse.osbp.xtext.cubedsl.CubeType;
import org.eclipse.osbp.xtext.datainterchange.DataInterchange;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeBean;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeGroup;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangePackage;
import org.eclipse.osbp.xtext.datamartdsl.DatamartCube;
import org.eclipse.osbp.xtext.datamartdsl.DatamartDSLPackage;
import org.eclipse.osbp.xtext.datamartdsl.DatamartDefinition;
import org.eclipse.osbp.xtext.datamartdsl.DatamartEntity;
import org.eclipse.osbp.xtext.datamartdsl.DatamartPackage;
import org.eclipse.osbp.xtext.datamartdsl.DatamartTask;
import org.eclipse.osbp.xtext.dialogdsl.Dialog;
import org.eclipse.osbp.xtext.dialogdsl.DialogDSLPackage;
import org.eclipse.osbp.xtext.dialogdsl.DialogPackage;
import org.eclipse.osbp.xtext.dialogdsl.mapper.AutowireUiFactory;
import org.eclipse.osbp.xtext.functionlibrarydsl.FunctionLibraryDSLPackage;
import org.eclipse.osbp.xtext.functionlibrarydsl.FunctionLibraryDialogGroup;
import org.eclipse.osbp.xtext.functionlibrarydsl.FunctionLibraryDialogHook;
import org.eclipse.osbp.xtext.functionlibrarydsl.FunctionLibraryPackage;
import org.eclipse.osbp.xtext.i18n.I18NKeyGenerator;
import org.eclipse.osbp.xtext.menu.MenuCategory;
import org.eclipse.osbp.xtext.menu.MenuDslPackage;
import org.eclipse.osbp.xtext.menu.MenuEntry;
import org.eclipse.osbp.xtext.menu.MenuTree;
import org.eclipse.osbp.xtext.organizationdsl.Organization;
import org.eclipse.osbp.xtext.perspective.Perspective;
import org.eclipse.osbp.xtext.perspective.PerspectiveBPMN;
import org.eclipse.osbp.xtext.perspective.PerspectiveBrowser;
import org.eclipse.osbp.xtext.perspective.PerspectiveChart;
import org.eclipse.osbp.xtext.perspective.PerspectiveDashboard;
import org.eclipse.osbp.xtext.perspective.PerspectiveDataInterchange;
import org.eclipse.osbp.xtext.perspective.PerspectiveDialog;
import org.eclipse.osbp.xtext.perspective.PerspectiveDslPackage;
import org.eclipse.osbp.xtext.perspective.PerspectiveElement;
import org.eclipse.osbp.xtext.perspective.PerspectiveGrid;
import org.eclipse.osbp.xtext.perspective.PerspectiveKanban;
import org.eclipse.osbp.xtext.perspective.PerspectiveOrganization;
import org.eclipse.osbp.xtext.perspective.PerspectivePackage;
import org.eclipse.osbp.xtext.perspective.PerspectivePart;
import org.eclipse.osbp.xtext.perspective.PerspectivePartStack;
import org.eclipse.osbp.xtext.perspective.PerspectiveReport;
import org.eclipse.osbp.xtext.perspective.PerspectiveSashContainer;
import org.eclipse.osbp.xtext.perspective.PerspectiveSaiku;
import org.eclipse.osbp.xtext.perspective.PerspectiveSearch;
import org.eclipse.osbp.xtext.perspective.PerspectiveSelection;
import org.eclipse.osbp.xtext.perspective.PerspectiveTable;
import org.eclipse.osbp.xtext.perspective.PerspectiveTitle;
import org.eclipse.osbp.xtext.perspective.PerspectiveTopology;
import org.eclipse.osbp.xtext.perspective.PerspectiveView;
import org.eclipse.osbp.xtext.perspective.PerspectiveWelcome;
import org.eclipse.osbp.xtext.reportdsl.DatamartContainer;
import org.eclipse.osbp.xtext.reportdsl.Element;
import org.eclipse.osbp.xtext.reportdsl.Report;
import org.eclipse.osbp.xtext.reportdsl.ReportDSLPackage;
import org.eclipse.osbp.xtext.reportdsl.ReportDesignTemplate;
import org.eclipse.osbp.xtext.reportdsl.ReportPackage;
import org.eclipse.osbp.xtext.signal.SignalDSLPackage;
import org.eclipse.osbp.xtext.signal.SignalDefinition;
import org.eclipse.osbp.xtext.signal.SignalPackage;
import org.eclipse.osbp.xtext.signal.SignalScheduler;
import org.eclipse.osbp.xtext.table.Table;
import org.eclipse.osbp.xtext.table.TableDSLPackage;
import org.eclipse.osbp.xtext.table.TableGrid;
import org.eclipse.osbp.xtext.table.TablePackage;
import org.eclipse.osbp.xtext.table.TableTable;
import org.eclipse.osbp.xtext.topologydsl.Topology;
import org.eclipse.osbp.xtext.topologydsl.TopologyDSLPackage;
import org.eclipse.osbp.xtext.topologydsl.TopologyPackage;
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider;
import org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor;
import org.eclipse.persistence.internal.jpa.deployment.SEPersistenceUnitInfo;
import org.eclipse.persistence.jpa.Archive;
import org.eclipse.persistence.jpa.PersistenceProvider;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.util.Pair;
import org.eclipse.xtext.util.Tuples;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The Class DSLBuilderParticipant.
 */
@SuppressWarnings("restriction")
@Component(service = { IBuilderParticipant.class }, property = { "service.ranking:Integer=1000" })
public class DSLBuilderParticipant extends AbstractBuilderParticipant {

	/** The Constant log. */
	private static final Logger log = LoggerFactory.getLogger(DSLBuilderParticipant.class);

	/** The meta data builder service. */
	@Inject
	private IMetadataBuilderService metadataBuilderService;

	/** The context. */
	private ComponentContext context;

	/** The dsl service register. */
	private ServiceRegistration<IDSLMetadataService> dslServiceRegister;

	/** The dsl bundles. */
	private Map<String, List<Bundle>> dslBundles = new HashMap<>();
	
	/** The entity class loaders. */
	private Map<String, ClassLoader> entityClassLoaders = new HashMap<>();

	/** The persistence units. */
	private Map<String, SEPersistenceUnitInfo> persistenceUnitInfos = new HashMap<>();

	/** The used keys. */
	private Map<Bundle, List<String>> usedKeys = new HashMap<>();

	/** The scanned bundles for translations. */
	private List<Bundle> scannedBundles = new ArrayList<>();

	/** The master bundles for translations. */
	private List<Bundle> masterBundles = new ArrayList<>();
	
	/** The translations. */
	private Map<String, Properties> translations = new HashMap<>();
	/** The translations source. */
	private Map<String, Properties> translationSource = new HashMap<>();
	/** The cache for nearest localeTag to a localeString */
	private Map<String, String> localeCache = new HashMap<>();
	/** to reduce regex matching */
	private Map<String, String> keyCache = new HashMap<>();

	private boolean osbee = false;

	/**
	 * Activate.
	 *
	 * @param context
	 *            the context
	 */
	@Activate
	protected void activate(ComponentContext context) {
		this.context = context;
	}

	/**
	 * Deactivate.
	 *
	 * @param context
	 *            the context
	 */
	@Deactivate
	protected void deactivate(ComponentContext context) {
		metadataBuilderService.removeFromBundleSpace(context.getBundleContext().getBundle());
		this.context = null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.xtext.builder.metadata.services.
	 * AbstractBuilderParticipant #getModels(org.osgi.framework.Bundle)
	 */
	@Override
	public List<URL> getModels(Bundle suspect) {
		List<URL> results = new ArrayList<>();
		BundleWiring wiring = suspect.adapt(BundleWiring.class);
		suspect.getState();
		if (wiring == null) {
			return results;
		}
		log.debug("visiting bundle {}", suspect.getSymbolicName());
		if(suspect.getSymbolicName().contains("osbee")) {
			osbee  = true;
		}
		scanModelBundles(suspect, results, wiring);
		scanRuntimeBundles(suspect);
		// bundles containing translations and don't scan translations twice
		scanTranslationBundles(suspect);

		Set<String> fragments = new HashSet<>();
		for (Iterator<URL> iterator = results.iterator(); iterator.hasNext();) {
			URL url = iterator.next();
			URI uri = URI.createURI(url.toString());
			if (fragments.contains(uri.lastSegment())) {
				iterator.remove();
			}
			fragments.add(uri.lastSegment());
		}

		return results;
	}

	/**
	 * Scan translation bundles containing translation resources.
	 *
	 * @param suspect
	 *            the suspect
	 */
	private void scanTranslationBundles(Bundle suspect) {
		if ((containsHeader(suspect, IExtenderConstants.FACTORY_TRANSLATIONS) || containsHeader(suspect, IExtenderConstants.FACTORY_MODEL_EXTENDER))
			&& !scannedBundles.contains(suspect)) {
			boolean isMasterTranslation=containsHeader(suspect, IExtenderConstants.FACTORY_MASTER_TRANSLATIONS);

			loadTranslations(suspect, isMasterTranslation);
			
			if (isMasterTranslation ) {
				masterBundles.add(suspect);
			}
			
			scannedBundles.add(suspect);
		}
	}

	/**
	 * Scan runtime bundles necessary at runtime to be called dynamically via
	 * uri.
	 *
	 * @param suspect
	 *            the suspect
	 */
	private void scanRuntimeBundles(Bundle suspect) { // NOSONAR
		if (containsHeader(suspect, IExtenderConstants.FACTORY_BUNDLE_EXTENDER)) {
			for (String extension : getExtensions(suspect, IExtenderConstants.FACTORY_BUNDLE_EXTENDER)) {
				extension = extension.trim();
				if (!extension.isEmpty()) {
					if (dslBundles.containsKey(extension)) {
						if (!dslBundles.get(extension).contains(suspect)) {
							dslBundles.get(extension).add(suspect);
						}
					} else {
						List<Bundle> list = new ArrayList<>();
						list.add(suspect);
						dslBundles.put(extension, list);
					}
				}
			}
		}
	}

	/**
	 * Scan model bundles containing model information
	 *
	 * @param suspect
	 *            the suspect
	 * @param results
	 *            the results
	 * @param wiring
	 *            the wiring
	 */
	private void scanModelBundles(Bundle suspect, List<URL> results, BundleWiring wiring) { // NOSONAR
		if (containsHeader(suspect, IExtenderConstants.FACTORY_MODEL_EXTENDER)) {
			for (String extension : getExtensions(suspect, IExtenderConstants.FACTORY_MODEL_EXTENDER)) {
				extension = extension.trim();
				if (!extension.isEmpty()) {
					List<URL> entries = wiring.findEntries("/", "*." + extension, BundleWiring.LISTRESOURCES_RECURSE);
					boolean hadEntries = false;
					for (URL entry : entries) {
						if (!entry.getPath().contains("META-INF")) {
							log.debug("found entry {}  from bundle {}", entry.getPath(), suspect.getSymbolicName());
							results.add(entry);
							hadEntries = true;
						}
					}
					if (hadEntries) {
						if (dslBundles.containsKey(extension)) {
							if (!dslBundles.get(extension).contains(suspect)) {
								dslBundles.get(extension).add(suspect);
							}
						} else {
							List<Bundle> list = new ArrayList<>();
							list.add(suspect);
							dslBundles.put(extension, list);
						}
						// don't scan translations twice
						if (!scannedBundles.contains(suspect)) {
							scanTranslationBundles(suspect);
						}
						if("entity".equals(extension)) {
							extractPersistenceUnits(wiring);
						}
					}
				}
			}
		}
	}

	private void extractPersistenceUnits(BundleWiring wiring) {
		List<URL> pUnits = wiring.findEntries("/", "persistence.xml", BundleWiring.LISTRESOURCES_RECURSE);
		for (URL pUnit : pUnits) {
			SEPersistenceUnitInfo persistenceUnitInfo = null;
			Set<Archive> pars;
			pars = PersistenceUnitProcessor.findPersistenceArchives(wiring.getClassLoader(), pUnit.getPath());
			try {
				for (Archive archive : pars) {
					Iterator<SEPersistenceUnitInfo> persistenceUnits = PersistenceUnitProcessor.getPersistenceUnits(archive, wiring.getClassLoader()).iterator();
					while(persistenceUnits.hasNext()) {
						persistenceUnitInfo = persistenceUnits.next();
						if (persistenceUnitInfo != null && isPersistenceProviderSupported(persistenceUnitInfo.getPersistenceProviderClassName())) {
							persistenceUnitInfos.put(persistenceUnitInfo.getPersistenceUnitName(), persistenceUnitInfo);
							for(String clz:persistenceUnitInfo.getManagedClassNames()) {
								entityClassLoaders.put(getPackageName(clz), wiring.getClassLoader());
							}
							
						}
					}
				}
			} finally {
				for (Archive archive : pars) {
					archive.close();
				}
			}
		}
	}

	public static String getPackageName(String className) {
		int lastDot = className.lastIndexOf('.');
		if (lastDot == -1) {
			return "";
		}
		return className.substring(0, lastDot);
	}

	private boolean isPersistenceProviderSupported(String providerClassName) {
		return (providerClassName == null || providerClassName.equals("")
				|| providerClassName.equals(EntityManagerFactoryProvider.class.getName())
				|| providerClassName.equals(PersistenceProvider.class.getName()));
	}
	
	/**
	 * Load translations from a bundle. Tries to find an i18n directory with
	 * different language properties.
	 *
	 * @param suspect
	 *            the suspect
	 */
	void loadTranslations(Bundle suspect, boolean isMasterTranslation ) {
		BundleWiring bundleWiring = suspect.adapt(BundleWiring.class);
		ClassLoader classLoader = bundleWiring.getClassLoader();
		// check for duplicate keys
		List<String> duplicateKeys = new ArrayList<>();
		try {
			final List<String> keys = Collections
					.list(ResourceBundle.getBundle("i18n.I18N", Locale.ROOT, classLoader).getKeys());
			for (Entry<Bundle, List<String>> used : usedKeys.entrySet()) {
				for (String entry : used.getValue()) {
					if (keys.contains(entry) && !isMasterTranslation ) {
						duplicateKeys.add(entry);
						if ( log.isDebugEnabled() ) {
							log.debug("{}  has the key >{}< but is already contained in {}",
									suspect.getSymbolicName(), entry, used.getKey().getSymbolicName());
						}
					} else {
						if ( log.isDebugEnabled() ) {
							log.debug("{}  has the key >{}< ",
									suspect.getSymbolicName(), entry);
						}
					}
				}
			}
			usedKeys.put(suspect, keys);
		} catch (MissingResourceException e) { // NOSONAR
		}
		for (String language : ProductConfiguration.getLanguages().keySet()) {
			if (language.equals("default")) {
				continue;
			}
			Properties properties = null;
			Properties propertiesMasterinfo = null;
			log.debug("bundle {} loads translations for locale {}", suspect.getSymbolicName(), language);
			if (translations.containsKey(language)) {
				properties = translations.get(language);
			
			} else {
				properties = new Properties();
			}
			if (translationSource.containsKey(language)) {
				propertiesMasterinfo = translationSource.get(language);
				
			} else {
				propertiesMasterinfo = new Properties();
			}
			try {
				ResourceBundle resource = ResourceBundle.getBundle("i18n.I18N", Locale.forLanguageTag(language),
						classLoader);
				computeTranslations(duplicateKeys, language, properties, propertiesMasterinfo, resource, isMasterTranslation);
			} catch (MissingResourceException e) {
				log.debug("bundle {} has no resource for locale {}", suspect.getSymbolicName(), language);
			}
		}
	}

	private void computeTranslations(List<String> duplicateKeys, String language, Properties properties, // NOSONAR
			Properties propertiesMasterinfo, ResourceBundle resource, boolean isMasterTranslation) {
		
		Enumeration<String> keyIterator = resource.getKeys();
		while (keyIterator.hasMoreElements()) {
			String element = keyIterator.nextElement();
			if (!element.isEmpty()) {
				
				if ( propertiesMasterinfo != null && propertiesMasterinfo.get(element) != null ) {
					// an existing entry is from a master translation file
					if ( log.isDebugEnabled() ) {
						log.debug("translation for {} of key >{}< with >{}< ignored. MasterTranslation exists! )",
								language, element, resource.getString(element) );
					}
					continue;
				}
				
				String value = resource.getString(element);

				if ( isMasterTranslation ) {
					// this is a master translation -> add it to the list
					if (value != null && value.length() != 0 && !value.equals(element)) {
						properties.put(element, value);
						propertiesMasterinfo.put(element, "1");
						log.debug("translation for {} of key >{}< with >{}< added. isMasterTranslation! )",
								language, element, value);
					}
					continue;
				}
									
				if (duplicateKeys.contains(element)) {

					// we have no master translation here, so we have to decide which translation to use
					
					// let the empty value be the one with the closest distance, so it will not be used if there is something better! 
					int distanceFromKey = 0;
					if ( value != null && value.length() > 0 ) {
						distanceFromKey = StringUtils.getLevenshteinDistance(value, element);
					}

					String prevValue = properties.getProperty(element);
					int distanceFromPrevious = 0;
					if (prevValue != null && value.length() > 0 ) {
						distanceFromPrevious = StringUtils.getLevenshteinDistance(prevValue, element);
					}
					
					if (distanceFromKey > 1 && distanceFromKey > distanceFromPrevious) {
						properties.put(element, value);
						log.debug( "translation for {} of key >{}< with >{}< was preferred due to its better levenshtein distance from the key.( {} > {} !)",
								language, element, value, distanceFromKey, distanceFromPrevious);
					}
					continue;
				}
				
				if (value != null && value.length() != 0 && !value.equals(element)) {
					
					// no master translation, no duplicate key -> just use it.
					
					properties.put(element, value);
					log.debug("translation for {} of key >{}< with >{}< added.  )",
							language, element, value);
				}
			}
		}
		if (!properties.isEmpty()) {
			translations.put(language, properties);
		}
		if (!propertiesMasterinfo.isEmpty()) {
			translationSource.put(language, propertiesMasterinfo);
		}
	}

	/**
	 * Returns true, if the bundle contains the header.
	 *
	 * @param bundle
	 *            the bundle
	 * @param header
	 *            the header
	 * @return true, if successful
	 */
	private boolean containsHeader(Bundle bundle, String header) {
		Dictionary<String, String> headers = bundle.getHeaders();
		Enumeration<String> keys = headers.keys();
		while (keys.hasMoreElements()) {
			String key = keys.nextElement();
			if (key.equals(header)) {
				return true;
			}
		}
		return false;
	}


	/**
	 * Gets the extensions.
	 *
	 * @param bundle
	 *            the bundle
	 * @param header
	 *            the header
	 * @return the extensions
	 */
	private List<String> getExtensions(Bundle bundle, String header) {
		return new ArrayList<>(Arrays.asList(bundle.getHeaders().get(header).split(",")));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.xtext.builder.metadata.services.
	 * AbstractBuilderParticipant
	 * #notifyLifecyle(org.eclipse.osbp.xtext.builder.metadata.services.
	 * IBuilderParticipant.LifecycleEvent)
	 */
	@Override
	public void notifyLifecyle(LifecycleEvent event) {
		if (event.getState() == IBuilderParticipant.LifecycleEvent.INITIALIZE) {
			initialize();
		} else if (event.getState() == IBuilderParticipant.LifecycleEvent.BUNDLES_SCANNED) {
			DSLMetadataService datatypesService = new DSLMetadataService();
			dslServiceRegister = context.getBundleContext().registerService(IDSLMetadataService.class, datatypesService,
					null);

		} else if (event.getState() == IBuilderParticipant.LifecycleEvent.DEACTIVATED) {
			if (dslServiceRegister != null) {
				dslServiceRegister.unregister();
				dslServiceRegister = null;
			}

			if (metadataBuilderService != null) {
				metadataBuilderService.removeFromBundleSpace(context.getBundleContext().getBundle());
			}
		}
	}

	/**
	 * Initialize.
	 */
	private void initialize() {
		StandaloneGrammarsSetup.setup();
		metadataBuilderService.addToBundleSpace(context.getBundleContext().getBundle());
	}

	/**
	 * Provided as an OSGi service to returnmodels for the given qualified name.
	 */
	public class DSLMetadataService implements IDSLMetadataService {
		
		/* (non-Javadoc)
		 * @see org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#reloadModel(java.lang.String)
		 */
		@Override
		public void unloadModel(String extension) {
			metadataBuilderService.unloadResource(extension);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getMetadata(
		 * java.lang.String, org.eclipse.emf.ecore.EClass)
		 */
		@Override
		public EObject getMetadata(String id, EClass eclass) {
			return metadataBuilderService.getMetadata(id, eclass);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getResourceURL(
		 * java.lang.String, java.lang.String)
		 */
		@Override
		public URL getResourceURL(String resourceName, String extension) {
			if (dslBundles.containsKey(extension)) {
				for (Bundle bundle : dslBundles.get(extension)) {
					BundleWiring wiring = bundle.adapt(BundleWiring.class);
					List<URL> entries = wiring.findEntries("/", resourceName, BundleWiring.LISTRESOURCES_RECURSE);
					if (!entries.isEmpty()) {
						return entries.get(0);
					}
				}
			}
			log.error("resource {} could not be found in bundles with extension {}", resourceName, extension);
			return null;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getClass(org.
		 * eclipse.emf.ecore.EObject, java.lang.String)
		 */
		@Override
		public Class<?> getClass(EObject eObject, String extension) {
			return getClass(getClassName(eObject, ""), extension);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getClass(java.lang.String, java.lang.String)
		 */
		@Override
		public Class<?> getClass(String fqn, String extension) {
			if (dslBundles.containsKey(extension)) {
				for (Bundle bundle : dslBundles.get(extension)) {
					BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
					ClassLoader classLoader = bundleWiring.getClassLoader();
					Class<?> clz = null;
					try {
						clz = classLoader.loadClass(fqn);
					} catch (ClassNotFoundException e) {
						// nothing to do
					}
					if (clz != null) {
						return clz;
					}
				}
			}
			log.error("class {} could not be found for extension {}", fqn, extension);
			return null;
		}
		
		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getClassInstance
		 * (org.eclipse.emf.ecore.EObject, java.lang.String)
		 */
		@Override
		public Object getClassInstance(EObject eObject, String extension) {
			return getClassInstance(getClass(eObject, extension), extension);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getClassInstance(java.lang.Class, java.lang.String)
		 */
		@Override
		public Object getClassInstance(Class<?> clz, String extension) {
			try {
				if (clz != null) {
					return clz.newInstance();
				}
			} catch (InstantiationException | IllegalAccessException e) {
				log.error("class {} could not be instantiated", clz.getCanonicalName());
				if (e.getCause() != null) {
					log.error("because {}", e.getCause());
				}
			}
			return null;
		}
		/**
		 * Gets the class URI. As more than one bundle could carry a model
		 * instance, we must try to load the requested class to be sure to have
		 * the right bundle for this class.
		 *
		 * @param className
		 *            the class name
		 * @param extension
		 *            the extension
		 * @return the class URI as string
		 */
		@Override
		public String getClassURI(String className, String extension) {
			if (dslBundles.containsKey(extension)) {
				for (Bundle bundle : dslBundles.get(extension)) {
					try {
						BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
						ClassLoader classLoader = bundleWiring.getClassLoader();
						Class<?> clz = classLoader.loadClass(className);
						if (clz != null) {
							return "bundleclass://" + bundle.getSymbolicName() + "/" + className;
						}
					} catch (ClassNotFoundException e) { // NOSONAR
					}
				}
			}
			return null;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getClassURI(
		 * org.eclipse.emf.ecore.EObject, java.lang.String)
		 */
		@Override
		public String getClassURI(EObject eObject, String kind) {
			return getClassURI(getClassName(eObject, kind), NamingConventions.toExtension(eObject));
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#
		 * getAllDescriptions (org.eclipse.emf.ecore.EClass)
		 */
		@Override
		public Iterable<IEObjectDescription> getAllDescriptions(EClass eClass) {
			return metadataBuilderService.getAllDescriptions(eClass);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getClassName
		 * (org.eclipse.emf.ecore.EObject, java.lang.String)
		 */
		@Override
		public String getClassName(EObject eObject, String kind) {
			return NamingConventions.toClassName(eObject);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#
		 * getFullyQualifiedName(org.eclipse.emf.ecore.EObject)
		 */
		@Override
		public String getFullyQualifiedName(EObject eObject) {
			return NamingConventions.toFQN(eObject);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#resolve(org.
		 * eclipse.emf.ecore.EObject)
		 */
		@Override
		public EObject resolve(EObject proxy) {
			return metadataBuilderService.resolve(proxy);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getAll(org.
		 * eclipse .emf.ecore.EClass)
		 */
		@Override
		public Iterable<EObject> getAll(EClass eClass) {
			return metadataBuilderService.getAll(eClass);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#translate(java
		 * .lang.String, java.lang.String)
		 */
		@Override
		public String translate(String localeString, String key) {
			if (localeString == null || key == null) {
				return key;
			}
			String localeTag = null;
			if(localeCache.containsKey(localeString)) {
				localeTag = localeCache.get(localeString);
			} else {
				List<Locale.LanguageRange> languageRanges = Locale.LanguageRange.parse(localeString + ";q=1.0");
				localeTag = Locale.lookupTag(languageRanges, translations.keySet());
				localeCache.put(localeString, localeTag);
			}
			
			if (localeTag != null) {
				Properties properties = translations.get(localeTag);
				if (properties != null) {
					String k = null;
					if(keyCache.containsKey(key)) {
						k = keyCache.get(key);
					} else {
						k = I18NKeyGenerator.key(key);
						// special solution for auto generated dto
						if (k.endsWith("_dto")) {
							k = k.substring(0, k.length() - 4);
						}
						keyCache.put(key, k);
					}
					if (properties.containsKey(k)) {
						return properties.getProperty(k);
					}
				} else {
					log.error("localeTag {} not supported", localeTag);
				}
			} else {
				log.error("locale {} not supported", localeString);
			}
			return key;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getTranslations
		 * ()
		 */
		@Override
		public Map<String, Properties> getTranslations() {
			return translations;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getTypeProvider
		 * ()
		 */
		@Override
		public BundleSpaceTypeProvider getTypeProvider() {
			return metadataBuilderService.getTypeProvider();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getAllTypeNames
		 * (java.lang.String, java.lang.String)
		 */
		@Override
		public Map<String, Object> getAllSubtypes(String localeTag, Class<?> type) {
			LinkedHashMap<String, Object> subTypesNames = new LinkedHashMap<>();
			subTypesNames.put(translate(localeTag, type.getSimpleName()), type);
			JvmDeclaredType jvmType = (JvmDeclaredType) metadataBuilderService.getTypeProvider().findTypeByName(type.getCanonicalName());
			Set<JvmDeclaredType> subTypes = metadataBuilderService.findSubTypes(jvmType);
			for (JvmDeclaredType subType : subTypes) {
				try {
					Class<?> subtypeClass = createType(subType.getQualifiedName());
					subTypesNames.put(translate(localeTag, subType.getSimpleName()), subtypeClass);
				} catch (ClassNotFoundException e) {
					log.error("{}", e);
				}
			}
			return subTypesNames;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#createType(java
		 * .lang.String)
		 */
		@Override
		public Class<?> createType(String typeName) throws ClassNotFoundException {
			return metadataBuilderService.getBundleSpace().forName(typeName);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#
		 * getDslGrammarElements
		 * (org.eclipse.osbp.ui.api.metadata.IDSLMetadataService.DSLLiterals)
		 */
		@SuppressWarnings("rawtypes")
		@Override
		public List<Pair> getDslGrammarElementNames(IDSLMetadataService.DSLLiterals literal) {
			List<Pair> result = new ArrayList<>();
			if (literal == DSLLiterals.PERSPECTIVES) {
				for (EObject obj : getAll(PerspectiveDslPackage.Literals.PERSPECTIVE)) {
					Perspective perspective = ((Perspective) obj);
					result.add(Tuples.pair(perspective.getName(), NamingConventions.getPerspectiveFQN(perspective)));
				}
			}
			return result;
		}

		@SuppressWarnings("unchecked")
		@Override
		public <T> void execute(T state, Object unitOfWork) {
			metadataBuilderService.execute(state, (IUnitOfWork<T>) unitOfWork);
		}

		@Override
		public Class<?> getDatamartRootClass(String canonicalName) {
			DatamartDefinition definition = (DatamartDefinition) getMetadata(canonicalName,
					DatamartDSLPackage.Literals.DATAMART_DEFINITION);
			if (definition == null) {
				return null;
			}
			if (!(definition.getSource() instanceof DatamartEntity)) {
				return null;
			}
			LEntity entity = ((DatamartEntity) definition.getSource()).getEntityRef();
			return getClass(entity, "entity");
		}

		@Override
		public String getDatamartRootClassIdentifierName(String canonicalName) {
			DatamartDefinition definition = (DatamartDefinition) getMetadata(canonicalName,
					DatamartDSLPackage.Literals.DATAMART_DEFINITION);
			if (definition == null) {
				return null;
			}
			if (!(definition.getSource() instanceof DatamartEntity)) {
				return null;
			}
			LEntity entity = ((DatamartEntity) definition.getSource()).getEntityRef();
			if (entity.getPrimaryKeyAttribute() == null) {
				return null;
			}
			return entity.getPrimaryKeyAttribute().getName();
		}

		@Override
		public String getECViewId(EObject dialog) {
			if(!(dialog instanceof Dialog)) {
				log.error("{} is not a dialog.", dialog);
				return "";
			}
			return NamingConventions.getECViewId((Dialog) dialog);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#isOsbee()
		 */
		@Override
		public boolean isOsbee() {
			return osbee;
		}

		
		/* (non-Javadoc)
		 * @see org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getClassLoader(java.lang.String)
		 */
		@Override
		public ClassLoader getClassLoader(String className) {
			for(Entry<String, ClassLoader> entityBundle:entityClassLoaders.entrySet()) {
				if(className.startsWith(entityBundle.getKey())) {
					return entityBundle.getValue();
				}
			}
			return null;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.osbp.ui.api.metadata.IDSLMetadataService#getPersistenceUnitInfo(java.lang.String)
		 */
		@Override
		public Object getPersistenceUnitInfo(String persistenceUnitName) {
			if(persistenceUnitInfos.containsKey(persistenceUnitName)) {
				return persistenceUnitInfos.get(persistenceUnitName);
			}
			return null;
		}

		@Override
		public boolean isMenuCategoryAuthorized(String fqn, IUserAccessService userAccessService) {
			Map<String, Boolean> authorized = new HashMap<>();
			MenuCategory category = (MenuCategory)getMetadata(fqn, MenuDslPackage.Literals.MENU_CATEGORY);
			for(MenuTree tree:category.getTrees()) {
				isMenuTreeAuthorized(tree, userAccessService, authorized);
			}
			return getAuthorization(authorized);
		}
		
		@Override
		public boolean isMenuTreeAuthorized(String fqn, IUserAccessService userAccessService) {
			Map<String, Boolean> authorized = new HashMap<>();
			MenuTree tree = (MenuTree)getMetadata(fqn, MenuDslPackage.Literals.MENU_TREE);
			isMenuTreeAuthorized(tree, userAccessService, authorized);
			return getAuthorization(authorized);
		}

		private void isMenuTreeAuthorized(MenuTree tree, IUserAccessService userAccessService,
				Map<String, Boolean> authorized) {
			for(MenuEntry entry:tree.getEntries()) {
				if(entry.isHasPerspective() && entry.getPerspective() != null) {
					for(PerspectiveElement element:entry.getPerspective().getElements()) {
						traverseModel(element, userAccessService, authorized);
					}
				} else if(entry.isHasProcess() && entry.getProcess() != null) {
					authorized.put(entry.getProcess().getName(), userAccessService.isGranted(Group.PROCESS, Action.STARTABLE, entry.getProcess().getName()));
				}
			}
		}
		
		@Override
		public boolean isPerspectiveAuthorized(String fqn, IUserAccessService userAccessService) {
			Map<String, Boolean> authorized = new HashMap<>();
			Perspective perspective = (Perspective)getMetadata(fqn, PerspectiveDslPackage.Literals.PERSPECTIVE);
			for(PerspectiveElement element:perspective.getElements()) {
				traverseModel(element, userAccessService, authorized);
			}
			return getAuthorization(authorized);
		}
		
		@Override
		public boolean isPerspectiveElementAuthorized(EObject modelElement, IUserAccessService userAccessService) {
			Map<String, Boolean> authorized = new HashMap<>();
			traverseModel((PerspectiveElement)modelElement, userAccessService, authorized);
			return getAuthorization(authorized);
		}
		
		private void traverseModel(PerspectiveElement modelElement, IUserAccessService userAccessService, Map<String, Boolean> authorized) {
			if (modelElement instanceof PerspectivePart) {
				PerspectiveView view = ((PerspectivePart)modelElement).getView(); 
				if(view != null) {
					isViewAuthorized(view, userAccessService, authorized);
				}
			} else {
				for (PerspectiveElement element : modelElement.getElements()) {
					traverseModel(element, userAccessService, authorized);
				}
			}
		}
		
		private boolean getAuthorization(Map<String, Boolean> authorized) {
			int vetoCount = 0;
			for(Entry<String, Boolean> auth:authorized.entrySet()) {
				if(!auth.getValue()) {
					vetoCount ++;
				}
			}
			return authorized.isEmpty() || vetoCount < authorized.size();
		}
		
		private void isViewAuthorized(PerspectiveView view, IUserAccessService userAccessService, Map<String, Boolean> authorized) {
			if(view instanceof PerspectiveSelection) {
				isTableAuthorized(((PerspectiveSelection)view).getRef(), userAccessService, authorized);
			} else if(view instanceof PerspectiveTable) {
				isTableAuthorized(((PerspectiveTable)view).getRef(), userAccessService, authorized);
			} else if(view instanceof PerspectiveGrid) {
				isTableAuthorized(((PerspectiveGrid)view).getRef(), userAccessService, authorized);
			} else if(view instanceof PerspectiveChart) {
				isChartAuthorized(((PerspectiveChart)view).getRef(), userAccessService, authorized);
			} else if(view instanceof PerspectiveReport) {
				isReportAuthorized(((PerspectiveReport)view).getRef(), userAccessService, authorized);
			} else if(view instanceof PerspectiveDialog) {
				isDialogAuthorized(((PerspectiveDialog)view).getRef(), userAccessService, authorized);
			} else if(view instanceof PerspectiveKanban) {
				isDtoAuthorized(((PerspectiveKanban)view).getDtoRef(), userAccessService, authorized);
				isDialogAuthorized(((PerspectiveKanban)view).getCardRef(), userAccessService, authorized);
				isDialogAuthorized(((PerspectiveKanban)view).getDialogRef(), userAccessService, authorized);
			} else if(view instanceof PerspectiveSearch) {
				isDtoAuthorized(((PerspectiveSearch)view).getDtoRef(), userAccessService, authorized);
			} else if(view instanceof PerspectiveDataInterchange) {
				isDatainterchangeGroupAuthorized(((PerspectiveDataInterchange)view).getRef(), userAccessService, authorized);
			} else if(view instanceof PerspectiveOrganization) {
				authorized.put(view.toString(), true);
			} else if(view instanceof PerspectiveTopology) {
				authorized.put(view.toString(), true);
			} else if(view instanceof PerspectiveBPMN) {
				authorized.put(view.toString(), true);
			} else if(view instanceof PerspectiveWelcome) {
				authorized.put(view.toString(), true);
			} else if(view instanceof PerspectiveTitle) {
				authorized.put(view.toString(), true);
			} else if(view instanceof PerspectiveDashboard) {
				authorized.put(view.toString(), true);
			} else if(view instanceof PerspectiveBrowser) {
				authorized.put(view.toString(), true);
			} else if(view instanceof PerspectiveSaiku) {
				authorized.put(view.toString(), true);
			} else {
				throw new IllegalViewException("no such view class:"+view.toString());
			}
		}

		private void isDatainterchangeGroupAuthorized(DataInterchangeGroup group, IUserAccessService userAccessService, Map<String, Boolean> authorized) {
			for(DataInterchange interchange:group.getDatInts()) {
				for(DataInterchangeBean path:interchange.getPath()) {
					isEntityAuthorized(path.getEntity(), userAccessService, authorized);
				}
			}
		}

		private void isReportAuthorized(Report report, IUserAccessService userAccessService, Map<String, Boolean> authorized) {
			if(report != null) {
				isDatamartAuthorized(report.getDatamartRef(), userAccessService, authorized);
				if(report.getDesign() instanceof ReportDesignTemplate) {
					if(((ReportDesignTemplate)report.getDesign()).getHeader() != null) {
						for(Element element : ((ReportDesignTemplate)report.getDesign()).getHeader().getElements()) {
							if(element instanceof DatamartContainer) {
								isDatamartAuthorized(((DatamartContainer)element).getDatamartRef(), userAccessService, authorized);
							}
						}
					}
					if(((ReportDesignTemplate)report.getDesign()).getDetail() != null) {
						for(Element element : ((ReportDesignTemplate)report.getDesign()).getDetail().getElements()) {
							if(element instanceof DatamartContainer) {
								isDatamartAuthorized(((DatamartContainer)element).getDatamartRef(), userAccessService, authorized);
							}
						}
					}
					if(((ReportDesignTemplate)report.getDesign()).getFooter() != null) {
						for(Element element : ((ReportDesignTemplate)report.getDesign()).getFooter().getElements()) {
							if(element instanceof DatamartContainer) {
								isDatamartAuthorized(((DatamartContainer)element).getDatamartRef(), userAccessService, authorized);
							}
						}
					}
				}
			}
		}

		private void isDialogAuthorized(Dialog dialog, IUserAccessService userAccessService, Map<String, Boolean> authorized) {
			if(dialog != null) {
				isDtoAuthorized(dialog.getDto(), userAccessService, authorized);
				if(dialog.getUiView() != null) {
					for(UiBeanSlot slot:dialog.getUiView().getBeanSlots()) {
		    			if(hasSupertype(slot.getJvmType(), IDto.class)) {
		    				authorized.put(slot.getJvmType().getQualifiedName(), userAccessService.isGranted(Group.DTO, Action.READABLE, slot.getJvmType().getQualifiedName()));
						}
					}
				}
			}
		}

		private void isChartAuthorized(Chart chart, IUserAccessService userAccessService,	Map<String, Boolean> authorized) {
			if(chart != null) {
				isDatamartAuthorized(chart.getSource().getDatamartRef(), userAccessService, authorized);
			}
		}

		private void isTableAuthorized(Table table, IUserAccessService userAccessService, Map<String, Boolean> authorized) {
			if(table != null) {
				if(table.getTabletype() instanceof TableTable) {
					isDatamartAuthorized(((TableTable)table.getTabletype()).getSource().getDatamartRef(), userAccessService, authorized);
				} else if(table.getTabletype() instanceof TableGrid) {
					isDtoAuthorized(((TableGrid)table.getTabletype()).getSource().getDtoSource(), userAccessService, authorized);
				} else {
					throw new IllegalViewException("no such table option:"+table.getTabletype().toString());
				}
			}
		}

		private void isDtoAuthorized(LDto dto, IUserAccessService userAccessService, Map<String, Boolean> authorized) {
			if(dto != null) {
				String dtoFqn = getFullyQualifiedName(dto);
				authorized.put(dtoFqn, userAccessService.isGranted(Group.DTO, Action.READABLE, dtoFqn));
			}
		}

		private void isDatamartAuthorized(DatamartDefinition datamart, IUserAccessService userAccessService, Map<String, Boolean> authorized) {
			if(datamart != null) {
				if(datamart.getSource() instanceof DatamartEntity) {
					isEntityAuthorized(((DatamartEntity)datamart.getSource()).getEntityRef(), userAccessService, authorized);
				} else if(datamart.getSource() instanceof DatamartCube) {
					isCubeAuthorized(((DatamartCube)datamart.getSource()).getCubeRef(), userAccessService, authorized);
				} else if(datamart.getSource() instanceof DatamartTask) {
					authorized.put(datamart.toString(), true);
				} else {
					throw new IllegalViewException("no such datamart source:"+datamart.getSource().toString());
				}
			}
		}

		private void isCubeAuthorized(CubeType cube, IUserAccessService userAccessService, Map<String, Boolean> authorized) {
			if(cube != null) {
				LEntity cubeEntity = cube.getCubeTypeEntity().getEntityRef().getEntityValue();
				isEntityAuthorized(cubeEntity, userAccessService, authorized);
				for(CubeDimensionUsage dimension:cube.getCubeTypeEntity().getDimensionUsages()) {
					for(CubeHierarchy hierarchy:dimension.getSourceValue().getHierarchies()) {
						if(hierarchy.getCubeDimEntity() != null) {
							if(hierarchy.getCubeDimEntity().getEntityRef() != null) {
								isEntityAuthorized(hierarchy.getCubeDimEntity().getEntityRef().getEntityValue(), userAccessService, authorized);
							}
							if(hierarchy.getCubeDimEntity().getDimEntity() != null && hierarchy.getCubeDimEntity().getDimEntity().getEntityRef() != null) {
								isEntityAuthorized(hierarchy.getCubeDimEntity().getDimEntity().getEntityRef().getEntityValue(), userAccessService, authorized);
							}
						}
					}
				}
			}
		}

		private void isEntityAuthorized(LEntity entity, IUserAccessService userAccessService, Map<String, Boolean> authorized) {
			if(entity != null) {
				String entityFqn = getFullyQualifiedName(entity);
				authorized.put(entityFqn, userAccessService.isGranted(Group.ENTITY, Action.READABLE, entityFqn));
			}
		}

		@SuppressWarnings("deprecation")
		@Override
		public boolean hasSupertype(JvmTypeReference typeReference, Class<?> clz) {
			SuperTypeCollector collector = new SuperTypeCollector();
			Set<String> result = new LinkedHashSet<>();
			collector.collectSuperTypes(typeReference, new SuperTypeCollector.SuperTypeAcceptor() {
				@Override
				public boolean accept(JvmTypeReference superType, int distance) {
					if(superType.getQualifiedName().equals(clz.getName())) {
						result.add(superType.getQualifiedName());
					}
					return true;
				}
			});
			return !result.isEmpty();
		}
	}

	/**
	 * The Class NamingConventions.
	 */
	private static class NamingConventions {
		private NamingConventions() {
		}

		/**
		 * To extension.
		 *
		 * @param eObject
		 *            the e object
		 * @return the string
		 */
		public static String toExtension(EObject eObject) {
			EPackage pkg = eObject.eClass().getEPackage();

			if (pkg == ChartDSLPackage.eINSTANCE) {
				return IPerspectiveProvider.PerspectiveViewType.CHART;
			} else if (pkg == DialogDSLPackage.eINSTANCE) {
				return IPerspectiveProvider.PerspectiveViewType.DIALOG;
			} else if (pkg == ReportDSLPackage.eINSTANCE) {
				return IPerspectiveProvider.PerspectiveViewType.REPORT;
			} else if (pkg == TableDSLPackage.eINSTANCE) {
				return IPerspectiveProvider.PerspectiveViewType.TABLE;
			} else if (pkg == TopologyDSLPackage.eINSTANCE) {
				return IPerspectiveProvider.PerspectiveViewType.TOPOLOGY;
			} else if (pkg == SignalDSLPackage.eINSTANCE) {
				return IPerspectiveProvider.PerspectiveViewType.SIGNAL;
			} else if (pkg == FunctionLibraryDSLPackage.eINSTANCE) {
				return IPerspectiveProvider.PerspectiveViewType.FUNCTIONLIBRARY;
			}
			throw new IllegalArgumentException(
					IDSLMetadataService.ThrowableMessages.NAMING_LOGIC_NOT_REGISTERD + eObject);
		}

		/**
		 * To FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the string
		 */
		public static String toFQN(EObject eObject) {
			if (eObject == null) {
				return null;
			}

			if (eObject instanceof Chart) {
				return getChartFQN(eObject);
			} else if (eObject instanceof Role) {
				return getAuthorizationFQN(eObject);
			} else if (eObject instanceof Dialog) {
				return getDialogFQN(eObject);
			} else if (eObject instanceof UiIDEView) {
				return getUiIdeFQN(eObject);
			} else if (eObject instanceof LDto) {
				return getDtoFQN(eObject);
			} else if (eObject instanceof LEntity) {
				return getEntityFQN(eObject);
			} else if (eObject instanceof Report) {
				return getReportFQN(eObject);
			} else if (eObject instanceof Table) {
				return getTableFQN(eObject);
			} else if (eObject instanceof Topology) {
				return getTopologyFQN(eObject);
			} else if (eObject instanceof DatamartDefinition) {
				return getDatamartFQN(eObject);
			} else if (eObject instanceof SignalDefinition) {
				return getSignalFQN(eObject);
			} else if (eObject instanceof ActionToolbar) {
				return getActionFQN(eObject);
			} else if (eObject instanceof FunctionLibraryDialogGroup) {
				return getDialogGroupFQN(eObject);
			} else if (eObject instanceof FunctionLibraryDialogHook) {
				return getDialogHookFQN(eObject);
			} else if (eObject instanceof Blip) {
				return getBlipFQN(eObject);
			}
			throw new IllegalArgumentException(
					IDSLMetadataService.ThrowableMessages.NAMING_LOGIC_NOT_REGISTERD + eObject);
		}

		/**
		 * To class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the string
		 */
		public static String toClassName(EObject eObject) {
			if (eObject == null) {
				return null;
			}

			if (eObject instanceof Chart) {
				return getChartClassName(eObject);
			} else if (eObject instanceof Dialog) {
				return getDialogClassName(eObject);
			} else if (eObject instanceof LDto) {
				return getDtoClassName(eObject);
			} else if (eObject instanceof LEntity) {
				return getEntityClassName(eObject);
			} else if (eObject instanceof Report) {
				return getReportClassName(eObject);
			} else if (eObject instanceof Table) {
				return getTableClassName(eObject);
			} else if (eObject instanceof Organization) {
				return getOrganizationClassName(eObject);
			} else if (eObject instanceof Topology) {
				return getTopologyClassName(eObject);
			} else if (eObject instanceof DatamartDefinition) {
				return getDatamartClassName(eObject);
			} else if (eObject instanceof DataInterchangePackage) {
				return getDataInterchangeClassName(eObject);
			} else if (eObject instanceof SignalPackage) {
				return getSignalClassName(eObject);
			} else if (eObject instanceof ActionToolbar) {
				return getActionToolbarClassName(eObject);
			}
			throw new IllegalArgumentException(
					IDSLMetadataService.ThrowableMessages.NAMING_LOGIC_NOT_REGISTERD + eObject);
		}

		/**
		 * Gets the dto FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the dto FQN
		 */
		private static String getDtoFQN(EObject eObject) {
			LDto dto = (LDto) eObject;
			if (dto == null) {
				return "";
			}
			LTypedPackage pkg = (LTypedPackage) dto.eContainer();
			return pkg.getName() + "." + dto.getName();
		}

		/**
		 * Gets the entity FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the entity FQN
		 */
		private static String getEntityFQN(EObject eObject) {
			LEntity entity = (LEntity) eObject;
			if (entity == null) {
				return "";
			}
			LTypedPackage pkg = (LTypedPackage) entity.eContainer();
			return pkg.getName() + "." + entity.getName();
		}

		/**
		 * Gets the authorization FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the table FQN
		 */
		private static String getAuthorizationFQN(EObject eObject) {
			Role role = (Role) eObject;
			if (role == null) {
				return "";
			}
			AuthorizationPackage pkg = (AuthorizationPackage) role.eContainer();
			return pkg.getName() + "." + role.getName();
		}

		/**
		 * Gets the table FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the table FQN
		 */
		private static String getTableFQN(EObject eObject) {
			Table table = (Table) eObject;
			if (table == null) {
				return "";
			}
			TablePackage pkg = (TablePackage) table.eContainer();
			return pkg.getName() + "." + table.getName();
		}

		/**
		 * Gets the chart FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the chart FQN
		 */
		private static String getChartFQN(EObject eObject) {
			Chart chart = (Chart) eObject;
			if (chart == null) {
				return "";
			}
			ChartPackage pkg = (ChartPackage) chart.eContainer();
			return pkg.getName() + "." + chart.getName();
		}

		/**
		 * Gets the report FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the report FQN
		 */
		private static String getReportFQN(EObject eObject) {
			Report report = (Report) eObject;
			if (report == null) {
				return "";
			}
			ReportPackage pkg = (ReportPackage) report.eContainer();
			return pkg.getName() + "." + report.getName();
		}

		/**
		 * Gets the dialog FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the dialog FQN
		 */
		private static String getDialogFQN(EObject eObject) {
			Dialog dialog = (Dialog) eObject;
			if (dialog == null) {
				return "";
			}
			DialogPackage pkg = (DialogPackage) dialog.eContainer();
			return pkg.getName() + "." + dialog.getName();
		}
		
		/**
		 * Gets the uiModel FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the dialog FQN
		 */
		private static String getUiIdeFQN(EObject eObject) {
			UiIDEView ui = (UiIDEView) eObject;
			if (ui == null) {
				return "";
			}
			UiModelPackage pkg = (UiModelPackage) ui.eContainer();
			return pkg.getName() + "." + ui.getName();
		}

		private static String getDatainterchangeFQN(EObject eObject) {
			DataInterchangePackage data = (DataInterchangePackage) eObject;
			if (data == null) {
				return "";
			}
			return data.getName();
		}

		/**
		 * Gets the perspective FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the perspective FQN
		 */
		private static String getPerspectiveFQN(EObject eObject) {
			Perspective perspective = (Perspective) eObject;
			if (perspective == null) {
				return "";
			}
			PerspectivePackage pkg = (PerspectivePackage) perspective.eContainer();
			return pkg.getName() + "." + perspective.getName();
		}

		/**
		 * Gets the topology FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the topology FQN
		 */
		private static String getTopologyFQN(EObject eObject) {
			Topology topology = (Topology) eObject;
			if (topology == null) {
				return "";
			}
			TopologyPackage pkg = (TopologyPackage) topology.eContainer();
			return pkg.getName() + "." + topology.getName();
		}

		/**
		 * Gets the datamart FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the datamart FQN
		 */
		private static String getDatamartFQN(EObject eObject) {
			DatamartDefinition datamart = (DatamartDefinition) eObject;
			if (datamart == null) {
				return "";
			}
			DatamartPackage pkg = (DatamartPackage) datamart.eContainer();
			return pkg.getName() + "." + datamart.getName();
		}
		
		/**
		 * Gets the action FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the action FQN
		 */
		private static String getActionFQN(EObject eObject) {
			ActionToolbar actionToolbar = (ActionToolbar) eObject;
			if (actionToolbar == null) {
				return "";
			}
			ActionPackage pkg = (ActionPackage) actionToolbar.eContainer();
			return pkg.getName() + "." + actionToolbar.getName();
		}
		
		/**
		 * Gets the blip FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the action FQN
		 */
		private static String getBlipFQN(EObject eObject) {
			Blip blip = (Blip) eObject;
			if (blip == null) {
				return "";
			}
			BlipPackage pkg = (BlipPackage) blip.eContainer();
			return pkg.getName() + "." + blip.getName();
		}
		
		/**
		 * Gets the functionLibraryInitializationGroup FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the action FQN
		 */
		private static String getDialogGroupFQN(EObject eObject) {
			FunctionLibraryDialogGroup functionLibraryDialogGroup = (FunctionLibraryDialogGroup) eObject;
			if (functionLibraryDialogGroup == null) {
				return "";
			}
			FunctionLibraryPackage pkg = (FunctionLibraryPackage) functionLibraryDialogGroup.eContainer();
			return pkg.getName() + "." + functionLibraryDialogGroup.getName();
		}
		
		/**
		 * Gets the functionLibraryInitialization FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the action FQN
		 */
		private static String getDialogHookFQN(EObject eObject) {
			FunctionLibraryDialogHook functionLibraryDialogHook = (FunctionLibraryDialogHook) eObject;
			if (functionLibraryDialogHook == null) {
				return "";
			}
			FunctionLibraryPackage pkg = (FunctionLibraryPackage) functionLibraryDialogHook.eContainer().eContainer();
			return pkg.getName() + "." + functionLibraryDialogHook.getName();
		}
		
		/**
		 * Gets the watcher FQN.
		 *
		 * @param eObject
		 *            the e object
		 * @return the watcher FQN
		 */
		private static String getSignalFQN(EObject eObject) {
			SignalDefinition signal = (SignalDefinition) eObject;
			if (signal == null) {
				return "";
			}
			SignalPackage pkg = (SignalPackage) signal.eContainer();
			if(signal instanceof SignalScheduler){
				return pkg.getName() + "." + signal.getName() + "Scheduler";			
		}
			return pkg.getName() + "." + signal.getName()  + "Watcher";
		}

		/**
		 * Gets the dto class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the dto class name
		 */
		private static String getDtoClassName(EObject eObject) {
			return getDtoFQN(eObject);
		}

		/**
		 * Gets the entity class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the entity class name
		 */
		private static String getEntityClassName(EObject eObject) {
			return getEntityFQN(eObject);
		}

		/**
		 * Gets the topology class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the topology class name
		 */
		private static String getTopologyClassName(EObject eObject) {
			return getTopologyFQN(eObject) + "Topology";
		}

		/**
		 * Gets the datamart class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the datamart class name
		 */
		private static String getDatamartClassName(EObject eObject) {
			return getDatamartFQN(eObject) + "Datamart";
		}
		
		/**
		 * Gets the watcher class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the watcher class name
		 */
		private static String getSignalClassName(EObject eObject) {
			return getSignalFQN(eObject);
		}

		/**
		 * Gets the toolbar class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the toolbar class name
		 */
		private static String getActionToolbarClassName(EObject eObject) {
			return getActionFQN(eObject) + "Toolbar";
		}
		/**
		 * Gets the report class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the report class name
		 */
		private static String getReportClassName(EObject eObject) {
			return getReportFQN(eObject) + "Report";
		}

		/**
		 * Gets the chart class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the chart class name
		 */
		private static String getChartClassName(EObject eObject) {
			return getChartFQN(eObject) + "Chart";
		}

		/**
		 * Gets the organization class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the organization class name
		 */
		private static String getOrganizationClassName(EObject eObject) {
			return getChartFQN(eObject) + "Organization";
		}

		/**
		 * Gets the table class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the table class name
		 */
		private static String getTableClassName(EObject eObject) {
			Table table = (Table) eObject;
			if (table.getTabletype() instanceof TableGrid) {
				return getTableFQN(eObject) + "Grid";
			} else {
				return getTableFQN(eObject) + "Table";
			}
		}

		/**
		 * Gets the dialog class name.
		 *
		 * @param eObject
		 *            the e object
		 * @return the dialog class name
		 */
		private static String getDialogClassName(EObject eObject) {
			Dialog dialog = (Dialog) eObject;
			if(dialog.isEmbedded()) {
				return getDialogFQN(eObject) + "DialogEmbedded";
			}else{
				return getDialogFQN(eObject) + "Dialog";
			}
		}

		private static String getDataInterchangeClassName(EObject eObject) {
			return getDatainterchangeFQN(eObject) + "TriggerView";
		}

		/**
		 * Gets the ecview id.
		 *
		 * @param dialog
		 *            the dialog
		 * @return the ecview id
		 */
		private static String getECViewId(Dialog dialog) {
			if (dialog == null) {
				return "";
			}
			return AutowireUiFactory.getECViewPackage(dialog) +"."+ AutowireUiFactory.getECViewName(dialog);
		}
	}

}
