/*******************************************************************************
 * Copyright (c) 2004-2008 Andras Schmidt, Andras Balogh, Istvan Rath and Daniel Varro
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Andras Schmidt, Andras Balogh, Istvan Rath - initial API and implementation
 *******************************************************************************/

package org.eclipse.viatra2.framework;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.viatra2.ViatraPlugin;
import org.eclipse.viatra2.codegen.CodeOutputPlugin;
import org.eclipse.viatra2.codegen.CodeOutputPluginFactory;
import org.eclipse.viatra2.core.IModelSpace;
import org.eclipse.viatra2.errors.VPMRuntimeException;
import org.eclipse.viatra2.exports.VPMExporter;
import org.eclipse.viatra2.framework.properties.IViatraPropertyProvider;
import org.eclipse.viatra2.framework.properties.VIATRAPreferences;
import org.eclipse.viatra2.framework.properties.VPMProperties;
import org.eclipse.viatra2.imports.IVPMImporter;
import org.eclipse.viatra2.imports.NativeImporter;
import org.eclipse.viatra2.imports.NativeImporterFactory;
import org.eclipse.viatra2.imports.VPMImporterSax;
import org.eclipse.viatra2.interpreters.IProgressReport;
import org.eclipse.viatra2.interpreters.ModelInterpreter;
import org.eclipse.viatra2.interpreters.ModelInterpreterFactory;
import org.eclipse.viatra2.loaders.Loader;
import org.eclipse.viatra2.loaders.Loader2;
import org.eclipse.viatra2.loaders.LoaderFactory;
import org.eclipse.viatra2.logger.Logger;
import org.eclipse.viatra2.logger.LoggerFactory;
import org.eclipse.viatra2.merger.Merger;
import org.eclipse.viatra2.merger.VPMMergeException;
import org.eclipse.viatra2.natives.ASMNativeFunction;
import org.eclipse.viatra2.natives.INativeFunctionManager;
import org.eclipse.viatra2.natives.NativeFunctionManager;
import org.eclipse.viatra2.tags.ITagManager;
import org.eclipse.viatra2.tags.impl.TagManager;

/**
 * @author Andras Balogh, Istvan Rath
 * @version 2.9.7
 * 
 *          Class supporting the basic framework services. One framework
 *          contains one model, importers, exporters, logger, and output streams
 *          for the model.
 * 
 *          Modified on 2006.08.10. by Istvan Rath: - clean up unused code,
 *          comments, etc - clean up and write proper javadoc
 * 
 */

public final class Framework implements IFramework {

	public static final String parserManagerServiceId = "org.eclipse.viatra2.loaders.vtcl_lpgparser.loader.VTCLParserManager";

	MultiCodeFormatter codeout; // = new MultiCodeFormatter();

	// BufferedCodeFormatter codeout;

	String modelmerger = "";

	/**
	 * Framework identifier.
	 */
	String id = "";

	/**
	 * The current file name with which the framework instance is associated.
	 */
	private String currentfilename = "";

	/**
	 * Reference to the native function manager.
	 */
	NativeFunctionManager nativeFunctionManager;

	/**
	 * Native importer factory registry.
	 */
	HashMap<String, NativeImporterFactory> imports = new HashMap<String, NativeImporterFactory>();

	/**
	 * Loader factory registry.
	 */
	HashMap<String, LoaderFactory> loaders = new HashMap<String, LoaderFactory>();

	/**
	 * Reference to the modelspace.
	 */
	IModelSpace topmodel;

	/**
	 * Framework multilogger.
	 */
	MultiLogger logger = new MultiLogger();

	/**
	 * Machine set listener registry.
	 */
	HashSet<IMachineSetChangedListener> machine_set_listeners = new HashSet<IMachineSetChangedListener>();

	/*
	 * Machine model storage. FQN ==> Machine map.
	 */
	private final HashMap<String, Object> machine_models = new HashMap<String, Object>();

	/**
	 * The map of service providers. Each service provider (e.g.
	 * VTCLParseController) is registered under a unique servicename.
	 */
	private final Map<String, IFrameworkService> service_providers = new HashMap<String, IFrameworkService>();

