text:
package net.roboconf.core.model;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;

import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import net.roboconf.core.Constants;
import net.roboconf.core.errors.ErrorCode;
import net.roboconf.core.errors.ErrorCode.ErrorLevel;
import net.roboconf.core.errors.ErrorDetails.ErrorDetailsKind;
import net.roboconf.core.errors.RoboconfError;
import net.roboconf.core.errors.RoboconfErrorHelpers;
import net.roboconf.core.internal.tests.TestUtils;
import net.roboconf.core.model.RuntimeModelIo.ApplicationLoadResult;
import net.roboconf.core.model.RuntimeModelIo.GraphFileFilter;
import net.roboconf.core.model.beans.Component;
import net.roboconf.core.model.beans.ExportedVariable.RandomKind;
import net.roboconf.core.model.beans.Facet;
import net.roboconf.core.model.beans.Graphs;
import net.roboconf.core.model.beans.ImportedVariable;
import net.roboconf.core.model.beans.Instance;
import net.roboconf.core.model.beans.Instance.InstanceStatus;
import net.roboconf.core.model.helpers.ComponentHelpers;
import net.roboconf.core.model.helpers.InstanceHelpers;
import net.roboconf.core.utils.Utils;

/**
 * @author Vincent Zurczak - Linagora
 */
public class RuntimeModelIoTest {

	@Rule
	public TemporaryFolder folder = new TemporaryFolder();

	@Test
	public void testLoadApplication_Lamp_Legacy_1() throws Exception {

		File directory = TestUtils.findTestFile( "/applications/lamp-legacy-with-only-components" );
		ApplicationLoadResult result = RuntimeModelIo.loadApplication( directory );
		Assert.assertNotNull( result );
		Assert.assertNotNull( result.applicationTemplate );
		Assert.assertEquals( 4, result.loadErrors.size());
		for( RoboconfError error : result.loadErrors )
			Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, error.getErrorCode());

		Assert.assertEquals( "Legacy LAMP", result.applicationTemplate.getName());
		Assert.assertEquals( "A sample LAMP application", result.applicationTemplate.getDescription());
		Assert.assertEquals( "1.0.1-SNAPSHOT", result.applicationTemplate.getVersion());

		List<String> tags = Arrays.asList( "test", "lamp", "example" );
		Assert.assertEquals( new TreeSet<>( tags ), result.applicationTemplate.getTags());

		Assert.assertNotNull( result.applicationTemplate.getGraphs());
		Graphs g = result.applicationTemplate.getGraphs();
		Assert.assertEquals( 1, g.getRootComponents().size());

		Component vmComponent = g.getRootComponents().iterator().next();
		Assert.assertEquals( "VM", vmComponent.getName());
		Assert.assertEquals( "target", vmComponent.getInstallerName());
		Assert.assertEquals( 3, vmComponent.getChildren().size());

		for( Component childComponent : ComponentHelpers.findAllChildren( vmComponent )) {
			Map<String,String> exportedVariables = ComponentHelpers.findAllExportedVariables( childComponent );
			Map<String,ImportedVariable> importedVariables = ComponentHelpers.findAllImportedVariables( childComponent );
			Collection<Component> children = ComponentHelpers.findAllChildren( childComponent );

			if( "Tomcat".equals( childComponent.getName())) {
				Assert.assertEquals( "puppet", childComponent.getInstallerName());
				Assert.assertEquals( 0, children.size());

				Assert.assertEquals( 2, exportedVariables.size());
				Assert.assertTrue( exportedVariables.containsKey( "Tomcat.ip" ));
				Assert.assertEquals( "8009", exportedVariables.get( "Tomcat.portAJP" ));

				Assert.assertEquals( 2, importedVariables.size());
				Assert.assertFalse( importedVariables.get( "MySQL.ip" ).isOptional());
				Assert.assertFalse( importedVariables.get( "MySQL.ip" ).isExternal());
				Assert.assertFalse( importedVariables.get( "MySQL.port" ).isOptional());
				Assert.assertFalse( importedVariables.get( "MySQL.port" ).isExternal());

				SourceReference sr = result.getObjectToSource().get( childComponent );
				Assert.assertNotNull( sr );
				Assert.assertEquals( new File( directory, "graph/lamp.graph" ), sr.getSourceFile());
				Assert.assertEquals( 22, sr.getLine());

			} else if( "MySQL".equals( childComponent.getName())) {
				Assert.assertEquals( "puppet", childComponent.getInstallerName());
				Assert.assertEquals( 0, children.size());

				Assert.assertEquals( 2, exportedVariables.size());
				Assert.assertTrue( exportedVariables.containsKey( "MySQL.ip" ));
				Assert.assertNull( exportedVariables.get( "MySQL.port" ));
				Assert.assertEquals( 0, importedVariables.size());

				SourceReference sr = result.getObjectToSource().get( childComponent );
				Assert.assertNotNull( sr );
				Assert.assertEquals( new File( directory, "graph/lamp.graph" ), sr.getSourceFile());
				Assert.assertEquals( 16, sr.getLine());

			} else if( "Apache".equals( childComponent.getName())) {
				Assert.assertEquals( "puppet", childComponent.getInstallerName());
				Assert.assertEquals( 0, children.size());
				Assert.assertEquals( 0, exportedVariables.size());

				Assert.assertEquals( 2, childComponent.importedVariables.size());
				Assert.assertFalse( importedVariables.get( "Tomcat.ip" ).isOptional());
				Assert.assertFalse( importedVariables.get( "Tomcat.ip" ).isExternal());
				Assert.assertFalse( importedVariables.get( "Tomcat.portAJP" ).isOptional());
				Assert.assertFalse( importedVariables.get( "Tomcat.portAJP" ).isExternal());

				SourceReference sr = result.getObjectToSource().get( childComponent );
				Assert.assertNotNull( sr );
				Assert.assertEquals( new File( directory, "graph/lamp.graph" ), sr.getSourceFile());
				Assert.assertEquals( 30, sr.getLine());

			} else {
				Assert.fail( "Unrecognized child." );
			}
		}

