public static void invokePlugin(final String pluginName, final PluginRef plugin, final List<Variable> variables) {
		try {
			if (pluginMethods.get(pluginName) == null) {
				throw new AzotException("Plugin '" + pluginName + "' not found.");
			}
			
			final List<Variable> inheritedVariables = new ArrayList<Variable>();
			inheritedVariables.addAll(variables);

			final List<Variable> pluginVariables = plugin.getVariables();
			for (final Variable pluginVariable : pluginVariables) {
				final String newValue = VariableHelper.substituteVariables(pluginVariable.getValue(), inheritedVariables);
				VariableHelper.addOrUpdateVariable(pluginVariable.getId(), newValue, true, false, inheritedVariables);
			}
			
			
			final Properties inProperties = new Properties();
			if (inheritedVariables != null) {
				for (final Variable variable : inheritedVariables) {
					inProperties.setProperty(variable.getId(), variable.getValue());
				}
			}
			
			final Object returnedValue = pluginMethods.get(pluginName).invoke(null, new Object[] {inProperties});
			
			if (returnedValue instanceof Properties) {
				final Properties outProperties = (Properties) returnedValue;
				
				//System.out.println("Variables received by Azot:");
				Set<Object> keyObjects = outProperties.keySet();
				for (Object keyObject : keyObjects) {
					final String key = (String)keyObject;
					final String value = outProperties.getProperty(key);
					//System.out.println("key: '" + key + "', value: '" + value + "'");
					
					println("Plugin returns the property '" + key + "' with value '" + value + "'");
					VariableHelper.addOrUpdateVariable(key, value, true, false, variables);
				}
			}
		} catch (Exception e) {
			println("Error: plugin invocation failed");
			if (AzotConfig.GLOBAL.VERBOSE) {
				System.out.print("Cause: ");
				e.printStackTrace();
			}
		}
	}