	/**
	 * The map of {@link IFrameworkServiceFactory} related to the unique name of
	 * service provider
	 */
	private final Map<String, IFrameworkServiceFactory> service_factories = new HashMap<String, IFrameworkServiceFactory>();

	/**
	 * The tag manager.
	 */
	private TagManager tagManager;

	public ITagManager getTagManager() {
		return tagManager;
	}

	public String getCurrentFilename() {
		return currentfilename;
	}

	public void setCurrentFileName(String fName) {
		currentfilename = fName;
		for (IFrameworkGlobalListener l : globalListeners)
			l.frameworkNameChanged();
	}

	public void dispose() {
		// Added by Daniel Varro
		unregisterFrameworkService(parserManagerServiceId);
	}

	public Framework() {
	}

	/**
	 * Returns the active code output plugin
	 * 
	 * @return the plugin
	 */
	public CodeOutputPlugin getCodeOutput() {
		return codeout;
	}

	/**
	 * Returns the current framework logger
	 * 
	 * @return the logger
	 */
	public Logger getLogger() {
		return logger;
	}

	/**
	 * Creates a new modelspace instance using the class specified in the
	 * properties file.
	 * 
	 * @return the new model space.
	 * @throws Exception
	 */
	IModelSpace getNewModelSpace() throws FrameworkException {
		IModelSpace ms = exProvider.getEmptyModelspace(props);
		try {
			ms.init(this);
		} catch (Exception e) {
			logger.fatal("Cannot init modelspace");
			throw new FrameworkException(
					"Exception initialising framework: cannot init modelspace class",
					e);
		}
		return ms;
	}

	private VPMProperties props;

	/**
	 * Gets the interpreter factory for the given interpretable object.
	 * 
	 * @param s
	 *            the name of the model element.
	 * @return The model interpreter class for the element, or null if there is
	 *         no one.
	 * @throws FrameworkException
	 */
	public ModelInterpreterFactory getInterpreterFactory(Object entrypoint)
			throws FrameworkException {
		ModelInterpreterFactory[] is = exProvider.getInterpreters();
		for (ModelInterpreterFactory iF : is) {
			final String[] types = iF.getInterpretedClasses();
			if (types != null) {
				for (int i = 0; i < types.length; ++i) {
					// System.out.println(entrypoint.getClass().getName());
					// System.out.println(types[i]);
					if (entrypoint.getClass().getCanonicalName()
							.equals(types[i].trim())) {
						iF.getInterpreter();
						return iF;
					}
				}
			} else {
				ModelInterpreter i = iF.getInterpreter();
				if (i != null)
					if (i.isRunnable(entrypoint, this))
						return iF;
			}
		}
		return null;
	}

	boolean isInit = false;

	ExtensionProvider exProvider;

	/**
	 * Framework initialisation. Must be called before using the framework
	 * services.
	 * 
	 * @throws FrameworkException
	 */
	public void init(String initialModelFileName, String id,
			ExtensionProvider exProvider) throws FrameworkException {
		try {
			init(new FileInputStream(initialModelFileName), id, exProvider,
					initialModelFileName);
		} catch (FileNotFoundException e) {
			throw new FrameworkException("init failed", e);
		}
	}