		// Instances
		Assert.assertEquals( 3, result.applicationTemplate.getRootInstances().size());
		for( Instance i : result.applicationTemplate.getRootInstances()) {
			if( "Apache VM".equals( i.getName())) {
				Assert.assertEquals( "VM", i.getComponent().getName());
				Assert.assertEquals( 1, i.getChildren().size());

				Instance child = i.getChildren().iterator().next();
				Assert.assertEquals( 0, child.getChildren().size());
				Assert.assertEquals( i, child.getParent());
				Assert.assertEquals( "Apache", child.getName());
				Assert.assertEquals( "Apache", child.getComponent().getName());

			} else if( "MySQL VM".equals( i.getName())) {
				Assert.assertEquals( "VM", i.getComponent().getName());
				Assert.assertEquals( 1, i.getChildren().size());

				Instance child = i.getChildren().iterator().next();
				Assert.assertEquals( 0, child.getChildren().size());
				Assert.assertEquals( i, child.getParent());
				Assert.assertEquals( "MySQL", child.getName());
				Assert.assertEquals( "MySQL", child.getComponent().getName());

				Map<String,String> exportedVariables = InstanceHelpers.findAllExportedVariables( child );
				Assert.assertEquals( "3306", exportedVariables.get( "MySQL.port" ));
				Assert.assertNull( child.getComponent().exportedVariables.get( "MySQL.port" ));
				Assert.assertNotNull( child.getComponent().exportedVariables.get( "port" ));
				Assert.assertNull( child.getComponent().exportedVariables.get( "port" ).getValue());

			} else if( "Tomcat VM 1".equals( i.getName())) {
				Assert.assertEquals( "VM", i.getComponent().getName());
				Assert.assertEquals( 1, i.getChildren().size());

				Instance child = i.getChildren().iterator().next();
				Assert.assertEquals( 0, child.getChildren().size());
				Assert.assertEquals( i, child.getParent());
				Assert.assertEquals( "Tomcat", child.getName());
				Assert.assertEquals( "Tomcat", child.getComponent().getName());

			} else {
				Assert.fail( "Unrecognized instance." );
			}
		}
	}

	@Test
	public void testLoadApplication_Lamp_Legacy_2() throws Exception {

		File directory = TestUtils.findTestFile( "/applications/lamp-legacy-with-facets-and-so-on" );
		ApplicationLoadResult result = RuntimeModelIo.loadApplication( directory );
		Assert.assertNotNull( result );
		Assert.assertNotNull( result.applicationTemplate );
		Assert.assertEquals( 3, result.loadErrors.size());
		for( RoboconfError error : result.loadErrors )
			Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, error.getErrorCode());

		// Test the graph and descriptor
		Assert.assertEquals( "Legacy LAMP", result.applicationTemplate.getName());
		Assert.assertEquals( "A sample LAMP application", result.applicationTemplate.getDescription());
		Assert.assertEquals( "1.0.1-SNAPSHOT", result.applicationTemplate.getVersion());
		Assert.assertEquals( "roboconf-1.0", result.applicationTemplate.getDslId());

		Assert.assertNotNull( result.applicationTemplate.getGraphs());
		Graphs g = result.applicationTemplate.getGraphs();
		Assert.assertEquals( 3, g.getRootComponents().size());

		Set<String> rootComponentNames = new HashSet<> ();
		for( Component c : g.getRootComponents()) {

			rootComponentNames.add( c.getName());
			Assert.assertEquals( Constants.TARGET_INSTALLER, ComponentHelpers.findComponentInstaller( c ));
			Collection<Facet> facets = ComponentHelpers.findAllFacets( c );
			Assert.assertEquals( 1, facets.size());
			Assert.assertEquals( "Virtual_Machine", facets.iterator().next().getName());
			Assert.assertEquals( 3, ComponentHelpers.findAllChildren( c ).size());

			for( Component childComponent : ComponentHelpers.findAllChildren( c )) {
				Map<String,String> exportedVariables = ComponentHelpers.findAllExportedVariables( childComponent );
				Map<String,ImportedVariable> importedVariables = ComponentHelpers.findAllImportedVariables( childComponent );
				Collection<Component> children = ComponentHelpers.findAllChildren( childComponent );

				if( "Tomcat".equals( childComponent.getName())) {
					Assert.assertEquals( "puppet", childComponent.getInstallerName());
					Assert.assertEquals( 0, children.size());

					Assert.assertEquals( 1, childComponent.getFacets().size());
					Assert.assertEquals( "deployable", childComponent.getFacets().iterator().next().getName());

					Assert.assertEquals( 2, exportedVariables.size());
					Assert.assertTrue( exportedVariables.containsKey( "Tomcat.ip" ));
					Assert.assertEquals( "8009", exportedVariables.get( "Tomcat.portAJP" ));

					Assert.assertEquals( 2, importedVariables.size());
					Assert.assertFalse( importedVariables.get( "MySQL.ip" ).isOptional());
					Assert.assertFalse( importedVariables.get( "MySQL.ip" ).isExternal());
					Assert.assertFalse( importedVariables.get( "MySQL.port" ).isOptional());
					Assert.assertFalse( importedVariables.get( "MySQL.port" ).isExternal());

				} else if( "MySQL".equals( childComponent.getName())) {
					Assert.assertEquals( "puppet", childComponent.getInstallerName());
					Assert.assertEquals( 0, children.size());

					Assert.assertEquals( 1, childComponent.getFacets().size());
					Assert.assertEquals( "deployable", childComponent.getFacets().iterator().next().getName());

					Assert.assertEquals( 2, exportedVariables.size());
					Assert.assertTrue( exportedVariables.containsKey( "MySQL.ip" ));
					Assert.assertEquals( "3306", exportedVariables.get( "MySQL.port" ));
					Assert.assertEquals( 0, importedVariables.size());

				} else if( "Apache".equals( childComponent.getName())) {
					Assert.assertEquals( "puppet", childComponent.getInstallerName());
					Assert.assertEquals( 0, children.size());
					Assert.assertEquals( 0, exportedVariables.size());

					Assert.assertEquals( 1, childComponent.getFacets().size());
					Assert.assertEquals( "deployable", childComponent.getFacets().iterator().next().getName());

					Assert.assertEquals( 2, importedVariables.size());
					Assert.assertFalse( importedVariables.get( "Tomcat.ip" ).isOptional());
					Assert.assertFalse( importedVariables.get( "Tomcat.ip" ).isExternal());
					Assert.assertFalse( importedVariables.get( "Tomcat.portAJP" ).isOptional());
					Assert.assertFalse( importedVariables.get( "Tomcat.portAJP" ).isExternal());

				} else {
					Assert.fail( "Unrecognized child." );
				}
			}
		}

		// Check we got everything in the graph
		Assert.assertEquals( 3, rootComponentNames.size());
		Assert.assertTrue( rootComponentNames.contains( "VM" ));
		Assert.assertTrue( rootComponentNames.contains( "VM_EC2" ));
		Assert.assertTrue( rootComponentNames.contains( "VM_Openstack" ));

		Component vmOpenstack = ComponentHelpers.findComponent( g, "VM_Openstack" );
		Map<String,String> exportedVariables = ComponentHelpers.findAllExportedVariables( vmOpenstack );
		Assert.assertEquals( 4, exportedVariables.size());
		Assert.assertEquals( "else", exportedVariables.get( "VM_Openstack.something" ));
		Assert.assertNull( exportedVariables.get( "Virtual_Machine.ip" ));

		Assert.assertTrue( exportedVariables.containsKey( "Virtual_Machine.ip" ));
		Assert.assertTrue( exportedVariables.containsKey( "VM_Openstack.ip" ));
		Assert.assertTrue( exportedVariables.containsKey( "VM.ip" ));

		Assert.assertEquals( ComponentHelpers.findComponent( g, "VM" ), vmOpenstack.getExtendedComponent());
		Assert.assertNotNull( vmOpenstack.getExtendedComponent());

		// Test the instances
		Set<String> expectedPaths = new HashSet<> ();
		expectedPaths.add( "/Apache VM" );
		expectedPaths.add( "/Apache VM/Apache" );
		expectedPaths.add( "/MySQL VM" );
		expectedPaths.add( "/MySQL VM/MySQL" );
		expectedPaths.add( "/Tomcat VM 1" );
		expectedPaths.add( "/Tomcat VM 1/Tomcat" );
		expectedPaths.add( "/Tomcat VM 2" );
		expectedPaths.add( "/Tomcat VM 2/Tomcat" );
		expectedPaths.add( "/Tomcat VM 3" );
		expectedPaths.add( "/Tomcat VM 3/Tomcat" );

		Set<String> realPaths = new HashSet<> ();
		for( Instance inst : InstanceHelpers.getAllInstances( result.getApplicationTemplate()))
			realPaths.add( InstanceHelpers.computeInstancePath( inst ));

		Assert.assertEquals( expectedPaths.size(), realPaths.size());
		realPaths.removeAll( expectedPaths );
		Assert.assertEquals( 0, realPaths.size());

		Instance tomcat1 = InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/Tomcat VM 1/Tomcat" );
		Instance tomcat2 = InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/Tomcat VM 2/Tomcat" );
		Instance tomcat3 = InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/Tomcat VM 3/Tomcat" );

		Assert.assertEquals( tomcat1.getComponent(), tomcat2.getComponent());
		Assert.assertEquals( tomcat1.getComponent(), tomcat3.getComponent());

		Assert.assertEquals( tomcat1.channels, tomcat2.channels );
		Assert.assertEquals( tomcat1.channels, tomcat3.channels );

		Assert.assertEquals( 0, tomcat1.getChildren().size());
		Assert.assertEquals( 1, tomcat1.overriddenExports.size());
		Assert.assertEquals( "9021", tomcat1.overriddenExports.get( "portAJP" ));
		Assert.assertEquals( "9021", InstanceHelpers.findAllExportedVariables( tomcat1 ).get( "Tomcat.portAJP" ));

		Assert.assertEquals( 0, tomcat2.getChildren().size());
		Assert.assertEquals( 1, tomcat2.overriddenExports.size());
		Assert.assertEquals( "9021", tomcat2.overriddenExports.get( "portAJP" ));
		Assert.assertEquals( "9021", InstanceHelpers.findAllExportedVariables( tomcat2 ).get( "Tomcat.portAJP" ));

		Assert.assertEquals( 0, tomcat3.getChildren().size());
		Assert.assertEquals( 1, tomcat3.overriddenExports.size());
		Assert.assertEquals( "9021", tomcat3.overriddenExports.get( "portAJP" ));
		Assert.assertEquals( "9021", InstanceHelpers.findAllExportedVariables( tomcat3 ).get( "Tomcat.portAJP" ));
	}

	@Test
	public void testLoadApplication_Mongo() throws Exception {

		File directory = TestUtils.findTestFile( "/applications/mongo" );
		ApplicationLoadResult result = RuntimeModelIo.loadApplication( directory );
		Assert.assertNotNull( result );
		Assert.assertNotNull( result.applicationTemplate );
		Assert.assertEquals( 0, result.applicationTemplate.externalExports.size());

		Assert.assertEquals( 2, result.loadErrors.size());
		for( RoboconfError error : result.loadErrors )
			Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, error.getErrorCode());

		Assert.assertEquals( "Mongo", result.applicationTemplate.getName());
		Assert.assertNotNull( result.applicationTemplate.getGraphs());
		Graphs g = result.applicationTemplate.getGraphs();
		Assert.assertEquals( 1, g.getRootComponents().size());

		Component vmComponent = g.getRootComponents().iterator().next();
		Assert.assertEquals( "VM", vmComponent.getName());
		Assert.assertEquals( "target", vmComponent.getInstallerName());
		Assert.assertEquals( 0, vmComponent.getFacets().size());

		Collection<Component> children = ComponentHelpers.findAllChildren( vmComponent );
		Assert.assertEquals( 1, children.size());

		Component childComponent = children.iterator().next();
		Assert.assertEquals( "puppet", childComponent.getInstallerName());
		Assert.assertEquals( 0, childComponent.getChildren().size());

		Assert.assertEquals( 2, childComponent.exportedVariables.size());
		Assert.assertNull( childComponent.exportedVariables.get( "Mongo.ip" ));
		Assert.assertEquals( "27017", ComponentHelpers.findAllExportedVariables( childComponent ).get( "Mongo.port" ));

		Assert.assertEquals( 2, childComponent.importedVariables.size());
		Assert.assertTrue( childComponent.importedVariables.containsKey( "Mongo.ip" ));
		Assert.assertTrue( childComponent.importedVariables.containsKey( "Mongo.port" ));
	}

	@Test
	public void testLoadApplication_AppWithExternalDependencies() throws Exception {

		File directory = TestUtils.findTestFile( "/applications/app-with-external-dependencies" );
		ApplicationLoadResult result = RuntimeModelIo.loadApplication( directory );
		Assert.assertNotNull( result );
		Assert.assertNotNull( result.applicationTemplate );

		Assert.assertEquals( 2, result.applicationTemplate.externalExports.size());
		Assert.assertEquals( "DEP.c", result.applicationTemplate.externalExports.get( "VM.config" ));
		Assert.assertEquals( "DEP.ip", result.applicationTemplate.externalExports.get( "App.ip" ));

		Assert.assertEquals( 2, result.loadErrors.size());
		for( RoboconfError error : result.loadErrors )
			Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, error.getErrorCode());

		Assert.assertEquals( "app-with-dep", result.applicationTemplate.getName());
		Assert.assertNotNull( result.applicationTemplate.getGraphs());
		Graphs g = result.applicationTemplate.getGraphs();
		Assert.assertEquals( 1, g.getRootComponents().size());

		Component vmComponent = g.getRootComponents().iterator().next();
		Assert.assertEquals( "VM", vmComponent.getName());
		Assert.assertEquals( "target", vmComponent.getInstallerName());
		Assert.assertEquals( 0, vmComponent.getFacets().size());

		Collection<Component> children = ComponentHelpers.findAllChildren( vmComponent );
		Assert.assertEquals( 1, children.size());

		Component childComponent = children.iterator().next();
		Assert.assertEquals( "App", childComponent.getName());
		Assert.assertEquals( "logger", childComponent.getInstallerName());
		Assert.assertEquals( 0, childComponent.getChildren().size());

		Assert.assertEquals( 1, childComponent.exportedVariables.size());
		Assert.assertNull( childComponent.exportedVariables.get( "App.ip" ));

		Assert.assertEquals( 2, childComponent.importedVariables.size());
		Assert.assertTrue( childComponent.importedVariables.containsKey( "VM.config" ));
		Assert.assertFalse( childComponent.importedVariables.get( "VM.config" ).isOptional());
		Assert.assertFalse( childComponent.importedVariables.get( "VM.config" ).isExternal());

		Assert.assertTrue( childComponent.importedVariables.containsKey( "App1.test" ));
		Assert.assertFalse( childComponent.importedVariables.get( "App1.test" ).isOptional());
		Assert.assertTrue( childComponent.importedVariables.get( "App1.test" ).isExternal());

	}

	@Test
	public void testLoadApplicationErrors() throws Exception {
		File tempDirectory = this.folder.newFolder();

		// Descriptor
		Iterator<RoboconfError> iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.PROJ_NO_DESC_DIR, iterator.next().getErrorCode());

		File appDir = new File( tempDirectory, Constants.PROJECT_DIR_DESC );
		if( ! appDir.mkdir())
			throw new IOException( "Failed to create the descriptor directory." );

		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.PROJ_NO_DESC_FILE, iterator.next().getErrorCode());

		Properties props = new Properties();
		props.setProperty( ApplicationTemplateDescriptor.APPLICATION_NAME, "app-name" );
		props.setProperty( ApplicationTemplateDescriptor.APPLICATION_VERSION, "1.0" );
		props.setProperty( ApplicationTemplateDescriptor.APPLICATION_DSL_ID, "roboconf-1.0" );
		props.setProperty( ApplicationTemplateDescriptor.APPLICATION_GRAPH_EP, "main.graph" );
		Utils.writePropertiesFile( props, new File( appDir, Constants.PROJECT_FILE_DESCRIPTOR ));

		// Graph
		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.PROJ_NO_GRAPH_DIR, iterator.next().getErrorCode());

		File graphDir = new File( tempDirectory, Constants.PROJECT_DIR_GRAPH );
		if( ! graphDir.mkdir())
			throw new IOException( "Failed to create the graph directory." );

		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.PROJ_MISSING_GRAPH_EP, iterator.next().getErrorCode());

		File graphFile = new File( graphDir, "main.graph" );
		if( ! graphFile.createNewFile())
			throw new IOException( "Faild to create a graph file." );

		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.P_EMPTY_FILE, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.RM_NO_ROOT_COMPONENT, iterator.next().getErrorCode());
		Assert.assertFalse( iterator.hasNext());

		Utils.writeStringInto( "   \n  \t\n\n ", graphFile );
		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.P_EMPTY_FILE, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.RM_NO_ROOT_COMPONENT, iterator.next().getErrorCode());
		Assert.assertFalse( iterator.hasNext());

		Utils.writeStringInto( "[ not supported by our parser ]", graphFile );
		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.P_UNRECOGNIZED_BLOCK, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.PM_INVALID_BLOCK_TYPE, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.CO_NOT_A_GRAPH, iterator.next().getErrorCode());
		Assert.assertFalse( iterator.hasNext());

		Utils.writeStringInto( "  \n\n [ not supported by our parser ] \n\n ", graphFile );
		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.P_UNRECOGNIZED_BLOCK, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.PM_INVALID_BLOCK_TYPE, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.CO_NOT_A_GRAPH, iterator.next().getErrorCode());
		Assert.assertFalse( iterator.hasNext());

		Utils.writeStringInto( "comp", graphFile );
		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.P_O_C_BRACKET_MISSING, iterator.next().getErrorCode());

		String fileContent = "my Toto {\n\tname: toto;\n}";
		Utils.copyStream( new ByteArrayInputStream( fileContent.getBytes( "UTF-8" )), graphFile );
		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.PM_INVALID_NAME, iterator.next().getErrorCode());

		fileContent = "instanceof Toto {\n\tname: toto;\n}";
		Utils.copyStream( new ByteArrayInputStream( fileContent.getBytes( "UTF-8" )), graphFile );
		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.PM_INVALID_NAME, iterator.next().getErrorCode());

		fileContent = "instance of Toto {\n\tname: toto;\n}";
		Utils.copyStream( new ByteArrayInputStream( fileContent.getBytes( "UTF-8" )), graphFile );
		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.CO_NOT_A_GRAPH, iterator.next().getErrorCode());

		fileContent = "facet MyFacet {\n}\n\nA {\n\tinstaller: target;\n\tfacets: MyFacet;\n}";
		Utils.copyStream( new ByteArrayInputStream( fileContent.getBytes( "UTF-8" )), graphFile );

		// Instances
		Collection<RoboconfError> errors = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors;
		Assert.assertEquals( 1, errors.size());
		Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, errors.iterator().next().getErrorCode());

		props.setProperty( ApplicationTemplateDescriptor.APPLICATION_INSTANCES_EP, "init.instances" );
		Utils.writePropertiesFile( props, new File( appDir, Constants.PROJECT_FILE_DESCRIPTOR ));

		File instDir = new File( tempDirectory, Constants.PROJECT_DIR_INSTANCES );
		if( ! instDir.mkdir())
			throw new IOException( "Failed to create the instances directory." );

		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.PROJ_MISSING_INSTANCE_EP, iterator.next().getErrorCode());

		File instancesFile = new File( instDir, "init.instances" );
		if( ! instancesFile.createNewFile())
			throw new IOException( "Failed to create " + instancesFile );

		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.P_EMPTY_FILE, iterator.next().getErrorCode());
		Assert.assertFalse( iterator.hasNext());

		Utils.writeStringInto( "   \n  \t\n\n ", instancesFile );
		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.P_EMPTY_FILE, iterator.next().getErrorCode());
		Assert.assertFalse( iterator.hasNext());

		Utils.writeStringInto( "[ not supported by our parser ]", instancesFile );
		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.P_UNRECOGNIZED_BLOCK, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.PM_INVALID_BLOCK_TYPE, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.CO_NOT_INSTANCES, iterator.next().getErrorCode());
		Assert.assertFalse( iterator.hasNext());

		Utils.writeStringInto( "  \n\n [ not supported by our parser ] \n\n ", instancesFile );
		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.P_UNRECOGNIZED_BLOCK, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.PM_INVALID_BLOCK_TYPE, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.CO_NOT_INSTANCES, iterator.next().getErrorCode());
		Assert.assertFalse( iterator.hasNext());

		Utils.writeStringInto( "  \n\n ip \n\n ", instancesFile );
		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.P_O_C_BRACKET_MISSING, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.PM_INVALID_BLOCK_TYPE, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.CO_NOT_INSTANCES, iterator.next().getErrorCode());
		Assert.assertFalse( iterator.hasNext());

		fileContent = "facet MyFacet {\n}\n\nA {\n\tinstaller: script;\n}";
		Utils.copyStream( new ByteArrayInputStream( fileContent.getBytes( "UTF-8" )), instancesFile );

		iterator = RuntimeModelIo.loadApplication( tempDirectory ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, iterator.next().getErrorCode());
		Assert.assertEquals( ErrorCode.CO_NOT_INSTANCES, iterator.next().getErrorCode());
		Assert.assertFalse( iterator.hasNext());

		fileContent = "instance of A {\n\tname: toto;\n}";
		Utils.copyStream( new ByteArrayInputStream( fileContent.getBytes( "UTF-8" )), instancesFile );
		errors =  RuntimeModelIo.loadApplication( tempDirectory ).loadErrors;
		Assert.assertEquals( 1, errors.size());
		Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, errors.iterator().next().getErrorCode());
	}

	@Test
	public void testLoadApplication_KarafJoramJndi() throws Exception {

		File directory = TestUtils.findTestFile( "/applications/karaf-joram-jndi" );
		ApplicationLoadResult result = RuntimeModelIo.loadApplication( directory );
		Assert.assertNotNull( result );
		Assert.assertNotNull( result.applicationTemplate );
		Assert.assertEquals( 6, result.loadErrors.size());
		for( RoboconfError error : result.loadErrors )
			Assert.assertEquals( ErrorCode.PROJ_NO_RESOURCE_DIRECTORY, error.getErrorCode());

		Assert.assertNotNull( InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/vmec2karaf" ));
		Assert.assertNotNull( InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/vmec2karaf/karafec21" ));
		Assert.assertNotNull( InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/vmec2karaf/karafec21/jndiec2" ));
		Assert.assertNotNull( InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/vmec2karaf/karafec22" ));
		Assert.assertNotNull( InstanceHelpers.findInstanceByPath( result.getApplicationTemplate(), "/vmec2karaf/karafec22/joramec2" ));
	}

	@Test
	public void testInvalidApplicationDescriptor() throws Exception {

		File appDirectory = this.folder.newFolder();
		File descDirectory = new File( appDirectory, Constants.PROJECT_DIR_DESC );
		if( ! descDirectory.mkdir())
			throw new IOException();

		File descFile = new File( descDirectory, Constants.PROJECT_FILE_DESCRIPTOR );
		if( ! descFile.createNewFile())
			throw new IOException();

		String content = "fail.read = true";
		Utils.copyStream( new ByteArrayInputStream( content.getBytes( "UTF-8" )), descFile );

		ApplicationLoadResult lr = RuntimeModelIo.loadApplication( appDirectory );
		Assert.assertTrue( lr.getLoadErrors().size() > 1 );
		Assert.assertEquals( ErrorCode.PROJ_READ_DESC_FILE, lr.getLoadErrors().iterator().next().getErrorCode());
	}

	@Test
	public void testWriteInstances_empty() throws Exception {

		File targetFile = this.folder.newFile();
		RuntimeModelIo.writeInstances( targetFile, new ArrayList<Instance>( 0 ));
		Assert.assertTrue( targetFile.exists());
		Assert.assertEquals( 0, targetFile.length());
	}

	@Test
	public void testWriteInstances_notEmpty() throws Exception {

		Component component = new Component( "comp" );
		Instance instance = new Instance( "inst" ).component( component ).status( InstanceStatus.DEPLOYING ).channel( "c" );
		instance.overriddenExports.put( "check", "true" );
		instance.data.put( "something", "else" );

		File targetFile = this.folder.newFile();
		RuntimeModelIo.writeInstances( targetFile, Arrays.asList( instance ));
		Assert.assertTrue( targetFile.exists());
		Assert.assertTrue( 0 < targetFile.length());
	}

	@Test
	public void testApplicationWithMissingGraph() throws Exception {

		File dir = this.folder.newFolder();
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_DESC ).mkdir());
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH ).mkdir());
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_INSTANCES ).mkdir());
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_INSTANCES + "/model.instances" ).createNewFile());

		ApplicationTemplateDescriptor desc = new ApplicationTemplateDescriptor();
		desc.setName( "app name" );
		desc.setVersion( "3.0" );
		desc.setInstanceEntryPoint( "model.instances" );
		desc.setDslId( "roboconf-1.0" );

		ApplicationTemplateDescriptor.save( new File( dir, Constants.PROJECT_DIR_DESC + "/" + Constants.PROJECT_FILE_DESCRIPTOR ), desc );
		Iterator<RoboconfError> it = RuntimeModelIo.loadApplicationFlexibly( dir ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.RM_MISSING_APPLICATION_GEP, it.next().getErrorCode());
		Assert.assertEquals( ErrorCode.CO_GRAPH_COULD_NOT_BE_BUILT, it.next().getErrorCode());
	}

	@Test
	public void testApplicationWithoutInstances() throws Exception {

		File dir = this.folder.newFolder();
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_DESC ).mkdir());
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH ).mkdir());
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_INSTANCES ).mkdir());

		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM" ).mkdir());
		Utils.writeStringInto(
				"id: tid\nhandler: test\nname: n",
				new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM/target.properties" ));

		File graphFile = new File( dir, Constants.PROJECT_DIR_GRAPH + "/app.graph" );
		Assert.assertTrue( graphFile.createNewFile());

		ApplicationTemplateDescriptor desc = new ApplicationTemplateDescriptor();
		desc.setName( "app name" );
		desc.setVersion( "3.0" );
		desc.setGraphEntryPoint( "app.graph" );
		desc.setDslId( "roboconf-1.0" );
		ApplicationTemplateDescriptor.save( new File( dir, Constants.PROJECT_DIR_DESC + "/" + Constants.PROJECT_FILE_DESCRIPTOR ), desc );

		Utils.writeStringInto( "VM {\ninstaller:target;\n}", graphFile );
		Assert.assertEquals( 0, RuntimeModelIo.loadApplication( dir ).loadErrors.size());
	}

	@Test
	public void testUnreachableFile() throws Exception {

		// Valid project
		File dir = this.folder.newFolder();
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_DESC ).mkdir());
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH ).mkdir());
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_INSTANCES ).mkdir());

		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM" ).mkdir());
		Utils.writeStringInto(
				"id: tid\nhandler: test\nname: n",
				new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM/target.properties" ));

		ApplicationTemplateDescriptor desc = new ApplicationTemplateDescriptor();
		desc.setName( "app name" );
		desc.setVersion( "3.0" );
		desc.setGraphEntryPoint( "app.graph" );
		desc.setDslId( "roboconf-1.0" );
		ApplicationTemplateDescriptor.save( new File( dir, Constants.PROJECT_DIR_DESC + "/" + Constants.PROJECT_FILE_DESCRIPTOR ), desc );

		File graphFile = new File( dir, Constants.PROJECT_DIR_GRAPH + "/app.graph" );
		Utils.writeStringInto( "VM {\ninstaller:target;\n}", graphFile );

		// Unreachable files
		final int length = 3;
		File[] copies = new File[ length ];
		for( int i=0; i<length; i++ ) {
			copies[ i ] = new File( new File( dir, Constants.PROJECT_DIR_GRAPH ), "not-used-" + i + ".graph" );
			Utils.copyStream( graphFile, copies[ i ]);
		}

		// Verify
		List<RoboconfError> errors = new ArrayList<>( RuntimeModelIo.loadApplication( dir ).loadErrors );
		Assert.assertEquals( length, errors.size());
		for( int i=0; i<length; i++ ) {
			Assert.assertEquals( ParsingError.class, errors.get( i ).getClass());
			Assert.assertEquals( ErrorCode.PROJ_UNREACHABLE_FILE, errors.get( i ).getErrorCode());
			Assert.assertEquals( copies[ i ], ((ParsingError) errors.get( i )).getFile());
		}
	}

	@Test
	public void testApplicationWithInvalidTarget() throws Exception {

		File dir = this.folder.newFolder();
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_DESC ).mkdir());
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH ).mkdir());
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_INSTANCES ).mkdir());

		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM" ).mkdir());
		Utils.writeStringInto(
				"handler: test\nname: n",
				new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM/target.properties" ));

		File graphFile = new File( dir, Constants.PROJECT_DIR_GRAPH + "/app.graph" );
		Assert.assertTrue( graphFile.createNewFile());

		ApplicationTemplateDescriptor desc = new ApplicationTemplateDescriptor();
		desc.setName( "app name" );
		desc.setVersion( "3.0" );
		desc.setGraphEntryPoint( "app.graph" );
		desc.setDslId( "roboconf-1.0" );
		ApplicationTemplateDescriptor.save( new File( dir, Constants.PROJECT_DIR_DESC + "/" + Constants.PROJECT_FILE_DESCRIPTOR ), desc );

		Utils.writeStringInto( "VM {\ninstaller:target;\n}", graphFile );
		Iterator<RoboconfError> it = RuntimeModelIo.loadApplication( dir ).loadErrors.iterator();
		Assert.assertEquals( ErrorCode.REC_TARGET_NO_ID, it.next().getErrorCode());
		Assert.assertFalse( it.hasNext());
	}

	@Test
	public void testInvalidFileLocation() throws Exception {

		// Valid project
		File dir = this.folder.newFolder();
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_DESC ).mkdir());
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH ).mkdir());
		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_INSTANCES ).mkdir());

		Assert.assertTrue( new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM" ).mkdir());
		Utils.writeStringInto(
				"id: tid\nhandler: test\nname: n",
				new File( dir, Constants.PROJECT_DIR_GRAPH + "/VM/target.properties" ));

		ApplicationTemplateDescriptor desc = new ApplicationTemplateDescriptor();
		desc.setName( "app name" );
		desc.setVersion( "3.0" );
		desc.setGraphEntryPoint( "app.graph" );
		desc.setDslId( "roboconf-1.0" );
		ApplicationTemplateDescriptor.save( new File( dir, Constants.PROJECT_DIR_DESC + "/" + Constants.PROJECT_FILE_DESCRIPTOR ), desc );

		File graphFile = new File( dir, Constants.PROJECT_DIR_GRAPH + "/app.graph" );
		Utils.writeStringInto( "VM {\ninstaller:target;\n}", graphFile );

		// File at an invalid location
		final int length = 3;
		File[] copies = new File[ length ];
		for( int i=0; i<length; i++ ) {
			copies[ i ] = new File( dir, "not-used-" + i + ".graph" );
			Utils.copyStream( graphFile, copies[ i ]);
		}

		// Such files are not validated
		File invalidInstFile = new File( dir, "invalid.instances" );
		Utils.writeStringInto( "inst of {", invalidInstFile );

		// Verify
		List<RoboconfError> errors = new ArrayList<>( RuntimeModelIo.loadApplication( dir ).loadErrors );
		Assert.assertEquals( length + 1, errors.size());
		for( int i=0; i<length; i++ ) {
			Assert.assertEquals( ParsingError.class, errors.get( i ).getClass());
			Assert.assertEquals( ErrorCode.PROJ_INVALID_FILE_LOCATION, errors.get( i ).getErrorCode());
			Assert.assertEquals( copies[ i ], ((ParsingError) errors.get( i )).getFile());
		}

		Assert.assertEquals( ParsingError.class, errors.get( length - 1 ).getClass());
		Assert.assertEquals( ErrorCode.PROJ_INVALID_FILE_LOCATION, errors.get( length - 1 ).getErrorCode());
		Assert.assertEquals( copies[ length - 1 ], ((ParsingError) errors.get( length - 1 )).getFile());
	}

	@Test
	public void testParsingWithRecipeProject() throws Exception {

		// Normal load
		File dir = TestUtils.findTestFile( "/reusable.recipe" );
		Assert.assertTrue( dir.exists());

		ApplicationLoadResult alr = RuntimeModelIo.loadApplication( dir );
		RoboconfErrorHelpers.filterErrorsForRecipes( alr );

		List<RoboconfError> errors = new ArrayList<>( alr.getLoadErrors());
		Assert.assertEquals( 2, errors.size());
		Assert.assertEquals( ErrorCode.PROJ_NO_DESC_DIR, errors.get( 0 ).getErrorCode());
		Assert.assertEquals( ErrorCode.PROJ_UNREACHABLE_FILE, errors.get( 1 ).getErrorCode());

		// Flexible load
		alr = RuntimeModelIo.loadApplicationFlexibly( dir );
		RoboconfErrorHelpers.filterErrorsForRecipes( alr );
		Assert.assertEquals( 0, alr.getLoadErrors().size());
	}

	@Test
	public void testParsingWithInvalidRecipeProject() throws Exception {

		File dir = TestUtils.findTestFile( "/reusable.recipe.with.errors" );
		Assert.assertTrue( dir.exists());

		ApplicationLoadResult alr = RuntimeModelIo.loadApplicationFlexibly( dir );
		RoboconfErrorHelpers.filterErrorsForRecipes( alr );
		Assert.assertEquals( 1, alr.getLoadErrors().size());
		Assert.assertEquals( ErrorCode.RM_UNRESOLVABLE_VARIABLE, alr.getLoadErrors().iterator().next().getErrorCode());

		RoboconfError error = alr.getLoadErrors().iterator().next();
		Assert.assertEquals( 1, error.getDetails().length );
		Assert.assertEquals( ErrorDetailsKind.VARIABLE, error.getDetails()[ 0 ].getErrorDetailsKind());
		Assert.assertTrue( error.getDetails()[ 0 ].getElementName().contains( "f.*" ));
	}

	@Test
	public void testGraphFileFilter() throws Exception {

		GraphFileFilter filter = new GraphFileFilter();
		Assert.assertFalse( filter.accept( new File( "inexisting" )));

		Assert.assertTrue( filter.accept( this.folder.newFile( "toto.graph" )));
		Assert.assertFalse( filter.accept( this.folder.newFile( "toto.txt" )));
		Assert.assertFalse( filter.accept( this.folder.newFolder( "sth.graph" )));
	}

	@Test
	public void testParsingWithRandomValues() throws Exception {

		File dir = TestUtils.findApplicationDirectory( "app-with-random-ports" );
		Assert.assertTrue( dir.isDirectory());

		ApplicationLoadResult alr = RuntimeModelIo.loadApplication( dir );
		Assert.assertFalse( RoboconfErrorHelpers.containsCriticalErrors( alr.getLoadErrors()));

		// Container 1
		Instance container1 = InstanceHelpers.findInstanceByPath( alr.getApplicationTemplate(), "/vm/container1" );
		Assert.assertNotNull( container1 );

		Assert.assertNull( container1.getComponent().exportedVariables.get( "httpPort" ).getValue());
		Assert.assertTrue( container1.getComponent().exportedVariables.get( "httpPort" ).isRandom());
		Assert.assertEquals( RandomKind.PORT, container1.getComponent().exportedVariables.get( "httpPort" ).getRandomKind());

		Assert.assertNull( container1.getComponent().exportedVariables.get( "ajpPort" ).getValue());
		Assert.assertTrue( container1.getComponent().exportedVariables.get( "ajpPort" ).isRandom());
		Assert.assertEquals( RandomKind.PORT, container1.getComponent().exportedVariables.get( "ajpPort" ).getRandomKind());

		Assert.assertEquals( "test", container1.getComponent().exportedVariables.get( "config" ).getValue());
		Assert.assertFalse( container1.getComponent().exportedVariables.get( "config" ).isRandom());
		Assert.assertNull( container1.getComponent().exportedVariables.get( "config" ).getRandomKind());

		Assert.assertNull( container1.getComponent().exportedVariables.get( "ip" ).getValue());
		Assert.assertFalse( container1.getComponent().exportedVariables.get( "ip" ).isRandom());
		Assert.assertNull( container1.getComponent().exportedVariables.get( "ip" ).getRandomKind());

		Map<String,String> exportedVariables = InstanceHelpers.findAllExportedVariables( container1 );
		Assert.assertEquals( "test", exportedVariables.get( "Container1.config" ));

		Assert.assertTrue( exportedVariables.containsKey( "Container1.ip" ));
		Assert.assertNull( exportedVariables.get( "Container1.ip" ));

		Assert.assertTrue( exportedVariables.containsKey( "Container1.httpPort" ));
		Assert.assertNull( exportedVariables.get( "Container1.httpPort" ));

		Assert.assertTrue( exportedVariables.containsKey( "Container1.ajpPort" ));
		Assert.assertNull( exportedVariables.get( "Container1.ajpPort" ));

		// Container 2
		Instance container2 = InstanceHelpers.findInstanceByPath( alr.getApplicationTemplate(), "/vm/container2" );
		Assert.assertNotNull( container2 );

		Assert.assertNull( container2.getComponent().exportedVariables.get( "port" ).getValue());
		Assert.assertTrue( container2.getComponent().exportedVariables.get( "port" ).isRandom());
		Assert.assertEquals( RandomKind.PORT, container2.getComponent().exportedVariables.get( "port" ).getRandomKind());

		Assert.assertNull( container2.getComponent().exportedVariables.get( "ip" ).getValue());
		Assert.assertFalse( container2.getComponent().exportedVariables.get( "ip" ).isRandom());
		Assert.assertNull( container2.getComponent().exportedVariables.get( "ip" ).getRandomKind());

		exportedVariables = InstanceHelpers.findAllExportedVariables( container2 );
		Assert.assertTrue( exportedVariables.containsKey( "Container2.ip" ));
		Assert.assertNull( exportedVariables.get( "Container2.ip" ));

		// This value is found in the instances.
		Assert.assertEquals( "45012", exportedVariables.get( "Container2.port" ));
	}

	@Test
	public void testParsingWithInvalidCommands() throws Exception {

		// Copy the application and update a command file
		File dir = TestUtils.findApplicationDirectory( "lamp" );
		Assert.assertTrue( dir.isDirectory());

		File newDir = this.folder.newFolder();
		Utils.copyDirectory( dir, newDir );

		File commandFile = new File( newDir, Constants.PROJECT_DIR_COMMANDS + "/scale.commands" );
		Assert.assertTrue( commandFile.isFile());

		File commandFileCopy = new File( newDir, Constants.PROJECT_DIR_COMMANDS + "/scale.invalid-extension" );
		Utils.copyStream( commandFile, commandFileCopy );
		Utils.writeStringInto( "this is an invalid command", commandFile );

		// Load it and verify it contains errors
		ApplicationLoadResult alr = RuntimeModelIo.loadApplication( newDir );
		List<RoboconfError> criticalErrors = new ArrayList<> ();

		for( RoboconfError error : alr.getLoadErrors()) {
			if( error.getErrorCode().getLevel() == ErrorLevel.SEVERE )
				criticalErrors.add( error );
		}

		Assert.assertEquals( 2, criticalErrors.size());
		Assert.assertEquals( ErrorCode.CMD_UNRECOGNIZED_INSTRUCTION, criticalErrors.get( 0 ).getErrorCode());
		Assert.assertEquals( ErrorCode.PROJ_INVALID_COMMAND_EXT, criticalErrors.get( 1 ).getErrorCode());
	}

	@Test
	public void testParsingWithInvalidAutonomicRules() throws Exception {

		// Copy the application and update a command file
		File dir = TestUtils.findApplicationDirectory( "lamp" );
		Assert.assertTrue( dir.isDirectory());

		File newDir = this.folder.newFolder();
		Utils.copyDirectory( dir, newDir );

		File ruleFile = new File( newDir, Constants.PROJECT_DIR_RULES_AUTONOMIC + "/sample.drl" );
		Assert.assertTrue( ruleFile.isFile());

		File ruleFileCopy = new File( newDir, Constants.PROJECT_DIR_RULES_AUTONOMIC + "/sample.drl-invalid-extension" );
		Utils.copyStream( ruleFile, ruleFileCopy );

		String s = Utils.readFileContent( ruleFile );
		s = s.replace( "scale", "inexisting-command" );
		Utils.writeStringInto( s, ruleFile );

		// Load it and verify it contains errors
		ApplicationLoadResult alr = RuntimeModelIo.loadApplication( newDir );
		List<RoboconfError> criticalErrors = new ArrayList<> ();

		for( RoboconfError error : alr.getLoadErrors()) {
			if( error.getErrorCode().getLevel() == ErrorLevel.SEVERE )
				criticalErrors.add( error );
		}

		Assert.assertEquals( 2, criticalErrors.size());
		Assert.assertEquals( ErrorCode.RULE_UNKNOWN_COMMAND, criticalErrors.get( 0 ).getErrorCode());
		Assert.assertEquals( ErrorCode.PROJ_INVALID_RULE_EXT, criticalErrors.get( 1 ).getErrorCode());
	}

	@Test
	public void testParsingWithInexistingDirectory() {

		ApplicationLoadResult alr = RuntimeModelIo.loadApplication( new File( "inexiting" ));
		Assert.assertNotNull( alr.getApplicationTemplate());
		Assert.assertNull( alr.getApplicationTemplate().getGraphs());
		Assert.assertNotSame( 0, alr.getLoadErrors().size());
	}

	@Test
	public void testParsingWithInstancesAndComponentExtensions() throws Exception {

		File dir = TestUtils.findApplicationDirectory( "component-extensions" );
		Assert.assertTrue( dir.isDirectory());

		ApplicationLoadResult alr = RuntimeModelIo.loadApplication( dir );
		Assert.assertFalse( RoboconfErrorHelpers.containsCriticalErrors( alr.getLoadErrors()));

		// Ambiguous overriding with multiple inheritance
		Instance ambiguous = InstanceHelpers.findInstanceByPath( alr.getApplicationTemplate(), "/container-bootstrap-vm/ambiguous" );
		Assert.assertNotNull( ambiguous );

		Map<String,String> exportedVariables = InstanceHelpers.findAllExportedVariables( ambiguous );
		Assert.assertEquals( 9, exportedVariables.size());

		Assert.assertEquals( "petals-sl-postgresql-9.4-1201-jdbc4", exportedVariables.get( "PetalsJBIComponent.componentId" ));
		Assert.assertEquals( "petals-sl-postgresql-9.4-1201-jdbc4", exportedVariables.get( "PetalsSL.componentId" ));
		Assert.assertEquals( "petals-sl-postgresql-9.4-1201-jdbc4", exportedVariables.get( "PetalsSLPostgreSQL.componentId" ));
		Assert.assertEquals( "petals-sl-postgresql-9.4-1201-jdbc4", exportedVariables.get( "componentId" ));

		Assert.assertEquals( "SL", exportedVariables.get( "PetalsSL.componentType" ));
		Assert.assertEquals( "SL", exportedVariables.get( "PetalsSLPostgreSQL.componentType" ));
		Assert.assertEquals( "true", exportedVariables.get( "PetalsSLPostgreSQL.present" ));

		Assert.assertEquals( "roboconf-demo", exportedVariables.get( "domainName" ));
		Assert.assertEquals( "roboconf-demo-1", exportedVariables.get( "subdomainName" ));

		// Specific overriding with multiple inheritance
		Instance specific = InstanceHelpers.findInstanceByPath( alr.getApplicationTemplate(), "/container-bootstrap-vm/specific" );
		Assert.assertNotNull( specific );

		exportedVariables = InstanceHelpers.findAllExportedVariables( specific );
		Assert.assertEquals( 7, exportedVariables.size());
		Assert.assertEquals( "comp", exportedVariables.get( "PetalsJBIComponent.componentId" ));
		Assert.assertEquals( "sl", exportedVariables.get( "PetalsSL.componentId" ));
		Assert.assertEquals( "last", exportedVariables.get( "PetalsSLPostgreSQL.componentId" ));
		Assert.assertNull( exportedVariables.get( "componentId" ));

		Assert.assertEquals( "SL", exportedVariables.get( "PetalsSL.componentType" ));
		Assert.assertEquals( "SL", exportedVariables.get( "PetalsSLPostgreSQL.componentType" ));
		Assert.assertEquals( "true", exportedVariables.get( "PetalsSLPostgreSQL.present" ));

		Assert.assertEquals( "roboconf-demo", exportedVariables.get( "domainName" ));
		Assert.assertNull( exportedVariables.get( "subdomainName" ));

		// Instance from a super component
		Instance superInstance = InstanceHelpers.findInstanceByPath( alr.getApplicationTemplate(), "/container-bootstrap-vm/superInstance" );
		Assert.assertNotNull( superInstance );

		exportedVariables = InstanceHelpers.findAllExportedVariables( superInstance );
		Assert.assertEquals( 4, exportedVariables.size());
		Assert.assertEquals( "my-sl", exportedVariables.get( "PetalsJBIComponent.componentId" ));
		Assert.assertEquals( "my-sl", exportedVariables.get( "PetalsSL.componentId" ));
		Assert.assertEquals( "my-sl", exportedVariables.get( "componentId" ));

		Assert.assertEquals( "SL", exportedVariables.get( "PetalsSL.componentType" ));

		Assert.assertNull( exportedVariables.get( "PetalsSLPostgreSQL.componentId" ));
		Assert.assertNull( exportedVariables.get( "domainName" ));
		Assert.assertNull( exportedVariables.get( "subdomainName" ));
	}
}


