//
// https://www.ramecera.it/myscrewdriver.html
// e-mail: screwdriver@ramecera.it
//
/* This program and the accompanying materials are made available under
 * the terms of the Eclipse Public License v1.0 which accompanies this
 * distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html */
package it.ramecera.screwdriver;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import it.ramecera.salad.everyday.Candies;
import it.ramecera.salad.everyday.ExactException;
import it.ramecera.salad.everyday.Mix;
import it.ramecera.salad.everyday.Strings;
import it.ramecera.salad.file.Abacus;
import it.ramecera.salad.file.Equipment;
import it.ramecera.salad.file.Folder;
import it.ramecera.salad.file.ReadMyFile;
import it.ramecera.salad.graphic.AskForDelete;
import it.ramecera.screwdriver.component.Base_jsp;
import it.ramecera.screwdriver.component.Bootstrap_css;
import it.ramecera.screwdriver.component.ControllerBelong_java;
import it.ramecera.screwdriver.component.Dispatcher_xml;
import it.ramecera.screwdriver.component.FileComponent;
import it.ramecera.screwdriver.component.GenericModel_java;
import it.ramecera.screwdriver.component.Hoof;
import it.ramecera.screwdriver.component.ImplementTabellaService_java;
import it.ramecera.screwdriver.component.ImplementTableDao_java;
import it.ramecera.screwdriver.component.InterfaceTabellaService_java;
import it.ramecera.screwdriver.component.InterfaceTableDao_java;
import it.ramecera.screwdriver.component.JspFormImpl_java;
import it.ramecera.screwdriver.component.JspForm_java;
import it.ramecera.screwdriver.component.JspPlainImpl_java;
import it.ramecera.screwdriver.component.JspPlain_java;
import it.ramecera.screwdriver.component.Navigation_jsp;
import it.ramecera.screwdriver.component.Orm_xml;
import it.ramecera.screwdriver.component.Pom_properties;
import it.ramecera.screwdriver.component.Pom_xml;
import it.ramecera.screwdriver.component.Quartz_job_xml;
import it.ramecera.screwdriver.component.Screwdriver_css;
import it.ramecera.screwdriver.component.Screwdriver_cssC;
import it.ramecera.screwdriver.component.Service_xml;
import it.ramecera.screwdriver.component.SpringProperties_xml;
import it.ramecera.screwdriver.component.SpringSecurity_xml;
import it.ramecera.screwdriver.component.Tiles_xml;
import it.ramecera.screwdriver.component.UserAuthenticationProvider_java;
import it.ramecera.screwdriver.component.UserContextImpl_java;
import it.ramecera.screwdriver.component.Web_xml;
import it.ramecera.screwdriver.component.Webflow_xml;
import it.ramecera.screwdriver.outfits.ControllerBelong;
import it.ramecera.screwdriver.outfits.DBPlaceKit;
import it.ramecera.screwdriver.outfits.JspBeanElement;
import it.ramecera.screwdriver.outfits.JspKit;
import it.ramecera.screwdriver.outfits.MenuKit;
import it.ramecera.screwdriver.outfits.RequestMap;
import it.ramecera.screwdriver.outfits.TableOutfit;
import it.ramecera.screwdriver.utilities.ValidConstScrew;

/**
 * <p>
 * The jspType ele file object.
 * </p>
 * <p>
 * Company: Ramecera™<br>
 * Creation date: 2020-04-09<br>
 * modification date: 2020-09-15<br>
 * </p>
 * <p>
 * History:<br>
 * The description of N# is in project plan report<br>
 * 2020-09-03 implementation of N3<br>
 * 2020-09-09 implementation of N8<br>
 * </p>
 * 
 * @author M. Maglioni */

final public class ElementaryFile {

	// PUBLIC

	/** the list of available markups */
	public HashMap<String, Markup> markupE;
	/** external properties */
	public CandyScrew candies;
	/** list of trains */
	public List<Train> trainE = new ArrayList<Train>();
	/** application name according to Maven, is also the 3rd qualifier
	 * of the package after the company's internet domain (e.g.
	 * it.ramecera) */
	public String appName;

	// PRIVATE

	/** number of lines in the elementary file */
	private int zQ;
	/** the stub of the row */
	private String stub = null;
	private int posizioneVisiva = 1;
	private Train train;
	private String securityY = null, newLdap = null, newResolver = null,
			newAnnotation = null, recycleBinY = null;
	private String new5 = null, new58 = null, new581 = null,
			new582 = null, new583 = null, new60 = null, new61 = null,
			new62 = null, new63 = null, new71 = null, new72 = null,
			new73 = null, new721 = null, new722 = null, new723 = null;
	private String new513 = null, brickAuthenticationY = null,
			brickAuthenticationAuthorityY = null, new515 = null,
			new516 = null, new518 = null, new519 = null, domainY = null;
	private Skill skill;
	private Train ultimaJsp;
	private JspKit kitLastJsp = null;
	private Train lastDeclaredMenu;
	private String stat = "";

	// COMPONENTS

	private FileComponent genericRailDaoImpl;
	private FileComponent service_xml;
	private FileComponent orm_xml;
	private FileComponent web_xml;
	private FileComponent pom_properties;
	private FileComponent quartz_job_xml;
	private FileComponent webflow_xml;
	private FileComponent pom_xml;
	private FileComponent springProps_xml;
	private FileComponent springSecurity_xml;
	private FileComponent dispatcher_xml;
	private FileComponent baseJsp;
	private FileComponent headerJsp;
	private FileComponent footerJsp;
	private FileComponent quartzJob_java;
	private FileComponent quartzTask_java;
	private FileComponent quartzTaskImpl_java;
	private FileComponent tiles_xml;
	private FileComponent doorControllerBelong_java;
	private FileComponent genericCrud_java;
	private FileComponent controllerBelong_java;
	private FileComponent jspForm_java;
	private FileComponent jspFormImpl_java;
	private FileComponent userAuthenticationProvider_java;
	private FileComponent jspPlain_java;
	private FileComponent jspPlainImpl_java;
	private FileComponent genericModel_java;
	private FileComponent bootstrap_css;
	private FileComponent screwdriver_css;
	private FileComponent screwdriver_cssC;
	private FileComponent[] navigation_jsps;
	private FileComponent springSecurityUserContext;
	private FileComponent userAuthorityUtils;
	private FileComponent interfacciaUserContext;
	private FileComponent king;
	private FileComponent kingDao;
	private FileComponent kingDaoImpl;
	private FileComponent userContextImpl;

	private static final String sep = System.getProperty(
			"file.separator");
	/** ordinary logger */
	private static final Logger logger = Logger.getLogger(
			ElementaryFile.class);

	// CONSTANTS

	// CONSTRUCTORS

	/**
	 * <p>
	 * The markups list is forfeited with this constructor.
	 * </p>
	 * 
	 * @param markupE list of available markup
	 * @param candies external properties */
	public ElementaryFile(HashMap<String, Markup> markupE,
			CandyScrew candies) {
		this.markupE = markupE;
		this.candies = candies;
	}

	// PUBLIC METHODS

	/**
	 * <p>
	 * Reading and accommodation of all markups.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Modifications:<br>
	 * </p>
	 * 
	 * @param inputY input directory
	 * @param inputF input file for conversion
	 * @param includeY directory containing the files include
	 * @throws ExactException exception specified by a numeric code */
	final public void trainFactory(final String inputY,
			final String inputF, final String includeY)

			throws ExactException {

		List<String> zebra;
		ExactException ne = new ExactException();
		try {
			zebra = ReadMyFile.zebra_A(inputY + inputF);
			int zebraQ = zebra.size();
			if (zebraQ == 0) {
				ne.code = 1703;
				ne.datum = "The file " + Mix.dress_A(inputF)
						+ " is empty.";
				ne.className = this.getClass().getName();
				throw ne;
			}
			trainE = composeTrains(zebra, includeY);
			logger.trace(trainE_toString(trainE, markupE));
			logger.trace(Hammer.markupE_toString(markupE));
		} catch (IOException e) {
			ne.code = 1704;
			ne.datum = "Error acceding file " + Mix.dress_A(inputF)
					+ ".";
			ne.className = this.getClass().getName();
			throw ne;
		}
	}

	/**
	 * <p>
	 * To convert a train sequence into a maven-spring application.
	 * </p>
	 * <p>
	 * Company: Ramecera™<br>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-09-15
	 * </p>
	 * <p>
	 * History:<br>
	 * The description of N# is in project plan report.<br>
	 * 2020-09-14 implementation of N16.<br>
	 * </p>
	 * 
	 * @throws ExactException exception specified by a numeric code
	 * @throws FileNotFoundException a standard exception
	 * @throws IOException a standard exception */
	final public void convert()