	public void init(InputStream initialModelFile, String id,
			ExtensionProvider exProvider, String name)
			throws FrameworkException {
		if (isInit)
			return;
		isInit = true;
		this.id = id;
		String initialModelFileName = name;
		this.currentfilename = initialModelFileName;
		this.exProvider = exProvider;

		Logger defaultLogger = exProvider.getDefaultLogger();
		if (defaultLogger != null)
			logger.addListener(defaultLogger);
		props = exProvider.getDefaultProperties();

		LoggerFactory[] logs = exProvider.getAvailableLoggers();
		for (LoggerFactory fact : logs) {
			Logger l = fact.getLogger();
			logger.addListener(l);
		}
		if (props.isRuntimePropertySet("Logging", "Log level")) {
			logger.setLevel(Integer.valueOf(
					props.getRuntimeProperty("Logging", "Log level"))
					.intValue());
		} else {
			// set default loglevel
			logger.setLevel(Logger.INFO);
		}
		logger.debug("Logging session started");
		
		// added by Istvan (2008-08-12), extended by Abel to enable trace-based modelspace creation
		// if needed, override property values from Plugin Preference Store
		Preferences prefs = ViatraPlugin.getDefault().getPluginPreferences();
		overrideVPMLProperties(prefs);
		
		topmodel = getNewModelSpace();
		if (initialModelFile != null) {
			try {
				getImporter().process(initialModelFile, topmodel, props);
				// properties are loaded here
			} catch (Exception e) {
				logger.message(Logger.ERROR,
						"Modelspace initialization failed.", e);
				throw new FrameworkException(
						"Exception initialising framework", e);
			}
		}

		overrideVPMLProperties(prefs);

		// re-init loggers with properties
		if (props.isRuntimePropertySet("Logging", "Log level")) {
			logger.setLevel(Integer.valueOf(
					props.getRuntimeProperty("Logging", "Log level"))
					.intValue());
		}

		tagManager = new TagManager();
		tagManager.init(this);

		codeout = new MultiCodeFormatter();
		codeout.init(this);

		CodeOutputPluginFactory[] allCodeOuts = exProvider
				.getCodeOutputPlugins();
		for (CodeOutputPluginFactory fact : allCodeOuts) {
			CodeOutputPlugin pl = fact.createCodeoutPlugin(this);
			if (pl != null) {
				pl.init(this);
				codeout.addListener(pl);
			}
		}

		// Initialising importers
		NativeImporterFactory[] natives = exProvider.getNativeImporters(props);
		for (NativeImporterFactory factory : natives) {
			addNativeImporterFactory(factory);
		}
		// Initialising loaders
		LoaderFactory[] programloaders = exProvider.getLoaders(props);
		for (LoaderFactory factory : programloaders) {
			addLoaderFactory(factory);
		}
		// Initialising native functions
		ASMNativeFunction[] natFuns = exProvider.getNativeFunctions();
		nativeFunctionManager = new NativeFunctionManager();
		nativeFunctionManager.addAllFunction(natFuns);

		// Added by Daniel Varro (2009-08-02)
		initializeServiceFactory(parserManagerServiceId);
		registerFrameworkService(parserManagerServiceId);
		service_providers.get(parserManagerServiceId).init(this);
	}

	/**
	 * @param prefs
	 */
	private void overrideVPMLProperties(Preferences prefs) {
		if (prefs.contains(VIATRAPreferences.DISABLE_VPML_OVERRIDE)) {
			if (prefs.getBoolean(VIATRAPreferences.DISABLE_VPML_OVERRIDE)) {
				// override loaded values
				for (IViatraPropertyProvider prov : ViatraPlugin.getDefault()
						.getPropertyProviders()) {
					for (String prop_id : prov.getAllPropertyIds()) {
						props.setRuntimeProperty(
								prov.getProviderID(),
								prop_id,
								prefs.getString(prov.getProviderID() + "::"
										+ prop_id));
					}
				}
			}
		}
	}

	/**
	 * Returns the top modelspace of this framework.
	 * 
	 * @return the modelspace.
	 */
	public IModelSpace getTopmodel() {
		return topmodel;
	}

	/**
	 * Add a native importer factory to the registry.
	 * 
	 * @param fact
	 *            the native importer factory to be added
	 */
	private void addNativeImporterFactory(NativeImporterFactory fact) {
		int f = 1;
		NativeImporterFactory s = fact;
		String preferredImporterId = s.getId();
		if (preferredImporterId == null)
			preferredImporterId = "noname";
		String importerId = preferredImporterId;
		while (imports.get(importerId) != null) {
			importerId = preferredImporterId + f;
			f++;
		}
		imports.put(importerId, s);
		logger.info("Added new importer plugin '" + importerId + "' ("
				+ s.getImporterName() + ")");
	}

	/**
	 * Add a loader factory to the registry.
	 */
	private void addLoaderFactory(LoaderFactory fact) {
		int f = 1;
		LoaderFactory s = fact;
		String preferredImporterId = s.getId();
		if (preferredImporterId == null)
			preferredImporterId = "noname";
		String importerId = preferredImporterId;
		while (loaders.get(importerId) != null) {
			importerId = preferredImporterId + f;
			f++;
		}
		loaders.put(importerId, s);
		logger.info("Added new loader plugin '" + importerId + "' ("
				+ s.getLoaderName() + ")");
	}