text:
import {Sensor} from "./Sensor";

export class SensorNode {
    constructor(private address: Number,
                private description: string,
                private name: string,
                private sensors: Sensor[]) {
        this.address = address;
        this.description = description;
        this.name = name;
        this.sensors = sensors;
    }
}

redpajama_set_name: RedPajamaGithub


text:
author: robmyers
comments: true
date: 2008-11-29 05:40:49+00:00
layout: post
slug: wacom-xorgconf-for-lenny-laptop
title: Wacom xorg.conf For Lenny Laptop
wordpress_id: 1696
categories:
- Art Computing
- Howto
---

# This may be useful to someone else

Section "InputDevice"
Identifier "Generic Keyboard"
Driver "kbd"
Option "XkbRules" "xorg"
Option "XkbModel" "pc105"
Option "XkbLayout" "gb"
EndSection

Section "InputDevice"
Identifier "Configured Mouse"
Driver "mouse"
EndSection

Section "Device"
Identifier "Configured Video Device"
EndSection

Section "Monitor"
Identifier "Configured Monitor"
EndSection

Section "Screen"
Identifier "Default Screen"
Monitor "Configured Monitor"
EndSection

Section "InputDevice"
Driver "wacom"
Identifier "stylus"
Option "Device" "/dev/input/wacom"
Option "Type" "stylus"
Option "USB" "on"
EndSection