			throws ExactException, FileNotFoundException, IOException {

		skill = new Skill(candies);
		String initial = candies.outputYS + appName + "/src/main/java";
		File myApp = new File(initial);
		if (myApp.exists()) {
			Folder folder = new Folder();
			skill.initialDirE = folder.dirImmersion(initial, ".+");
		}
		logger.trace(Candies.LF + "INITIAL DIRECTORIES");
		for (String s : skill.initialDirE) {
			logger.debug(s);
		}
		/* FUTURE RELEASE N6 */
		// if (markupE.get("hddl").occorrenzaE.size() == 1) {
		// skill.ddl = (String[]) markupE.get("hddl").occorrenzaE.get(
		// 0).locomotor.substance;
		// }
		@SuppressWarnings("unused")
		boolean done = false;
		skill.factory_A(markupE, trainE, candies);
		recycleBinY = candies.boxYS + "recycleBin";
		File recycleBin = new File(recycleBinY);
		directoriesFactory_B();
		componentsInstanceExecution();
		pom_xml.directory(markupE);
		fileModelPositions();

		/* THE NECESSARY DIRECTORIES */
		genericModel_java.directory(markupE);
		webflow_xml.directory(markupE);
		controllerBelong_java.directory(markupE);
		/* add Notice.java */
		FileComponent.addClass("Notice.java",
				skill.javaWebModelUtilityY, "Notice.java", candies,
				recycleBinY, skill, -1, markupE, "java");
		if (skill.antiSamy) {
			FileComponent.addClass("CrossSiteScriptingFilter.java",
					new513, "CrossSiteScriptingFilter.java", candies,
					recycleBinY, skill, -1, markupE, "java");
			FileComponent.addClass("JsessionIdRemoveFilter.java",
					new513, "JsessionIdRemoveFilter.java", candies,
					recycleBinY, skill, -1, markupE, "java");
			FileComponent.addClass("HttpRequestWrapper.java", new519,
					"HttpRequestWrapper.java", candies, recycleBinY,
					skill, -1, markupE, "java");
			FileComponent.addClass("AntiSamyListener.java", new515,
					"AntiSamyListener.java", candies, recycleBinY,
					skill, -1, markupE, "java");
			FileComponent.addClass("XssSanitizer.java", new518,
					"XssSanitizer.java", candies, recycleBinY, skill,
					-1, markupE, "java");
			FileComponent.addFile("policy.xml", "policy.xml", new518,
					candies, recycleBinY, skill);
		} else {
			new File(new513 + "/" + "CrossSiteScriptingFilter.java")
					.delete();
			new File(new513 + "/" + "JsessionIdRemoveFilter.java")
					.delete();
			new File(new519 + "/" + "HttpRequestWrapper.java").delete();
			new File(new515 + "/" + "AntiSamyListener.java").delete();
			/* I don't want antisamy, so the web / sanitizer directory
			 * should be deleted */
			if (new File(new518).exists()) {
				Abacus.destroyDirectory(new518);
				done = new File(new518).delete();
			}
		}
		if (skill.ldap) {
			FileComponent.addFile("security-ldap-explicitly.xml",
					"security-ldap-explicitly.xml", new71, candies,
					recycleBinY, skill);
		} else {
			new File(new71 + "/" + "security-ldap-explicitly.xml")
					.delete();
		}

		/* THE SUMMARY */

		// BASEJSP - 1st LOOP ON JSP

		logger.trace(Candies.LF + Cst.CUT0 + "1° LOOP OVER JSP"
				+ Candies.LF + Cst.CUT0);
		for (int i = 0; i < markupE.get("jsp").recurrenceE
				.size(); i++) {
			Train f = markupE.get("jsp").recurrenceE.get(i);
			baseJsp.jspKit = ((JspKit) f.locomotor.substance);
			baseJsp.jspKit.classeCss = f.wagonE.get("cssclass").text;
			logger.trace(baseJsp.jspKit.toString());

			// FORM
			/* if there are graphic controls the JSP type is 1 (form),
			 * otherwise it takes the type of the first request map */
			if (baseJsp.jspKit.controlE.size() > 0) {
				baseJsp.jspKit.jspType = Cst.FORM;
			} else if (baseJsp.jspKit.requestMapE.size() == 0) {
				baseJsp.jspKit.jspType = Cst.MESSAGE;
			} else {
				baseJsp.jspKit.jspType = baseJsp.jspKit.requestMapE.get(
						0).tipo;
			}
			if (baseJsp.jspKit.crud
					& baseJsp.jspKit.jspType != Cst.FORM) {
				ExactException ne = new ExactException();
				String messaggio = "Per la JSP «" + f.locomotor.text
						+ "» si dichiara il CRUD, ma non è un form;"
						+ " occorre specificare i tag formX+.";
				ne.code = 1709;
				ne.datum = messaggio;
				ne.className = this.getClass().getName();
				throw ne;
			}
			// BELONG
			Wagon v = f.wagonE.get("belong");
			if (v != null) {
				// x2c is the comma
				String[] partecipaE = v.text.split("\\x2c");
				for (String p : partecipaE) {
					int m = 0;
					p = p.trim();
					List<JspBeanElement> propertyE = baseJsp.jspKit.stringPropertyE;
					for (; m < propertyE.size(); m++) {
						if (p.equals(propertyE.get(m).name)) {
							break;
						}
					}
					if (m == propertyE.size()) {
						/* if I haven't found it among the ordinary
						 * properties, then I look for it among the
						 * array properties */
						List<JspBeanElement> propertiesArrayE = baseJsp.jspKit.arrayStringPropertyE;
						int mm = 0;
						for (; mm < propertiesArrayE.size(); mm++) {
							if (p.equals(propertiesArrayE.get(
									mm).name)) {
								break;
							}
						}
						if (mm == propertiesArrayE.size()) {
							ExactException ne = new ExactException();
							String messaggio = "For the JSP «" + Mix
									.dress_A(f.locomotor.text)
									+ " is declared a value of belong "
									+ Mix.dress_A(v.text)
									+ " not present in its bean properties.";
							ne.code = 1740;
							ne.datum = messaggio;
							ne.className = this.getClass().getName();
							throw ne;
						} else {
							propertiesArrayE.get(mm).participate = true;
						}
					} else {
						propertyE.get(m).participate = true;
					}
				}
			}
			// BMENU
			if (f.wagonE.get("bmenu") != null) {
				baseJsp.jspKit.navigationBar = f.wagonE.get(
						"bmenu").text;
				int j = 0;
				for (; j < markupE.get("bdefmenu").recurrenceE
						.size(); j++) {
					if (markupE.get("bdefmenu").recurrenceE.get(
							j).locomotor.text.equals(f.wagonE.get(
									"bmenu").text)) {
						break;
					}
				}
				if (j == markupE.get("bdefmenu").recurrenceE.size()) {
					ExactException ce = new ExactException();
					String messaggio = "The data " + Mix.dress_A(
							f.wagonE.get("bmenu").text)
							+ " in markup «bmenu» does not "
							+ "correspond to any menu definition";
					ce.code = 1711;
					ce.datum = messaggio;
					ce.className = this.getClass().getName();
				} else {
					baseJsp.jspKit.menuKit = (MenuKit) markupE.get(
							"bdefmenu").recurrenceE.get(
									j).locomotor.substance;
				}
			}
		}

		// BASEJSP - 2nd LOOP ON JSP

		/* fundamental loop, it contains sitesi and write for each of
		 * the jsp */
		logger.trace(Candies.LF + Cst.CUT0 + "2° LOOP SULLE JSP"
				+ Candies.LF + Cst.CUT0);
		for (int i = 0; i < markupE.get("jsp").recurrenceE
				.size(); i++) {
			Train f = markupE.get("jsp").recurrenceE.get(i);
			baseJsp.jspKit = (JspKit) f.locomotor.substance;
			logger.trace(baseJsp.jspKit.toString());
			if (baseJsp.jspKit.fileName.equalsIgnoreCase("login")
					& skill.springSecurity) {
				ExactException ne = new ExactException("The JSP «"
						+ baseJsp.jspKit.fileName
						+ "» does not have to be declared with the"
						+ " jsp+ markup, because it is implicit in"
						+ " the use of Spring Security.");
				ne.code = 1700;
				ne.datum = ne.getMessage();
				ne.className = this.getClass().getName();
				throw ne;
			}
			/* no duplication check */
			int d = 0;
			for (; d < i; d++) {
				Train trainD = markupE.get("jsp").recurrenceE.get(d);
				if (baseJsp.jspKit.fileName.equals(
						((JspKit) trainD.locomotor.substance).fileName)) {
					break;
				}
			}
			if (d < i) {
				ExactException ne = new ExactException("The JSP «"
						+ baseJsp.jspKit.fileName
						+ "» is present more than once, a different"
						+ " name must be chosen.");
				ne.code = 1701;
				ne.datum = ne.getMessage();
				ne.className = this.getClass().getName();
				throw ne;
			}
			String ospiteY = new72;
			if (baseJsp.jspKit.path.length() > 0) {
				ospiteY += "/" + baseJsp.jspKit.path;
				skill.buildDirectory(ospiteY);
			}
			baseJsp.synthesis(markupE, trainE, candies);
			if (!baseJsp.jspKit.fileName.equals("login")) {
				baseJsp.write(ospiteY, baseJsp.jspKit.fileName + "."
						+ baseJsp.jspKit.extension,
						baseJsp.jspKit.fileName + "."
								+ baseJsp.jspKit.extension, "jsp",
						candies, recycleBinY);
			}
			for (int k = 0; k < baseJsp.jspKit.requestMapE
					.size(); k++) {
				RequestMap requestMap = baseJsp.jspKit.requestMapE.get(
						k);
				// LOOP ON THE REQUEST MAP
				if (!requestMap.pathRedirect.isEmpty()) {
					Train train0 = null;
					int n = 0;
					for (; n < markupE.get("requmap").recurrenceE
							.size(); n++) {
						train0 = markupE.get("requmap").recurrenceE.get(
								n);
						if (train0.locomotor.text.equals(
								requestMap.pathRedirect)) {
							break;
						}
					}
					if (n == markupE.get("requmap").recurrenceE
							.size()) {
						ExactException ne = new ExactException();
						String message = "For the «requmap+"
								+ requestMap.firstSegmentPath + "/"
								+ requestMap.jsp + "» with «redirect+"
								+ requestMap.pathRedirect
								+ "» there is no match in the "
								+ "request maps list.";
						ne.code = 1631;
						ne.datum = message;
						ne.className = this.getClass().getName();
						throw ne;
					}
				}
				requestMap.tipo = baseJsp.jspKit.jspType;
				int j = 0;
				for (; j < skill.correlationE.size(); j++) {
					ControllerBelong correlazione = skill.correlationE
							.get(j);
					if (requestMap.firstSegmentPath.equals(
							correlazione.gruppo)) {
						correlazione.rmE.add(requestMap);
						break;
					}
				}
				if (j == skill.correlationE.size()) {
					List<RequestMap> zE = new ArrayList<RequestMap>();
					zE.add(requestMap);
					logger.trace(Candies.LF + Cst.CUT3
							+ "          * Not having found the first segment of path «"
							+ requestMap.firstSegmentPath + "»,"
							+ Candies.LF + "          * I insert my new"
							+ " request map:" + Candies.LF
							+ "          * " + requestMap.toString()
							+ Cst.CUT3);
					skill.correlationE.add(new ControllerBelong(
							requestMap.firstSegmentPath, zE));
				}
			}
		}

		// JSPFORM - 3rd LOOP ON JSP

		logger.trace(Candies.LF + Cst.CUT0 + "3° LOOP SULLE JSP"
				+ Candies.LF + Cst.CUT0);
		skill.tableDBE = new ArrayList<TableOutfit>();
		for (int i = 0; i < markupE.get("hdefrail").recurrenceE
				.size(); i++) {
			railFactory(i);
		}

		skill.factory_B(markupE, trainE);

		// DB TABLES

		for (int j = 0; j < skill.tableDBE.size(); j++) {
			dbTablesComponents(j);
		}
		skill.methodsFactory(markupE, trainE);
		for (int i = 0; i < markupE.get("jsp").recurrenceE
				.size(); i++) {
			jspComponents(i);
		}
		genericModel_java.synthesis(markupE, trainE, candies);
		genericModel_java.write(skill.javaWebModelY,
				"GenericModel.java", "GenericModel.java", "java",
				candies, recycleBinY);
		if (skill.indexJsp) {
			baseJsp.jspKit = (JspKit) markupE.get(
					"indexjsp").recurrenceE.get(0).locomotor.substance;
			baseJsp.jspKit.fileName = "index";
			if (markupE.get("indexjsp").recurrenceE.get(0).wagonE.get(
					"bmenu").text != null) {
				baseJsp.jspKit.navigationBar = markupE.get(
						"indexjsp").recurrenceE.get(0).wagonE.get(
								"bmenu").text;
			}
			baseJsp.synthesis(markupE, trainE, candies);
		}
		bootstrap_css.synthesis(markupE, trainE, candies);
		screwdriver_css.synthesis(markupE, trainE, candies);
		screwdriver_cssC.synthesis(markupE, trainE, candies);
		for (int m = 0; m < markupE.get("bdefmenu").recurrenceE
				.size(); m++) {
			navigation_jsps[m].menuKit = (MenuKit) markupE.get(
					"bdefmenu").recurrenceE.get(m).locomotor.substance;
			navigation_jsps[m].synthesis(markupE, trainE, candies);
		}
		if (skill.quartzVers != null) {
			quartz_job_xml.synthesis(markupE, trainE, candies);
		}
		web_xml.synthesis(markupE, trainE, candies);
		pom_properties.synthesis(markupE, trainE, candies);
		doorControllerBelong_java.synthesis(markupE, trainE, candies);
		genericCrud_java.synthesis(markupE, trainE, candies);
		if (skill.internalProperties) {
			springProps_xml.synthesis(markupE, trainE, candies);
		}
		if (skill.webFlow) {
			webflow_xml.synthesis(markupE, trainE, candies);
		}
		if (skill.spring) {
			dispatcher_xml.synthesis(markupE, trainE, candies);
		}
		if (skill.tiles) {
			tiles_xml.synthesis(markupE, trainE, candies);
		} else {
			headerJsp.synthesis(markupE, trainE, candies);
			footerJsp.synthesis(markupE, trainE, candies);
		}
		if (skill.quartzVers != null) {
			quartzJob_java.synthesis(markupE, trainE, candies);
			quartzTask_java.synthesis(markupE, trainE, candies);
			quartzTaskImpl_java.synthesis(markupE, trainE, candies);
		}
		if (skill.springSecurity) {
			springSecurity_xml.synthesis(markupE, trainE, candies);
		}
		pom_xml.synthesis(markupE, trainE, candies);
		if (skill.hasUseridPassword) {
			if (skill.authenticationMode.equals("trivial")) {
				king.synthesis(markupE, trainE, candies);
				kingDao.synthesis(markupE, trainE, candies);
				kingDaoImpl.synthesis(markupE, trainE, candies);
			} else {
				springSecurityUserContext.synthesis(markupE, trainE,
						candies);
				userAuthorityUtils.synthesis(markupE, trainE, candies);
			}
			interfacciaUserContext.synthesis(markupE, trainE, candies);
			userContextImpl.synthesis(markupE, trainE, candies);
		}

		/* THE SCRIPTURES */

		if (skill.indexJsp) {
			baseJsp.write(new722, "index.jsp", "index.jsp", "jsp",
					candies, recycleBinY);
		}
		pom_xml.write(skill.eclipseProjectY, "pom.xml", "pom.xml",
				"xml", candies, recycleBinY);
		web_xml.write(skill.webInfY, "web.xml", "web.xml", "xml",
				candies, recycleBinY);
		pom_properties.write(skill.eclipseProjectY, "pom.properties",
				"pom.properties", "properties", candies, recycleBinY);
		if (skill.quartzVers != null) {
			quartz_job_xml.write(new71, skill.applicationNameLower
					+ "-quartz-job.xml", skill.applicationNameLower
							+ "-quartz-job.xml", "xml", candies,
					recycleBinY);
		}
		doorControllerBelong_java.write(skill.javaWebController,
				"DoorControllerBelong.java",
				"DoorControllerBelong.java", "java", candies,
				recycleBinY);
		if (skill.hibernate) {
			genericCrud_java.write(new58, "GenericCrud.java",
					"GenericCrud.java", "java", candies, recycleBinY);
		} else {
			done = FileComponent.deleteComponent(new58,
					"GenericCrud.java", recycleBin, skill);
		}
		if (skill.internalProperties) {
			springProps_xml.write(new71, skill.applicationNameLower
					+ "-props.xml", skill.applicationNameLower
							+ "-props.xml", "xml", candies,
					recycleBinY);
		} else {
			done = FileComponent.deleteComponent(new71,
					skill.applicationNameLower + "-props.xml",
					recycleBin, skill);
		}
		if (skill.springSecurity) {
			springSecurity_xml.write(new71, skill.applicationNameLower
					+ "-security.xml", skill.applicationNameLower
							+ "-security.xml", "xml", candies,
					recycleBinY);
		} else {
			done = FileComponent.deleteComponent(new71,
					skill.applicationNameLower + "-security.xml",
					recycleBin, skill);
		}
		if (skill.spring) {
			dispatcher_xml.write(new71, "DispatcherServlet.xml",
					"DispatcherServlet.xml", "xml", candies,
					recycleBinY);
		} else {
			done = FileComponent.deleteComponent(new71,
					"DispatcherServlet.xml", recycleBin, skill);
		}
		if (skill.webFlow) {
			for (int i = 0; i < markupE.get("wparams").recurrenceE
					.size(); i++) {
				Train f = markupE.get("wparams").recurrenceE.get(i);
				String nome = f.locomotor.text;
				String newF1 = skill.webFlowY + "/" + nome;
				skill.buildDirectory(newF1);
				webflow_xml.write(newF1, nome + "-flow.xml", nome
						+ "-flow.xml", "xml", candies, recycleBinY);
			}
		}
		if (skill.tiles) {
			tiles_xml.write(new73, "tiles.xml", "tiles.xml", "xml",
					candies, recycleBinY);
		} else {
			headerJsp.write(new721, "header.jsp", "header.jsp", "jsp",
					candies, recycleBinY);
			footerJsp.write(new721, "footer.jsp", "footer.jsp", "jsp",
					candies, recycleBinY);
		}
		if (skill.quartzVers != null) {
			quartzJob_java.write(new63, skill.clockHands.jobNameU
					+ ".java", skill.clockHands.jobNameU + ".java",
					"java", candies, recycleBinY);
			quartzTask_java.write(new60, skill.clockHands.jobNameU
					+ "Task.java", skill.clockHands.jobNameU
							+ "Task.java", "java", candies,
					recycleBinY);
			quartzTaskImpl_java.write(new61, skill.clockHands.jobNameU
					+ "TaskImpl.java", skill.clockHands.jobNameU
							+ "TaskImpl.java", "java", candies,
					recycleBinY);
		}
		bootstrap_css.write(new62, "bootstrap.css", "bootstrap.css",
				"css", candies, recycleBinY);
		screwdriver_css.write(new62, "screwdriver.css",
				"screwdriver.css", "css", candies, recycleBinY);
		// screwdriver_cssC.write(new62, "screwdriverC.css",
		// "screwdriverC.css", "css", candies, recycleBinY);
		for (int m = 0; m < markupE.get("bdefmenu").recurrenceE
				.size(); m++) {
			Train train = markupE.get("bdefmenu").recurrenceE.get(m);
			navigation_jsps[m].write(new721, "navigation_"
					+ train.locomotor.text + ".jsp", "navigation_"
							+ train.locomotor.text + ".jsp", "jsp",
					candies, recycleBinY);
		}
		FileComponent.addFile("root-context.xml", "root-context.xml",
				new71, candies, recycleBinY, skill);
		FileComponent.addFile("ok_jsp.txt", "ok.jsp", new723, candies,
				recycleBinY, skill);
		FileComponent.addFile("warning_jsp.txt", "warning.jsp", new723,
				candies, recycleBinY, skill);

		// CONTROLLERS CREATION
		for (int i = 0; i < skill.correlationE.size(); i++) {
			ControllerBelong cnt = skill.correlationE.get(i);
			skill.cntK = i;
			skill.groupControllerF = cnt.gruppoMaius
					+ "GroupController";
			logger.info("CONTROLLER: skill.groupControllerF="
					+ skill.groupControllerF);
			controllerBelong_java = new ControllerBelong_java(skill,
					"java/ControllerBelong.java");
			controllerBelong_java.synthesis(markupE, trainE, candies);
			controllerBelong_java.write(skill.javaWebController,
					skill.groupControllerF + ".java",
					skill.groupControllerF + ".java", "java", candies,
					recycleBinY);
		}
		if (skill.springSecurity) {
			securityWrite();
		} else {
			securityClean();
		}
		if (skill.initialDirE.size() > 0 & skill.proposedDirE
				.size() > 0) {
			String[] iE = new String[skill.initialDirE.size()];
			for (int ij = 0; ij < skill.initialDirE.size(); ij++) {
				iE[ij] = skill.initialDirE.get(ij).replace(Candies.H92,
						Candies.H47);
			}
			String[] pE = new String[skill.proposedDirE.size()];
			for (int pj = 0; pj < skill.proposedDirE.size(); pj++) {
				pE[pj] = skill.proposedDirE.get(pj).replace(Candies.H92,
						Candies.H47);
			}
			Arrays.sort(iE);
			Arrays.sort(pE);
			int i = 0;
			int p = 0;
			while (i < iE.length) {
				/* with this if I exclude every subdirectory because the
				 * comparison has already been done with the parent
				 * directory */
				int x = iE[i].compareTo(pE[p]);
				if (x == 0) {
					i++;
					p++;
				} else if (x > 0) {
					p++;
				} else { // < 0
					int iW = i;
					do {
						i++;
					} while (i < iE.length && iE[i].startsWith(iE[i - 1]
							+ "/"));
					iE[iW] = Cst.MAGIC0 + iE[iW];
				}
			}
			int z = 0;
			for (int ij = 0; ij < iE.length; ij++) {
				if (iE[ij].startsWith(Cst.MAGIC0)) {
					z++;
				}
			}
			if (z > 0) {
				String question = null;
				if (z == 1) {
					question = "I am about to delete " + z
							+ " directory, because it has become useless:"
							+ " can I execute?";
				} else {
					question = "I am about to delete " + z
							+ " directories, because they have become"
							+ " useless: can I execute?";
				}
				AskForDelete askForDelete = new AskForDelete(null,
						question, "Question", false);
				logger.info(question);
				logger.info(askForDelete.answer ? "Yes" : "No");
				if (askForDelete.answer) {
					String x = Skill.datePosition(recycleBinY);
					for (int ij = 0; ij < iE.length; ij++) {
						if (iE[ij].startsWith(Cst.MAGIC0)) {
							File f = new File(iE[ij].substring(
									Cst.MAGIC0.length()));
							String[] sectionE = iE[ij].split("/");
							String y = x + sectionE[sectionE.length
									- 1];
							new File(y).mkdir();
							Abacus.copyDirectoryRecursion(f, new File(
									y), true);
							Abacus.deleteDirectoryRecursion(f);
						}
					}
				}
			}
		}

		// STATISTICS
		File logF = new File(candies.inputYS + "logs");
		File statF = new File(candies.inputYS + "logs" + sep
				+ "statistics.log");
		Path log = logF.toPath();
		if (Files.exists(log) && !Files.isDirectory(log)) {
			Files.delete(log);
		}
		if (!Files.exists(log)) {
			Files.createDirectory(log);
		}
		SimpleDateFormat df = new SimpleDateFormat(
				"yyyy-MM-dd hh:mm:ss");
		String s = df.format(new Date());
		stat += "Application " + appName + " - Markups statistics on "
				+ s + Candies.LF + Candies.LF;
		markupE.forEach((key, value) -> {
			if (markupE.get(key).recurrenceE.size() > 0) {
				int i = markupE.get(key).recurrenceE.size();
				stat += key + ": " + i + " " + (i == 1 ? "time"
						: "times") + Candies.LF;
			}
		});
		Equipment.writeFileFromOneString_economy(statF, stat);
	}