	/**
	 * Returns all native importer classes recognized by the framework.
	 * 
	 * @return hashmap of the classes key = importer id, entity=importer class
	 */
	public Map<String, NativeImporterFactory> getNativeImporters() {
		return imports;
	}

	public Map<String, LoaderFactory> getLoaders() {
		return loaders;
	}

	public void addMachine(String fqn, Object machine)
			throws FrameworkException {
		if (this.machine_models.get(fqn) != null) {
			removeMachine(fqn);
		}
		this.machine_models.put(fqn, machine);
		for (IMachineSetChangedListener l : this.machine_set_listeners) {
			l.machineAdded(machine);
		}
	}

	public void removeMachine(String fqn) throws FrameworkException {
		Object machine = this.machine_models.get(fqn);
		this.machine_models.remove(fqn);
		for (IMachineSetChangedListener l : this.machine_set_listeners) {
			l.machineRemoved(machine);
		}
	}

	public Object loadMachine(String fileName, String loaderName)
			throws FrameworkException {
		/*
		 * try { loadMachine(new FileInputStream(fileName), loaderName); } catch
		 * (FileNotFoundException e) { throw new
		 * FrameworkException("File not found"); }
		 */
		LoaderFactory lf = loaders.get(loaderName);
		if (lf == null)
			throw new FrameworkException("Loader for type " + loaderName
					+ " is not defined.");
		Loader l;
		try {
			l = lf.getLoaderInstance();
		} catch (Exception e) {
			logger.message(Logger.ERROR, "Error loading loader: " + loaderName,
					e);
			throw new FrameworkException("Error loading loader: " + loaderName,
					e);
		}
		if (l == null) {
			throw new FrameworkException("Loader for type " + loaderName
					+ " is not defined.");
		}
		// Object program_model = null;
		try {
			// program_model =
			return l.processFile(fileName, this);
		} catch (VPMRuntimeException e) {
			throw new FrameworkException("Loader ended with error", e);
		}
		// store program model
		// REMOVED: it is the loaders responsibility to do this.
		/*
		 * if (program_model!=null) { this.machine_models.add(program_model);
		 * for (IMachineSetChangedListener lis : machine_set_listeners) {
		 * lis.machineAdded(program_model); } } else throw new
		 * FrameworkException("Loader returned invalid model");
		 */
	}

	public Object loadMachineURI(String _URI, String loaderName)
			throws FrameworkException {
		LoaderFactory lf = loaders.get(loaderName);
		if (lf == null)
			throw new FrameworkException("Loader for type " + loaderName
					+ " is not defined.");
		Loader2 l;
		try {
			l = (Loader2)lf.getLoaderInstance();
		} catch (Exception e) {
			logger.message(Logger.ERROR, "Error loading loader, probably does not support Loader2 interface: " + loaderName, e);
			throw new FrameworkException("Error loading loader, probably does not support Loader2 interface: " + loaderName, e);
		}
		if (l == null) {
			throw new FrameworkException("Loader for type " + loaderName
					+ " is not defined.");
		}
		// Object program_model = null;
		try {
			// program_model =
			return l.processURI(_URI, this);
		} catch (VPMRuntimeException e) {
			throw new FrameworkException("Loader ended with error", e);
		}
	}

	public Object loadMachine(InputStream stream, String loaderName)
			throws FrameworkException {
		LoaderFactory lf = loaders.get(loaderName);
		if (lf == null)
			throw new FrameworkException("Loader for type " + loaderName
					+ " is not defined.");
		Loader l;
		try {
			l = lf.getLoaderInstance();
		} catch (Exception e) {
			logger.message(Logger.ERROR, "Error loading loader: " + loaderName,
					e);
			throw new FrameworkException("Error loading loader: " + loaderName,
					e);
		}
		if (l == null) {
			throw new FrameworkException("Loader for type " + loaderName
					+ " is not defined.");
		}
		try {
			// program_model =
			return l.process(stream, this);
		} catch (VPMRuntimeException e) {
			throw new FrameworkException("Loader ended with error", e);
		}
		// store program model
		// REMOVED -- it is the Loaders responsibility to do this.
		/*
		 * if (program_model!=null) { this.machine_models.add(program_model);
		 * for (IMachineSetChangedListener lis : machine_set_listeners) {
		 * lis.machineAdded(program_model); } } else throw new
		 * FrameworkException("Loader returned invalid model");
		 */
	}