Section "InputDevice"
Driver "wacom"
Identifier "eraser"
Option "Device" "/dev/input/wacom"
Option "Type" "eraser"
Option "USB" "on"
EndSection

Section "InputDevice"
Driver "wacom"
Identifier "cursor"
Option "Device" "/dev/input/wacom"
Option "Type" "cursor"
Option "USB" "on"
EndSection

Section "InputDevice"
Driver "wacom"
Identifier "pad"
Option "Device" "/dev/input/wacom"
Option "Type" "pad"
Option "USB" "on"
EndSection
Section "ServerLayout"
Identifier "Default Layout"
Screen 0 "Default Screen" 0 0
InputDevice "Configured Mouse" "CorePointer"
InputDevice "Generic Keyboard" "CoreKeyboard"
InputDevice "stylus" "SendCoreEvents"
InputDevice "eraser" "SendCoreEvents"
InputDevice "cursor" "SendCoreEvents" # For non-LCD tablets only
# InputDevice "touch" "SendCoreEvents" # Only a few TabletPCs support this type
InputDevice "pad" # For Intuos3/CintiqV5/Graphire4/Bamboo tablets
EndSection


text:
#import "RCTPickerManager.h"

#import <React/RCTUIManager.h>
#import "RCTBridge.h"
#import "RCTFont.h"
#import "RCTPicker.h"