	/**
	 * <p>
	 * Checks on markups.
	 * </p>
	 * <p>
	 * Creation date: 2020-04-09<br>
	 * Last updated: 2020-04-09
	 * </p>
	 * <p>
	 * Modifications:<br>
	 * </p>
	 * 
	 * @throws ExactException error checking the contents of the file */
	final public void substantialChecks()

			throws ExactException {

		ExactException ne = new ExactException();
		for (int i = 0; i < trainE.size(); i++) {
			Markup m = markupE.get(trainE.get(i).locomotor.stub);

			// CHECKING THE VALUE OF THE PRESUMED MARKUP
			if (m.implyE != null) {
				for (int n = 0; n < m.implyE.length; n++) {
					if (!m.implyE[n].stub.equals("")) {
						String ps = m.implyE[n].stub;
						String pv = m.implyE[n].value;
						boolean pd = m.implyE[n].direct;
						int j = 0;
						for (; j < trainE.size(); j++) {
							if (trainE.get(j).locomotor.stub.equals(
									ps)) {
								break;
							}
						}
						if (j == trainE.size() & pd) {
							ne.datum = "The markup " + Mix.dress_A(ps)
									+ " presupposto da «" + trainE.get(
											i).locomotor.stub
									+ "» non è presente tra i treni!";
							ne.code = 1705;
							ne.className = this.getClass().getName();
							throw ne;
						} else if (j < trainE.size() & !pd) {
							ne.datum = "The markup " + Mix.dress_A(ps)
									+ ", recalled by " + Mix.dress_A(
											trainE.get(
													i).locomotor.stub)
									+ ", was not to be present among the trains!";
							ne.code = 1706;
							ne.className = this.getClass().getName();
							throw ne;
						} else if (!pv.isEmpty() && m.p == 5) {
							if (((Integer) trainE.get(
									i).locomotor.substance)
											.intValue() > ((Integer) trainE
													.get(j).locomotor.substance)
															.intValue()) {
								ne.datum = "The markup " + Mix.dress_A(
										ps) + " implied by " + Mix
												.dress_A(trainE.get(
														i).locomotor.stub)
										+ " has version " + trainE.get(
												j).locomotor.text
										+ ", less than required by "
										+ trainE.get(i).locomotor.stub
										+ ", which is " + Mix.dress_A(
												trainE.get(
														i).locomotor.text)
										+ ".";
								ne.code = 1707;
								ne.className = this.getClass()
										.getName();
								throw ne;
							}
						} else if (j < trainE.size() && !pv.isEmpty()
								&& !trainE.get(j).locomotor.text.equals(
										pv)) {
							ne.datum = "The markup " + Mix.dress_A(ps)
									+ ", connected to " + Mix.dress_A(
											trainE.get(
													i).locomotor.stub)
									+ ", has value " + Mix.dress_A(
											trainE.get(
													j).locomotor.text)
									+ ", not conforming to that necessary for the presence of "
									+ Mix.dress_A(trainE.get(
											i).locomotor.stub)
									+ ", which would like " + Mix
											.dress_A(pv) + ".";
							ne.code = 1708;
							ne.className = this.getClass().getName();
							throw ne;
						}
					}
				}
			}
		}
	}