	/**
	 * Imports the given file to the current modelspace, using one of the
	 * configured native model interpreters.
	 * 
	 * @param fileName
	 *            input filename
	 * @param importerName
	 *            import class id
	 * @throws FrameworkException
	 */
	public void nativeImport(String fileName, String importerName)
			throws FrameworkException {
		NativeImporterFactory claf = imports.get(importerName);
		if (claf == null) {
			throw new FrameworkException("Native importer for type "
					+ importerName + " is not defined.");
		}
		NativeImporter cla;
		try {
			cla = claf.getImporterInstance();
		} catch (Exception e) {
			logger.message(Logger.ERROR, "Error loading importer: "
					+ importerName, e);
			throw new FrameworkException("Error loading importer: "
					+ importerName, e);
		}
		if (cla == null) {
			throw new FrameworkException("Native importer for type "
					+ importerName + " is not defined.");
		}
		try {
			topmodel.getTransactionManager().beginTransaction(Boolean.TRUE);
			cla.processFile(fileName, this);
		} catch (VPMRuntimeException ex) {
			throw new FrameworkException("Native import ended with error", ex);
		} catch (Exception ex2) {
			throw new FrameworkException("Native import ended with error", ex2);
		} finally {
			topmodel.getTransactionManager().commitTransaction();
		}
	}

	/**
	 * Imports the given file to the current modelspace, using one of the
	 * configured native model interpreters.
	 * 
	 * @param stream
	 *            input InputStream
	 * @param importerName
	 *            import class id
	 * @throws Exception
	 */
	public void nativeImport(InputStream stream, String importerName)
			throws FrameworkException {
		NativeImporterFactory claf = imports.get(importerName);
		if (claf == null) {
			throw new FrameworkException("Native importer for type "
					+ importerName + " is not defined.");
		}
		NativeImporter cla;
		try {
			cla = claf.getImporterInstance();
		} catch (Exception e) {
			logger.message(Logger.ERROR, "Error loading importer: "
					+ importerName, e);
			throw new FrameworkException("Error loading importer: "
					+ importerName, e);
		}
		if (cla == null) {
			throw new FrameworkException("Native importer for type "
					+ importerName + " is not defined.");
		}
		try {
			topmodel.getTransactionManager().beginTransaction(Boolean.TRUE);
			cla.process(stream, this);
		} catch (VPMRuntimeException ex) {
			throw new FrameworkException("Native import ended with error", ex);
		} catch (Exception ex2) {
			throw new FrameworkException("Native import ended with error", ex2);
		} finally {
			topmodel.getTransactionManager().commitTransaction();
		}
	}

	// public void nativeImport(IResource resource, String importerName) throws
	// FrameworkException {
	// TODO implement resource native import better
	// nativeImport(resource.getFullPath().toOSString(),importerName);
	// }

	/**
	 * Return's the frameworks' identifier.
	 */
	public String getId() {
		return id;
	}

	/**
	 * Gets a VPML importer.
	 */
	private IVPMImporter getImporter() {
		return new VPMImporterSax();
	}

	/**
	 * Gets a native importer's full name based on its string id.
	 * 
	 * @param tt
	 *            native importer string id
	 * @return full name
	 */
	public String getImporterName(String tt) {
		NativeImporterFactory cla = imports.get(tt);
		if (cla == null) {
			logger.error("Native importer for type " + tt + " is not defined.");
			return null;
		}
		try {
			return cla.getImporterName();

		} catch (Exception ex2) {
			logger.error("Unable to load native importer class: "
					+ ex2.getMessage());
			return null;
		}

	}