@implementation RCTPickerManager

RCT_EXPORT_MODULE()

- (UIView *)view
{
  return [RCTPicker new];
}

RCT_EXPORT_VIEW_PROPERTY(items, NSArray<NSDictionary *>)
RCT_EXPORT_VIEW_PROPERTY(selectedIndex, NSInteger)
RCT_REMAP_VIEW_PROPERTY(accessibilityLabel, reactAccessibilityElement.accessibilityLabel, NSString)
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(color, UIColor)
RCT_EXPORT_VIEW_PROPERTY(textAlign, NSTextAlignment)
RCT_CUSTOM_VIEW_PROPERTY(fontSize, NSNumber, RCTPicker)
{
  view.font = [RCTFont updateFont:view.font withSize:json ?: @(defaultView.font.pointSize)];
}
RCT_CUSTOM_VIEW_PROPERTY(fontWeight, NSString, __unused RCTPicker)
{
  view.font = [RCTFont updateFont:view.font withWeight:json]; // defaults to normal
}
RCT_CUSTOM_VIEW_PROPERTY(fontStyle, NSString, __unused RCTPicker)
{
  view.font = [RCTFont updateFont:view.font withStyle:json]; // defaults to normal
}
RCT_CUSTOM_VIEW_PROPERTY(fontFamily, NSString, RCTPicker)
{
  view.font = [RCTFont updateFont:view.font withFamily:json ?: defaultView.font.familyName];
}

RCT_EXPORT_METHOD(setNativeSelectedIndex : (nonnull NSNumber *)viewTag toIndex : (nonnull NSNumber *)index)
{
  [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
    UIView *view = viewRegistry[viewTag];

    if ([view isKindOfClass:[RCTPicker class]]) {
      [(RCTPicker *)view setSelectedIndex:index.integerValue];
    } else {
      // This component is used in Fabric through LegacyInteropLayer.
      // `RCTPicker` view is subview of `RCTLegacyViewManagerInteropComponentView`.
      // `viewTag` passed as parameter to this method is tag of the `RCTLegacyViewManagerInteropComponentView`.
      UIView *subview = [uiManager viewForReactTag:viewTag].subviews.firstObject;
      if ([subview isKindOfClass:[RCTPicker class]]) {
        [(RCTPicker *)subview setSelectedIndex:index.integerValue];
      } else {
        RCTLogError(@"view type must be RCTPicker");
      }
    }
  }];
}

@end


text:
CREATE TABLE ports (
	pid INTEGER PRIMARY KEY NOT NULL,
	name VARCHAR(255) NOT NULL,
	version VARCHAR(255) NOT NULL,
	revision INTEGER NOT NULL
);

CREATE TABLE keywords (
	pid INTEGER NOT NULL,
	keyword VARCHAR(255) NOT NULL,
	value VARCHAR(255)
);


text:
@interface LMGroupChooseNoteMemberlistPage : BaseViewController

- (instancetype)initWithMembers:(NSArray *)members;

@property (nonatomic ,copy) void (^ChooseGroupMemberCallBack)(AccountInfo *member);

@end


text:
import { addCronJob } from '../cronUtil';

export const releaseEmailBatches = ({now}) => {
}

addCronJob({
  name: "Hourly notification batch",
  schedule(parser) {
    return parser.cron('0 ? * * *');
  },
  job() {
    releaseEmailBatches({ now: new Date() });
  }
});


text:
package org.apache.beehive.netui.script.common.bundle;

import java.util.Locale;
import java.util.Enumeration;

import org.apache.struts.util.MessageResources;
import org.apache.beehive.netui.util.internal.InternalStringBuilder;

/**
 */
class StrutsBundleNode
    extends BundleNode {

    private Locale _locale;
    private MessageResources _messageResource;

    StrutsBundleNode(Locale locale, MessageResources messageResource) {
        _locale = locale;
        _messageResource = messageResource;
    }

    public boolean containsKey(String key) {
        assert _messageResource != null;
        return _messageResource.getMessage(_locale, key) != null;
    }

    public String getString(String key) {
        assert _messageResource != null;
        return _messageResource.getMessage(_locale, key);
    }

    public Enumeration getKeys() {
        throw new UnsupportedOperationException("The getKeys() method is not supported on the MessageResources type.");
    }

    public String toString() {
        InternalStringBuilder sb = new InternalStringBuilder();
        sb.append("StrutsBundleNode ");
        sb.append("messageResource: ");
        sb.append(_messageResource);
        sb.append(" ");
        sb.append("locale: ");
        sb.append(_locale);
        return sb.toString();
    }
}