	// PRIVATE METHODS

	private void componentsInstanceExecution() {
		web_xml = new Web_xml(skill, null);
		pom_properties = new Pom_properties(skill, null);
		quartz_job_xml = new Quartz_job_xml(skill, "testaOrm_"
				+ skill.springVersion + ".txt");
		webflow_xml = new Webflow_xml(skill, "xml/webflow.xml");
		pom_xml = new Pom_xml(skill, null);
		springProps_xml = new SpringProperties_xml(skill,
				"testaSpringProperties_" + skill.springVersion
						+ ".txt");
		springSecurity_xml = new SpringSecurity_xml(skill,
				"testaSpringSecurity_"
						+ skill.springSecurityReductVersion + ".txt");
		dispatcher_xml = new Dispatcher_xml(skill, "testaDispatcher_"
				+ skill.springVersion + ".txt");
		baseJsp = new Base_jsp(skill, "jsp/base_jsp.txt");
		headerJsp = new Hoof(skill, "jsp/header_jsp.txt");
		footerJsp = new Hoof(skill, "jsp/footer_jsp.txt");
		quartzJob_java = new Hoof(skill, "java/QuartzJob.java");
		quartzTask_java = new Hoof(skill, "java/QuartzTask.java");
		quartzTaskImpl_java = new Hoof(skill,
				"java/QuartzTaskImpl.java");
		if (skill.jpaVersion == 1) {
			genericRailDaoImpl = new Hoof(skill,
					"java/GenericRailDaoImplJPA1.java");
		} else {
			genericRailDaoImpl = new Hoof(skill,
					"java/GenericRailDaoImplJPA2.java");
		}
		tiles_xml = new Tiles_xml(skill, null);
		service_xml = new Service_xml(skill, "testaService_"
				+ skill.springVersion + ".txt");
		orm_xml = new Orm_xml(skill, "testaOrm_" + skill.springVersion
				+ ".txt");
		doorControllerBelong_java = new Hoof(skill,
				"java/DoorControllerBelong.java");
		genericCrud_java = new Hoof(skill, "java/GenericCrud.java");
		controllerBelong_java = new ControllerBelong_java(skill,
				"java/ControllerBelong.java");
		jspForm_java = new JspForm_java(skill, null);
		jspFormImpl_java = new JspFormImpl_java(skill, null);
		jspPlain_java = new JspPlain_java(skill, null);
		jspPlainImpl_java = new JspPlainImpl_java(skill, null);
		genericModel_java = new GenericModel_java(skill,
				"java/GenericModel.java", candies);
		userAuthenticationProvider_java = new UserAuthenticationProvider_java(
				skill, "java/ApplicUserAuthenticationProvider.java");
		userContextImpl = new UserContextImpl_java(skill, null);
		bootstrap_css = new Bootstrap_css(skill, "css/bootstrap.css");
		screwdriver_css = new Screwdriver_css(skill,
				"css/screwdriver.css");
		screwdriver_cssC = new Screwdriver_cssC(skill,
				"css/screwdriver.css");
		navigation_jsps = new Navigation_jsp[markupE.get(
				"bdefmenu").recurrenceE.size()];
		for (int m = 0; m < markupE.get("bdefmenu").recurrenceE
				.size(); m++) {
			navigation_jsps[m] = new Navigation_jsp(skill, "");
		}
		king = new Hoof(skill, "java/King.java");
		kingDao = new Hoof(skill, "java/KingDao.java");
		kingDaoImpl = new Hoof(skill, "java/KingDaoImpl.java");
		springSecurityUserContext = new Hoof(skill, "java/" + Mix
				.uppercaseFirstChar(skill.authenticationMode)
				+ "SpringSecurityUserContext.java");
		userAuthorityUtils = new Hoof(skill,
				"java/UserAuthorityUtils.java");
		interfacciaUserContext = new Hoof(skill,
				"java/UserContext.java");
	}

	private void jspComponents(final int i)

			throws ExactException, FileNotFoundException, IOException {

		Train f = markupE.get("jsp").recurrenceE.get(i);
		baseJsp.jspKit = ((JspKit) f.locomotor.substance);
		logger.trace(baseJsp.jspKit.toString());
		/* if it is a form jsp ... */
		if (baseJsp.jspKit.jspType == 1) {
			jspForm_java.jspKit = baseJsp.jspKit;
			jspFormImpl_java.jspKit = baseJsp.jspKit;
			jspForm_java.directory(markupE);
			jspFormImpl_java.directory(markupE);
			jspForm_java.synthesis(markupE, trainE, candies);
			jspFormImpl_java.synthesis(markupE, trainE, candies);
			String formName = baseJsp.jspKit.nomeFileU + Cst.FORMU
					+ ".java";
			jspForm_java.write(skill.javaWebModelBodyY, formName,
					formName, "java", candies, recycleBinY);
			formName = baseJsp.jspKit.nomeFileU + Cst.FORMU
					+ "Impl.java";
			/* here I add to the freeze list two classes that end with
			 * the string "Impl" */
			if (!candies.inside) {
				candies.freezeDueE.add(formName);
			}
			jspFormImpl_java.write(skill.javaWebModelBodyY, formName,
					formName, "java", candies, recycleBinY);
			new File(skill.javaWebModelBodyY + "/"
					+ baseJsp.jspKit.nomeFileU + "Plain.java").delete();
			new File(skill.javaWebModelBodyY + "/"
					+ baseJsp.jspKit.nomeFileU + "PlainImpl.java")
							.delete();
		} else if (baseJsp.jspKit.jspType == 0) {
			/* ... then it is of the plain type */
			jspPlain_java.jspKit = baseJsp.jspKit;
			jspPlainImpl_java.jspKit = baseJsp.jspKit;
			jspPlain_java.directory(markupE);
			jspPlainImpl_java.directory(markupE);
			jspPlain_java.synthesis(markupE, trainE, candies);
			jspPlainImpl_java.synthesis(markupE, trainE, candies);
			String modelName = baseJsp.jspKit.nomeFileU + Cst.PLAINU
					+ ".java";
			jspPlain_java.write(skill.javaWebModelBodyY, modelName,
					modelName, "java", candies, recycleBinY);
			modelName = baseJsp.jspKit.nomeFileU + Cst.PLAINU
					+ "Impl.java";
			/* here I add to the freeze list two classes that end with
			 * the string "Impl" */
			if (!candies.inside) {
				candies.freezeDueE.add(modelName);
			}
			jspPlainImpl_java.write(skill.javaWebModelBodyY, modelName,
					modelName, "java", candies, recycleBinY);
			new File(skill.javaWebModelBodyY + "/"
					+ baseJsp.jspKit.nomeFileU + "Form.java").delete();
			new File(skill.javaWebModelBodyY + "/"
					+ baseJsp.jspKit.nomeFileU + "FormImpl.java")
							.delete();
		}
	}

	private void dbTablesComponents(final int j)

			throws FileNotFoundException, ExactException, IOException,
			ExactException {

		skill.tK = j;
		TableOutfit ct = skill.tableDBE.get(skill.tK);
		FileComponent interfacciaTabellaDao_java = new InterfaceTableDao_java(
				skill, null, candies);
		FileComponent interfacciaTabellaService_java = new InterfaceTabellaService_java(
				skill, null, candies);
		FileComponent tabellaDaoImpl_java = new ImplementTableDao_java(
				skill, null, candies);
		FileComponent tabellaServiceImpl_java = new ImplementTabellaService_java(
				skill, null, candies);
		interfacciaTabellaDao_java.synthesis(markupE, trainE, candies);
		interfacciaTabellaDao_java.write(new5 + "/" + ct.railLowercase
				+ "/dao", "I" + ct.railUppercase + ct.entityName
						+ "Dao.java", "I" + ct.railUppercase
								+ ct.entityName + "Dao.java", "java",
				candies, recycleBinY);
		interfacciaTabellaService_java.synthesis(markupE, trainE,
				candies);
		interfacciaTabellaService_java.write(new5 + "/"
				+ ct.railLowercase + "/service", "I" + ct.railUppercase
						+ ct.entityName + "Service.java", "I"
								+ ct.railUppercase + ct.entityName
								+ "Service.java", "java", candies,
				recycleBinY);
		tabellaDaoImpl_java.synthesis(markupE, trainE, candies);
		tabellaDaoImpl_java.write(new5 + "/" + skill.tableDBE.get(
				j).railLowercase + "/dao/impl", ct.railUppercase
						+ ct.entityName + "Dao.java", ct.railUppercase
								+ ct.entityName + "Dao.java", "java",
				candies, recycleBinY);
		tabellaServiceImpl_java.synthesis(markupE, trainE, candies);
		tabellaServiceImpl_java.write(new5 + "/" + ct.railLowercase
				+ "/service/impl", ct.railUppercase + skill.tableDBE
						.get(j).entityName + "Service.java",
				ct.railUppercase + ct.entityName + "Service.java",
				"java", candies, recycleBinY);
	}

	private static String trainE_toString(List<Train> fE,
			HashMap<String, Markup> mE) {
		String s = "";
		s += Candies.LF + Candies.LF + Candies.LF;
		s += Cst.CUT0;
		s += "ELENCO DEI TRENI" + Candies.LF;
		for (int i = 0; i < fE.size(); i++) {
			s += Cst.CUT0;
			Train f = fE.get(i);
			Wagon v0 = f.locomotor;
			s += v0.toString(0, mE);
			if (f.wagonE.size() > 1) {
				s += Cst.CUT1;
			}
			Collection<Wagon> valueE = f.wagonE.values();
			Iterator<Wagon> iterator = valueE.iterator();
			int j = 0;
			while (iterator.hasNext()) {
				Wagon v = iterator.next();
				s += v.toString(j, mE);
				j++;
			}
		}
		s += Candies.LF;
		return s;
	}

	/* i is the index of the occurrence of the markup rail */
	final private void railFactory(final int i)