	/**
	 * Gets a loader's full name based on its string id.
	 * 
	 * @param tt
	 *            native importer string id
	 * @return full name
	 */
	public String getLoaderName(String tt) {
		LoaderFactory cla = loaders.get(tt);
		if (cla == null) {
			logger.error("Loader for type " + tt + " is not defined.");
			return null;
		}
		try {
			return cla.getLoaderName();

		} catch (Exception ex2) {
			logger.error("Unable to load loader class: " + ex2.getMessage());
			return null;
		}

	}

	/**
	 * Saves the modelspace to a file.
	 * 
	 * @param s
	 *            the destination filename.
	 * @throws IOException
	 */
	public void saveFile(String s) throws FrameworkException, IOException {
		(new VPMExporter()).export(this, s);
		this.currentfilename = s;
	}

	public Collection<Object> getMachines() {
		return machine_models.values();
	}

	public Object getMachineByFQN(String fqn) {
		return machine_models.get(fqn);
	}

	public boolean isRunnable(Object machine) throws FrameworkException {
		return getInterpreterFactory(machine) != null;
	}

	public void runEntrypoint(Object entrypoint, Map<String, Object> params,
			IProgressReport pr) throws VPMRuntimeException {
		if (params == null)
			params = new TreeMap<String, Object>();
		ModelInterpreter interpreter = null;
		try {
			interpreter = getInterpreterFactory(entrypoint).getInterpreter();
		} catch (Exception e) {
			logger.message(Logger.FATAL,
					"couldn't load Model Interpreter class. ", e);
			throw new VPMRuntimeException("could not run entrypoint");
		}
		try {
			if (interpreter != null) {
				interpreter.run(this, entrypoint, params, pr);
				logger.info("Entity successfully interpreted.");
			}
		} catch (java.lang.RuntimeException e) {
			String exMessage = e.getMessage();
			String message = "Error happened while running interpreter, please report to VIATRA2 developers"
					+ (exMessage == null ? ". " : (": " + exMessage + " "));
			logger.message(Logger.ERROR, message, e);
			throw new VPMRuntimeException(message, e);
		}
	}

	public String[] getEntrypointParameters(Object machine)
			throws FrameworkException {
		ModelInterpreter interpreter = null;
		try {
			interpreter = getInterpreterFactory(machine).getInterpreter();
		} catch (Exception e) {
			logger.message(Logger.FATAL,
					"couldn't load Model Interpreter class. ", e);
			throw new FrameworkException("could not load model interpreter");
		}
		try {
			if (interpreter != null) {
				return interpreter.getParameters(this, machine);
			}
		} catch (VPMRuntimeException e) {
			logger.error(e.getMessage()); // wrpa error meassage
			throw new FrameworkException(e.getMessage(), e);
		} catch (Exception e) {
			try {
				FileOutputStream fo = new FileOutputStream("log.out");
				PrintWriter pw = new PrintWriter(fo);
				e.printStackTrace(pw);
				pw.flush();
				fo.close();
			} catch (Exception eee) {
			}
			logger.error(e.getMessage()
					+ " error log created in file log.out. Please report");
			throw new FrameworkException(
					"could not run initialize model interpreter");
		}
		return new String[0];
	}