text:
'use strict';

const mongoose = require('mongoose');

const { imageSchema } = require('./image-model');

const authorSchema = mongoose.Schema({
    username: {
        type: String,
        required: true
    }
});

let imagePostSchema = mongoose.Schema({
    title: {
        type: String,
        required: true
    },
    createdOn: {
        type: Date
        // required: true
    },
    //Just for now, image is url from www
    // imageUrl: {
    //     type: String
    //     // required: true
    // },
    image: {
        type: imageSchema,
        required: true
    },
    // author: {
    //     type: String,
    //     required: true
    // },
    author: {
        type: authorSchema,
        required: true
    },
    likes: {
        type: Number,
        default: 0
    },
    comments: {
        type: [{}]
    },
    category: {
        type: String,
        required: true
    },
    usersLiked: [String]
});

mongoose.model('ImagePost', imagePostSchema);
module.exports = {
    ImagePost: mongoose.model('ImagePost'),
    imagePostSchema
};


text:
La classe DataSource est typiquement un objet avec un aspect client et un aspect server.
Sous-classable.

### attributes

### category initServer

#### setQueries(queries: any): void
#### setSafeValidators(validators: any): void

### category local

Traitements faisable en local, c'est à dire sans accéder à la base de données.

#### filter(objects: [0, *, VersionedObject], conditions: dictionary): [0, *, VersionedObject]
Filtre un ensemble d'objets d'après les conditions données.

### farCategory client

Point d'entrée coté client pour l'utilisation de DataSource, ces méthodes implémentent des vérifications locales autour des appels distants (farCategory server)

#### query(q: dictionary): { * :[0, *, VersionedObject]}

#### load(l: {objects: [0, *, VersionedObject], scope: { *: { *: [0, *, string] } } | [0, *, string] }): [0, *, VersionedObject]

#### save(objects: [0, *, VersionedObject]): [0, *, VersionedObject]

### farCategory Public

Partie accessible depuis l'exterieur de la DataSource

#### publicQuery(q: { id: string, *: any }):  { * :[0, *, VersionedObject{ LoadedScope }]}

#### publicLoad(l: {objects: [0, *, VersionedObject], scope: { *: { *: [0, *, string] } } | [0, *, string] }): [0, *, VersionedObject{ LoadedScope }]

#### publicSave(objects: [0, *, VersionedObject{ LoadedScope }]): [0, *, VersionedObject{ LoadedScope }]

### farCategory safe

Partie accessible depuis le serveur qui implemente toutes les vérifications relatives à la cohérence et aux droits

#### safeQuery(q: dictionary): { * :[0, *, VersionedObject]}
query permet de récupérer des objets en posant une question et de les ramener en spécifiant les attributs à ramener pour chaque classe d'objets.
Ex: ramener les Person dont le nom commence par A, en ramenant juste le nom.

#### safeLoad(l: {objects: [0, *, VersionedObject], scope: { *: { *: [0, *, string] } } | [0, *, string] }): [0, *, VersionedObject]
Retourne un ensemble d'objets sous forme de dico avec pour clé les identifiants.
Pas de profondeur, quand la valeur est un objet la valeur retournée est juste l'identifiant.

#### safeSave(objects: [0, *, VersionedObject]): [0, *, VersionedObject]
Enregistre la liste d'objets fournis et renvoie les objets modifiés (nouvelle version courante ou conflits).

Appelle `implSave` pour réaliser effectivement l'enregistrement sur la liste filtré d'objets qui ont effectivement des modifications.

### farCategory raw

Accès direct aux méthodes de base sans __aucune vérification de droit ni de cohérence__.
A utiliser le plus rarement possible, jamais si possible.

#### rawQuery(query: dictionary): { * :[0, *, VersionedObject]}

> __Attention__: `rawQuery` n'effectue aucune vérification de droits sur les objets à charger (contrairement à `rawQuery`). A utiliser en connaissance de causes.

#### rawLoad(l: { objects: [0, *, VersionedObject], scope: { *: { *: [0, *, string] } } | [0, *, string] }): [0, *, VersionedObject]

> __Attention__: `rawLoad` n'effectue aucune vérification de droits sur les objets à charger (contrairement à `safeLoad`). A utiliser en connaissance de causes.

#### rawSave(objects: [0, *, VersionedObject]): [0, *, VersionedObject]
Enregistre la liste d'objets fournis et renvoie les objets modifiés (nouvelle version courante ou conflits).

> __Attention__: `rawSave` n'effectue aucune vérification de cohérence et de droits sur les objets à sauver (contrairement à `safeSave`). A utiliser en connaissance de causes.

Appelle `implSave` pour réaliser effectivement l'enregistrement sur la liste filtré d'objets qui ont effectivement des modifications.

### farCategory implementation

Méthodes à implémenter par les dataSources.

#### implBeginTransaction(): any

Démarre une transaction

>#### implLock(a: { tr: any, on: [0, *, string] }): void

Vérouille la datasource sur le tuple `on`. Tant que `implEndTransaction` n'a pas été appelée et que l'application tourne, personne ne peut prendre le véroux si le tuple `on`.

#### implQuery(a: { tr: any | undefined, sets: [0, *, ObjectSet] }): { * :[0, *, VersionedObject]}

Effectue une requête et retourne le résultat

#### implLoad(a: { tr: any | undefined, objects: [0, *, VersionedObject], scope: ResolvedScope }): [0, *, VersionedObject]

Charge les attributs de `objects` et retourne les objets.

#### implSave(a: { tr: any, objects: [0, *, VersionedObject] }): void

Enregistre la liste d'objets fournis et retourne la forme en base des objets.
Tous les objets ont des modifications en attentes.

Les valeurs locales en attente d'enregistrement sont passé en valeurs version courante que si tous les objets sont sauvés avec succès.
En cas de conflits, rien n'est sauvé et les informations sur les conflits sont passés aux objets.

#### implEndTransaction(a: { tr: any, commit: boolean }): void

Valide une transaction si `commit` est vrai, sinon annule la transaction.

### aspect client
#### categories: local client
#### farCategories: Public

### aspect server
#### categories: local Public safe raw implementation initServer


text:
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main" >> /etc/apt/sources.list.d/postgresql.list'

sudo apt-get update

# Install Postgres
sudo apt-get install -y postgresql-9.6 postgresql-contrib-9.6

# Configure Postgres Remote Access
sudo sh -c "echo 'host    all             all             all                     md5' >> /etc/postgresql/9.6/main/pg_hba.conf"
sudo sed -i "s/[# ]*listen_addresses\([[:space:]]*\)=\([[:space:]]*\).*/listen_addresses = '\*'/g" /etc/postgresql/9.6/main/postgresql.conf

# Create database for vagrant user
sudo -u postgres psql -c "CREATE ROLE vagrant LOGIN UNENCRYPTED PASSWORD 'secret' SUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;"
sudo -u postgres /usr/bin/createdb --echo --owner=vagrant vagrant

sudo systemctl restart postgresql

# Add Postgres entry for UFW firewall
sudo bash -c "cat > /etc/ufw/applications.d/postgres" << EOL
[PostgreSQL]
title=PostgreSQL
description=PostgreSQL, often simply Postgres, is an object-relational database management system (ORDBMS) with an emphasis on extensibility and standards-compliance.
ports=5432/tcp
EOL

# Add allow rule for Postgres in firewall
sudo ufw allow 'PostgreSQL'


text:
package de.tum.in.www1.artemis.repository.hestia;

import java.util.Optional;
import java.util.Set;

import javax.validation.constraints.NotNull;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import de.tum.in.www1.artemis.domain.hestia.ProgrammingExerciseTask;
import de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException;

/**
 * Spring Data repository for the ProgrammingExerciseTask entity.
 */
public interface ProgrammingExerciseTaskRepository extends JpaRepository<ProgrammingExerciseTask, Long> {

    Set<ProgrammingExerciseTask> findByExerciseId(Long exerciseId);

    @NotNull
    default ProgrammingExerciseTask findByIdElseThrow(long programmingExerciseTaskId) throws EntityNotFoundException {
        return findById(programmingExerciseTaskId).orElseThrow(() -> new EntityNotFoundException("Programming Exercise Task", programmingExerciseTaskId));
    }

    /**
     * Gets a task with its programming exercise, test cases and solution entries of the test cases
     *
     * @param entryId The id of the task
     * @return The task with the given ID if found
     * @throws EntityNotFoundException If no task with the given ID was found
     */
    @NotNull
    default ProgrammingExerciseTask findByIdWithTestCaseAndSolutionEntriesElseThrow(long entryId) throws EntityNotFoundException {
        return findByIdWithTestCaseAndSolutionEntries(entryId).orElseThrow(() -> new EntityNotFoundException("Programming Exercise Task", entryId));
    }

    /**
     * Gets a task with its programming exercise, test cases and solution entries of the test cases
     *
     * @param entryId The id of the task
     * @return The task with the given ID
     */
    @Query("""
            SELECT t
            FROM ProgrammingExerciseTask t
            LEFT JOIN FETCH t.testCases tc
            LEFT JOIN FETCH tc.solutionEntries
            WHERE t.id = :entryId
            """)
    Optional<ProgrammingExerciseTask> findByIdWithTestCaseAndSolutionEntries(@Param("entryId") long entryId);

    /**
     * Gets a task by its name and associated programming exercise
     *
     * @param taskName The name of the task
     * @param exerciseId The programming exercise the task should be associated with
     * @return The task with the given name and programming exercise
     */
    @Query("""
            SELECT t
            FROM ProgrammingExerciseTask t
            LEFT JOIN FETCH t.testCases tc
            WHERE t.taskName = :taskName
            AND t.exercise.id = :exerciseId
            """)
    Optional<ProgrammingExerciseTask> findByNameAndExerciseId(@Param("taskName") String taskName, @Param("exerciseId") long exerciseId);

    /**
     * Gets all tasks with its test cases and solution entries of the test case for a programming exercise
     * @param exerciseId of the exercise
     * @return All tasks with solution entries and associated test cases
     * @throws EntityNotFoundException If the exercise with exerciseId does not exist
     */
    @NotNull
    default Set<ProgrammingExerciseTask> findByExerciseIdWithTestCaseAndSolutionEntriesElseThrow(long exerciseId) throws EntityNotFoundException {
        return findByExerciseIdWithTestCaseAndSolutionEntries(exerciseId).orElseThrow(() -> new EntityNotFoundException("Programming Exercise Task", exerciseId));
    }

    /**
     * Gets all tasks with its test cases and solution entries of the test case for a programming exercise
     * @param exerciseId of the exercise
     * @return All tasks with solution entries and associated test cases
     */
    @Query("""
            SELECT t
            FROM ProgrammingExerciseTask t
            LEFT JOIN FETCH t.testCases tc
            LEFT JOIN FETCH tc.solutionEntries
            WHERE t.exercise.id = :exerciseId
            AND tc.exercise.id = :exerciseId
            """)
    Optional<Set<ProgrammingExerciseTask>> findByExerciseIdWithTestCaseAndSolutionEntries(@Param("exerciseId") long exerciseId);

    /**
     * Gets all tasks with its test cases for a programming exercise
     * @param exerciseId of the exercise
     * @return All tasks with solution entries and associated test cases
     */
    @Query("""
            SELECT t
            FROM ProgrammingExerciseTask t
            LEFT JOIN FETCH t.testCases tc
            LEFT JOIN FETCH tc.solutionEntries
            WHERE t.exercise.id = :exerciseId
            """)
    Set<ProgrammingExerciseTask> findByExerciseIdWithTestCases(@Param("exerciseId") Long exerciseId);

    /**
     * Returns the task name with the given id
     *
     * @param taskId the id of the task
     * @return the name of the task or null if the task does not exist
     */
    @Query("""
            SELECT t.taskName
            FROM ProgrammingExerciseTask t
            WHERE t.id = :taskId
            """)
    String getTaskName(@Param("taskId") Long taskId);
}