			throws IOException, ExactException {

		Train t = markupE.get("hdefrail").recurrenceE.get(i);
		if (t.wagonE.get("hjndi") != null) {
			skill.jndi = t.wagonE.get("hjndi").text;
		}
		if (t.wagonE.get("hdbschema") == null) {
			ExactException ne = new ExactException("Il luogo-DB «rail+"
					+ t.locomotor.text
					+ "» non è accompagnato dal markup «hdbschema».");
			ne.code = 1732;
			ne.datum = ne.getMessage();
			ne.className = this.getClass().getName();
			throw ne;
		} else {
			skill.dbSchema = t.wagonE.get("hdbschema").text;
		}
		// skill.dbms = null;
		if (t.wagonE.get("hdbms") == null) {
			ExactException ne = new ExactException(
					"The rail (pir datasource-DBschema «rail+"
							+ t.locomotor.text
							+ "» is not accompanied by markup «hdbms».");
			ne.code = 1710;
			ne.datum = ne.getMessage();
			ne.className = this.getClass().getName();
			throw ne;
		} else {
			skill.dbms = t.wagonE.get("hdbms").text;
			/* FUTURE RELEASE N6 */
			// skill.dbmsE.add(dbmsW);
		}
		if (t.wagonE.get("hjarv") != null) {
			skill.versioneArtifactJPA = t.wagonE.get("hjarv").text;
		}
		t.locomotor.substance = new DBPlaceKit(skill.dbSchema,
				skill.jndi, skill.dbms);
		if (skill.hibernateVersion != null & markupE.get(
				"hv").recurrenceE.get(0).wagonE.get("hjpav").text
						.equals("2")) {
			FileComponent.addClass("GenericController.java",
					skill.javaWebController, "GenericController.java",
					candies, recycleBinY, skill, -1, markupE, "java");
			FileComponent.addClass("GenericComponent.java",
					skill.javaWebController, "GenericComponent.java",
					candies, recycleBinY, skill, -1, markupE, "java");
			FileComponent.addClass("Filter.java", new581, "Filter.java",
					candies, recycleBinY, skill, -1, markupE,
					"java/jpa2");
			FileComponent.addClass("Order.java", new581, "Order.java",
					candies, recycleBinY, skill, -1, markupE,
					"java/jpa2");
			FileComponent.addClass("OrderBuilder.java", new581,
					"OrderBuilder.java", candies, recycleBinY, skill,
					-1, markupE, "java/jpa2");
			FileComponent.addClass("PaginatedFilter.java", new581,
					"PaginatedFilter.java", candies, recycleBinY, skill,
					-1, markupE, "java/jpa2");
			FileComponent.addClass("SearchParameter.java", new581,
					"SearchParameter.java", candies, recycleBinY, skill,
					-1, markupE, "java/jpa2");
			FileComponent.addClass("SingularParameter.java", new581,
					"SingularParameter.java", candies, recycleBinY,
					skill, -1, markupE, "java/jpa2");
			FileComponent.addClass("StringParameter.java", new581,
					"StringParameter.java", candies, recycleBinY, skill,
					-1, markupE, "java/jpa2");
			FileComponent.addClass("GenericDao.java", new582,
					"GenericDao.java", candies, recycleBinY, skill, -1,
					markupE, "java/jpa2");
		}
		/* the double id is the sequence of java naming and DB schema */
		String doppioId = skill.jndi.toLowerCase() + "-"
				+ skill.dbSchema;
		String new6 = new5 + "/" + Cst.RAIL + t.locomotor.text;
		hibernateDirectoriesFactory(new6, new5, t);
		File progettoJpa = new File(candies.outputYS + doppioId);
		File persistence = new File(candies.outputYS + doppioId
				+ "/src/META-INF/persistence.xml");
		if (!progettoJpa.exists()) {
			String messaggio = "The project JPA " + Mix.dress_A(
					doppioId)
					+ " does not exist, it's impossible to continue.";
			ExactException ce = new ExactException(messaggio);
			ce.code = 1733;
			ce.datum = ce.getMessage();
			ce.className = this.getClass().getName();
			throw ce;
		} else if (!persistence.exists()) {
			String message = "The file"
					+ " persistence.xml does not exist in directory «"
					+ "src/META-INF» of the JPA project " + Mix.dress_A(
							doppioId);
			Mix.discloseInfo(message, "Alarm", logger);
		} else {
			Document document = null;
			NodeList nodeList0, nodeList1;
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			Node nodeDoc0, nodeDoc1;
			// I create the document of the "persistence" file
			DocumentBuilder builder;
			try {
				builder = factory.newDocumentBuilder();
				document = builder.parse(persistence);
			} catch (ParserConfigurationException e) {
				e.printStackTrace();
			} catch (SAXException e) {
				e.printStackTrace();
			}
			logger.trace(
					"I've created the DOM document of persistence.xml"
							+ " for the DB-place " + Mix.dress_A(
									doppioId));
			nodeList0 = document.getChildNodes();
			nodeDoc0 = nodeList0.item(0);
			nodeList1 = nodeDoc0.getChildNodes();
			nodeDoc1 = nodeList1.item(1);
			String[] rigaE = Strings.compact_A(nodeDoc1
					.getTextContent()).split("\\x20");
			for (String riga : rigaE) {
				if (!riga.endsWith("PK")) {
					riga += "+"; // trick to avoid exception, then
								 // I take off
					String[] z = riga.split("\\x2e"); // x2e is the
													  // dot
					if (z.length < 4) {
						ExactException ne = new ExactException(
								"The line of the file persistence.xml in the JPA project «"
										+ doppioId + "» is «" + riga
										+ "», but it is wrong.");
						ne.code = 1712;
						ne.datum = ne.getMessage();
						ne.className = this.getClass().getName();
						throw ne;
					}
					String ultimo = z[z.length - 1];
					String path = riga.substring(0, riga.indexOf(ultimo)
							- 1);
					ultimo = ultimo.substring(0, ultimo.length() - 1);
					TableOutfit kit = new TableOutfit(ultimo, path,
							z[z.length - 2], candies, z[z.length - 3],
							Cst.RAIL, t.locomotor.text);
					logger.debug(kit);
					skill.tableDBE.add(kit);
				}
			}
		}
		skill.railK = i;
		service_xml.synthesis(markupE, trainE, candies);
		service_xml.write(new71, Cst.RAIL + t.locomotor.text
				+ "-service.xml", Cst.RAIL + t.locomotor.text
						+ "-service.xml", "xml", candies, recycleBinY);
		orm_xml.synthesis(markupE, trainE, candies);
		orm_xml.write(new71, Cst.RAIL + t.locomotor.text + "-orm.xml",
				Cst.RAIL + t.locomotor.text + "-orm.xml", "xml",
				candies, recycleBinY);
		genericRailDaoImpl.synthesis(markupE, trainE, candies);
		genericRailDaoImpl.write(new5 + "/" + Cst.RAIL
				+ t.locomotor.text, "Generic" + Cst.RAILU
						+ t.locomotor.text + "DaoImpl.java", "Generic"
								+ Cst.RAILU + t.locomotor.text
								+ "DaoImpl.java", "java", candies,
				recycleBinY);

	}

	/* the directory to be created does not exist, but there was one,
	 * with a different name, which was really our application */
	final private void scruple(final String corrente,
			final String superiore) {
		File y = new File(corrente);
		/* first I deal with the case that a file corresponds to that
		 * name, in which case I delete it */
		if (y.exists() & !y.isDirectory()) {
			y.delete();
		} else if (!y.exists()) {
			/* if it does not exist, I list the files and directories */
			Folder folder = new Folder();
			/* this is the list of what is contained in the parent, or
			 * parent, directory */
			File[] parentE = folder.fileObjects(".+", superiore);
			/* this list is empty ... */
			if (parentE.length == 0) {
				/* .. create the directory */
				skill.buildDirectory(y);
			} else { /* if instead there is a list */
				int i = 0;
				/* ... check if there is at least one directory */
				for (; i < parentE.length; i++) {
					/* if you found it ... */
					if (parentE[i].isDirectory()) {
						parentE[i].renameTo(y);
						break;
					}
				}
				/* if there is not even a directory, create it */
				if (i == parentE.length) {
					skill.buildDirectory(y);
				}
			}
		} else {
			skill.proposedDirE.add(corrente);
		}
	}

	/* this method adds the creation of the typical Hibernate
	 * directories to the previous one */
	final private void hibernateDirectoriesFactory(
			final String levelRail, final String superiore, Train t) {

		skill.buildDirectory(levelRail);
		String brickServiceY = levelRail + "/service";
		skill.buildDirectory(brickServiceY);
		String brickServiceImplY = brickServiceY + "/impl";
		skill.buildDirectory(brickServiceImplY);
		String brickDaoY = levelRail + "/dao";
		skill.buildDirectory(brickDaoY);
		String brickDaoImplY = brickDaoY + "/impl";
		skill.buildDirectory(brickDaoImplY);
	}

	final private void directoriesFactory_B()