	/**
	 * Merge the model in topModel with the given modelspace. The modelspace to
	 * merge with is given with its filename. The file should be a vpml file.
	 * 
	 * @param fileName
	 * @throws FrameworkException
	 *             if opening file fails
	 * @throws VPMMergeException
	 *             if merge fails
	 */
	public void merge(String fileName) throws VPMMergeException,
			FrameworkException {
		IModelSpace toMerge;
		toMerge = getNewModelSpace();
		try {
			getImporter().process(fileName, toMerge, new VPMProperties());
		} catch (VPMRuntimeException e) {
			throw new FrameworkException("Opening file failed", e);
		}
		merge(toMerge);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.viatra2.framework.IFramework#mergeStream(java.io.InputStream)
	 */
	public void mergeStream(InputStream stream) throws FrameworkException,
			IOException {
		IModelSpace toMerge;
		toMerge = getNewModelSpace();
		try {
			// getImporter().process(fileName,toMerge, new Properties());
			// FIXME what happens to properties on merge???
			getImporter().process(stream, toMerge, new VPMProperties());
		} catch (VPMRuntimeException e) {
			throw new FrameworkException("Opening file failed", e);
		}
		try {
			merge(toMerge);
		} catch (VPMMergeException mex) {
			throw new FrameworkException("error merging", mex);
		}
	}

	/**
	 * Merge the model in topModel with the given modelspace. The given
	 * modelspace will not change.
	 * 
	 * @param modelSpace
	 * @throws VPMMergeException
	 */
	public void merge(IModelSpace modelSpace) throws VPMMergeException {
		Merger mg = new Merger();
		getTopmodel().getTransactionManager().beginTransaction(Boolean.TRUE);
		mg.merge(modelSpace, getTopmodel());
		getTopmodel().getTransactionManager().commitTransaction();
	}

	public void addLoggerListener(Logger l) {
		logger.addListener(l);
	}

	public Collection<Logger> getAllLoggerListeners() {
		return logger.getListeners();
	}

	public void removeLoggerListener(Logger l) {
		logger.removeListener(l);

	}

	public void addCodeOutListener(CodeOutputPlugin l) {
		codeout.addListener(l);
	}

	public Collection<CodeOutputPlugin> getAllCodeOutListeners() {
		return codeout.getListeners();
	}

	public void removeCodeOutListener(CodeOutputPlugin l) {
		codeout.removeListener(l);
	}

	/**
	 * Collect all output plugins from the extension provider.
	 */
	public Collection<CodeOutputPluginFactory> getAvailableCodeOutPlugins() {
		ArrayList<CodeOutputPluginFactory> ret = new ArrayList<CodeOutputPluginFactory>();
		try {
			for (CodeOutputPluginFactory factory : exProvider
					.getCodeOutputPlugins()) {
				ret.add(factory);
			}
		} catch (FrameworkException e) {
			logger.fatal("Fatal error querying code output plugins");
		}
		return ret;
	}

	/**
	 * Collect all loggers from the extension provider.
	 */
	public Collection<LoggerFactory> getAvailableLoggers() {
		ArrayList<LoggerFactory> ret = new ArrayList<LoggerFactory>();
		try {
			for (LoggerFactory factory : exProvider.getAvailableLoggers()) {
				ret.add(factory);
			}
		} catch (FrameworkException e) {
			logger.fatal("Fatal error querying code available loggers");
			// well well well :) something of an oxymoron here
		}
		return ret;
	}

	/**
	 * Collect all interpreters from the extension provider.
	 */
	public Collection<ModelInterpreterFactory> getAvailableInterpreters() {
		ArrayList<ModelInterpreterFactory> ret = new ArrayList<ModelInterpreterFactory>();
		for (ModelInterpreterFactory factory : exProvider.getInterpreters()) {
			ret.add(factory);
		}
		return ret;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.framework.IFramework#getNativeFunctionManager()
	 */
	public INativeFunctionManager getNativeFunctionManager() {
		return nativeFunctionManager;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.framework.IFramework#mergeFile(java.lang.String)
	 */
	public void mergeFile(String fileName) throws FrameworkException,
			IOException {
		try {
			merge(fileName);
		} catch (VPMMergeException mex) {
			throw new FrameworkException("error merging", mex);
		}
	}

	/**
	 * Saves the modelspace to the file designated by the currentFileName
	 * parameter.
	 */
	public void saveFile(OutputStream os, String currentFileName)
			throws FrameworkException, IOException {
		(new VPMExporter()).export(this, os);
		this.currentfilename = currentFileName;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.framework.IFramework#getProperties()
	 */
	public VPMProperties getProperties() {
		return props;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.viatra2.framework.IFramework#getNativeImportersForExtension
	 * (java.lang.String)
	 */
	public Set<String> getNativeImportersForExtension(String ext) {// throws
																	// FrameworkException
																	// {
		HashSet<String> ret = new HashSet<String>();
		for (NativeImporterFactory f : imports.values()) {
			String[] exts = f.getFileExtensionList();
			for (int i = 0; i < exts.length; i++) {
				if (exts[i].equalsIgnoreCase(ext)) {
					ret.add(f.getId());
				}
			}
		}
		// if (ret.isEmpty())
		// throw new FrameworkException("No importer found for extension "+ext);
		return ret;
	}

	public Set<String> getLoadersForExtension(String ext) // throws
															// FrameworkException
															// {
	{
		HashSet<String> ret = new HashSet<String>();
		for (LoaderFactory f : loaders.values()) {
			String[] exts = f.getFileExtensionList();
			for (int i = 0; i < exts.length; i++) {
				if (exts[i].equalsIgnoreCase(ext)) {
					ret.add(f.getId());
				}
			}
		}
		// if (ret.isEmpty())
		// throw new FrameworkException("No loader found for extension "+ext);
		return ret;
	}

	public void addMachineSetListener(IMachineSetChangedListener l) {
		if (!machine_set_listeners.contains(l))
			machine_set_listeners.add(l);

	}

	public void removeMachineSetListener(IMachineSetChangedListener l) {
		machine_set_listeners.remove(l);
	}

	HashSet<IFrameworkGlobalListener> globalListeners = new HashSet<IFrameworkGlobalListener>();

	public void addFrameworkGlobalListener(IFrameworkGlobalListener l) {
		globalListeners.add(l);

	}

	public Collection<IFrameworkGlobalListener> getAllGlobalListeners() {
		return globalListeners;
	}

	public void removeFrameworkGlobalListener(IFrameworkGlobalListener l) {
		globalListeners.remove(l);

	}

	/**
	 * Adapter implementation function. Supports the following types: -
	 * ITagManager - IModelSpace
	 */
	public Object getAdapter(Class adapter) {
		if (adapter.equals(ITagManager.class)) {
			return getTagManager();
		} else if (adapter.equals(IModelSpace.class)) {
			return getTopmodel();
		}
		// etc...
		return null;
	}

	public IFrameworkService getVTCLParserManager() {
		return service_providers.get(parserManagerServiceId);
	}

	/**
	 * Registers a framework service with (unique) name "serviceName" Services
	 * are stored in a map where the "serviceName" identifies the service
	 * provider class as defined in the extenders of the "frameworkservice"
	 * extension point.
	 * 
	 * @param serviceName
	 *            : unique name of the service (defined by extenders of the
	 *            frameworkservice extension point)
	 * @throws FrameworkException
	 */
	public void registerFrameworkService(String serviceName)
			throws FrameworkException {
		// Seek for corresponding factory
		IFrameworkServiceFactory factory = service_factories.get(serviceName);
		if (factory != null) { // factory found
			IFrameworkService service = factory.create();
			// TODO: Maybe, the service should be initialized here
			service_providers.put(serviceName, service);
		} else { // throw exception if factory is unavailable
			throw new FrameworkException(
					"Factory class cannot be found for service" + serviceName);
		}

	}

	/**
	 * Unregisters a service with a unique "serviceName" from the map of service
	 * providers
	 * 
	 * @param serviceName
	 *            : unique name of the service to be unregistered
	 */
	public void unregisterFrameworkService(String serviceName) {
		IFrameworkService service = service_providers.get(serviceName);
		if (service != null) {
			service_providers.remove(serviceName);
		}

	}

	/**
	 * The service factory is initialized (created) for the service with the
	 * given service name
	 * 
	 * @param serviceName
	 *            : the unique name of the framework service
	 * @throws FrameworkException
	 */
	protected void initializeServiceFactory(String serviceName)
			throws FrameworkException {
		if (service_factories.get(serviceName) == null) {
			IConfigurationElement[] configs = Platform.getExtensionRegistry()
					.getConfigurationElementsFor(
							"org.eclipse.viatra2.core2.frameworkservice");
			boolean found = false;
			for (int i = 0; !found && i < configs.length; i++) {
				IConfigurationElement config = configs[i];
				String currentServiceName = config.getAttribute("servicename");
				if (serviceName.equals(currentServiceName)) {
					found = true;
					try {
						IFrameworkServiceFactory factory = (IFrameworkServiceFactory) config
								.createExecutableExtension("factoryclass");
						service_factories.put(serviceName, factory);
					} catch (CoreException e) {
						throw new FrameworkException(
								"Framework service factory cannot be found", e);
					}
				}
			}
		}
	}

}