text:
SYNONYM

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Bull. Imp. Bur. Pl. Breed. Genet. , Cambridge 76, 131. 1944

#### Original name
null

### Remarks
null


text:
package xworker.javafx.dataobject.beans;

import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleDoubleProperty;
import org.xmeta.ActionContext;
import org.xmeta.Thing;
import xworker.dataObject.DataObject;
import xworker.dataObject.DataObjectListener;

public class DataObjectDoubleProperty  extends SimpleDoubleProperty implements AutoSaveable{
    DataObject dataObject;
    String name;
    boolean autoSave;

    public DataObjectDoubleProperty(DataObject dataObject, String name){
        this.dataObject = dataObject;
        this.name = name;

        if(dataObject.isInited()) {
            super.set(dataObject.getDouble(name));
        }else{
            dataObject.loadBackground(new ActionContext());
        }

        this.dataObject.addListener(new DataObjectListener() {
            @Override
            public void changed(DataObject dataObject) {
                DataObjectDoubleProperty.super.set(dataObject.getDouble(name));
            }
        });
    }

    public DataObjectDoubleProperty(DataObject dataObject, Thing attribute, String name){
        this(dataObject, name);
    }

    @Override
    public void set(double v) {
        super.set(v);

        dataObject.put(name, v);

        if(isAutoSave()){
            dataObject.update(new ActionContext());
        }
    }

    @Override
    public boolean isAutoSave() {
        return autoSave;
    }

    public void setAutoSave(boolean autoSave){
        this.autoSave = autoSave;
    }
}


text:
layout: post
title:  "Encolher Item"
date:   2018-01-01
source: Módulo Básico 170, Módulo Básico Edição Revisada 180.
tags: [nenhum, bardo]
---

**arcana 3 (transmutação)**

**Alcance**: toque

**Teste de Resistência**: nenhum.

**Duração**: 1 semana (D)

**Alvo**: 1 objeto de tamanho Enorme ou menor

**Tempo de Execução**: ação padrão

Esta magia diminui o tamanho de um item mundano em quatro categorias (um objeto Enorme vira Mínimo, por exemplo). Você também pode mudar a consistência do item, deixando-o rígido como pedra ou flexível como seda. Uma palavra de comando definida por você faz o objeto voltar ao tamanho normal.


text:
<?php
use SoapBox\Formatter\Formatter;

/**
 * Created by PhpStorm.
 * User: Tom
 * Date: 15/10/2014
 * Time: 19:05
 */
class APIController extends BaseController
{
    public function listPosts($ext = '.xml')
    {
        $page = 0;
        if(Input::has('page')) {
            if(is_numeric(Input::get('page')))
            $page = Input::get('page') * 5;
        }
        if (!(Input::has('images')
            || Input::has('user')
            || Input::has('sitterType')
            || Input::has('content')
            || Input::has('title')
            || Input::has('type')
            || Input::has('postcode')
            || Input::has('location'))
        ) {

            $posts = Post::with('images', 'sitterTypes')->take(5)->skip($page)->get()->toArray();
            if ($ext == '.xml') {
                return Response::xml("post", $posts);
            } else if ($ext == '.json') {
                return Response::json(array('posts' => $posts));
            } else {
                return Response::make('Response type not understood, available: .json, .xml', 404);
            }
        }
        // run the validation rules on the inputs from the form
        $validator = Validator::make(Input::all(), static::$searchPostRules);
        if ($validator->fails()) {
            return Response::make('Area supplied was not a greenwich postcode', 400); // send back the input (not the password) so that we can repopulate the form
        }

        $query = new Post;
        if (Input::has('user')) {
            $query = $query->byuser(Input::get('user'));
        }
        if (Input::has('sitterType')) {
            $query = $query->ofType(Input::get('sitterType'));
        }
        if (Input::has('type')) {
            $query = $query->likeType(Input::get('type'));
        }
        if (Input::has('content')) {
            $query = $query->content(Input::get('content'));
        }
        if (Input::has('title')) {
            $query = $query->title(Input::get('title'));
        }
        if (Input::has('location')) {
            $query = $query->location(Input::get('location'));
        }
        if (Input::has('postcode')) {
            $postcode = trim(Input::get('postcode'));
            if (!empty($postcode)) {
                $postcodeDetails = Postcode::getCoordinates(Input::get('postcode'));
                if (is_null($postcodeDetails)) {
                    return Response::make('Internal error occured when attempting to get the
                     location specified, are you sure you entered it correctly?', 400);
                }
                $query = $query->distance($postcodeDetails['latitude'], $postcodeDetails['longitude']);
            }
        }
        $withimages = true;
        if (Input::has('images')) {
            $imgs = trim(Input::get('images'));
            if (strcasecmp($imgs, '0') == '0') {
                $query = $query->withoutimages();
                $withimages = false;
            } else {
                $query = $query->withimages();
            }
        }
        $array = array(
            'sitterTypes' => SitterType::all(),
            'posts' => $query->paginate(10),
            'title' => 'Search',
        );
        if (Input::has('postcode')) {
            foreach ($array['posts'] as $post) {
                $coordA = Geotools::coordinate(array($postcodeDetails['latitude'], $postcodeDetails['longitude']));
                $coordB = Geotools::coordinate(array($post->lat, $post->lon));
                $distance = number_format(Geotools::distance()->setFrom($coordA)->setTo($coordB)->in('mi')->vincenty(), 2);
                $post->distance = $distance;
            }
        }
        if ($withimages) {
            $query = $query->with('images');
        }
        if ($ext == '.xml') {
            return Response::xml("post", $query->with('sitterTypes')->take(5)->skip($page)->get()->toArray());
        } else if ($ext == '.json') {
            return Response::json(array('posts' => $query->with('sitterTypes')->take(5)->skip($page)->get()->toArray()));
        } else {
            return Response::make('Response type not understood, available: .json, .xml', 404);
        }
    }

    public function getImage($id)
    {
        if (is_null($image = PostImage::find($id))) {
            return Response::make("image not found", 404);
        }
        header("Cache-Control: public");
        header("Content-Description: File Transfer");
        header("Content-Disposition: inline; filename=\"" . $image->file_name . "\"");
        header("Content-Type: image/jpg");
        header("Content-Transfer-Encoding: binary");
        readfile(public_path()."/img/posts/".$image->file_name, $image->file_name);
    }

    public function getUser($ext = ".xml", $id)
    {
        $user = User::find($id);
        if (is_null($user)) {
            return Response::make("", 404);
        }
        if ($ext == '.xml') {
            return Response::xml("user", $user->toArray(), "ArrayOfUser");
        } else if ($ext == '.json') {
            return Response::json(array('users' => $user));
        } else {
            return Response::make('Response type not understood, available: .json, .xml', 404);
        }
    }

    public function getSingleUser($id)
    {
        return $this->getUser(".xml", $id);
    }

    public function listUsers($ext = ".xml")
    {
        $users = User::all();
        if ($ext == '.xml') {
            return Response::xml("users", $users->toArray(), "ArrayOfUser");
        } else if ($ext == '.json') {
            return Response::json(array('users' => $users));
        } else {
            return Response::make('Response type not understood, available: .json, .xml', 404);
        }
    }

    public function listSitterTypes($ext = ".xml")
    {
        $users = SitterType::all();
        if ($ext == '.xml') {
            return Response::xml("sitterTypes", $users->toArray(),"ArrayOfSitterType");
        } else if ($ext == '.json') {
            return Response::json(array('sitterTypes' => $users));
        } else {
            return Response::make('Response type not understood, available: .json, .xml', 404);
        }
    }

    public function getSinglePost($id)
    {
        return $this->getPost(".xml", $id);
    }

    public function getPost($ext = '.xml', $id)
    {
        $posts = Post::with('images', 'sitterTypes')->find($id);
        if (is_null($posts)) {
            return Response::make("", 404);
        }
        if ($ext == '.xml') {
            return Response::xml("post", $posts->toArray());
        } else if ($ext == '.json') {
            return Response::json(array('post' => $posts));
        } else {
            return Response::make('Response type not understood, available: .json, .xml', 404);
        }
    }

    public function deletePost($id)
    {
        $post = Post::find($id);
        if (!is_null($post)) {
            return Response::make("", 204);
        }
        return Response::xml(array('posts' => $post));
    }

    public function createPost()
    {
        HelperUtil::toEloquent(new Post, Request::instance()->getContent())->save();
        return Response::make("", 204);
    }

    public static $searchPostRules = [
        'postcode' => 'greenwich|postcode'
    ];

    public function updatePost()
    {

    }

}


text:
/**
 *
 * App.react.js
 *
 * This component is the skeleton around the actual pages, and should only
 * contain code that should be seen on all pages. (e.g. navigation bar)
 *
 * NOTE: while this component should technically be a stateless functional
 * component (SFC), hot reloading does not currently support SFCs. If hot
 * reloading is not a necessity for you then you can refactor it and remove
 * the linting exception.
 */

import React from 'react';
import NavBar from 'components/NavBar';
import AppWrapper from 'components/App/AppWrapper';
import { initAuth } from 'actions/AuthActions';
import { connect } from 'react-redux';
import Notification from 'components/Notification';

class App extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function

  static propTypes = {
    children: React.PropTypes.node,
  };

  componentDidMount() {
    const { dispatch } = this.props;
    dispatch(initAuth());
  }

  render() {
    return (
      <AppWrapper>
        <NavBar {...this.props} />
        {React.Children.toArray(this.props.children)}
        <Notification {...this.props} />
      </AppWrapper>
    );
  }
}

App.propTypes = {
  dispatch: React.PropTypes.func.isRequired,
};

function mapStateToProps(state) {
  return {
    auth: state.get('auth'),
    notification: state.get('notification')
  };
}

export default connect(mapStateToProps)(App);


text:
from weatherfact import WeatherFact

"""
A class for storing data about a transitioning attribute of the weather
"""
class ChangingWeatherFact(WeatherFact):
  def __init__(self, fromValue, toValue):
    assert isinstance(fromValue, WeatherFact), "Can't create a ChangingWeatherFact from not-WeatherFacts"
    assert isinstance(fromValue, toValue.__class__), "Can't create a ChangingWeatherFact between different types"
    super(ChangingWeatherFact, self).__init__(toValue, toValue.details)
    self.fromValue = fromValue

  def toDictionary(self):
    return {
      'changing': True,
      'value': self.value.toDictionary(),
      'from': self.fromValue.toDictionary()
    }

  @staticmethod
  def isChangingWeatherDictionary(dictionary):
    return dictionary.get("changing", False)

  @classmethod
  def fromDictionary(cls, rehydrator, dictionary):
    assert cls.isChangingWeatherDictionary(dictionary), "Trying to create a ChangingWeatherFact from bad dictionary"

    fromValue = rehydrator(dictionary['from'])
    toValue = rehydrator(dictionary['value'])

    return cls(fromValue, toValue)


text:
package ospatch

import (
	"encoding/json"

	"github.com/centurylinkcloud/clc-go-cli/errors"
	"github.com/centurylinkcloud/clc-go-cli/models/server"
)

var (
	packages = map[string]server.PackageDef{
		"Windows2012": server.PackageDef{
			PackageId: "b229535c-a313-4a31-baf8-6aa71ff4b9ed",
		},
		"RedHat": server.PackageDef{
			PackageId: "c3c6642e-24e1-4c37-b56a-1cf1476ee360",
			Parameters: map[string]string{
				"patch.debug.mode": "false",
			},
		},
	}
)

type Patch struct {
	ServerIds []string `json:"servers"`
	OsType    string   `valid:"required" oneOf:"Windows2012,RedHat"`
}

func (p *Patch) Validate() error {
	if len(p.ServerIds) == 0 {
		return errors.EmptyField("server-ids")
	}
	return nil
}