			throws ExactException, IOException {

		@SuppressWarnings("unused")
		boolean done = false;
		File f = null;
		FileComponent.addFile("config.properties", "config.properties",
				skill.mainResources, candies, recycleBinY, skill);
		/* FUTURE RELEASE N6 */
		// if (skill.embedded) {
		// f = new File(skill.mainResources + "/database");
		// skill.buildDirectory(f);
		// Iterator<String> iterator = skill.dbmsE.iterator();
		// while (iterator.hasNext()) {
		// f = new File(skill.mainResources + "/database/" + Mix
		// .inizialeMinuscola((String) (iterator.next())));
		// skill.buildDirectory(f);
		// }
		// }
		String new520 = skill.mainResources + "/ldif";
		f = new File(new520);
		if (skill.ldap) {
			skill.buildDirectory(f);
			File newFile = new File(new520 + "/"
					+ skill.applicationNameLower + ".ldif");
			done = newFile.createNewFile();
			Markup mFile = markupE.get("file");

			int i = 0;
			for (; i < mFile.recurrenceE.size(); i++) {
				if (mFile.recurrenceE.get(i).locomotor.text.equals(
						skill.applicationNameLower + ".ldif")) {
					break;
				}
			}
			if (i < mFile.recurrenceE.size()) {
				Equipment.scriviFileDaStringa(newFile,
						(String) mFile.recurrenceE.get(
								i).locomotor.substance);
			}
		} else if (f.exists()) {
			Abacus.destroyDirectory(new520);
			done = f.delete();
		}
		skill.webAppG = skill.mainY + "/webapp";
		String newMetaInf = skill.webAppG + "/META-INF";
		skill.webAppResourcesY = skill.webAppG + "/resources";
		new62 = skill.webAppResourcesY + "/css";
		String new64 = skill.webAppResourcesY + "/fonts";
		String new65 = skill.webAppResourcesY + "/images";
		String new66 = skill.webAppResourcesY + "/js";
		skill.webInfY = skill.webAppG + "/WEB-INF";
		new71 = skill.webInfY + "/spring";
		new72 = skill.webInfY + "/views";
		new721 = new72 + "/includes";
		new723 = new72 + "/answers";
		new722 = new72 + "/home";
		new73 = skill.webInfY + "/tiles";
		String newLib = skill.webInfY + "/lib";
		String newT0 = skill.eclipseProjectY + "src/test";
		String newT1 = newT0 + "/java";
		String newT2 = newT0 + "/resources";
		skill.buildDirectory(skill.mainY);
		skill.buildDirectory(newT0);
		skill.buildDirectory(skill.mainJavaY);
		skill.buildDirectory(skill.webAppG);
		skill.buildDirectory(skill.webInfY);
		skill.buildDirectory(newMetaInf);
		skill.buildDirectory(newLib);
		skill.buildDirectory(new72);
		if (!skill.tiles) {
			skill.buildDirectory(new721);
		}
		skill.buildDirectory(new722);
		skill.buildDirectory(new723);
		f = new File(new73);
		if (skill.tiles) {
			skill.buildDirectory(f);
		} else if (f.exists()) {
			done = new File(new73).renameTo(new File(recycleBinY
					+ "/tiles"));
		}
		skill.buildDirectory(skill.webAppResourcesY);
		skill.buildDirectory(new62);
		skill.buildDirectory(new64);
		skill.buildDirectory(new65);
		skill.buildDirectory(new66);
		if (skill.spring) {
			skill.buildDirectory(new71);
			/* I don't want spring, so the WEB-INF / spring directory
			 * must be deleted */
		} else if (new File(new71).exists()) {
			Abacus.destroyDirectory(new71);
			done = new File(new71).delete();
		}
		skill.buildDirectory(newT1);
		skill.buildDirectory(newT2);
		String new4 = skill.mainJavaY;
		String[] u = null;
		u = skill.networkDomain.split("\\x2e");
		skill.pckg = skill.networkDomain;
		for (int i = 0; i < u.length; i++) {
			new4 += "/" + u[i];
			skill.buildDirectory(new4);
		}
		new5 = new4 + "/" + skill.applicationNameLower;
		skill.pckg += "." + skill.applicationNameLower;
		scruple(new5, new4);
		skill.javaWebY = new5 + "/web";
		skill.javaUtilY = new5 + "/utilities";
		skill.buildDirectory(skill.javaWebY);
		skill.buildDirectory(skill.javaUtilY);
		String new53 = new5 + "/exception";
		skill.buildDirectory(new53);
		new58 = new5 + "/generic";
		skill.buildDirectory(new58);
		new581 = new5 + "/jpa";
		skill.buildDirectory(new581);
		new582 = new581 + "/dao";
		skill.buildDirectory(new582);
		new583 = new582 + "/impl";
		skill.buildDirectory(new583);
		new60 = new5 + "/task";
		new61 = new60 + "/impl";
		new63 = new5 + "/job";
		if (skill.quartzVers == null) {
			if (new File(new60).exists()) {
				Abacus.destroyDirectory(new60);
				done = new File(new60).delete();
			}
			if (new File(new63).exists()) {
				Abacus.destroyDirectory(new63);
				done = new File(new63).delete();
			}
		} else {
			skill.buildDirectory(new60);
			skill.buildDirectory(new63);
		}
		skill.buildDirectory(new60);
		skill.buildDirectory(new61);
		String new59 = new5 + "/mail";
		skill.buildDirectory(new59);
		domainY = new5 + "/domain";
		skill.buildDirectory(domainY);
		securityY = new5 + "/security";
		if (skill.springSecurity) {
			skill.buildDirectory(securityY);
		}
		if (skill.ldap) {
			newLdap = securityY + "/ldap";
			skill.buildDirectory(newLdap);
			newLdap += "/userdetails";
			skill.buildDirectory(newLdap);
			newLdap += "/ad";
			skill.buildDirectory(newLdap);
			FileComponent.addClass(
					"ActiveDirectoryLdapAuthoritiesPopulator.java",
					newLdap,
					"ActiveDirectoryLdapAuthoritiesPopulator.java",
					candies, recycleBinY, skill, -1, markupE, "java");
		}
		newAnnotation = skill.javaWebY + "/annotation";
		skill.buildDirectory(newAnnotation);
		new513 = skill.javaWebY + "/filter";
		if (skill.filter) {
			skill.buildDirectory(new513);
			/* I don't want filters, so the directory needs to be
			 * cleared */
		} else if (new File(new513).exists()) {
			Abacus.destroyDirectory(new513);
			done = new File(new513).delete();
		}
		brickAuthenticationY = skill.javaWebY + "/authentication";
		if (skill.authenticationProvider != null
				&& !skill.authenticationProvider.equals("ldap")) {
			skill.buildDirectory(brickAuthenticationY);
			/* ... then it means that I don't want filters, so the
			 * directory must be deleted */
		} else if (new File(brickAuthenticationY).exists()) {
			Abacus.destroyDirectory(brickAuthenticationY);
			done = new File(brickAuthenticationY).delete();
		}
		if (skill.hasUseridPassword) {
			brickAuthenticationAuthorityY = brickAuthenticationY
					+ "/authority";
			skill.buildDirectory(brickAuthenticationAuthorityY);
		}
		new515 = skill.javaWebY + "/listener";
		skill.buildDirectory(new515);
		new516 = skill.javaWebY + "/mapping";
		skill.buildDirectory(new516);
		newResolver = skill.javaWebY + "/resolver";
		skill.buildDirectory(newResolver);
		new518 = skill.javaWebY + "/sanitizer";
		skill.buildDirectory(new518);
		new519 = skill.javaWebY + "/servlet";
		skill.buildDirectory(new519);
		String new51a = skill.javaWebY + "/validator";
		skill.buildDirectory(new51a);
	}

	/* treatment of the links between markups that are significant for
	 * their position; es. formt, valconst */
	final private void eachTrainHooks(Train train,
			final int posizioneVisiva)

			throws ExactException {

		List<ValidConstScrew> vcE = new ArrayList<ValidConstScrew>();
		/* the first time the markup file appears, I prepare the
		 * substance that will accept the text of the file */
		if (train.locomotor.stub.equals("file")) {
			train.locomotor.substance = "";
		}
		/* trattasiIndexJsp would seem useless, for now I leave it */
		if (train.locomotor.stub.equals("jsp")) {
			// questionIndexJsp = false;
			ultimaJsp = train;
		} else if (train.locomotor.stub.equals("indexjsp")) {
			ultimaJsp = train;
			ultimaJsp.locomotor.substance = new JspKit();
		}
		String ultimaFormLabel = "";
		if (train.wagonE.get("flabel") != null) {
			ultimaFormLabel = train.wagonE.get("flabel").text;
		}
		if (train.locomotor.stub.length() > 4
				&& train.locomotor.text != null && train.locomotor.text
						.length() > 1 && train.locomotor.stub.substring(
								0, 4).equals("form")) {
			String secondaLettera = train.locomotor.text.substring(1,
					2);
			if (secondaLettera.toUpperCase().equals(secondaLettera)) {
				ExactException ce = new ExactException(
						"In un tag «formt+» la seconda lettera del name «"
								+ train.locomotor.text
								+ "» è maiuscola, is incorrect.");
				ce.code = 1730;
				ce.datum = ce.getMessage();
				ce.className = this.getClass().getName();
				throw ce;
			}
		}
		JspBeanElement jbe = null;
		if (train.locomotor.stub.equals("formt")) {
			kitLastJsp = (JspKit) ultimaJsp.locomotor.substance;
			jbe = new JspBeanElement(Mix.lowercaseFirstChar(
					train.locomotor.text), null, true, ultimaFormLabel,
					train.wagonE.get("mybutton"), vcE, Cst.TEXT_BOX);
			kitLastJsp.controlE.add(jbe);
		} else if (train.locomotor.stub.equals("forma")) {
			kitLastJsp = (JspKit) ultimaJsp.locomotor.substance;
			jbe = new JspBeanElement(Mix.lowercaseFirstChar(
					train.locomotor.text), null, true, ultimaFormLabel,
					train.wagonE.get("mybutton"), vcE, Cst.TEXT_AREA);
			kitLastJsp.controlE.add(jbe);
		} else if (train.locomotor.stub.equals("formc")) {
			kitLastJsp = (JspKit) ultimaJsp.locomotor.substance;
			jbe = new JspBeanElement(Mix.lowercaseFirstChar(
					train.locomotor.text), null, true, ultimaFormLabel,
					train.wagonE.get("mybutton"), vcE, Cst.CHECK_BOX);
			kitLastJsp.controlE.add(jbe);
		} else if (train.locomotor.stub.equals("formr")) {
			kitLastJsp = (JspKit) ultimaJsp.locomotor.substance;
			int start = 0;
			if (train.wagonE.get("fstart") != null) {
				start = Integer.valueOf(train.wagonE.get(
						"fstart").text);
			}
			jbe = new JspBeanElement(Mix.lowercaseFirstChar(
					train.locomotor.text), null, true, ultimaFormLabel,
					null, train.wagonE.get("mybutton"), null, null,
					Cst.RADIO_BUTTON, train.wagonE.get("ftokens"),
					start);
			kitLastJsp.controlE.add(jbe);
		} else if (train.locomotor.stub.equals("formn")) {
			kitLastJsp = (JspKit) ultimaJsp.locomotor.substance;
			jbe = new JspBeanElement(Mix.lowercaseFirstChar(
					train.locomotor.text), null, true, ultimaFormLabel,
					train.wagonE.get("fcartel"), train.wagonE.get(
							"mybutton"), train.wagonE.get("dao"),
					train.wagonE.get("hsqln"), Cst.LIST_BOX,
					train.wagonE.get("ftokens"), 0);
			kitLastJsp.controlE.add(jbe);
		}
		if (train.locomotor.stub.equals("valcons")) {
			jbe = kitLastJsp.controlE.get(kitLastJsp.controlE.size()
					- 1);
			ValidConstScrew vc = new ValidConstScrew(train.locomotor,
					train.wagonE.get("valparams"), train.wagonE.get(
							"valtag"));
			jbe.validConstE.add(vc);
		}
		if (train.locomotor.stub.equals("bdefmenu")) {
			lastDeclaredMenu = (markupE.get("bdefmenu").recurrenceE.get(
					markupE.get("bdefmenu").recurrenceE.size() - 1));
			lastDeclaredMenu.locomotor.substance = new MenuKit();
			((MenuKit) lastDeclaredMenu.locomotor.substance).navbarFixedTop = lastDeclaredMenu.wagonE
					.containsKey("bfixedtop");
		}
		if (train.locomotor.stub.equals("blabel")
				& lastDeclaredMenu != null) {
			String[] clic = new String[2];
			clic[0] = train.locomotor.text;
			clic[1] = train.wagonE.get("burl").text;
			((MenuKit) lastDeclaredMenu.locomotor.substance).clicE.add(
					clic);
		}
		if (train.locomotor.stub.equals("pragma") & ultimaJsp == null) {
			String message = "The markup " + Mix.dress_A(
					train.locomotor.stub) + " at the row "
					+ posizioneVisiva
					+ " must be preceded (even not immediately)"
					+ " by markup «jsp+».";
			ExactException ce = new ExactException();
			ce.code = 1713;
			ce.datum = message;
			ce.className = this.getClass().getName();
			throw ce;
		} else if (train.locomotor.stub.equals("pragma")) {
			/* I take the train of the last jsp */
			((JspKit) (ultimaJsp.locomotor.substance)).pragma = true;
		}
	}

	/**
	 * <p>
	 * Checking the presence of markups.
	 * </p>
	 * 
	 * @throws ExactException standard exception */
	final public void controlloPresenze()

