/// <summary>
		/// Item1 = name. Item2 = directory.
		/// </summary>
		/// <param name="templateID"></param>
		/// <returns></returns>
		public static Tuple<string, string> GetTemplateById(string templateID)
		{
			string strFileName          = string.Empty;
			string strFolderName        = string.Empty;
			List<Template> retList      = new List<Template>();
			DirectoryInfo directoryInfo = new DirectoryInfo(
				Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Program.Model.Settings.TemplateDirectory));

			if (directoryInfo.Exists)
			{
				try
				{
					var serializer = new XmlSerializer(typeof(Template));

					var files = directoryInfo.GetFiles("*.xml");

					foreach (FileInfo file in files)
					{
						try
						{
							var doc = new XmlDocument();
							doc.Load(file.FullName);

							if (AppVersionHelper.IsNotDebug())
							{
								var cryptoProcessor = new CryptoProcessor(
									Program.Model.Settings.SystemSettings.PublicKeyXmlSign,
									Program.Model.Settings.SystemSettings.PrivateKeyXmlDecrypt);

								cryptoProcessor.DecryptXmlDocument(doc);
							}

							//
							// #248 - fix memory leaks during XML files processing
							//
							// var nodeReader = new XmlNodeReader(doc);
							using (var nodeReader = new XmlNodeReader(doc))
							{
								using (var xmlReader = XmlReader.Create(nodeReader, XmlUtils.GetXmlReaderSettings()))
								{
									var template = (Template)serializer.Deserialize(xmlReader);

									if (templateID == template.Id)
									{
										strFileName   = file.Name;
										strFolderName = file.DirectoryName;
									}
								}
							}
						}
						catch (Exception ex)
						{
							log.Error(ex);

							if (file != null)
							{
								log.ErrorFormat("File:'{0}'", file);
							}

							log.ErrorFormat("Folder:'{0}'", directoryInfo);
						}
					}
				}
				catch (Exception ex)
				{
					log.Error(ex);
					log.ErrorFormat("Folder:'{0}'", directoryInfo);
				}
			}
			else
			{
				log.Error("Folder with models is not exists");
				log.ErrorFormat("Folder:'{0}'", directoryInfo);
			}

			return new Tuple<string, string>(strFileName, strFolderName);
		}
		/// <summary>
		/// Load queries from Xml-file
		/// </summary>
		/// <param name="fileName">Xml-file name</param>
		/// <param name="cryptoProcessor">Encoder</param>
		/// <param name="isExternal">Is opened from user file template</param>
		/// <returns>List of queries</returns>
		public static List<QueryInfo> LoadFromXml(string fileName, CryptoProcessor cryptoProcessor, bool isExternal)
		{
			if (AppVersionHelper.IsDebug() || isExternal)
			{
				if (cryptoProcessor == null)
				{
					return LoadFromXml(fileName);
				}
			}

			try
			{
				XmlDocument doc = new XmlDocument();
				doc.PreserveWhitespace = true;
				doc.Load(fileName);

				if (AppVersionHelper.IsRelease() || (AppVersionHelper.IsNotRelease() && cryptoProcessor != null))
				{
					cryptoProcessor.DecryptXmlDocument(doc);
				}

				byte[] bytes = Encoding.UTF8.GetBytes(doc.OuterXml);

				XmlSerializer s = new XmlSerializer(typeof (LoaderRootWrapper));

				using (var includingReader = new MemoryStream(bytes))
				{
					using (var xmlReader = XmlReader.Create(includingReader, XmlUtils.GetXmlReaderSettings()))
					{
						return GetQueries(((LoaderRootWrapper) s.Deserialize(xmlReader)));
					}
				}
			}
			catch (Exception exception)
			{
				log.Error(exception);

				if (AppVersionHelper.IsDebug() || isExternal)
				{
					return LoadFromXml(fileName);
				}

				throw;
			}
		}
		/// <summary>
		/// Save queries to encoded file
		/// </summary>
		/// <param name="fileName">Xml-file name</param>
		/// <param name="queries">Collection of queries</param>
		/// <param name="cryptoProcessor">Encoder</param>
		public static void SaveToXml(string fileName, List<QueryInfo> queries, CryptoProcessor cryptoProcessor)
		{
			XmlDocument doc = new XmlDocument();

			SaveToXml(fileName, queries);

			doc.PreserveWhitespace = true;

			doc.Load(fileName);

			cryptoProcessor.EncryptXmlDocument(doc);

			doc.Save(fileName);
		}
		private void processQueryFilesInner(
			Dictionary<String, List<String>> queriesInQueryFiles,
			string                           srcFolder,
			CryptoProcessor                  cryptoProcessor
		)
		{
			var systemSettings = SystemSettingsInfo.LoadFrom(Settings.SystemSettingsFile);

			foreach (var pair in queriesInQueryFiles)
			{
				try
				{
					var srcFileName = Path.Combine(srcFolder, pair.Key);

					this._logger.WriteToLog("Start file processing: {0}", srcFileName);

					if (File.Exists(srcFileName))
					{
						List<QueryInfo> queries = QueriesLoader.LoadFromXml(srcFileName);

						foreach (string qName in pair.Value)
						{
							if (queries.All(c => c.Name != qName))
							{
								this._logger.WriteToLog(string.Format(GetText("QueriyNotFoundInFile"), qName, pair.Key));
							}
						}

						string dstQueriesFileName = GetDstFileName(pair.Key, true, subDir: systemSettings.TemplateDirectory);

						processQueryFile(srcFileName, dstQueriesFileName, cryptoProcessor);
					}
					else
					{
						this._logger.WriteToLog("QueryFile was not found: {0}", srcFileName);
					}

					this._logger.WriteToLog("File has been processed: {0}", srcFileName);
				}
				catch (Exception e)
				{
					this._logger.WriteToLog("ERROR: Some files has not been processed: {0}", srcFolder);
					this._logger.WriteToLog("ERROR: Query processing error: {0}", e.Message);
				}
			}

			this._logger.WriteToLog("Query processing has been completed.");
		}
		/// <summary>
		/// The sign query item.
		/// </summary>
		/// <param name="cryptoProcessor">The crypto processor.</param>
		/// <param name="itemInfo">The item info.</param>
		/// <param name="query">The query.</param>
		private void SignQueryItem(CryptoProcessor cryptoProcessor, QueryItemInfo itemInfo, QueryInfo query)
		{
			this._logger.WriteToLog("prepare to sign the query....");

			itemInfo.ParentQuery = query;
			new QueryPreparator(this.Settings, this._logger).PrepareIfNeeds(itemInfo);

			this._logger.WriteToLog("Sign query....");

			itemInfo.Signature = cryptoProcessor.Sign(itemInfo.Text);
		}
		/// <summary>
		/// Load queries with signature check
		/// </summary>
		/// <param name="filename">Xml-file name</param>
		/// <param name="isExternal">Is opened from user file template</param>
		/// <returns>Queries list</returns>
		public List<QueryInfo> LoadQueries(string filename, bool isExternal)
		{
			log.InfoFormat("filename:'{0}',isExternal:'{1}'",
				filename ?? "<null>",
				isExternal
			);

			List<string> wrongQueries = new List<string>();
			CryptoProcessor cryptoProcessor = null;

			try
			{
				if (AppVersionHelper.IsNotDebug())
				{
					cryptoProcessor = new CryptoProcessor(
						Settings.SystemSettings.PublicKeyXmlSign,
						Settings.SystemSettings.PrivateKeyXmlDecrypt
					);
				}
			}
			catch (System.Security.XmlSyntaxException ex)
			{
				log.Error(ex);
			}
			catch (Exception ex)
			{
				log.Error(ex);
				log.Error(ex.GetBaseException());
			}

			List<QueryInfo> queries = QueriesLoader.LoadFromXml(filename, cryptoProcessor, isExternal);

			for (int i = queries.Count - 1; i >= 0; i--)
			{
				QueryInfo query = queries[i];

				log.InfoFormat("query:'{0}'", query);

				if (AppVersionHelper.IsNotDebug() && !isExternal)
				{
					for (int j = query.DatabaseSelect.Count - 1; j >= 0; j--)
					{
						QueryItemInfo queryItem = query.DatabaseSelect[j];

						if (cryptoProcessor != null && !cryptoProcessor.Verify(queryItem.Text, queryItem.Signature))
						{
							if (!wrongQueries.Contains(query.Name))
							{
								wrongQueries.Add(query.Name);
							}

							query.DatabaseSelect.RemoveAt(j);
						}
					}

					for (int j = query.Items.Count - 1; j >= 0; j--)
					{
						QueryItemInfo queryItem = query.Items[j];

						log.InfoFormat("queryItem.Text:'{0}'", queryItem.Text);

						if (cryptoProcessor != null && !cryptoProcessor.Verify(queryItem.Text, queryItem.Signature))
						{
							if (!wrongQueries.Contains(query.Name))
							{
								wrongQueries.Add(query.Name);
							}

							query.Items.RemoveAt(j);
						}
					}
				}

				if (query.Items.Count == 0)
				{
					queries.RemoveAt(i);
				}
			}

			if ((Settings.WarnAboutUnsignedQuery) && (wrongQueries.Count > 0))
			{
				StringBuilder sb = new StringBuilder();

				sb.Append(filename + Environment.NewLine + Environment.NewLine);

				foreach (string wrongQuery in wrongQueries)
				{
					sb.Append(wrongQuery + Environment.NewLine);
				}

				MessageBox.Show(sb.ToString(), LocaleManager.GetLocalizedText(LocaleManager.Exceptions, "wrongQueriesSignatures"));
			}

			return queries;
		}
		//private void ProcessQueryFilesRootAnnotation(Dictionary<String, List<String>> queriesInQueryFiles, string srcFolder,
		//                               CryptoProcessor cryptoProcessor)
		//{
		//    this._logger.WriteToLog("Обработка запросов Root Annotation");
		//    processQueryFilesInner(queriesInQueryFiles, srcFolder, cryptoProcessor);
		//    this._logger.WriteToLog("Обработка запросов Root Annotation");
		//}

		/// <summary>
		/// Processes query file
		/// </summary>
		/// <param name="srcFileName">The source query file</param>
		/// <param name="dstFileName">The destination query file</param>
		/// <param name="cryptoProcessor">The crypto processor</param>
		private void processQueryFile(string srcFileName, string dstFileName, CryptoProcessor cryptoProcessor)
		{
			this._logger.WriteToLog(
				"Start file processing: '{0}' -> '{1}'",
				srcFileName,
				dstFileName
			);

			if (File.Exists(srcFileName))
			{
				try
				{
					List<QueryInfo> queries = QueriesLoader.LoadFromXml(srcFileName);

					foreach (QueryInfo query in queries)
					{
						this._logger.WriteToLog(
							"Query processing:{0}-{1}-{2}",
							query.Id,
							query.Source,
							query.Name
						);

						foreach (var itemInfo in query.DatabaseSelect)
						{
							this._logger.WriteToLog("Обработка запроса на выборку БД({0}-{1})", itemInfo.MinVersion, itemInfo.MaxVersion);
							this.SignQueryItem(cryptoProcessor, itemInfo, query);
						}

						foreach (var itemInfo in query.GroupSelect)
						{
							this._logger.WriteToLog("Обработка запроса на выборку групп({0}-{1})", itemInfo.MinVersion, itemInfo.MaxVersion);
							this.SignQueryItem(cryptoProcessor, itemInfo, query);
						}

						foreach (var itemInfo in query.Items)
						{
							this._logger.WriteToLog("Обработка запроса на выборку данных ({0}-{1})", itemInfo.MinVersion, itemInfo.MaxVersion);
							this.SignQueryItem(cryptoProcessor, itemInfo, query);
						}

						this._logger.WriteToLog(
							"Query has been processed:{0}-{1}-{2}",
							query.Id,
							query.Source,
							query.Name
						);
					}

					SureDirForFileExists(dstFileName);

					QueriesLoader.SaveToXml(dstFileName, queries, cryptoProcessor);

					this._logger.WriteToLog(
						"File has been SUCESSFULLY processed: {0} -> {1}",
						srcFileName,
						dstFileName
					);
				}
				catch (Exception e)
				{
					this._logger.WriteToLog("ERROR: File has not been processed: {0}", srcFileName);
					this._logger.WriteToLog("ERROR: Query processing error: {0}", e.Message);
					this._logger.WriteToLog("ERROR: File has NOT been processed: {0} -> {1}", srcFileName, dstFileName);
				}
			}
			else
			{
				this._logger.WriteToLog("QueryFile is not found: {0}", srcFileName);
			}
		}
		/// <summary>
		/// Processes the XSL template files.
		/// </summary>

		/// <summary>
		/// Processes the XSL template files.
		/// </summary>
		/// <param name="srcFolder">The SRC folder.</param>
		/// <param name="cryptoProcessor">The crypto processor.</param>
		private void ProcessPostBuildDbTemplateFiles(string srcFolder, CryptoProcessor cryptoProcessor)
		{
			string srcFileName    = String.Empty;
			string dstFileName    = String.Empty;
			var    systemSettings = SystemSettingsInfo.LoadFrom(Settings.SystemSettingsFile);

			this._logger.WriteToLog(
				"{Begin: processing system SQL scripts...."
			);

			//
			// PostBuildCurrentDb
			// processing SQL scripts for current SQLite database
			//
			this._logger.WriteToLog(
				"systemSettings.PostBuildCurrentDb:'{0}'",
				systemSettings.PostBuildCurrentDb
			);

			srcFileName = Path.Combine(
				srcFolder,
				String.Empty,
				String.Empty,
				systemSettings.PostBuildCurrentDb
			);

			this._logger.WriteToLog(
				"srcFileName:'{0}'",
				srcFileName
			);

			dstFileName = Path.Combine(
				this._settings.DstFolderFull,
				String.Empty,
				String.Empty,
				systemSettings.PostBuildCurrentDb
			);

			this._logger.WriteToLog(
				"dstFileName:'{0}'",
				dstFileName
			);

			processQueryFile(
				srcFileName,
				dstFileName,
				cryptoProcessor
			);

			//
			// PostBuildHistoricDbs
			// processing SQL scripts for all SQLite historical databases
			//
			foreach (var postBuildHistoricDb in systemSettings.PostBuildSQLiteDbs)
			{
				this._logger.WriteToLog(
					"systemSettings.PostBuildHistoricDb:Script'{0}';Alias:{1};Filename:{2}",
					postBuildHistoricDb.PostBuildScript,
					postBuildHistoricDb.Alias,
					postBuildHistoricDb.FileName
				);

				srcFileName = Path.Combine(
					srcFolder,
					String.Empty,
					String.Empty,
					postBuildHistoricDb.PostBuildScript
				);

				this._logger.WriteToLog(
					"srcFileName:'{0}'",
					srcFileName
				);

				dstFileName = Path.Combine(
					this._settings.DstFolderFull,
					String.Empty,
					String.Empty,
					postBuildHistoricDb.PostBuildScript
				);

				this._logger.WriteToLog(
					"dstFileName:'{0}'",
					dstFileName
				);

				processQueryFile(
					srcFileName,
					dstFileName,
					cryptoProcessor
				);
			}

			this._logger.WriteToLog("}End: processing system SQL scripts");
		}
		/// <param name="xslTemplateFileNames">The XSL templates.</param>
		/// <param name="srcFolder">The SRC folder.</param>
		/// <param name="cryptoProcessor">The crypto processor.</param>
		private void ProcessXslTemplateFiles(IEnumerable<string> xslTemplateFileNames, string srcFolder, CryptoProcessor cryptoProcessor)
		{
			var languageFolders = GetReportLanguages().ToArray();
			var systemSettings = SystemSettingsInfo.LoadFrom(Settings.SystemSettingsFile);

			this._logger.WriteToLog(
				"start modules processing...."
			);

			foreach (var fileName in xslTemplateFileNames)
			{
				try
				{
					this._logger.WriteToLog(
						"Start module file name processing. File:'{0}'",
						fileName
					);

					foreach (var localeFolder in languageFolders)
					{
						var srcFileName = Path.Combine(
							srcFolder,
							"Templates",
							localeFolder,
							fileName
						);

						if (!File.Exists(srcFileName))
						{
							this._logger.WriteToLog(
								"ERROR: Module not found. File name: '{0}'",
								srcFileName
							);

							continue;
						}

						string dstFileName = Path.Combine(
							this._settings.DstFolderFull
							+ @"\"
							+ systemSettings.TemplateDirectory
							+ @"\",
							"Templates",
							localeFolder,
							fileName
						);

						this.SureCopy(srcFileName, dstFileName);

						new XSLPreparator(new KeyValuePair<string, string>(dstFileName, localeFolder), this._logger)
							.Prepare(this._settings.AdditionalTemplates);

						if (AppVersionHelper.IsNotDebug())
						{
							var doc = new XmlDocument();

							doc.Load(dstFileName);

							this._logger.WriteToLog(
								"EncryptXmlDocument: file name: '{0}'",
								dstFileName
							);

							cryptoProcessor.EncryptXmlDocument(doc);

							doc.Save(dstFileName);
						}
					}
				}
				catch (Exception e)
				{
					this._logger.WriteToLog(
						"ERROR: Module has not been processed. File:'{0}';Error:'{1}'",
						fileName,
						e.Message
					);
				}
			}

			this._logger.WriteToLog(
				"Modules processing is completed."
			);
		}
		public void ExecuteSign()
		{
			var srcFolder = this._settings.SrcFolder;

			var systemSettings = SystemSettingsInfo.LoadFrom(Settings.SystemSettingsFile);

			if (!Directory.Exists(this._settings.DstFolderFull))
			{
				Directory.CreateDirectory(this._settings.DstFolderFull);
			}

			//var connections = ConnectionsLoader.LoadFromXml(_settings.ConnectionsFileName);
			var cryptoProcessor = new CryptoProcessor(this._settings.PrivateKeySign, this._settings.PrivateKeyDecrypt);

			//SignLicenses(connections, cryptoProcessor);

			//string dstConnectionsFileName = GetDstFileName(_settings.ConnectionsFileName);
			//ConnectionsLoader.SaveToXml(dstConnectionsFileName, connections);

			// process ini files for SQLite databases
			ProcessPostBuildDbTemplateFiles(srcFolder, cryptoProcessor);

			List<string>                     xslTemplates;
			Dictionary<String, List<String>> queriesInQueryFiles;

			//var treeNodeTemplateFileNames = connections.Select(cnn => cnn.TemplateFileName).Distinct().ToList();

			ProcessTreeNodeTemplateFiles(this._settings.TemplateFiles, out xslTemplates, out queriesInQueryFiles, cryptoProcessor);

			ProcessXslTemplateFiles(xslTemplates, srcFolder+@"\"+systemSettings.TemplateDirectory+@"\", cryptoProcessor);

			ProcessQueryFiles(queriesInQueryFiles, srcFolder + @"\" + systemSettings.TemplateDirectory + @"\", cryptoProcessor);
			//ProcessQueryFilesRootAnnotation(queriesInRootAnnotationQueryFiles, srcFolder, cryptoProcessor);
		}
		private void ProcessTreeNodeTemplateFiles(
			IEnumerable<string>                  treeNodeTemplateFileNames,
			out List<string>                     xslTemplateFiles,
			out Dictionary<string, List<string>> queriesInQueryFiles,
			CryptoProcessor                      cryptoProcessor
		)
		{
			xslTemplateFiles = new List<string>();
			queriesInQueryFiles = new Dictionary<string, List<string>>();
			var systemSettings = SystemSettingsInfo.LoadFrom(Settings.SystemSettingsFile);

			foreach (string templateFileName in treeNodeTemplateFileNames)
			{
				string fullTemplateFileName = Path.GetFullPath(templateFileName);

				if (File.Exists(fullTemplateFileName))
				{
					string dstTemplateFileName = Path.Combine(
						this._settings.DstFolderFull
						+ @"\"
						+ systemSettings.TemplateDirectory
						+ @"\",
						Path.GetFileName(templateFileName)
					);

					this.SureCopy(fullTemplateFileName, dstTemplateFileName);

					XmlDocument doc = new XmlDocument();

					doc.Load(dstTemplateFileName);

					string        startupTemplateId          = null;
					Stack<string> startupTemplateInfoIdStack = null;
					var           rootNode                   = TemplateNodesLoader.LoadFromXml(null, doc, out startupTemplateId, out startupTemplateInfoIdStack);
					var           allNodesInTemplate         = ToPlainList(rootNode);

					foreach (TemplateNodeInfo node in allNodesInTemplate)
					{
						//foreach (TemplateNodeLocaleInfo locale in
						//        node.Locales.Where(l => !string.IsNullOrEmpty(l.TemplateFile)))
						//{
						//    if (!xslTemplates.ContainsKey(locale.TemplateFile))
						//    {
						//        xslTemplates.Add(locale.TemplateFile, locale.Language);
						//    }
						//}

						if (!string.IsNullOrWhiteSpace(node.XslTemplateFileName) && !xslTemplateFiles.Contains(node.XslTemplateFileName))
						{
							xslTemplateFiles.Add(node.XslTemplateFileName);
						}

						var allQueries = node.Queries.Union(node.GroupQueries);

						foreach (TemplateNodeQueryInfo query in allQueries)
						{
							if (!queriesInQueryFiles.ContainsKey(query.QueryFileName))
							{
								queriesInQueryFiles.Add(query.QueryFileName, new List<string>());
							}

							if (!queriesInQueryFiles[query.QueryFileName].Contains(query.QueryName))
							{
								queriesInQueryFiles[query.QueryFileName].Add(query.QueryName);
							}
						}

						foreach (TemplateNodeQueryInfo query in node.ConnectionQueries)
						{
							if (!queriesInQueryFiles.ContainsKey(query.QueryFileName))
							{
								queriesInQueryFiles.Add(query.QueryFileName, new List<string>());
							}

							if (!queriesInQueryFiles[query.QueryFileName].Contains(query.QueryName))
							{
								queriesInQueryFiles[query.QueryFileName].Add(query.QueryName);
							}
						}
					}

					if (AppVersionHelper.IsNotDebug())
					{
						cryptoProcessor.EncryptXmlDocument(doc);

						doc.Save(dstTemplateFileName);
					}
				}
				else
				{
					this._logger.WriteToLog(this.GetText("TemplateTreeFileNotFound") + templateFileName);
				}
			}
		}
		private void SignLicenses(IEnumerable<ConnectionGroupInfo> connections, CryptoProcessor cp)
		{
			foreach (ConnectionGroupInfo connection in connections)
			{
				foreach (InstanceInfo instance in connection.Connections)
				{
					if (instance.LicenseInfo == null)
					{
						this._logger.WriteToLog(GetText("NoLicenseDataForInstance") + instance.Instance);
					}
					else
					{
						instance.LicenseInfo.Signature = cp.Sign(instance.GetHash());
					}
				}
			}
		}
		public void SignLicense(string inFile, string outFile)
		{
			var connections     = ConnectionsLoader.LoadFromXml(inFile);
			var cryptoProcessor = new CryptoProcessor(this._settings.PrivateKeySign, this._settings.PrivateKeyDecrypt);

			SignLicenses(connections, cryptoProcessor);

			ConnectionsLoader.SaveToXml(outFile, connections);
		}
		/// <summary>
		/// The validate license.
		/// </summary>
		/// <param name="fullSlowCheck">The full slow check.</param>
		/// <returns>
		/// The <see cref="LicenseState" />.
		/// </returns>
		public LicenseState ValidateLicense(bool fullSlowCheck, bool withCheckConnection = true)
		{
			if (this._foundLicenseState != null)
			{
				return this._foundLicenseState;
			}

			this._foundLicenseState = new LicenseState
			{
				Instance = this.Instance
			};

			if (this.LicenseInfo == null)
			{
				if (AppVersionHelper.IsNotRelease())
				{
					return this._foundLicenseState;
				}

				this._foundLicenseState.AddProblem(LicenseProblemType.LicenseNotDefined, string.Empty);
			}
			else
			{
				this._foundLicenseState.AddProblems(this.LicenseInfo.IsLicenseInfoCorrect());

				DateTime dateTime;

				if (fullSlowCheck && withCheckConnection)
				{
					if (this._serverProperties != null)
					{
						dateTime = this._serverProperties.Date;
					}
					else
					{
						try
						{
							ServerProperties props = ServerProperties.Query(this);

							dateTime = props.Date;

							this._serverProperties = props;
						}
						catch (Exception exc)
						{
							log.Error("Exception:", exc);

							log.ErrorFormat(
								"Instance:'{0}';Authentication:'{1}';Exception:'{2}'",
								Instance,
								Authentication,
								exc
							);

							dateTime = DateTime.MaxValue;
						}
					}
				}
				else
				{
					dateTime = DateTime.Now;
				}

				var buildDateObject =
					Assembly.GetExecutingAssembly()
						.GetCustomAttributes(typeof (BuildDateAttribute), false)
						.FirstOrDefault();

				DateTime buildDate = DateTime.MaxValue;

				if (buildDateObject is BuildDateAttribute)
				{
					buildDate = (buildDateObject as BuildDateAttribute).BuildDate;
				}

				if (dateTime == DateTime.MaxValue)
				{
					this._foundLicenseState.AddProblem(LicenseProblemType.CantConnect, string.Empty);
				}
				else if (this._foundLicenseState.IsCorrect && fullSlowCheck && (dateTime > this.LicenseInfo.ExpiryDate))
				{
					this._foundLicenseState.AddProblem(LicenseProblemType.Expired, string.Empty);
				}
				else if (buildDate > this.LicenseInfo.BuildExpiryDate)
				{
					this._foundLicenseState.AddProblem(LicenseProblemType.BuildExpiryDateNotValid, string.Empty);
				}
				else
				{
					if (AppVersionHelper.IsNotDebug())
					{
						string hash = this.GetHash();

						CryptoProcessor cryptoProcessor =
							new CryptoProcessor(
								Program.Model.Settings.SystemSettings.PublicKeyXmlSign,
								Program.Model.Settings.SystemSettings.PrivateKeyXmlDecrypt
							);

						if (!cryptoProcessor.Verify(hash, this.LicenseInfo.Signature))
						{
							this._foundLicenseState.AddProblem(LicenseProblemType.WrongSignature, string.Empty);
						}
					}
				}
			}

			var result = this._foundLicenseState;

			if (!fullSlowCheck)
			{
				this._foundLicenseState = null;
			}

			return result;
		}
		public static Template GetTemplateByFile(string strFileName)
		{
			try
			{
				XmlDocument doc = new XmlDocument();
				doc.Load(strFileName);

				Template retTemplate;

				if (AppVersionHelper.IsNotDebug())
				{
					var cryptoProcessor = new CryptoProcessor(
						Program.Model.Settings.SystemSettings.PublicKeyXmlSign,
						Program.Model.Settings.SystemSettings.PrivateKeyXmlDecrypt);

					cryptoProcessor.DecryptXmlDocument(doc);
				}

				using (var nodeReader = new XmlNodeReader(doc))
				{
					XmlSerializer serializer = new XmlSerializer(typeof(Template));

					using (var xmlReader = XmlReader.Create(nodeReader, XmlUtils.GetXmlReaderSettings()))
					{
						retTemplate = (Template)serializer.Deserialize(xmlReader);
					}
				}

				return retTemplate;
			}
			catch (Exception ex)
			{
				log.Error(ex);
			}

			return null;
		}
		private void ProcessQueryFiles(
			Dictionary<String, List<String>> queriesInQueryFiles,
			string                           srcFolder,
			CryptoProcessor                  cryptoProcessor
		)
		{
			this._logger.WriteToLog(
				"Start queries processing..."
			);

			processQueryFilesInner(queriesInQueryFiles, srcFolder, cryptoProcessor);

			this._logger.WriteToLog(
				"Queries processing is completed."
			);
		}
		public VisualizeData GetVisualizeData(
			NodeDataProvider dataProvider,
			GraphicsInfo     graphicsInfo
		)
		{
			XmlDocument          xmlData       = dataProvider.XmlDocument;
			MultyQueryResultInfo queriesResult = dataProvider.QueryResult;

			VisualizeData result = new VisualizeData
			{
				NodeLastUpdated        = queriesResult.NodeLastUpdated,
				NodeLastUpdateDuration = queriesResult.NodeLastUpdateDuration
			};

			if (xmlData != null && xmlData.DocumentElement != null)
			{
				result.SourceXml = xmlData.FormatXml();
			}

			ConcreteTemplateNodeDefinition nodeDefinition = dataProvider.NodeDefinition;

			string xslFileName = GetXslFileName(nodeDefinition);

			if (xslFileName != null && File.Exists(xslFileName))
			{
				XmlDocument xslDoc = new XmlDocument();

				xslDoc.Load(xslFileName);

				ConnectionGroupInfo connectionGroup = nodeDefinition.Connection;

				if (AppVersionHelper.IsNotDebug() && !connectionGroup.IsExternal)
				{
					CryptoProcessor cryptoProcessor = new CryptoProcessor(
						this._model.Settings.SystemSettings.PublicKeyXmlSign,
						this._model.Settings.SystemSettings.PrivateKeyXmlDecrypt
					);

					cryptoProcessor.DecryptXmlDocument(xslDoc);
				}

				try
				{
					XslPreprocessManager preprocessManager = GetManager(
						dataProvider,
						graphicsInfo
					);

					List<PreprocessorAreaData> datas;

					using (preprocessManager.ExecuteXslPreprocessing(xslDoc, out datas))
					{
					}

					foreach (PreprocessorAreaData preprocessorAreaData in datas)
					{
						preprocessorAreaData.CheckPreprocessors();
					}

					result.PreprocessorAreas = datas.ToList();
				}
				catch (Exception ex)
				{
					log.ErrorFormat(
						"nodeDefinition.TemplateNode.Queries(.Name)='{0}';xslFileName='{1}';Exception:'{2}'",
						nodeDefinition.TemplateNode.Queries.Select(q => q.QueryName).Join(", "),
						xslFileName,
						ex
					);
				}
			}

			return result;
		}
		//void ReloadConectionGroupInfos()
		//{
		//    var filenames = _filesProvider.GetConnectionsFilenames();
		//    _connections = new List<ConnectionGroupInfo>();
		//    foreach (var filename in filenames)
		//    {
		//        _connections.AddRange(ConnectionsLoader.LoadFromXml(filename));
		//    }
		//}

		/// <summary>
		/// Load Template
		/// </summary>
		/// <param name="filename">Xml-file name</param>
		/// <param name="connectionGroup"></param>
			/// <param name="isExternal">Is opened from user file template</param>
		/// <returns>Tree template</returns>
		public TemplateNodeInfo LoadTemplateNodes(
			string            filename,
			bool              isExternal,
			out string        startupTemplateId,
			out Stack<string> startupTemplateInfoIdStack
		)
		{
			if (!File.Exists(filename))
			{
				throw new FileNotFoundException("Template needed!");
			}

			var doc = new XmlDocument();

			doc.Load(filename);

			if (AppVersionHelper.IsNotDebug() && !isExternal)
			{
				var cryptoProcessor = new CryptoProcessor(
					this.Settings.SystemSettings.PublicKeyXmlSign,
					this.Settings.SystemSettings.PrivateKeyXmlDecrypt
				);

				cryptoProcessor.DecryptXmlDocument(doc);
			}

			return TemplateNodesLoader.LoadFromXml(this, doc, out startupTemplateId, out startupTemplateInfoIdStack);
		}