func (p *Patch) MarshalJSON() ([]byte, error) {
	return json.Marshal(server.ExecutePackage{
		ServerIds: p.ServerIds,
		Package:   packages[p.OsType],
	})
}

type List struct {
	server.Server `argument:"composed" URIParam:"ServerId"`
}

type ListDetails struct {
	server.Server `argument:"composed" URIParam:"ServerId"`
	ExecutionId   string `URIParam:"yes" valid:"required"`
}


text:
package doc

import (
	"bytes"
	"fmt"
	"os"
	"strings"
	"testing"
)

var _ = fmt.Println
var _ = os.Stderr

func translate(in string) string {
	return strings.Replace(in, "-", "\\-", -1)
}

func TestGenManDoc(t *testing.T) {
	c := initializeWithRootCmd()
	// Need two commands to run the command alphabetical sort
	cmdEcho.AddCommand(cmdTimes, cmdEchoSub, cmdDeprecated)
	c.AddCommand(cmdPrint, cmdEcho)
	cmdRootWithRun.PersistentFlags().StringVarP(&flags2a, "rootflag", "r", "two", strtwoParentHelp)

	out := new(bytes.Buffer)

	header := &GenManHeader{
		Title:   "Project",
		Section: "2",
	}
	// We generate on a subcommand so we have both subcommands and parents
	if err := GenMan(cmdEcho, header, out); err != nil {
		t.Fatal(err)
	}
	found := out.String()

	// Make sure parent has - in CommandPath() in SEE ALSO:
	parentPath := cmdEcho.Parent().CommandPath()
	dashParentPath := strings.Replace(parentPath, " ", "-", -1)
	expected := translate(dashParentPath)
	expected = expected + "(" + header.Section + ")"
	checkStringContains(t, found, expected)

	// Our description
	expected = translate(cmdEcho.Name())
	checkStringContains(t, found, expected)

	// Better have our example
	expected = translate(cmdEcho.Name())
	checkStringContains(t, found, expected)

	// A local flag
	expected = "boolone"
	checkStringContains(t, found, expected)

	// persistent flag on parent
	expected = "rootflag"
	checkStringContains(t, found, expected)

	// We better output info about our parent
	expected = translate(cmdRootWithRun.Name())
	checkStringContains(t, found, expected)

	// And about subcommands
	expected = translate(cmdEchoSub.Name())
	checkStringContains(t, found, expected)

	unexpected := translate(cmdDeprecated.Name())
	checkStringOmits(t, found, unexpected)

	// auto generated
	expected = translate("Auto generated")
	checkStringContains(t, found, expected)
}

func TestGenManNoGenTag(t *testing.T) {
	c := initializeWithRootCmd()
	// Need two commands to run the command alphabetical sort
	cmdEcho.AddCommand(cmdTimes, cmdEchoSub, cmdDeprecated)
	c.AddCommand(cmdPrint, cmdEcho)
	cmdRootWithRun.PersistentFlags().StringVarP(&flags2a, "rootflag", "r", "two", strtwoParentHelp)
	cmdEcho.DisableAutoGenTag = true
	out := new(bytes.Buffer)

	header := &GenManHeader{
		Title:   "Project",
		Section: "2",
	}
	// We generate on a subcommand so we have both subcommands and parents
	if err := GenMan(cmdEcho, header, out); err != nil {
		t.Fatal(err)
	}
	found := out.String()

	unexpected := translate("#HISTORY")
	checkStringOmits(t, found, unexpected)
}


text:
<?php

namespace Google\Service\AnalyticsReporting;

class Dimension extends \Google\Collection
{
  protected $collection_key = 'histogramBuckets';
  /**
   * @var string[]
   */
  public $histogramBuckets;
  /**
   * @var string
   */
  public $name;

  /**
   * @param string[]
   */
  public function setHistogramBuckets($histogramBuckets)
  {
    $this->histogramBuckets = $histogramBuckets;
  }
  /**
   * @return string[]
   */
  public function getHistogramBuckets()
  {
    return $this->histogramBuckets;
  }
  /**
   * @param string
   */
  public function setName($name)
  {
    $this->name = $name;
  }
  /**
   * @return string
   */
  public function getName()
  {
    return $this->name;
  }
}

// Adding a class alias for backwards compatibility with the previous class name.
class_alias(Dimension::class, 'Google_Service_AnalyticsReporting_Dimension');


text:
/* seqio.c */
/* -------------------------------------------------------------------
 * miRanda- An miRNA target scanner, aims to predict mRNA targets for microRNAs,
 * using dynamic-programming alignment and thermodynamics
 *
 * Copyright (C) (2003) Memorial Sloan-Kettering Cancer Center, New York
 *
 * Distributed under the GNU Public License (GPL)
 * See the files 'COPYING' and 'LICENSE' for details
 *
 * Authors: Anton Enright, Bino John, Chris Sander and Debora Marks
 * Email: mirnatargets (at) cbio.mskcc.org - reaches all authors
 *
 * Written By: Anton Enright
 *
 * Please send bug reports to: miranda (at) cbio.mskcc.org
 *
 * If you use miRanda in your research please cite:
 * Enright AJ, John B, Gaul U, Tuschl T, Sander C and Marks DS;
 * (2003) Genome Biology; 5(1):R1.
 *
 * This software will be further developed under the open source model,
 * coordinated by Anton Enright and Chris Sander:
 * miranda (at) cbio.mskcc.org (reaches both).
 *
 * Copyright (C) (2003) Memorial Sloan-Kettering Cancer Center
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * -------------------------------------------------------------------
 */

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "miranda.h"

/* invalid nucleotide matrix */
/* '!' indicates an illegal character */

char nt_invalid[256];

int initialize_nt_invalid() {
	int i;
	for (i = 0; i < 256; i++) nt_invalid[i] = '\1';
	nt_invalid['a'] = '\0';
	nt_invalid['A'] = '\0';
	nt_invalid['c'] = '\0';
	nt_invalid['C'] = '\0';
	nt_invalid['g'] = '\0';
	nt_invalid['G'] = '\0';
	nt_invalid['u'] = '\0';
	nt_invalid['U'] = '\0';
	nt_invalid['t'] = '\0';
	nt_invalid['T'] = '\0';
	nt_invalid['n'] = '\0';
	nt_invalid['N'] = '\0';
	nt_invalid['r'] = '\0';
	nt_invalid['R'] = '\0';
	nt_invalid['y'] = '\0';
	nt_invalid['Y'] = '\0';
	nt_invalid['k'] = '\0';
	nt_invalid['K'] = '\0';
	nt_invalid['m'] = '\0';
	nt_invalid['M'] = '\0';
	nt_invalid['s'] = '\0';
	nt_invalid['S'] = '\0';
	nt_invalid['w'] = '\0';
	nt_invalid['W'] = '\0';
	nt_invalid['b'] = '\0';
	nt_invalid['B'] = '\0';
	nt_invalid['d'] = '\0';
	nt_invalid['D'] = '\0';
	nt_invalid['h'] = '\0';
	nt_invalid['H'] = '\0';
	nt_invalid['v'] = '\0';
	nt_invalid['V'] = '\0';
	nt_invalid['x'] = '\0';
	nt_invalid['X'] = '\0';
	return 0;
}

ExpString *sequence_buffer = 0;
ExpString *description_buffer = 0;
ExpString *name_buffer = 0;

void initialize_seqio_buffers() {
	initialize_nt_invalid();
	create_ExpString(&sequence_buffer);
	create_ExpString(&description_buffer);
	create_ExpString(&name_buffer);
}

void destroy_seqio_buffers() {
	destroy_ExpString(&sequence_buffer);
	destroy_ExpString(&description_buffer);
	destroy_ExpString(&name_buffer);
}

/* returns 0 if EOF is reached, otherwise 1 */
int skip_leading_whitespace(FILE* fp) {
	for (;;) {
		int cbuf = fgetc(fp);
		switch (cbuf) {
			case '\n': case '\r': case '\t': case ' ': break;
			case EOF: return 0;
			default: ungetc((char)cbuf, fp); return 1;
		}
	}
	return 0; /* never reached */
}

int skip_leading_space(FILE* fp) {
	for (;;) {
		int cbuf = fgetc(fp);
		switch (cbuf) {
			case '\r': case '\t': case ' ': break;
			case EOF: return 0;
			default: ungetc((char)cbuf, fp); return 1;
		}
	}
	return 0; /* never reached */
}

/* requires file position to be at '>' */
void read_fasta_name_into_buffer(FILE* fp, ExpString *name_buf) {
	int cbuf = fgetc(fp);
	if (cbuf != '>') {
		fprintf(stderr, "Error: illegal format in sequence file (record does not start with '>')\n");
		exit(1);
	}
	clear_ExpString(name_buf);
	for (;;) {
		cbuf = fgetc(fp);
		if (cbuf == EOF) {
			fprintf(stderr, "Error: illegal format in sequence file (EOF while reading name)\n");
			exit(1);
		}
		if (cbuf == '\n' || cbuf == '\r' || cbuf == '\t' || cbuf == ' ') {
			ungetc((char)cbuf, fp);
			break;
		}
		append_char_ExpString(name_buf, (char)cbuf);
	}
}

void read_fasta_description_into_buffer(FILE* fp, ExpString *description_buf) {
	if (skip_leading_space(fp) == 0) {
		fprintf(stderr, "Error: illegal format in sequence file (EOF while reading description)\n");
		exit(1);
	}
	clear_ExpString(description_buf);
	for (;;) {
		int cbuf = fgetc(fp);
		if (cbuf == EOF) {
			fprintf(stderr, "Error: illegal format in sequence file (EOF while reading description)\n");
			exit(1);
		}
		if (cbuf == '\n') return;
		append_char_ExpString(description_buf, (char)cbuf);
	}
}

void read_fasta_sequence_into_buffer(FILE* fp, ExpString *sequence_buf, ExpString *name_buf) {
	clear_ExpString(sequence_buf);
	for (;;) {
		int cbuf = fgetc(fp);
		if (cbuf == EOF) return;
		if (cbuf == '\n' || cbuf == '\r' || cbuf == '\t' || cbuf == ' ') continue;
		if (cbuf == '>') {
			ungetc((char)cbuf,fp);
			return;
		}
		if (nt_invalid[cbuf]) {
			fprintf(stderr, "Error: illegal character '%c' in sequence file in sequence: %s\n", (char)cbuf, access_ExpString(name_buf));
			exit(1);
		}
		append_char_ExpString(sequence_buf, (char)cbuf);
	}
}

int readinseq(FILE* fp, char** sequence, char** description, char** name, int* seqlen) {
	if (skip_leading_whitespace(fp) == 0) return 0; /* end of file reached */
	read_fasta_name_into_buffer(fp, name_buffer);
	read_fasta_description_into_buffer(fp, description_buffer);
	read_fasta_sequence_into_buffer(fp, sequence_buffer, name_buffer);
	if (length_ExpString(name_buffer) == 0) {
		fprintf(stderr, "Error: sequence file contains a record with a length 0 name\n");
		exit(1);
	}
	if (length_ExpString(sequence_buffer) == 0) {
		fprintf(stderr, "Error: sequence file contains a record with a length 0 sequence\n");
		exit(1);
	}
	*name = realloc(*name, (length_ExpString(name_buffer) + 1) * sizeof(char));
	*description = realloc(*description, (length_ExpString(description_buffer) + 1) * sizeof(char));
	*sequence = realloc(*sequence, (length_ExpString(sequence_buffer) + 1) * sizeof(char));
	if (*name == 0 || *description == 0 || *sequence == 0) {
		fprintf(stderr,"Error: memory allocation failed\n");
		exit(1);
	}
	strcpy(*name, access_ExpString(name_buffer));
	strcpy(*description, access_ExpString(description_buffer));
	strcpy(*sequence, access_ExpString(sequence_buffer));
	*seqlen = length_ExpString(sequence_buffer);
	return 1;
}