			throws ExactException {

		ExactException ce = new ExactException();
		Collection<Markup> valueE = markupE.values();
		Iterator<Markup> iterator = valueE.iterator();
		while (iterator.hasNext()) {
			Markup markup = iterator.next();
			/* I check the markups that must always be present at least
			 * once, but only if they are locomotives; to verify that
			 * they are locomotives */
			if (markup.presenza == 1 && (markup.implyE == null
					|| !markup.implyE[0].isWagon) && markup.recurrenceE
							.size() != 1) {
				// if (markup.presence == 1 && markup.occurrenceE
				// .size ()! = 1) {
				ce.code = 1714;
				ce.datum = "The markup " + Mix.dress_A(markup.stub)
						+ " has to be present once and only once.";
				ce.className = this.getClass().getName();
				throw ce;
			}
			if (markup.recurrenceE.size() == 0) {
				continue;
			}
			if (markup.presenza == 2 & markup.recurrenceE.size() > 1) {
				ce.code = 1715;
				ce.datum = "The markup " + Mix.dress_A(markup.stub)
						+ " has to be present no more than once.";
				ce.className = this.getClass().getName();
				throw ce;
			}
			if (markup.presenza == 3 | markup.presenza == 5
					& markup.recurrenceE.size() == 0) {
				ce.code = 1716;
				ce.datum = "The markup " + Mix.dress_A(markup.stub)
						+ " has to be present at least once.";
				ce.className = this.getClass().getName();
				throw ce;
			}
			if (markup.implyE != null) {
				/* the algorithm is based on a series of hours because,
				 * if I speak of "it presupposes a locomotive", there
				 * can be a range of possible locomotives, therefore the
				 * test must be satisfied at least once. Unfortunately,
				 * the algorithm is not adequate when other markups are
				 * assumed, which are not locomotives of the markup we
				 * are checking, but which must still be present */
				/* a column should be added in the Hammer class table:
				 * the current one becomes "presupposes locomotor", the
				 * new "presupposes markup" */
				boolean presente = false;
				boolean assente = false;
				String totalPresent = "";
				String totalAbsent = "";
				int totalPresentOnesQ = 0;
				int totalAbsentOnesQ = 0;
				for (int n = 0; n < markup.implyE.length; n++) {
					if (markup.implyE[n].direct) {
						presente |= markupE.get(
								markup.implyE[n].stub).recurrenceE
										.size() > 0;
						totalPresent += markup.implyE[n].stub + " ";
						totalPresentOnesQ++;
					} else {
						assente |= markupE.get(
								markup.implyE[n].stub).recurrenceE
										.size() == 0;
						totalAbsent += markup.implyE[n].stub + " ";
						totalAbsentOnesQ++;
					}
				}
				/* if there is, remove the final space) */
				if (totalPresent.endsWith(Candies.SPACE)) {
					totalPresent = totalPresent.substring(0,
							totalPresent.length() - 1);
				}
				if (totalAbsent.endsWith(Candies.SPACE)) {
					totalAbsent = totalAbsent.substring(0, totalAbsent
							.length() - 1);
				}
				if (totalPresentOnesQ > 0 & !presente) {
					ce.code = 1717;
					if (totalPresentOnesQ == 1) {
						ce.datum = "The markup " + Mix.dress_A(
								totalPresent)
								+ " has to be present at least once,"
								+ " it is required by the presence of "
								+ Mix.dress_A(markup.stub) + ".";
					} else {
						ce.datum = "The markup " + Mix.dress_A(
								totalPresent)
								+ " has to be present at least once,"
								+ " they are required by the presence of "
								+ Mix.dress_A(markup.stub) + ".";

					}
					ce.className = this.getClass().getName();
					throw ce;
				}
				if (totalAbsentOnesQ > 0 & !assente) {
					ce.code = 1736;
					if (totalAbsentOnesQ == 1) {
						ce.datum = "The markup " + Mix.dress_A(
								totalAbsent)
								+ " it should not be present,"
								+ " as determined by the configuration of "
								+ Mix.dress_A(markup.stub) + ".";
					} else {
						ce.datum = "None of the markups " + Mix.dress_A(
								totalAbsent)
								+ " it should not be present,"
								+ " as determined by the configuration of "
								+ Mix.dress_A(markup.stub) + ".";
					}
					ce.className = this.getClass().getName();
					throw ce;
				}
			}
			if (markup.mandatoryWagE != null) {
				for (int m = 0; m < markup.mandatoryWagE.length; m++) {
					for (int n = 0; n < markup.recurrenceE
							.size(); n++) {
						Train train = markup.recurrenceE.get(n);
						if (train.wagonE.get(
								markup.mandatoryWagE[m]) == null) {
							ce.code = 1718;
							ce.datum = "The markup " + Mix.dress_A(
									markup.mandatoryWagE[m])
									+ " is missing after the markup "
									+ Mix.dress_A(markup.stub + "+"
											+ train.locomotor.text)
									+ ".";
							ce.className = this.getClass().getName();
							throw ce;
						}
					}
				}
			}
			if (markup.optionalWagE != null) {
				for (int n = 0; n < markup.recurrenceE.size(); n++) {
					Train train = markup.recurrenceE.get(n);

					Collection<Wagon> valueWagonE = train.wagonE
							.values();
					Iterator<Wagon> iteratorWagon = valueWagonE
							.iterator();
					while (iteratorWagon.hasNext()) {
						Wagon wagon = iteratorWagon.next();
						int m = 0;
						for (; m < markup.unioneE.length; m++) {
							if (wagon.stub.equals(markup.unioneE[m])) {
								break;
							}
						}
						if (m == markup.unioneE.length) {
							ce.code = 1731;
							ce.datum = "The markup " + Mix.dress_A(
									wagon.stub + "+" + wagon.text)
									+ " following " + Mix.dress_A(
											train.locomotor.stub + "+"
													+ train.locomotor.text)
									+ " it is not expected in optional"
									+ " wagons nor in mandatory ones.";
							ce.className = this.getClass().getName();
							throw ce;
						}
					}
				}
			}
		}
		int i = 0;
		for (; i < markupE.get("blabel").recurrenceE.size(); i++) {
			Train blabelTrain = markupE.get("blabel").recurrenceE.get(
					i);
			Wagon burlWagon = blabelTrain.wagonE.get("burl");
			int j = 0;
			for (; j < markupE.get("requmap").recurrenceE.size(); j++) {
				Train rmTrain = markupE.get("requmap").recurrenceE.get(
						j);
				if (rmTrain.locomotor.substance.equals(
						burlWagon.substance)) {
					break;
				}
			}
			if (j == markupE.get("requmap").recurrenceE.size()
					& !burlWagon.text.equals("/")) {
				ce.code = 1738;
				ce.datum = "The markup " + Mix.dress_A("blabel+"
						+ blabelTrain.locomotor.text)
						+ " calls an inexistent Request Map: " + Mix
								.dress_A(burlWagon.text) + ".";
				ce.className = this.getClass().getName();
				throw ce;
			}
		}
	}

	final private List<Train> composeTrains(List<String> zebra,
			final String includeY)

			throws ExactException {

		String s = null;
		int p = 0;
		int rigaJ = 0;
		String[] complessoE;
		ExactException ne = new ExactException();
		for (rigaJ = 0; rigaJ < zebra.size(); rigaJ++) {
			// here I trim the text, but only here
			s = zebra.get(rigaJ).replaceAll("\\t", " ").trim();
			if (s.endsWith(Markup.PIU)) {
				s += " ";
				complessoE = s.split("\\x" + Markup.PIUX);
				complessoE[complessoE.length - 1] = "";
			} else {
				complessoE = s.split("\\x" + Markup.PIUX);
			}
			int complessoL = complessoE.length;
			p = s.indexOf(Markup.PIUC);
			/* if there is a + sign, and it is a file, and there are too
			 * many + signs ... */
			if (p > -1 && stub != null && stub.equals("file")
					&& complessoE.length != 2) {
				ne.datum = "Nel markup " + Mix.dress_A(stub)
						+ " at line " + posizioneVisiva
						+ " the file name cannot contain the sign +.";
				ne.code = 1719;
				ne.n = rigaJ;
				ne.className = this.getClass().getName();
				throw ne;
			} else if (s == null || s.length() == 0 || s.startsWith(
					"#")) {
				/* if a line starts with a pound sign, it is a
				 * comment */
				posizioneVisiva++;
				continue;
				/* if the + sign is not there, or is in such a position
				 * that it cannot be a markup, we have a file markup,
				 * and it is not the first line (stub! = null) and the
				 * last valid stub is "file "... */
			} else if (s.length() > 0 && stub != null && markupE.get(
					train.locomotor.stub).p == 20 && (p == -1
							|| p < Markup.MAR_LP || p > Markup.MAR_LM
									- 1 || !markupE.containsKey(s
											.substring(0, p)
											.toLowerCase()))) {
				/* ... then accumulates the line as file content */
				String z = (String) train.locomotor.substance;
				z += zebra.get(rigaJ) + Candies.LINE_FEED;
				train.locomotor.substance = z;
				/* if a line is null, empty or comment, skip it, but
				 * count it with indication */
			} else if (p > -1 && s.length() > 1 && p < s.length()
					&& complessoL > 2 // that is, it has more than 1 +
									  // sign
					&& markupE.containsKey(s.substring(0, p)
							.toLowerCase()) && markupE.get(s.substring(
									0, p).toLowerCase()).wagon) {
				ne.datum = "The markup " + Mix.dress_A(stub)
						+ " at line " + posizioneVisiva
						+ " must have one + sign, being a"
						+ " \"wagon\" type.";
				ne.code = 1720;
				ne.n = rigaJ;
				ne.className = this.getClass().getName();
				throw ne;
			} else if (p > -1 && s.length() > 1 && p < s.length()
					&& complessoL % 2 == 1 && markupE.containsKey(s
							.substring(0, p).toLowerCase()) && !markupE
									.get(s.substring(0, p)
											.toLowerCase()).wagon) {
				ne.datum = "The markup «" + s.substring(0, p)
						+ "+» in the row " + posizioneVisiva
						+ " must have an odd number of  symbols +.";
				ne.code = 1721;
				ne.n = rigaJ;
				ne.className = this.getClass().getName();
				throw ne;
			} else if (p > -1 & s.length() > 1 && p < s.length()) {
				String[] pezzoE = new String[complessoE.length / 2];
				for (int j = 0; j < pezzoE.length; j++) {
					pezzoE[j] = complessoE[j * 2] + Markup.PIU
							+ complessoE[j * 2 + 1];
					pezzoE[j] = pezzoE[j].trim();
					eValido(pezzoE[j], rigaJ, includeY, zebra, j);
				}
				eachTrainHooks(train, posizioneVisiva);
				trainE.add(train);
				/* if instead the markup is not present, there is a text
				 * and we are on the first train ... */
			} else if (s.length() > 0 & zQ == 0) {
				ne.datum = "The file \"ele\" must begin with a valid"
						+ " markup, not with a text: " + s;
				ne.code = 1722;
				ne.n = rigaJ;
				ne.className = this.getClass().getName();
				throw ne;
			} else if (s.length() > 0 & p > -1) {

				// NOT CREATION OF A NEW TRAIN, BUT ANYWAY INSTANTIATION
				Wagon seg = new Wagon(markupE, stub, s, rigaJ, zQ,
						train, posizioneVisiva);
				Train f = new Train(seg, rigaJ);
				eachTrainHooks(f, posizioneVisiva);
			}
			posizioneVisiva++;
		}
		return trainE;
	}

	private void eValido(final String s, final int rigaJ,
			final String includeY, List<String> zebra, final int m)

			throws ExactException {

		File include = null;
		ExactException ne = new ExactException();
		Wagon wagon = null;
		try {
			int p = s.indexOf(Markup.PIUC);
			stub = s.substring(0, p).toLowerCase();
			String dato = s.substring(p + 1);
			if (!markupE.containsKey(stub)) {
				ne.datum = "The markup " + Mix.dress_A(stub + "+")
						+ " at line " + posizioneVisiva
						+ " it is not present among those expected.";
				ne.code = 1723;
				ne.n = rigaJ;
				ne.className = this.getClass().getName();
				throw ne;
			} else {

				// sigh of relief, CREATION OF A NEW TRAIN

				/* if it is the first train (undead, i.e. not of type
				 * 0) */
				if (zQ == 0) {
					wagon = new Wagon(markupE, stub, dato, rigaJ, zQ,
							null, posizioneVisiva);
				} else { // otherwise write down the previous one
					wagon = new Wagon(markupE, stub, dato, rigaJ, zQ,
							train, posizioneVisiva);
				}
				if (m == 0) {
					train = new Train();
				}
				if (train.locomotor == null) {
					train.locomotor = wagon;
				} else if (train.wagonE.get(wagon.stub) != null) {
					ne.datum = "The markup " + Mix.dress_A(wagon.stub)
							+ " is repeated at line " + posizioneVisiva
							+ " following " + Mix.dress_A(
									train.locomotor.stub + "+"
											+ train.locomotor.text)
							+ ", " + "it is not acceptable.";
					ne.code = 1734;
					ne.n = rigaJ;
					ne.className = this.getClass().getName();
					throw ne;
				} else if (!markupE.get(wagon.stub).wagon) {
					ne.datum = "The markup " + Mix.dress_A(wagon.stub)
							+ " is a locomotor, it cannot stay in a"
							+ " wagon position after " + Mix.dress_A(
									train.locomotor.stub) + ".";
					ne.code = 1735;
					ne.n = rigaJ;
					ne.className = this.getClass().getName();
					throw ne;
				} else { // ... finally okay, I create the train
					train.wagonE.put(wagon.stub, wagon);
					int j = 0;
					for (; j < markupE.get(
							wagon.stub).implyE.length; j++) {
						if (markupE.get(wagon.stub).implyE[j].isWagon
								& markupE.get(wagon.stub).implyE[j].stub
										.equals(train.locomotor.stub)) {
							break;
						}
					}
					if (j == markupE.get(wagon.stub).implyE.length) {
						ne.datum = "The markup " + Mix.dress_A(
								wagon.stub) + " is found after " + Mix
										.dress_A(train.locomotor.stub)
								+ ", " + "it is not acceptable.";
						ne.code = 1728;
						ne.n = rigaJ;
						ne.className = this.getClass().getName();
						throw ne;
					}
				}
				if (m == 0) {
					markupE.get(stub).recurrenceE.add(train);
				}
				/* when p calls an include (.eli) */
				if (m == 0 & (markupE.get(train.locomotor.stub).p == 9
						| markupE.get(train.locomotor.stub).p == 10
						| markupE.get(train.locomotor.stub).p == 11
						| markupE.get(train.locomotor.stub).p == 21)) {
					train.locomotor.positionJ = trainE.size();
					Collection<Wagon> valueE = train.wagonE.values();
					Iterator<Wagon> iterator = valueE.iterator();
					while (iterator.hasNext()) {
						Wagon v = iterator.next();
						v.positionJ = trainE.size();
					}
					zQ++;
					include = new File(includeY + train.locomotor.stub
							+ "_" + train.locomotor.substance + ".eli");
					if (include.exists()) {
						List<String> includeZ = ReadMyFile.zebra_A(
								include.getPath());
						zebra.addAll(rigaJ + 1, includeZ);
						posizioneVisiva -= includeZ.size();
					} else {
						ne.datum = "The file " + Mix.dress_A(include
								.getName()) + " does not exist.";
						ne.code = 1724;
						ne.n = rigaJ;
						ne.className = this.getClass().getName();
						throw ne;
					}
					/* only if he's not follower ... */
				} else if (!train.locomotor.follower) {
					train.locomotor.positionJ = trainE.size();
					Collection<Wagon> valueE = train.wagonE.values();
					Iterator<Wagon> iterator = valueE.iterator();
					while (iterator.hasNext()) {
						Wagon v = iterator.next();
						v.positionJ = trainE.size();
					}
					zQ++;
				}
			}
		} catch (FileNotFoundException e) {
			ne.code = 1726;
			ne.datum = "The file " + include.getPath()
					+ " does not exist.";
			ne.className = this.getClass().getName();
			throw ne;
		} catch (IOException e) {
			ne.code = 1727;
			ne.datum = "Error in acceding file «" + include.getPath()
					+ "».";
			ne.className = this.getClass().getName();
			throw ne;
		}
	}

	private void fileModelPositions() {

		if (skill.hibernate) {
			skill.hibernateVersion = markupE.get("hv").recurrenceE.get(
					0).locomotor.text;
			String depenHiberF = "hv_" + skill.hibernateVersion
					+ ".txt";
			skill.depenHiberG = candies.snippetsYS + depenHiberF;
		}
		if (skill.jackson) {
			String depenJacksonF = "depen_jackson.txt";
			skill.depenJacksonG = candies.snippetsYS + depenJacksonF;
		}
		if (skill.hiberValid) {
			String depenHValidF = "depen_hvalid.txt";
			skill.depenHValidG = candies.snippetsYS + depenHValidF;
		}
		if (skill.springValid) {
			String depenValidatorF = "depen_validator.txt";
			skill.depenValidatorG = candies.snippetsYS
					+ depenValidatorF;
		}
	}

	private void securityWrite()

			throws FileNotFoundException, ExactException, IOException {

		FileComponent.addClass("LoggedUser.java", newAnnotation,
				"LoggedUser.java", candies, recycleBinY, skill, -1,
				markupE, "java");
		FileComponent.addClass("LoggedUserMethodArgumentResolver.java",
				newResolver, "LoggedUserMethodArgumentResolver.java",
				candies, recycleBinY, skill, -1, markupE, "java");
		FileComponent.addClass("Belonger.java", securityY,
				"Belonger.java", candies, recycleBinY, skill, -1,
				markupE, "java");
		if (skill.authenticationProvider.equals("class")
				&& skill.authenticationMode != null
				&& !skill.authenticationMode.endsWith("trivial")) {
			userAuthenticationProvider_java.synthesis(markupE, trainE,
					candies);
			userAuthenticationProvider_java.write(brickAuthenticationY,
					Mix.uppercaseFirstChar(skill.applicationNameLower)
							+ "UserAuthenticationProvider.java",
					"ApplicUserAuthenticationProvider.java", "java",
					candies, recycleBinY);
		}
		FileComponent.addFile("error_jsp.txt", "error.jsp", new723,
				candies, recycleBinY, skill);
		if (skill.hasUseridPassword) {
			FileComponent.addFile("login_jsp.txt", "login.jsp", new722,
					candies, recycleBinY, skill);
			if (skill.authenticationMode.equals("trivial")) {
				king.write(domainY, "King.java", "King.java", "java",
						candies, recycleBinY);
				kingDao.write(brickAuthenticationY, "KingDao.java",
						"KingDao.java", "java", candies, recycleBinY);
				kingDaoImpl.write(brickAuthenticationY,
						"KingDaoImpl.java", "KingDaoImpl.java", "java",
						candies, recycleBinY);
			} else {
				userAuthorityUtils.write(brickAuthenticationAuthorityY,
						"UserAuthorityUtils.java",
						"UserAuthorityUtils.java", "java", candies,
						recycleBinY);
				springSecurityUserContext.write(brickAuthenticationY,
						"springSecurityUserContext.java",
						"springSecurityUserContext.java", "java",
						candies, recycleBinY);
			}
			interfacciaUserContext.write(brickAuthenticationY,
					"UserContext.java", "UserContext.java", "java",
					candies, recycleBinY);
			userContextImpl.write(brickAuthenticationY,
					"UserContextStub.java", "UserContextImpl.java",
					"java", candies, recycleBinY);
		}
		if (skill.hasUseridPassword) {
			if (!new File(brickAuthenticationY).exists()) {
				ExactException ne = new ExactException(
						"You declared the \"userpass\" markup, but"
								+ " you did not declare an authentication "
								+ "provider with the \"xprovider\" markups,"
								+ " or you declared \"ldap\".");
				ne.code = 1725;
				ne.datum = ne.getMessage();
				ne.className = this.getClass().getName();
				throw ne;
			}
			if (skill.tableDBE.size() == 0 & !skill.authenticationMode
					.equals("trivial")) {
				ExactException ne = new ExactException(
						"You have declared the \"userpass\" markup,"
								+ " but you have not declared any group"
								+ " of tables using the \"hdefrail\" markup.");
				ne.code = 1729;
				ne.datum = ne.getMessage();
				ne.className = this.getClass().getName();
				throw ne;
			} else if (skill.tableDBE.size() > 0 & markupE.get(
					"utabuser").recurrenceE.size() > 0) {
				int j = 0;
				for (; j < skill.tableDBE.size(); j++) {
					if (skill.tableDBE.get(j).dbSchema.equalsIgnoreCase(
							skill.tabUser[3]) & skill.tableDBE.get(
									j).railLowercase.equalsIgnoreCase(
											Cst.RAIL + skill.tabUser[1])
							& skill.tableDBE.get(j).entityName
									.equalsIgnoreCase(
											skill.tabUser[0])) {
						break;
					}
				}
				if (j == skill.tableDBE.size()) {
					ExactException ne = new ExactException(
							"The \"utabuser\" markup value indicates a non-existent table name: «"
									+ skill.tabUser[0]
									+ "», or a non-existent code «rail» : «"
									+ skill.tabUser[1]
									+ "», or a non-existent DB schema: «"
									+ skill.tabUser[2] + "»");
					ne.code = 1702;
					ne.datum = ne.getMessage();
					ne.className = this.getClass().getName();
					throw ne;
				} else {
					skill.tabUserJ = j;
				}
			}
		}
		if (skill.authenticationMode == null) {
			/* do nothing */
		} else if (skill.authenticationMode.equals("domain")) {
			FileComponent.deleteComponent(brickAuthenticationY,
					"SimpleUsernamePasswordAuthenticationToken.java",
					recycleBinY, skill);
			FileComponent.deleteComponent(brickAuthenticationY,
					"SimpleUsernamePasswordAuthenticationFilter.java",
					recycleBinY, skill);
			FileComponent.addClass(
					"DomainUsernamePasswordAuthenticationFilter.java",
					brickAuthenticationY,
					"DomainUsernamePasswordAuthenticationFilter.java",
					candies, recycleBinY, skill, -1, markupE, "java");
			/* for the token class, the index of the users table must be
			 * provided */
			FileComponent.addClass(
					"DomainUsernamePasswordAuthenticationToken.java",
					brickAuthenticationY,
					"DomainUsernamePasswordAuthenticationToken.java",
					candies, recycleBinY, skill, skill.tabUserJ,
					markupE, "java");
		} else if (skill.authenticationMode.equals("simple")) {
			FileComponent.deleteComponent(brickAuthenticationY,
					"DomainUsernamePasswordAuthenticationToken.java",
					recycleBinY, skill);
			FileComponent.deleteComponent(brickAuthenticationY,
					"DomainUsernamePasswordAuthenticationFilter.java",
					recycleBinY, skill);
			FileComponent.addClass(
					"SimpleUsernamePasswordAuthenticationFilter.java",
					brickAuthenticationY,
					"SimpleUsernamePasswordAuthenticationFilter.java",
					candies, recycleBinY, skill, -1, markupE, "java");
			/* for the token class, the index of the users table must be
			 * provided */
			FileComponent.addClass(
					"SimpleUsernamePasswordAuthenticationToken.java",
					brickAuthenticationY,
					"SimpleUsernamePasswordAuthenticationToken.java",
					candies, recycleBinY, skill, skill.tabUserJ,
					markupE, "java");
		}
	}

	private void securityClean() {
		File dest = new File(recycleBinY + "/LoggedUser.java");
		dest.delete();
		new File(newAnnotation + "/LoggedUser.java").renameTo(dest);
		dest = new File(recycleBinY + "/Belonger.java");
		dest.delete();
		new File(securityY + "/Belonger.java").renameTo(dest);
		dest = new File(recycleBinY
				+ "/LoggedUserMethodArgumentResolver.java");
		dest.delete();
		new File(newResolver + "/LoggedUserMethodArgumentResolver.java")
				.renameTo(dest);
	}
}
