diff --git a/.gitignore b/.gitignore
index 9491a2f..ab36761 100644
--- a/.gitignore
+++ b/.gitignore
@@ -360,4 +360,6 @@ MigrationBackup/
.ionide/
# Fody - auto-generated XML schema
-FodyWeavers.xsd
\ No newline at end of file
+FodyWeavers.xsd
+
+!DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/Debug_2/Debug
\ No newline at end of file
diff --git a/Assemblers.Automation/Assemblers.Automation.csproj b/Assemblers.Automation/Assemblers.Automation.csproj
new file mode 100644
index 0000000..040212f
--- /dev/null
+++ b/Assemblers.Automation/Assemblers.Automation.csproj
@@ -0,0 +1,38 @@
+
+
+
+ netstandard2.0
+ Skyline.DataMiner.CICD.Assemblers.Automation
+ Skyline.DataMiner.CICD.Assemblers.Automation
+ True
+ True
+ SkylineCommunications
+ Skyline Communications
+ LICENSE.txt
+ True
+ icon.png
+ https://skyline.be/
+ Skyline;DataMiner;CICD
+ Library providing methods for converting Visual Studio DIS Automation Solutions to individual DataMiner AutomationScript artifacts (e.g. XML, DLLs,...).
+ README.md
+ https://github.com/SkylineCommunications/Skyline.DataMiner.CICD.Packages
+ git
+ 0.0.2-local
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Assemblers.Automation/AutomationScriptBuilder.cs b/Assemblers.Automation/AutomationScriptBuilder.cs
new file mode 100644
index 0000000..3c57687
--- /dev/null
+++ b/Assemblers.Automation/AutomationScriptBuilder.cs
@@ -0,0 +1,725 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Automation
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Reflection;
+ using System.Text.RegularExpressions;
+ using System.Threading.Tasks;
+
+ using NuGet.Packaging.Core;
+ using NuGet.Versioning;
+
+ using Skyline.DataMiner.CICD.Assemblers.Common;
+ using Skyline.DataMiner.CICD.Common.NuGet;
+ using Skyline.DataMiner.CICD.FileSystem;
+ using Skyline.DataMiner.CICD.Loggers;
+ using Skyline.DataMiner.CICD.Parsers.Automation.Xml;
+ using Skyline.DataMiner.CICD.Parsers.Common.VisualStudio.Projects;
+ using Skyline.DataMiner.CICD.Parsers.Common.Xml;
+
+ using EditXml = Skyline.DataMiner.CICD.Parsers.Common.XmlEdit;
+
+ ///
+ /// Automation script builder.
+ ///
+ public class AutomationScriptBuilder
+ {
+ private static readonly Regex RegexProjectPlaceholder = new Regex(@"\[Project:(?.*)\]", RegexOptions.Compiled & RegexOptions.IgnoreCase);
+ private static readonly HashSet NetFramework481ReferenceAssemblies = new HashSet(new[] { "Accessibility.dll", "CustomMarshalers.dll", "ISymWrapper.dll", "Microsoft.Activities.Build.dll", "Microsoft.Build.Conversion.v4.0.dll", "Microsoft.Build.dll", "Microsoft.Build.Engine.dll", "Microsoft.Build.Framework.dll", "Microsoft.Build.Tasks.v4.0.dll", "Microsoft.Build.Utilities.v4.0.dll", "Microsoft.CSharp.dll", "Microsoft.JScript.dll", "Microsoft.VisualBasic.Compatibility.Data.dll", "Microsoft.VisualBasic.Compatibility.dll", "Microsoft.VisualBasic.dll", "Microsoft.VisualC.dll", "Microsoft.VisualC.STLCLR.dll", "Microsoft.Win32.Primitives.dll", "mscorlib.dll", "netstandard.dll", "PresentationBuildTasks.dll", "PresentationCore.dll", "PresentationFramework.Aero.dll", "PresentationFramework.Aero2.dll", "PresentationFramework.AeroLite.dll", "PresentationFramework.Classic.dll", "PresentationFramework.dll", "PresentationFramework.Luna.dll", "PresentationFramework.Royale.dll", "ReachFramework.dll", "sysglobl.dll", "System.Activities.Core.Presentation.dll", "System.Activities.dll", "System.Activities.DurableInstancing.dll", "System.Activities.Presentation.dll", "System.AddIn.Contract.dll", "System.AddIn.dll", "System.AppContext.dll", "System.Collections.Concurrent.dll", "System.Collections.dll", "System.Collections.NonGeneric.dll", "System.Collections.Specialized.dll", "System.ComponentModel.Annotations.dll", "System.ComponentModel.Composition.dll", "System.ComponentModel.Composition.Registration.dll", "System.ComponentModel.DataAnnotations.dll", "System.ComponentModel.dll", "System.ComponentModel.EventBasedAsync.dll", "System.ComponentModel.Primitives.dll", "System.ComponentModel.TypeConverter.dll", "System.Configuration.dll", "System.Configuration.Install.dll", "System.Console.dll", "System.Core.dll", "System.Data.Common.dll", "System.Data.DataSetExtensions.dll", "System.Data.dll", "System.Data.Entity.Design.dll", "System.Data.Entity.dll", "System.Data.Linq.dll", "System.Data.OracleClient.dll", "System.Data.Services.Client.dll", "System.Data.Services.Design.dll", "System.Data.Services.dll", "System.Data.SqlXml.dll", "System.Deployment.dll", "System.Design.dll", "System.Device.dll", "System.Diagnostics.Contracts.dll", "System.Diagnostics.Debug.dll", "System.Diagnostics.FileVersionInfo.dll", "System.Diagnostics.Process.dll", "System.Diagnostics.StackTrace.dll", "System.Diagnostics.TextWriterTraceListener.dll", "System.Diagnostics.Tools.dll", "System.Diagnostics.TraceSource.dll", "System.Diagnostics.Tracing.dll", "System.DirectoryServices.AccountManagement.dll", "System.DirectoryServices.dll", "System.DirectoryServices.Protocols.dll", "System.dll", "System.Drawing.Design.dll", "System.Drawing.dll", "System.Drawing.Primitives.dll", "System.Dynamic.dll", "System.Dynamic.Runtime.dll", "System.EnterpriseServices.dll", "System.EnterpriseServices.Thunk.dll", "System.EnterpriseServices.Wrapper.dll", "System.Globalization.Calendars.dll", "System.Globalization.dll", "System.Globalization.Extensions.dll", "System.IdentityModel.dll", "System.IdentityModel.Selectors.dll", "System.IdentityModel.Services.dll", "System.IO.Compression.dll", "System.IO.Compression.FileSystem.dll", "System.IO.Compression.ZipFile.dll", "System.IO.dll", "System.IO.FileSystem.dll", "System.IO.FileSystem.DriveInfo.dll", "System.IO.FileSystem.Primitives.dll", "System.IO.FileSystem.Watcher.dll", "System.IO.IsolatedStorage.dll", "System.IO.Log.dll", "System.IO.MemoryMappedFiles.dll", "System.IO.Pipes.dll", "System.IO.UnmanagedMemoryStream.dll", "System.Linq.dll", "System.Linq.Expressions.dll", "System.Linq.Parallel.dll", "System.Linq.Queryable.dll", "System.Management.dll", "System.Management.Instrumentation.dll", "System.Messaging.dll", "System.Net.dll", "System.Net.Http.dll", "System.Net.Http.Rtc.dll", "System.Net.Http.WebRequest.dll", "System.Net.NameResolution.dll", "System.Net.NetworkInformation.dll", "System.Net.Ping.dll", "System.Net.Primitives.dll", "System.Net.Requests.dll", "System.Net.Security.dll", "System.Net.Sockets.dll", "System.Net.WebHeaderCollection.dll", "System.Net.WebSockets.Client.dll", "System.Net.WebSockets.dll", "System.Numerics.dll", "System.ObjectModel.dll", "System.Printing.dll", "System.Reflection.Context.dll", "System.Reflection.dll", "System.Reflection.Emit.dll", "System.Reflection.Emit.ILGeneration.dll", "System.Reflection.Emit.Lightweight.dll", "System.Reflection.Extensions.dll", "System.Reflection.Primitives.dll", "System.Resources.Reader.dll", "System.Resources.ResourceManager.dll", "System.Resources.Writer.dll", "System.Runtime.Caching.dll", "System.Runtime.CompilerServices.VisualC.dll", "System.Runtime.dll", "System.Runtime.DurableInstancing.dll", "System.Runtime.Extensions.dll", "System.Runtime.Handles.dll", "System.Runtime.InteropServices.dll", "System.Runtime.InteropServices.RuntimeInformation.dll", "System.Runtime.InteropServices.WindowsRuntime.dll", "System.Runtime.Numerics.dll", "System.Runtime.Remoting.dll", "System.Runtime.Serialization.dll", "System.Runtime.Serialization.Formatters.dll", "System.Runtime.Serialization.Formatters.Soap.dll", "System.Runtime.Serialization.Json.dll", "System.Runtime.Serialization.Primitives.dll", "System.Runtime.Serialization.Xml.dll", "System.Security.Claims.dll", "System.Security.Cryptography.Algorithms.dll", "System.Security.Cryptography.Csp.dll", "System.Security.Cryptography.Encoding.dll", "System.Security.Cryptography.Primitives.dll", "System.Security.Cryptography.X509Certificates.dll", "System.Security.dll", "System.Security.Principal.dll", "System.Security.SecureString.dll", "System.ServiceModel.Activation.dll", "System.ServiceModel.Activities.dll", "System.ServiceModel.Channels.dll", "System.ServiceModel.Discovery.dll", "System.ServiceModel.dll", "System.ServiceModel.Duplex.dll", "System.ServiceModel.Http.dll", "System.ServiceModel.NetTcp.dll", "System.ServiceModel.Primitives.dll", "System.ServiceModel.Routing.dll", "System.ServiceModel.Security.dll", "System.ServiceModel.Web.dll", "System.ServiceProcess.dll", "System.Speech.dll", "System.Text.Encoding.dll", "System.Text.Encoding.Extensions.dll", "System.Text.RegularExpressions.dll", "System.Threading.dll", "System.Threading.Overlapped.dll", "System.Threading.Tasks.dll", "System.Threading.Tasks.Parallel.dll", "System.Threading.Thread.dll", "System.Threading.ThreadPool.dll", "System.Threading.Timer.dll", "System.Transactions.dll", "System.ValueTuple.dll", "System.Web.Abstractions.dll", "System.Web.ApplicationServices.dll", "System.Web.DataVisualization.Design.dll", "System.Web.DataVisualization.dll", "System.Web.dll", "System.Web.DynamicData.Design.dll", "System.Web.DynamicData.dll", "System.Web.Entity.Design.dll", "System.Web.Entity.dll", "System.Web.Extensions.Design.dll", "System.Web.Extensions.dll", "System.Web.Mobile.dll", "System.Web.RegularExpressions.dll", "System.Web.Routing.dll", "System.Web.Services.dll", "System.Windows.Controls.Ribbon.dll", "System.Windows.dll", "System.Windows.Forms.DataVisualization.Design.dll", "System.Windows.Forms.DataVisualization.dll", "System.Windows.Forms.dll", "System.Windows.Input.Manipulations.dll", "System.Windows.Presentation.dll", "System.Workflow.Activities.dll", "System.Workflow.ComponentModel.dll", "System.Workflow.Runtime.dll", "System.WorkflowServices.dll", "System.Xaml.dll", "System.Xml.dll", "System.Xml.Linq.dll", "System.Xml.ReaderWriter.dll", "System.Xml.Serialization.dll", "System.Xml.XDocument.dll", "System.Xml.XmlDocument.dll", "System.Xml.XmlSerializer.dll", "System.Xml.XPath.dll", "System.Xml.XPath.XDocument.dll", "UIAutomationClient.dll", "UIAutomationClientsideProviders.dll", "UIAutomationProvider.dll", "UIAutomationTypes.dll", "WindowsBase.dll", "WindowsFormsIntegration.dll", "XamlBuildTask.dll" });
+
+
+ private readonly IFileSystem _fileSystem = FileSystem.Instance;
+ private readonly ILogCollector logCollector;
+ private readonly string directoryForNuGetConfig;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Automation script.
+ /// The projects corresponding with the C# Exe blocks.
+ /// All the scripts in the Automation script solution.
+ /// is .
+ [Obsolete("Use the constructor with the directoryForNuGetConfig so it can take in account the NuGet.config from the solution.")]
+ public AutomationScriptBuilder(Script script, IDictionary projects, IEnumerable
+";
+
+ string expected = @"
+
+";
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", new Project("Script_1", new[]{ new ProjectFile("Script.cs", "using System;") }) },
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", new Project("Script_1", new[]{ new ProjectFile("Script.cs", "using System;") }) },
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", new Project("Script_1", new[]{ new ProjectFile("Script.cs", "using System;") }) },
+ { "Script_2", new Project("Script_2", new[]{ new ProjectFile("Script.cs", "using System.Xml;") }) },
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", new Project("Script_1", new[]{ new ProjectFile("Script.cs", "using System;"), new ProjectFile("Class1.cs", "using System; class Class1 {}") }) },
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ var projects = new Dictionary();
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", new Project("Script_1", Array.Empty()) },
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projectFiles = new[] { new ProjectFile("Script.cs", "using System;") };
+ var references = new[] { new Reference("System.Data.dll") };
+ var project1 = new Project("Script_1", projectFiles: projectFiles, references: references);
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", project1},
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projectFiles = new[] { new ProjectFile("Script.cs", "using System;") };
+ var references = new[] { new Reference(@"C:\Skyline DataMiner\Files\System.Data.dll") };
+ var project1 = new Project("Script_1", projectFiles: projectFiles, references: references);
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", project1},
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projectFiles_project1 = new[] { new ProjectFile("Script.cs", "using System;") };
+ var projectFiles_project63000 = new[] { new ProjectFile("Script.cs", "namespace Skyline.DataMiner.Library { }") };
+ var references_project1 = new[] { new Reference("System.Data.dll") };
+ var projectReferences_project1 = new[] { new ProjectReference("AutomationScript_ClassLibrary") };
+ var project1 = new Project("Script_1", projectFiles: projectFiles_project1, references: references_project1, projectReferences: projectReferences_project1);
+ var project63000 = new Project("Script_63000", projectFiles: projectFiles_project63000);
+
+ var projects = new Dictionary()
+ {
+ { "Script_63000", project63000},
+ { "Script_1", project1},
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projectFiles_project1 = new[] { new ProjectFile("Script.cs", "using System;") };
+ var projectFiles_project2 = new[] { new ProjectFile("Script.cs", "using System.Xml;") };
+ var projectReferences_project2 = new[] { new ProjectReference("Script_1") };
+ var project1 = new Project("Script_1", projectFiles: projectFiles_project1);
+ var project2 = new Project("Script_2", projectFiles: projectFiles_project2, projectReferences: projectReferences_project2);
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", project1},
+ { "Script_2", project2},
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projectFiles = new[] { new ProjectFile("Script.cs", "using System;") };
+ var packageReferences = new[]
+ {
+ new PackageReference("Skyline.DataMiner.Core.DataMinerSystem.Automation", "1.0.0.1"),
+ new PackageReference("Skyline.DataMiner.Dev.Automation", "10.3.5"),
+ new PackageReference("Skyline.DataMiner.Files.SLManagedScripting", "10.3.5"),
+ new PackageReference("Skyline.DataMiner.Files.SLManagedAutomation", "10.3.5"),
+ new PackageReference("Skyline.DataMiner.Files.SLMediationSnippets", "10.3.5")
+ };
+ var project1 = new Project("Script_1", tfm: ".NETFramework,Version=v4.6.2", projectFiles: projectFiles, packageReferences: packageReferences);
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", project1},
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projectFiles = new[] { new ProjectFile("Script.cs", "using System;") };
+ var references = new[] { new Reference("Newtonsoft.Json.dll") };
+ var project1 = new Project("Script_1", projectFiles: projectFiles, references: references);
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", project1},
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projectFiles = new[] { new ProjectFile("Script.cs", "using System;") };
+ var references = new[] { new Reference("Newtonsoft.Json.dll") };
+ var project1 = new Project("Script_1", projectFiles: projectFiles, references: references);
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", project1},
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projectFiles = new[] { new ProjectFile("Script.cs", "using System;") };
+ var references = new[] { new Reference("Newtonsoft.Json.dll") };
+ var project1 = new Project("Script_1", projectFiles: projectFiles, references: references);
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", project1},
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var project1 = new Project("Script_1", new[] { new ProjectFile("Script.cs", "using System;") });
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", project1},
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projects = new Dictionary();
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", new Project("Script_1", new[]{ new ProjectFile("Script.cs", "using Characterø;") }) },
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+";
+
+ string expected = @"
+
+";
+
+ var projectFiles = new[] { new ProjectFile("Script.cs", "using System;") };
+ var packageReferences = new[]
+ {
+ new PackageReference("Skyline.DataMiner.Dev.Automation", "10.3.5"),
+ new PackageReference("Newtonsoft.Json", "13.0.3"),
+ new PackageReference("NPOI", "2.4.1"),
+ new PackageReference("Skyline.DataMiner.ConnectorAPI.EVS.IPD-VIA", "1.0.0.4-Test1"),
+ new PackageReference("Skyline.DataMiner.ConnectorAPI.YLE.OrderManager", "1.0.0.2-Test1"),
+ new PackageReference("Skyline.DataMiner.Utils.InteractiveAutomationScriptToolkit", "6.1.0"),
+ new PackageReference("Skyline.DataMiner.Utils.YLE.Integrations", "1.0.1.6-Test1"),
+ };
+ var project1 = new Project("Script_1", tfm: ".NETFramework,Version=v4.7.2", projectFiles: projectFiles, packageReferences: packageReferences);
+
+ var projects = new Dictionary()
+ {
+ { "Script_1", project1},
+ };
+
+ Script script = new Script(XmlDocument.Parse(original));
+ AutomationScriptBuilder builder = new AutomationScriptBuilder(script, projects, new List
+
+";
+
+ var baseDir = FileSystem.Instance.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ var dir = FileSystem.Instance.Path.GetFullPath(FileSystem.Instance.Path.Combine(baseDir, @"TestFiles\Solutions\Solution6"));
+ var path = FileSystem.Instance.Path.Combine(dir, "AutomationScript.sln");
+
+ var solution = AutomationScriptSolution.Load(path);
+ var builder = new AutomationScriptSolutionBuilder(solution);
+
+ // act
+ var result = await builder.BuildAsync().ConfigureAwait(false);
+
+ // check
+ Assert.IsNotNull(result);
+ Assert.HasCount(2, result);
+ Assert.AreEqual(expectedResult, result.Single(x => x.Key.Name == "SimpleScript").Value.Document);
+ }
+
+ ///
+ /// Test for Automation script that refers to a library exe block defined in the same script.
+ ///
+ ///
+ [TestMethod]
+ public async Task AutomationScriptCompiler_Solution7_BuildAsync()
+ {
+ // arrange
+ string expectedResult = @"
+
+ LibraryInOwnScript
+
+ Automation
+ SKYLINE2\Pedro
+ FALSE
+
+
+
+
+
+
+
+
+
+
+
+
+";
+
+ var baseDir = FileSystem.Instance.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ var dir = FileSystem.Instance.Path.GetFullPath(FileSystem.Instance.Path.Combine(baseDir, @"TestFiles\Solutions\Solution7"));
+ var path = FileSystem.Instance.Path.Combine(dir, "AutomationScript.sln");
+
+ var solution = AutomationScriptSolution.Load(path);
+ var builder = new AutomationScriptSolutionBuilder(solution);
+
+ // act
+ var result = await builder.BuildAsync().ConfigureAwait(false);
+
+ // check
+ Assert.IsNotNull(result);
+ Assert.HasCount(1, result);
+ Assert.AreEqual(expectedResult, result[0].Value.Document);
+ }
+
+ [TestMethod]
+ public async Task AutomationScriptCompilerUsingNuGetPackages_Solution8_SrmAsync()
+ {
+ var baseDir = FileSystem.Instance.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ var dir = FileSystem.Instance.Path.GetFullPath(FileSystem.Instance.Path.Combine(baseDir, @"TestFiles\Solutions\Solution8"));
+ var path = FileSystem.Instance.Path.Combine(dir, "Solution8.sln");
+
+ var solution = AutomationScriptSolution.Load(path);
+ var builder = new AutomationScriptSolutionBuilder(solution);
+
+ var result = await builder.BuildAsync().ConfigureAwait(false);
+
+ Assert.HasCount(1, result, "Expected 1 script in build result.");
+
+ var firstItem = result.FirstOrDefault();
+ string automationScriptXml = firstItem.Value.Document;
+
+ var document = XDocument.Parse(automationScriptXml);
+ XNamespace ns = document.Root.GetDefaultNamespace();
+
+ var referenceNodes = document
+ ?.Element(ns + "DMSScript")
+ ?.Element(ns + "Script")
+ ?.Element(ns + "Exe")
+ ?.Elements(ns + "Param");
+
+ Assert.IsNotNull(referenceNodes);
+
+ List generatedEntries = new List();
+ foreach (var referenceNode in referenceNodes)
+ {
+ generatedEntries.Add(referenceNode.Value);
+ }
+
+ List expectedEntries = new List
+ {
+ @"Microsoft.CSharp.dll",
+ @"System.Data.dll",
+ @"System.Data.DataSetExtensions.dll",
+ @"System.Drawing.dll",
+ @"System.IO.Compression.FileSystem.dll",
+ @"System.Runtime.Caching.dll",
+ @"System.Runtime.Serialization.dll",
+ @"System.Xml.Linq.dll",
+
+ @"C:\Skyline DataMiner\ProtocolScripts\DllImport\SRM\SLSRMLibrary.dll",
+ @"C:\Skyline DataMiner\ProtocolScripts\DllImport\SRM\SLDijkstraSearch.dll"
+ };
+
+ generatedEntries.Should().BeEquivalentTo(expectedEntries);
+ }
+
+ [Ignore("Only usable internally, until there is an 'official' NuGet that has SRM as a dependency")]
+ [TestMethod]
+ public async Task AutomationScriptCompilerUsingNuGetPackages_Solution9_SrmAsDependencyAsync()
+ {
+ var baseDir = FileSystem.Instance.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ var dir = FileSystem.Instance.Path.GetFullPath(FileSystem.Instance.Path.Combine(baseDir, @"TestFiles\Solutions\Solution9"));
+ var path = FileSystem.Instance.Path.Combine(dir, "Solution9.sln");
+
+ var solution = AutomationScriptSolution.Load(path);
+ var builder = new AutomationScriptSolutionBuilder(solution);
+
+ var result = await builder.BuildAsync().ConfigureAwait(false);
+
+ Assert.HasCount(1, result, "Expected 1 script in build result.");
+
+ var firstItem = result.FirstOrDefault();
+ string automationScriptXml = firstItem.Value.Document;
+
+ var document = XDocument.Parse(automationScriptXml);
+ XNamespace ns = document.Root.GetDefaultNamespace();
+
+ var referenceNodes = document
+ ?.Element(ns + "DMSScript")
+ ?.Element(ns + "Script")
+ ?.Element(ns + "Exe")
+ ?.Elements(ns + "Param");
+
+ Assert.IsNotNull(referenceNodes);
+
+ List generatedEntries = new List();
+ foreach (var referenceNode in referenceNodes)
+ {
+ generatedEntries.Add(referenceNode.Value);
+ }
+
+ List expectedEntries = new List
+ {
+ @"Microsoft.CSharp.dll",
+ @"System.Data.dll",
+ @"System.Data.DataSetExtensions.dll",
+ @"System.Drawing.dll",
+ @"System.IO.Compression.FileSystem.dll",
+ @"System.Runtime.Caching.dll",
+ @"System.Runtime.Serialization.dll",
+ @"System.Xml.Linq.dll",
+
+ @"C:\Skyline DataMiner\ProtocolScripts\DllImport\SRM\SLSRMLibrary.dll",
+
+ // This one has a dependency on SRM package
+ @"C:\Skyline DataMiner\ProtocolScripts\DllImport\skyline.dataminer.testing.mod\1.0.0-1.0.0.x.3\lib\net462\Skyline.DataMiner.Testing.MOD.dll",
+ };
+
+ generatedEntries.Should().BeEquivalentTo(expectedEntries);
+ }
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Projects/Project1/Project1.cs b/Assemblers.AutomationTests/TestFiles/Projects/Project1/Project1.cs
new file mode 100644
index 0000000..6c641fc
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Projects/Project1/Project1.cs
@@ -0,0 +1,107 @@
+/*
+****************************************************************************
+* Copyright (c) 2025, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+11/09/2025 1.0.0.1 MOD, Skyline Initial version
+****************************************************************************
+*/
+
+namespace Project1
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Text;
+ using Skyline.DataMiner.Automation;
+
+ ///
+ /// Represents a DataMiner Automation script.
+ ///
+ public class Script
+ {
+ ///
+ /// The script entry point.
+ ///
+ /// Link with SLAutomation process.
+ public void Run(IEngine engine)
+ {
+ try
+ {
+ RunSafe(engine);
+ }
+ catch (ScriptAbortException)
+ {
+ // Catch normal abort exceptions (engine.ExitFail or engine.ExitSuccess)
+ throw; // Comment if it should be treated as a normal exit of the script.
+ }
+ catch (ScriptForceAbortException)
+ {
+ // Catch forced abort exceptions, caused via external maintenance messages.
+ throw;
+ }
+ catch (ScriptTimeoutException)
+ {
+ // Catch timeout exceptions for when a script has been running for too long.
+ throw;
+ }
+ catch (InteractiveUserDetachedException)
+ {
+ // Catch a user detaching from the interactive script by closing the window.
+ // Only applicable for interactive scripts, can be removed for non-interactive scripts.
+ throw;
+ }
+ catch (Exception e)
+ {
+ engine.ExitFail("Run|Something went wrong: " + e);
+ }
+ }
+
+ private void RunSafe(IEngine engine)
+ {
+ // TODO: Define code here
+ }
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Projects/Project1/Project1.csproj b/Assemblers.AutomationTests/TestFiles/Projects/Project1/Project1.csproj
new file mode 100644
index 0000000..b515203
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Projects/Project1/Project1.csproj
@@ -0,0 +1,21 @@
+
+
+ net48
+ true
+
+
+ AutomationScript
+ False
+ 10.3.0.0 - 12752
+ 1.0.0
+ Initial Version
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Projects/Project1/Project1.xml b/Assemblers.AutomationTests/TestFiles/Projects/Project1/Project1.xml
new file mode 100644
index 0000000..528dae8
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Projects/Project1/Project1.xml
@@ -0,0 +1,26 @@
+
+
+ Project1
+
+ Automation
+ MOD
+ FALSE
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Projects/global.json b/Assemblers.AutomationTests/TestFiles/Projects/global.json
new file mode 100644
index 0000000..95be308
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Projects/global.json
@@ -0,0 +1,5 @@
+{
+ "msbuild-sdks": {
+ "Skyline.DataMiner.Sdk": "2.1.1"
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/AutomationScript.sln b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/AutomationScript.sln
new file mode 100644
index 0000000..1a66932
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/AutomationScript.sln
@@ -0,0 +1,73 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30503.244
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{83A162A2-0BE3-4E70-B178-448B71D02A0D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{DC12C1A8-4C06-40EA-B204-30608CE534A6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{0BA1D4BE-635D-4E90-87CC-8DF145A5C25C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Script_1", "Script_1", "{F1C34D24-E21D-4477-B37C-07E5C234FE6C}"
+ ProjectSection(SolutionItems) = preProject
+ Script_1.xml = Script_1.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Script_2", "Script_2", "{1BB5378B-1540-4FF6-815B-CEDAB5F7C03B}"
+ ProjectSection(SolutionItems) = preProject
+ Script_2.xml = Script_2.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{D0EA8C5C-5350-42FA-B9BA-3E5D86070D20}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{BA001170-3E31-42E9-808A-BC7626B683F5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Script_1a", "Script_1a\Script_1a.csproj", "{C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Script_1b", "Script_1b\Script_1b.csproj", "{3048B168-DC53-4143-ADF1-DCD95B8539ED}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Script_2", "Script_2\Script_2.csproj", "{1AE71A40-7865-4106-A15D-D8688AB231A6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutomationScript_ClassLibrary", "AutomationScript_ClassLibrary\AutomationScript_ClassLibrary.csproj", "{07DBE185-5EB9-4DF9-898E-1874A2907DA6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {F1C34D24-E21D-4477-B37C-07E5C234FE6C} = {0BA1D4BE-635D-4E90-87CC-8DF145A5C25C}
+ {1BB5378B-1540-4FF6-815B-CEDAB5F7C03B} = {0BA1D4BE-635D-4E90-87CC-8DF145A5C25C}
+ {D0EA8C5C-5350-42FA-B9BA-3E5D86070D20} = {F1C34D24-E21D-4477-B37C-07E5C234FE6C}
+ {BA001170-3E31-42E9-808A-BC7626B683F5} = {1BB5378B-1540-4FF6-815B-CEDAB5F7C03B}
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653} = {D0EA8C5C-5350-42FA-B9BA-3E5D86070D20}
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED} = {D0EA8C5C-5350-42FA-B9BA-3E5D86070D20}
+ {1AE71A40-7865-4106-A15D-D8688AB231A6} = {BA001170-3E31-42E9-808A-BC7626B683F5}
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6} = {DC12C1A8-4C06-40EA-B204-30608CE534A6}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {58942BE7-5A68-461B-8F90-E06699C84F5C}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.cs
new file mode 100644
index 0000000..b936d2f
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.cs
@@ -0,0 +1,5 @@
+// This is auto-generated code by DIS. Do not modify.
+namespace Skyline.DataMiner.Library
+{
+
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.csproj
new file mode 100644
index 0000000..5a72698
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.csproj
@@ -0,0 +1,47 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}
+ Library
+ Properties
+ AutomationScript_ClassLibrary
+ AutomationScript_ClassLibrary
+ v4.7
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1.xml b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1.xml
new file mode 100644
index 0000000..0b19b6d
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1.xml
@@ -0,0 +1,29 @@
+
+ Script_1
+
+ Automation
+ FALSE
+ MyFolder
+
+
+
+
+
+
+ Reservation ID
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1a/Script.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1a/Script.cs
new file mode 100644
index 0000000..8a88f75
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1a/Script.cs
@@ -0,0 +1,7 @@
+public class Script
+{
+ public void Run()
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1a/Script_1a.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1a/Script_1a.csproj
new file mode 100644
index 0000000..4f11644
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1a/Script_1a.csproj
@@ -0,0 +1,58 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}
+ Library
+ Properties
+ Script_1a
+ Script_1a
+ v4.7
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+ ..\Newtonsoft.Json.dll
+ C:\Skyline DataMiner\Files\Newtonsoft.Json.dll
+
+
+ ..\MySql.Data.dll
+ C:\Skyline DataMiner\ProtocolScripts\MySql.Data.dll
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1b/Class1.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1b/Class1.cs
new file mode 100644
index 0000000..0da90bf
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1b/Class1.cs
@@ -0,0 +1,6 @@
+namespace Script_1b
+{
+ public class Class1
+ {
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1b/Script.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1b/Script.cs
new file mode 100644
index 0000000..8a88f75
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1b/Script.cs
@@ -0,0 +1,7 @@
+public class Script
+{
+ public void Run()
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1b/Script_1b.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1b/Script_1b.csproj
new file mode 100644
index 0000000..2b81127
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_1b/Script_1b.csproj
@@ -0,0 +1,51 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}
+ Library
+ Properties
+ Script_1b
+ Script_1b
+ v4.7
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_2.xml b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_2.xml
new file mode 100644
index 0000000..4cfbf6d
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_2.xml
@@ -0,0 +1,23 @@
+
+ Script_2
+
+ Automation
+ FALSE
+ MyFolder
+
+
+
+
+
+
+ Reservation ID
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_2/Script.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_2/Script.cs
new file mode 100644
index 0000000..8a88f75
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_2/Script.cs
@@ -0,0 +1,7 @@
+public class Script
+{
+ public void Run()
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_2/Script_2.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_2/Script_2.csproj
new file mode 100644
index 0000000..44e4775
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution1/Script_2/Script_2.csproj
@@ -0,0 +1,50 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}
+ Library
+ Properties
+ Script_2
+ Script_2
+ v4.7
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/AutomationScript.sln b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/AutomationScript.sln
new file mode 100644
index 0000000..1071fd9
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/AutomationScript.sln
@@ -0,0 +1,79 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30503.244
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{83A162A2-0BE3-4E70-B178-448B71D02A0D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{DC12C1A8-4C06-40EA-B204-30608CE534A6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{0BA1D4BE-635D-4E90-87CC-8DF145A5C25C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Script_1", "Script_1", "{F1C34D24-E21D-4477-B37C-07E5C234FE6C}"
+ ProjectSection(SolutionItems) = preProject
+ Script_1.xml = Script_1.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Script_2", "Script_2", "{1BB5378B-1540-4FF6-815B-CEDAB5F7C03B}"
+ ProjectSection(SolutionItems) = preProject
+ Script_2.xml = Script_2.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{D0EA8C5C-5350-42FA-B9BA-3E5D86070D20}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{BA001170-3E31-42E9-808A-BC7626B683F5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Script_1a", "Script_1a\Script_1a.csproj", "{C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Script_1b", "Script_1b\Script_1b.csproj", "{3048B168-DC53-4143-ADF1-DCD95B8539ED}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Script_2", "Script_2\Script_2.csproj", "{1AE71A40-7865-4106-A15D-D8688AB231A6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutomationScript_ClassLibrary", "AutomationScript_ClassLibrary\AutomationScript_ClassLibrary.csproj", "{07DBE185-5EB9-4DF9-898E-1874A2907DA6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Subfolder1", "Subfolder1", "{88943879-C091-4E67-9707-F464F9F0546F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Subfolder2", "Subfolder2", "{4F2BD299-2ED7-49CD-A8A0-604C53F0329D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {F1C34D24-E21D-4477-B37C-07E5C234FE6C} = {88943879-C091-4E67-9707-F464F9F0546F}
+ {1BB5378B-1540-4FF6-815B-CEDAB5F7C03B} = {4F2BD299-2ED7-49CD-A8A0-604C53F0329D}
+ {D0EA8C5C-5350-42FA-B9BA-3E5D86070D20} = {F1C34D24-E21D-4477-B37C-07E5C234FE6C}
+ {BA001170-3E31-42E9-808A-BC7626B683F5} = {1BB5378B-1540-4FF6-815B-CEDAB5F7C03B}
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653} = {D0EA8C5C-5350-42FA-B9BA-3E5D86070D20}
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED} = {D0EA8C5C-5350-42FA-B9BA-3E5D86070D20}
+ {1AE71A40-7865-4106-A15D-D8688AB231A6} = {BA001170-3E31-42E9-808A-BC7626B683F5}
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6} = {DC12C1A8-4C06-40EA-B204-30608CE534A6}
+ {88943879-C091-4E67-9707-F464F9F0546F} = {0BA1D4BE-635D-4E90-87CC-8DF145A5C25C}
+ {4F2BD299-2ED7-49CD-A8A0-604C53F0329D} = {0BA1D4BE-635D-4E90-87CC-8DF145A5C25C}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {58942BE7-5A68-461B-8F90-E06699C84F5C}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.cs
new file mode 100644
index 0000000..b936d2f
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.cs
@@ -0,0 +1,5 @@
+// This is auto-generated code by DIS. Do not modify.
+namespace Skyline.DataMiner.Library
+{
+
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.csproj
new file mode 100644
index 0000000..5a72698
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.csproj
@@ -0,0 +1,47 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}
+ Library
+ Properties
+ AutomationScript_ClassLibrary
+ AutomationScript_ClassLibrary
+ v4.7
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1.xml b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1.xml
new file mode 100644
index 0000000..0b19b6d
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1.xml
@@ -0,0 +1,29 @@
+
+ Script_1
+
+ Automation
+ FALSE
+ MyFolder
+
+
+
+
+
+
+ Reservation ID
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1a/Script.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1a/Script.cs
new file mode 100644
index 0000000..8a88f75
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1a/Script.cs
@@ -0,0 +1,7 @@
+public class Script
+{
+ public void Run()
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1a/Script_1a.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1a/Script_1a.csproj
new file mode 100644
index 0000000..99e2362
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1a/Script_1a.csproj
@@ -0,0 +1,50 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}
+ Library
+ Properties
+ Script_1a
+ Script_1a
+ v4.7
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1b/Class1.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1b/Class1.cs
new file mode 100644
index 0000000..0da90bf
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1b/Class1.cs
@@ -0,0 +1,6 @@
+namespace Script_1b
+{
+ public class Class1
+ {
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1b/Script.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1b/Script.cs
new file mode 100644
index 0000000..8a88f75
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1b/Script.cs
@@ -0,0 +1,7 @@
+public class Script
+{
+ public void Run()
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1b/Script_1b.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1b/Script_1b.csproj
new file mode 100644
index 0000000..2b81127
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_1b/Script_1b.csproj
@@ -0,0 +1,51 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}
+ Library
+ Properties
+ Script_1b
+ Script_1b
+ v4.7
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_2.xml b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_2.xml
new file mode 100644
index 0000000..4cfbf6d
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_2.xml
@@ -0,0 +1,23 @@
+
+ Script_2
+
+ Automation
+ FALSE
+ MyFolder
+
+
+
+
+
+
+ Reservation ID
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_2/Script.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_2/Script.cs
new file mode 100644
index 0000000..8a88f75
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_2/Script.cs
@@ -0,0 +1,7 @@
+public class Script
+{
+ public void Run()
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_2/Script_2.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_2/Script_2.csproj
new file mode 100644
index 0000000..44e4775
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution2/Script_2/Script_2.csproj
@@ -0,0 +1,50 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}
+ Library
+ Properties
+ Script_2
+ Script_2
+ v4.7
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/AutomationScript.sln b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/AutomationScript.sln
new file mode 100644
index 0000000..089a900
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/AutomationScript.sln
@@ -0,0 +1,85 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.1267
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{83A162A2-0BE3-4E70-B178-448B71D02A0D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{DC12C1A8-4C06-40EA-B204-30608CE534A6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{0BA1D4BE-635D-4E90-87CC-8DF145A5C25C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Script_1", "Script_1", "{F1C34D24-E21D-4477-B37C-07E5C234FE6C}"
+ ProjectSection(SolutionItems) = preProject
+ Script_1.xml = Script_1.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Script_2", "Script_2", "{1BB5378B-1540-4FF6-815B-CEDAB5F7C03B}"
+ ProjectSection(SolutionItems) = preProject
+ Script_2.xml = Script_2.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{D0EA8C5C-5350-42FA-B9BA-3E5D86070D20}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{BA001170-3E31-42E9-808A-BC7626B683F5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Script_1a", "Script_1a\Script_1a.csproj", "{C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Script_1b", "Script_1b\Script_1b.csproj", "{3048B168-DC53-4143-ADF1-DCD95B8539ED}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Script_2", "Script_2\Script_2.csproj", "{1AE71A40-7865-4106-A15D-D8688AB231A6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutomationScript_ClassLibrary", "AutomationScript_ClassLibrary\AutomationScript_ClassLibrary.csproj", "{07DBE185-5EB9-4DF9-898E-1874A2907DA6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Subfolder1", "Subfolder1", "{88943879-C091-4E67-9707-F464F9F0546F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Subfolder2", "Subfolder2", "{4F2BD299-2ED7-49CD-A8A0-604C53F0329D}"
+EndProject
+Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SharedProject", "SharedProject\SharedProject.shproj", "{1EC081DC-91E9-437F-8E08-47AD8048EF64}"
+EndProject
+Global
+ GlobalSection(SharedMSBuildProjectFiles) = preSolution
+ SharedProject\SharedProject.projitems*{1ec081dc-91e9-437f-8e08-47ad8048ef64}*SharedItemsImports = 13
+ SharedProject\SharedProject.projitems*{3048b168-dc53-4143-adf1-dcd95b8539ed}*SharedItemsImports = 4
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {F1C34D24-E21D-4477-B37C-07E5C234FE6C} = {88943879-C091-4E67-9707-F464F9F0546F}
+ {1BB5378B-1540-4FF6-815B-CEDAB5F7C03B} = {4F2BD299-2ED7-49CD-A8A0-604C53F0329D}
+ {D0EA8C5C-5350-42FA-B9BA-3E5D86070D20} = {F1C34D24-E21D-4477-B37C-07E5C234FE6C}
+ {BA001170-3E31-42E9-808A-BC7626B683F5} = {1BB5378B-1540-4FF6-815B-CEDAB5F7C03B}
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653} = {D0EA8C5C-5350-42FA-B9BA-3E5D86070D20}
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED} = {D0EA8C5C-5350-42FA-B9BA-3E5D86070D20}
+ {1AE71A40-7865-4106-A15D-D8688AB231A6} = {BA001170-3E31-42E9-808A-BC7626B683F5}
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6} = {DC12C1A8-4C06-40EA-B204-30608CE534A6}
+ {88943879-C091-4E67-9707-F464F9F0546F} = {0BA1D4BE-635D-4E90-87CC-8DF145A5C25C}
+ {4F2BD299-2ED7-49CD-A8A0-604C53F0329D} = {0BA1D4BE-635D-4E90-87CC-8DF145A5C25C}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {58942BE7-5A68-461B-8F90-E06699C84F5C}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.cs
new file mode 100644
index 0000000..7e8f0cc
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.cs
@@ -0,0 +1,5 @@
+// --- auto-generated code --- do not modify ---
+namespace Skyline.DataMiner.Library
+{
+
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.csproj
new file mode 100644
index 0000000..5a72698
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/AutomationScript_ClassLibrary/AutomationScript_ClassLibrary.csproj
@@ -0,0 +1,47 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {07DBE185-5EB9-4DF9-898E-1874A2907DA6}
+ Library
+ Properties
+ AutomationScript_ClassLibrary
+ AutomationScript_ClassLibrary
+ v4.7
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1.xml b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1.xml
new file mode 100644
index 0000000..0b19b6d
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1.xml
@@ -0,0 +1,29 @@
+
+ Script_1
+
+ Automation
+ FALSE
+ MyFolder
+
+
+
+
+
+
+ Reservation ID
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1a/Script.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1a/Script.cs
new file mode 100644
index 0000000..8a88f75
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1a/Script.cs
@@ -0,0 +1,7 @@
+public class Script
+{
+ public void Run()
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1a/Script_1a.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1a/Script_1a.csproj
new file mode 100644
index 0000000..99e2362
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1a/Script_1a.csproj
@@ -0,0 +1,50 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {C17D3C87-4F2C-47B4-AC1A-0B3BB66E1653}
+ Library
+ Properties
+ Script_1a
+ Script_1a
+ v4.7
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1b/Class1.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1b/Class1.cs
new file mode 100644
index 0000000..0da90bf
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1b/Class1.cs
@@ -0,0 +1,6 @@
+namespace Script_1b
+{
+ public class Class1
+ {
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1b/Script.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1b/Script.cs
new file mode 100644
index 0000000..fbc9e04
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1b/Script.cs
@@ -0,0 +1,10 @@
+using SharedProject;
+public class Script
+{
+ public void Run()
+ {
+
+ SharedCode myCode = new SharedCode();
+ myCode.TestSharedCall();
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1b/Script_1b.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1b/Script_1b.csproj
new file mode 100644
index 0000000..9ceb518
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_1b/Script_1b.csproj
@@ -0,0 +1,52 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {3048B168-DC53-4143-ADF1-DCD95B8539ED}
+ Library
+ Properties
+ Script_1b
+ Script_1b
+ v4.7
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_2.xml b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_2.xml
new file mode 100644
index 0000000..4cfbf6d
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_2.xml
@@ -0,0 +1,23 @@
+
+ Script_2
+
+ Automation
+ FALSE
+ MyFolder
+
+
+
+
+
+
+ Reservation ID
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_2/Script.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_2/Script.cs
new file mode 100644
index 0000000..8a88f75
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_2/Script.cs
@@ -0,0 +1,7 @@
+public class Script
+{
+ public void Run()
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_2/Script_2.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_2/Script_2.csproj
new file mode 100644
index 0000000..44e4775
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/Script_2/Script_2.csproj
@@ -0,0 +1,50 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {1AE71A40-7865-4106-A15D-D8688AB231A6}
+ Library
+ Properties
+ Script_2
+ Script_2
+ v4.7
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/SharedProject/MoreSharedCode.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/SharedProject/MoreSharedCode.cs
new file mode 100644
index 0000000..e8d3927
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/SharedProject/MoreSharedCode.cs
@@ -0,0 +1,12 @@
+namespace SharedProject
+{
+ using System.Threading;
+
+ public class UnusedSharedCode
+ {
+ public void JustAnotherCall()
+ {
+ Thread.Sleep(100);
+ }
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/SharedProject/SharedCode.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/SharedProject/SharedCode.cs
new file mode 100644
index 0000000..a8bf4f8
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/SharedProject/SharedCode.cs
@@ -0,0 +1,10 @@
+namespace SharedProject
+{
+ public class SharedCode
+ {
+ public bool TestSharedCall()
+ {
+ return true;
+ }
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/SharedProject/SharedProject.projitems b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/SharedProject/SharedProject.projitems
new file mode 100644
index 0000000..31f694d
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/SharedProject/SharedProject.projitems
@@ -0,0 +1,15 @@
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+ true
+ 1ec081dc-91e9-437f-8e08-47ad8048ef64
+
+
+ SharedProject
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/SharedProject/SharedProject.shproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/SharedProject/SharedProject.shproj
new file mode 100644
index 0000000..a8c4b15
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution3/SharedProject/SharedProject.shproj
@@ -0,0 +1,13 @@
+
+
+
+ 1ec081dc-91e9-437f-8e08-47ad8048ef64
+ 14.0
+
+
+
+
+
+
+
+
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/AutomationScript.sln b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/AutomationScript.sln
new file mode 100644
index 0000000..a65093d
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/AutomationScript.sln
@@ -0,0 +1,58 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.1684
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{E7D3511B-D22F-4DBD-B2C2-7A8C727B3C0F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{48D8F878-FAEF-4765-B4CF-80FF2639D521}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{DB881A31-8F8F-47B9-8FAE-4CF141CF9587}"
+ ProjectSection(SolutionItems) = preProject
+ Dlls\readme.txt = Dlls\readme.txt
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{C7CE0082-E626-4AAC-B896-FA9633E802DD}"
+ ProjectSection(SolutionItems) = preProject
+ Documentation\readme.txt = Documentation\readme.txt
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code Analysis", "Code Analysis", "{B48FAA81-E887-4C35-8C4D-0C22E76AD7D7}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\Code Analysis\SonarLint-QuickActions-Active.ruleset = Internal\Code Analysis\SonarLint-QuickActions-Active.ruleset
+ Internal\Code Analysis\SonarLint-QuickActions-Inactive.ruleset = Internal\Code Analysis\SonarLint-QuickActions-Inactive.ruleset
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NewNugetTest", "NewNugetTest", "{A9C49E31-C166-481A-82F8-1884440C9A1A}"
+ ProjectSection(SolutionItems) = preProject
+ NewNugetTest.xml = NewNugetTest.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{46AAC8F1-FF8D-43BC-BA59-E8E52C22BAF7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NewNugetTest_1", "NewNugetTest_1\NewNugetTest_1.csproj", "{6CD1E51A-B664-48D4-8A51-8E6D987774F2}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6CD1E51A-B664-48D4-8A51-8E6D987774F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6CD1E51A-B664-48D4-8A51-8E6D987774F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6CD1E51A-B664-48D4-8A51-8E6D987774F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6CD1E51A-B664-48D4-8A51-8E6D987774F2}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {B48FAA81-E887-4C35-8C4D-0C22E76AD7D7} = {E7D3511B-D22F-4DBD-B2C2-7A8C727B3C0F}
+ {A9C49E31-C166-481A-82F8-1884440C9A1A} = {48D8F878-FAEF-4765-B4CF-80FF2639D521}
+ {46AAC8F1-FF8D-43BC-BA59-E8E52C22BAF7} = {A9C49E31-C166-481A-82F8-1884440C9A1A}
+ {6CD1E51A-B664-48D4-8A51-8E6D987774F2} = {46AAC8F1-FF8D-43BC-BA59-E8E52C22BAF7}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {9769F039-DCCE-4887-8816-3C2B8E219941}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest.xml b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest.xml
new file mode 100644
index 0000000..5041371
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest.xml
@@ -0,0 +1,26 @@
+
+
+ NewNugetTest
+
+ Automation
+ SKYLINE2\Pedro
+ FALSE
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/.editorconfig b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/NewNugetTest_1.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/NewNugetTest_1.cs
new file mode 100644
index 0000000..1ce974e
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/NewNugetTest_1.cs
@@ -0,0 +1,71 @@
+/*
+****************************************************************************
+* Copyright (c) 2022, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+dd/mm/2022 1.0.0.1 XXX, Skyline Initial version
+****************************************************************************
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using Skyline.DataMiner.Automation;
+
+///
+/// DataMiner Script Class.
+///
+public class Script
+{
+ ///
+ /// The Script entry point.
+ ///
+ /// Link with SLAutomation process.
+ public void Run(Engine engine)
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/NewNugetTest_1.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/NewNugetTest_1.csproj
new file mode 100644
index 0000000..0afdb1c
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/NewNugetTest_1.csproj
@@ -0,0 +1,83 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {6CD1E51A-B664-48D4-8A51-8E6D987774F2}
+ Library
+ Properties
+ NewNugetTest_1
+ NewNugetTest_1
+ v4.6.2
+ 512
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\SonarLint-QuickActions-Active.ruleset
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\SonarLint-QuickActions-Inactive.ruleset
+
+
+ None
+
+
+
+
+ C:\Skyline DataMiner\Files\SLManagedAutomation.dll
+
+
+ C:\Skyline DataMiner\Files\SLNetTypes.dll
+
+
+
+ C:\Skyline DataMiner\Files\Skyline.DataMiner.Storage.Types.dll
+
+
+ C:\Skyline DataMiner\ProtocolScripts\SLLoggerUtil.dll
+
+
+
+
+
+
+
+
+
+
+ 0.1.0
+
+
+ 1.0.2
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/Properties/AssemblyInfo.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a4785c2
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("NewNugetTest_1")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("NewNugetTest_1")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("61EDA42D-AB3D-40AA-9D1C-EBC5AEEB2C67")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/Settings.StyleCop b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/Settings.StyleCop
new file mode 100644
index 0000000..341ff75
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution4/NewNugetTest_1/Settings.StyleCop
@@ -0,0 +1,301 @@
+
+
+ NoMerge
+
+
+
+
+
+
+ False
+
+
+
+
+
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+
+ ab
+ ac
+ ad
+ af
+ ai
+ al
+ ao
+ as
+ ax
+ b
+ by
+ c
+ d
+ dt
+ e
+ f
+ hs
+ i
+ ip
+ is
+ l
+ lb
+ lc
+ ld
+ lf
+ li
+ ll
+ lo
+ ls
+ lx
+ no
+ o
+ qb
+ qc
+ qd
+ qf
+ qi
+ ql
+ qo
+ qs
+ qx
+ rx
+ s
+ sb
+ sc
+ sd
+ sf
+ sh
+ si
+ sl
+ so
+ ss
+ sx
+ to
+ ts
+ tx
+ ui
+ ul
+ x
+
+
+
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ True
+
+
+
+
+ True
+
+
+
+
+ True
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/.gitignore b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/.gitignore
new file mode 100644
index 0000000..7ded850
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/.gitignore
@@ -0,0 +1,17 @@
+**/bin/*
+**/obj/*
+.vs/*
+packages/*
+**/.svn
+_git2_*
+**/StyleCop.Cache
+# solution user option files
+*.suo
+# protocol checklist template
+**/*.dotx
+# Temporary MS Office file (opened document)
+~$*
+# visual studio project user setting
+**/*.csproj.user
+# resharper solution user settings
+*sln.DotSettings.user
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/AutomationScript.sln b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/AutomationScript.sln
new file mode 100644
index 0000000..85a836d
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/AutomationScript.sln
@@ -0,0 +1,58 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33110.190
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{3362CAC5-3701-4E61-83EF-3CB7BF5F3E94}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{03C1835A-27E5-4514-B9A9-19F184AFFB5D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{0B655075-9F22-4C94-B53F-6F403E25AC0E}"
+ ProjectSection(SolutionItems) = preProject
+ Dlls\readme.txt = Dlls\readme.txt
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{D9AD8CEE-CE8F-41E6-97D0-241941A6A5AD}"
+ ProjectSection(SolutionItems) = preProject
+ Documentation\readme.txt = Documentation\readme.txt
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code Analysis", "Code Analysis", "{C6E1C69B-206C-4E66-B2C2-681032A75D80}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\Code Analysis\qaction-debug.ruleset = Internal\Code Analysis\qaction-debug.ruleset
+ Internal\Code Analysis\qaction-release.ruleset = Internal\Code Analysis\qaction-release.ruleset
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "New", "New", "{93EAC44B-4FA9-477D-9362-3C0E1913F54B}"
+ ProjectSection(SolutionItems) = preProject
+ New.xml = New.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{ED261820-7657-4A75-B768-893FE426237E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "New_1", "New_1\New_1.csproj", "{E4790A62-ED3B-4FE8-8B27-75CAA38C3F74}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E4790A62-ED3B-4FE8-8B27-75CAA38C3F74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E4790A62-ED3B-4FE8-8B27-75CAA38C3F74}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E4790A62-ED3B-4FE8-8B27-75CAA38C3F74}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E4790A62-ED3B-4FE8-8B27-75CAA38C3F74}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {C6E1C69B-206C-4E66-B2C2-681032A75D80} = {3362CAC5-3701-4E61-83EF-3CB7BF5F3E94}
+ {93EAC44B-4FA9-477D-9362-3C0E1913F54B} = {03C1835A-27E5-4514-B9A9-19F184AFFB5D}
+ {ED261820-7657-4A75-B768-893FE426237E} = {93EAC44B-4FA9-477D-9362-3C0E1913F54B}
+ {E4790A62-ED3B-4FE8-8B27-75CAA38C3F74} = {ED261820-7657-4A75-B768-893FE426237E}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {92A0A026-B765-43A6-98A0-931CA4DBD93E}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Dlls/MyCustomDll.dll b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Dlls/MyCustomDll.dll
new file mode 100644
index 0000000..d6c69d5
Binary files /dev/null and b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Dlls/MyCustomDll.dll differ
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Dlls/readme.txt b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Dlls/readme.txt
new file mode 100644
index 0000000..a3170b3
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Dlls/readme.txt
@@ -0,0 +1 @@
+This folder contains DLL files that should be placed under the ProtocolScripts folder of DataMiner for this solution to work correctly.
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Documentation/readme.txt b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Documentation/readme.txt
new file mode 100644
index 0000000..11d30e6
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Documentation/readme.txt
@@ -0,0 +1 @@
+This folder can be used to add documentation related to this solution.
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Internal/Code Analysis/qaction-debug.ruleset b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Internal/Code Analysis/qaction-debug.ruleset
new file mode 100644
index 0000000..d7c0503
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Internal/Code Analysis/qaction-debug.ruleset
@@ -0,0 +1,355 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Internal/Code Analysis/qaction-release.ruleset b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Internal/Code Analysis/qaction-release.ruleset
new file mode 100644
index 0000000..4981097
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/Internal/Code Analysis/qaction-release.ruleset
@@ -0,0 +1,484 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New.xml b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New.xml
new file mode 100644
index 0000000..db68c5a
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New.xml
@@ -0,0 +1,26 @@
+
+
+ New
+
+ Automation
+ SKYLINE2\Pedro
+ FALSE
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/.editorconfig b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/Class1.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/Class1.cs
new file mode 100644
index 0000000..bf47ca4
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/Class1.cs
@@ -0,0 +1,72 @@
+/*
+****************************************************************************
+* Copyright (c) 2022, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+dd/mm/2022 1.0.0.1 XXX, Skyline Initial version
+****************************************************************************
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+
+using Skyline.DataMiner.Automation;
+
+///
+/// DataMiner Script Class.
+///
+public class Script
+{
+ ///
+ /// The Script entry point.
+ ///
+ /// Link with SLAutomation process.
+ public void Run(Engine engine)
+ {
+ engine.GenerateInformation("testing");
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/New_1.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/New_1.csproj
new file mode 100644
index 0000000..e506387
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/New_1.csproj
@@ -0,0 +1,30 @@
+
+
+
+ netframework462
+ disable
+ disable
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+ ..\Dlls\MyCustomDll.dll
+ myCustomValue
+
+
+
+
+
+
+
+
+
+
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/Subfolder/Class2.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/Subfolder/Class2.cs
new file mode 100644
index 0000000..04de83f
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/Subfolder/Class2.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace New_1.Subfolder
+{
+ internal class Class2
+ {
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/stylecop.json b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution5/New_1/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/AutomationScript.sln b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/AutomationScript.sln
new file mode 100644
index 0000000..32898ba
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/AutomationScript.sln
@@ -0,0 +1,74 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33502.453
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{892C2BFC-8E2F-48DD-9B8A-890124492FE7}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{34958EFF-5785-4B05-820A-539D79CEF5AB}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{DE6BEE84-EFC7-412F-95A6-19AFBF1D1C4C}"
+ ProjectSection(SolutionItems) = preProject
+ Dlls\readme.txt = Dlls\readme.txt
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{5E0D403E-AF71-4AEB-8209-B1FA672633B0}"
+ ProjectSection(SolutionItems) = preProject
+ Documentation\readme.txt = Documentation\readme.txt
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code Analysis", "Code Analysis", "{C5010500-5CCC-415A-B900-839A85064AD5}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\Code Analysis\qaction-debug.ruleset = Internal\Code Analysis\qaction-debug.ruleset
+ Internal\Code Analysis\qaction-release.ruleset = Internal\Code Analysis\qaction-release.ruleset
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{1C822BEE-4BD0-42B3-AFE4-E7187B995140}"
+ ProjectSection(SolutionItems) = preProject
+ Utils.xml = Utils.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{B96B64C6-06B9-4B2C-9AB3-1034A4FCB5EC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utils_2", "Utils_2\Utils_2.csproj", "{87166617-8543-461B-AAD9-D1251586D3A9}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SimpleScript", "SimpleScript", "{64B29F28-AD64-4691-AD38-B2DEDF3047F8}"
+ ProjectSection(SolutionItems) = preProject
+ SimpleScript.xml = SimpleScript.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{CB60A7F9-F32C-4673-A492-44CDE4583280}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleScript_2", "SimpleScript_2\SimpleScript_2.csproj", "{9A325A21-7645-4FD2-98B7-98BBB53464F3}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {87166617-8543-461B-AAD9-D1251586D3A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {87166617-8543-461B-AAD9-D1251586D3A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {87166617-8543-461B-AAD9-D1251586D3A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {87166617-8543-461B-AAD9-D1251586D3A9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9A325A21-7645-4FD2-98B7-98BBB53464F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9A325A21-7645-4FD2-98B7-98BBB53464F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9A325A21-7645-4FD2-98B7-98BBB53464F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9A325A21-7645-4FD2-98B7-98BBB53464F3}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {C5010500-5CCC-415A-B900-839A85064AD5} = {892C2BFC-8E2F-48DD-9B8A-890124492FE7}
+ {1C822BEE-4BD0-42B3-AFE4-E7187B995140} = {34958EFF-5785-4B05-820A-539D79CEF5AB}
+ {B96B64C6-06B9-4B2C-9AB3-1034A4FCB5EC} = {1C822BEE-4BD0-42B3-AFE4-E7187B995140}
+ {87166617-8543-461B-AAD9-D1251586D3A9} = {B96B64C6-06B9-4B2C-9AB3-1034A4FCB5EC}
+ {64B29F28-AD64-4691-AD38-B2DEDF3047F8} = {34958EFF-5785-4B05-820A-539D79CEF5AB}
+ {CB60A7F9-F32C-4673-A492-44CDE4583280} = {64B29F28-AD64-4691-AD38-B2DEDF3047F8}
+ {9A325A21-7645-4FD2-98B7-98BBB53464F3} = {CB60A7F9-F32C-4673-A492-44CDE4583280}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {FEBD1C0E-0FBA-4B7B-8B02-991A1E16EF9A}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Dlls/readme.txt b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Dlls/readme.txt
new file mode 100644
index 0000000..a3170b3
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Dlls/readme.txt
@@ -0,0 +1 @@
+This folder contains DLL files that should be placed under the ProtocolScripts folder of DataMiner for this solution to work correctly.
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Documentation/readme.txt b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Documentation/readme.txt
new file mode 100644
index 0000000..11d30e6
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Documentation/readme.txt
@@ -0,0 +1 @@
+This folder can be used to add documentation related to this solution.
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Internal/Code Analysis/qaction-debug.ruleset b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Internal/Code Analysis/qaction-debug.ruleset
new file mode 100644
index 0000000..d7c0503
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Internal/Code Analysis/qaction-debug.ruleset
@@ -0,0 +1,355 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Internal/Code Analysis/qaction-release.ruleset b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Internal/Code Analysis/qaction-release.ruleset
new file mode 100644
index 0000000..4981097
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Internal/Code Analysis/qaction-release.ruleset
@@ -0,0 +1,484 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript.xml b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript.xml
new file mode 100644
index 0000000..f20d465
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript.xml
@@ -0,0 +1,20 @@
+
+ SimpleScript
+
+ Automation
+ SKYLINE2\Pedro
+ FALSE
+
+
+
+
+
+
+
+
+
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/.editorconfig b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/Properties/AssemblyInfo.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..26421d8
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("SimpleScript_2")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("SimpleScript_2")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("B0CE18F2-D752-484B-AFB6-7872E5EE9C3E")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/SimpleScript_2.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/SimpleScript_2.cs
new file mode 100644
index 0000000..b959a14
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/SimpleScript_2.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using Skyline.DataMiner.Automation;
+using MyUtils;
+
+///
+/// DataMiner Script Class.
+///
+public class Script
+{
+ ///
+ /// The Script entry point.
+ ///
+ /// Link with SLAutomation process.
+ public void Run(Engine engine)
+ {
+ engine.GenerateInformation(Utils.MakeUppercase("test"));
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/SimpleScript_2.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/SimpleScript_2.csproj
new file mode 100644
index 0000000..b02bde5
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/SimpleScript_2.csproj
@@ -0,0 +1,78 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {9A325A21-7645-4FD2-98B7-98BBB53464F3}
+ Library
+ Properties
+ SimpleScript_2
+ SimpleScript_2
+ v4.6.2
+ 512
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\SimpleScript_2.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\SimpleScript_2.xml
+
+
+ None
+
+
+
+ {87166617-8543-461b-aad9-d1251586d3a9}
+ Utils_2
+
+
+
+
+
+
+
+
+
+
+
+ 10.0.0.5
+
+
+ 1.1.118
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/stylecop.json b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/SimpleScript_2/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils.xml b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils.xml
new file mode 100644
index 0000000..67dbc74
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils.xml
@@ -0,0 +1,22 @@
+
+ Utils
+
+ Automation
+ SKYLINE2\Pedro
+ FALSE
+
+
+
+
+
+
+
+
+
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/.editorconfig b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/Properties/AssemblyInfo.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..8c5e770
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Utils_2")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("Utils_2")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("25C16F9B-80D8-45DE-B4F6-A17E277E12DD")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/Utils_2.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/Utils_2.cs
new file mode 100644
index 0000000..b0fb546
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/Utils_2.cs
@@ -0,0 +1,10 @@
+namespace MyUtils
+{
+ public static class Utils
+ {
+ public static string MakeUppercase(string input)
+ {
+ return input.ToUpper();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/Utils_2.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/Utils_2.csproj
new file mode 100644
index 0000000..8d2492d
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/Utils_2.csproj
@@ -0,0 +1,74 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {87166617-8543-461B-AAD9-D1251586D3A9}
+ Library
+ Properties
+ Utils_2
+ Utils_2
+ v4.6.2
+ 512
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\Utils_2.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\Utils_2.xml
+
+
+ None
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.0.0.5
+
+
+ 1.1.118
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/stylecop.json b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution6/Utils_2/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/AutomationScript.sln b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/AutomationScript.sln
new file mode 100644
index 0000000..0d00cfd
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/AutomationScript.sln
@@ -0,0 +1,65 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33502.453
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{74EC3B5D-279A-4458-B23E-235E86366109}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{82AC8482-EA26-4153-9C1B-994469D318CC}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{6940B21B-8AC6-4D0D-B025-F49C90DDE4DA}"
+ ProjectSection(SolutionItems) = preProject
+ Dlls\readme.txt = Dlls\readme.txt
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{F100D64F-A820-4171-ACC1-D832C68B0B5F}"
+ ProjectSection(SolutionItems) = preProject
+ Documentation\readme.txt = Documentation\readme.txt
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code Analysis", "Code Analysis", "{A13EA19C-3E66-422E-9342-ACDE32D832C9}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\Code Analysis\qaction-debug.ruleset = Internal\Code Analysis\qaction-debug.ruleset
+ Internal\Code Analysis\qaction-release.ruleset = Internal\Code Analysis\qaction-release.ruleset
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LibraryInOwnScript", "LibraryInOwnScript", "{1EF77561-8791-4C0E-B761-83971BB91E91}"
+ ProjectSection(SolutionItems) = preProject
+ LibraryInOwnScript.xml = LibraryInOwnScript.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{91D5272F-D073-4BFF-9902-A3B9D5E55628}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibraryInOwnScript_1", "LibraryInOwnScript_1\LibraryInOwnScript_1.csproj", "{294DDEE0-3E2C-404D-8800-42FE6E040093}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibraryInOwnScript_2", "LibraryInOwnScript_2\LibraryInOwnScript_2.csproj", "{11CD0370-EB38-4DC2-8889-A8F4C9153618}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {294DDEE0-3E2C-404D-8800-42FE6E040093}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {294DDEE0-3E2C-404D-8800-42FE6E040093}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {294DDEE0-3E2C-404D-8800-42FE6E040093}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {294DDEE0-3E2C-404D-8800-42FE6E040093}.Release|Any CPU.Build.0 = Release|Any CPU
+ {11CD0370-EB38-4DC2-8889-A8F4C9153618}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {11CD0370-EB38-4DC2-8889-A8F4C9153618}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {11CD0370-EB38-4DC2-8889-A8F4C9153618}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {11CD0370-EB38-4DC2-8889-A8F4C9153618}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {A13EA19C-3E66-422E-9342-ACDE32D832C9} = {74EC3B5D-279A-4458-B23E-235E86366109}
+ {1EF77561-8791-4C0E-B761-83971BB91E91} = {82AC8482-EA26-4153-9C1B-994469D318CC}
+ {91D5272F-D073-4BFF-9902-A3B9D5E55628} = {1EF77561-8791-4C0E-B761-83971BB91E91}
+ {294DDEE0-3E2C-404D-8800-42FE6E040093} = {91D5272F-D073-4BFF-9902-A3B9D5E55628}
+ {11CD0370-EB38-4DC2-8889-A8F4C9153618} = {91D5272F-D073-4BFF-9902-A3B9D5E55628}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {FFF3BC1D-E941-48A5-810C-4733E5CDB21A}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/Dlls/readme.txt b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/Dlls/readme.txt
new file mode 100644
index 0000000..a3170b3
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/Dlls/readme.txt
@@ -0,0 +1 @@
+This folder contains DLL files that should be placed under the ProtocolScripts folder of DataMiner for this solution to work correctly.
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/Documentation/readme.txt b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/Documentation/readme.txt
new file mode 100644
index 0000000..11d30e6
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/Documentation/readme.txt
@@ -0,0 +1 @@
+This folder can be used to add documentation related to this solution.
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/Internal/Code Analysis/qaction-debug.ruleset b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/Internal/Code Analysis/qaction-debug.ruleset
new file mode 100644
index 0000000..d7c0503
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/Internal/Code Analysis/qaction-debug.ruleset
@@ -0,0 +1,355 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/Internal/Code Analysis/qaction-release.ruleset b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/Internal/Code Analysis/qaction-release.ruleset
new file mode 100644
index 0000000..4981097
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/Internal/Code Analysis/qaction-release.ruleset
@@ -0,0 +1,484 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript.xml b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript.xml
new file mode 100644
index 0000000..06a1fe8
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript.xml
@@ -0,0 +1,33 @@
+
+
+ LibraryInOwnScript
+
+ Automation
+ SKYLINE2\Pedro
+ FALSE
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/.editorconfig b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/LibraryInOwnScript_1.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/LibraryInOwnScript_1.cs
new file mode 100644
index 0000000..e44f3e9
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/LibraryInOwnScript_1.cs
@@ -0,0 +1,11 @@
+using MyUtils;
+
+using Skyline.DataMiner.Automation;
+
+public class Script
+{
+ public void Run(Engine engine)
+ {
+ engine.GenerateInformation(Utils.MakeUppercase("test"));
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/LibraryInOwnScript_1.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/LibraryInOwnScript_1.csproj
new file mode 100644
index 0000000..c123d58
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/LibraryInOwnScript_1.csproj
@@ -0,0 +1,80 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {294DDEE0-3E2C-404D-8800-42FE6E040093}
+ Library
+ Properties
+ LibraryInOwnScript_1
+ LibraryInOwnScript_1
+ v4.6.2
+ 512
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\LibraryInOwnScript_1.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\LibraryInOwnScript_1.xml
+
+
+ None
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.0.0.5
+
+
+ 1.1.118
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+ {11cd0370-eb38-4dc2-8889-a8f4c9153618}
+ LibraryInOwnScript_2
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/Properties/AssemblyInfo.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..11a9e3b
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("LibraryInOwnScript_1")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("LibraryInOwnScript_1")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("94A92E5F-97D1-4154-92AB-6739FA50259B")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/stylecop.json b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_1/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/.editorconfig b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/LibraryInOwnScript_2.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/LibraryInOwnScript_2.cs
new file mode 100644
index 0000000..b0fb546
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/LibraryInOwnScript_2.cs
@@ -0,0 +1,10 @@
+namespace MyUtils
+{
+ public static class Utils
+ {
+ public static string MakeUppercase(string input)
+ {
+ return input.ToUpper();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/LibraryInOwnScript_2.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/LibraryInOwnScript_2.csproj
new file mode 100644
index 0000000..53fe672
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/LibraryInOwnScript_2.csproj
@@ -0,0 +1,74 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {11CD0370-EB38-4DC2-8889-A8F4C9153618}
+ Library
+ Properties
+ LibraryInOwnScript_2
+ LibraryInOwnScript_2
+ v4.6.2
+ 512
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\LibraryInOwnScript_2.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\LibraryInOwnScript_2.xml
+
+
+ None
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.0.0.5
+
+
+ 1.1.118
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/Properties/AssemblyInfo.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..ed58ab8
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("LibraryInOwnScript_2")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("LibraryInOwnScript_2")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("E78B87C1-A88E-4D9D-B050-82B9C27D0B8E")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/stylecop.json b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution7/LibraryInOwnScript_2/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/CompanionFiles/Skyline DataMiner/AboutThisFolder.md b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/CompanionFiles/Skyline DataMiner/AboutThisFolder.md
new file mode 100644
index 0000000..a7fc8db
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/CompanionFiles/Skyline DataMiner/AboutThisFolder.md
@@ -0,0 +1 @@
+This folder can contain any file you would like to add under the Skyline DataMiner folder while installing the Automation scripts.
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Directory.Build.props b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Directory.Build.props
new file mode 100644
index 0000000..5c71c5b
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Directory.Build.props
@@ -0,0 +1,20 @@
+
+
+ x86
+ true
+
+
+
+ Properties\stylecop.json
+
+
+ Properties\.editorconfig
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Dlls/ABOUT.md b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Dlls/ABOUT.md
new file mode 100644
index 0000000..a3170b3
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Dlls/ABOUT.md
@@ -0,0 +1 @@
+This folder contains DLL files that should be placed under the ProtocolScripts folder of DataMiner for this solution to work correctly.
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Documentation/ABOUT.md b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Documentation/ABOUT.md
new file mode 100644
index 0000000..a150545
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Documentation/ABOUT.md
@@ -0,0 +1 @@
+Looking for README.md? Check your Solution Root folder. This folder can be used to add documentation related to this solution.
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Internal/.editorconfig b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Internal/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Internal/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Internal/Code Analysis/qaction-debug.ruleset b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Internal/Code Analysis/qaction-debug.ruleset
new file mode 100644
index 0000000..26e7d46
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Internal/Code Analysis/qaction-debug.ruleset
@@ -0,0 +1,355 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Internal/Code Analysis/qaction-release.ruleset b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Internal/Code Analysis/qaction-release.ruleset
new file mode 100644
index 0000000..de0890a
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Internal/Code Analysis/qaction-release.ruleset
@@ -0,0 +1,484 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Internal/Code Analysis/stylecop.json b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Internal/Code Analysis/stylecop.json
new file mode 100644
index 0000000..b2d519d
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Internal/Code Analysis/stylecop.json
@@ -0,0 +1,74 @@
+{
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "indentation": {
+ "useTabs": true,
+ "tabSize": 4
+ },
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/README.md b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/README.md
new file mode 100644
index 0000000..f325b14
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/README.md
@@ -0,0 +1 @@
+# SRM_References
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/SRM_References.xml b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/SRM_References.xml
new file mode 100644
index 0000000..9700ca2
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/SRM_References.xml
@@ -0,0 +1,26 @@
+
+
+ SRM_References
+
+ Automation
+ SKYLINE2\XXX
+ FALSE
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/SRM_References_1/SRM_References_1.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/SRM_References_1/SRM_References_1.cs
new file mode 100644
index 0000000..4c6d345
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/SRM_References_1/SRM_References_1.cs
@@ -0,0 +1,74 @@
+/*
+****************************************************************************
+* Copyright (c) 2024, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+09/01/2024 1.0.0.1 XXX, Skyline Initial version
+****************************************************************************
+*/
+
+namespace SRM_References_1
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Text;
+ using Skyline.DataMiner.Automation;
+
+ ///
+ /// Represents a DataMiner Automation script.
+ ///
+ public class Script
+ {
+ ///
+ /// The script entry point.
+ ///
+ /// Link with SLAutomation process.
+ public void Run(IEngine engine)
+ {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/SRM_References_1/SRM_References_1.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/SRM_References_1/SRM_References_1.csproj
new file mode 100644
index 0000000..e48e0d6
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/SRM_References_1/SRM_References_1.csproj
@@ -0,0 +1,29 @@
+
+
+ net462
+ Skyline Communications
+ © Skyline Communications
+ true
+
+
+ full
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+
+
+ pdbonly
+ ..\Internal\Code Analysis\qaction-release.ruleset
+
+
+ $(DefineConstants);DCFv1;DBInfo;ALARM_SQUASHING
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Solution8.sln b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Solution8.sln
new file mode 100644
index 0000000..9018e75
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution8/Solution8.sln
@@ -0,0 +1,73 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33502.453
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{A87088A1-0B35-4491-909D-187087198E1B}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\.editorconfig = Internal\.editorconfig
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{6F70CA70-E53E-4109-92E7-265D98D548BE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{471BB13E-D62E-407F-9F53-B3EA4653F9BD}"
+ ProjectSection(SolutionItems) = preProject
+ Dlls\ABOUT.md = Dlls\ABOUT.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CompanionFiles", "CompanionFiles", "{26FCFCA0-71B5-4026-B097-AA5A17659EC0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Skyline DataMiner", "Skyline DataMiner", "{5032461D-2741-41E8-B247-27EBBA68E05E}"
+ ProjectSection(SolutionItems) = preProject
+ CompanionFiles\Skyline DataMiner\AboutThisFolder.md = CompanionFiles\Skyline DataMiner\AboutThisFolder.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{B3274593-F594-45F2-932A-16488B459B5B}"
+ ProjectSection(SolutionItems) = preProject
+ Documentation\ABOUT.md = Documentation\ABOUT.md
+ README.md = README.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{F8938D60-51A0-4880-9CFC-19C66379BB5D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code Analysis", "Code Analysis", "{EE32BE80-C8BB-4815-B894-A5C78DD4E4E1}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\Code Analysis\qaction-debug.ruleset = Internal\Code Analysis\qaction-debug.ruleset
+ Internal\Code Analysis\qaction-release.ruleset = Internal\Code Analysis\qaction-release.ruleset
+ Internal\Code Analysis\stylecop.json = Internal\Code Analysis\stylecop.json
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SRM_References", "SRM_References", "{8DF060FB-76A9-43D6-85DD-1BEA7F4D34E7}"
+ ProjectSection(SolutionItems) = preProject
+ SRM_References.xml = SRM_References.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{7D094640-D749-4446-9BC3-F6BC0FA431CE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SRM_References_1", "SRM_References_1\SRM_References_1.csproj", "{8C08780C-A0D6-4957-A375-ABC625462D26}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8C08780C-A0D6-4957-A375-ABC625462D26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8C08780C-A0D6-4957-A375-ABC625462D26}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8C08780C-A0D6-4957-A375-ABC625462D26}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8C08780C-A0D6-4957-A375-ABC625462D26}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {5032461D-2741-41E8-B247-27EBBA68E05E} = {26FCFCA0-71B5-4026-B097-AA5A17659EC0}
+ {EE32BE80-C8BB-4815-B894-A5C78DD4E4E1} = {A87088A1-0B35-4491-909D-187087198E1B}
+ {8DF060FB-76A9-43D6-85DD-1BEA7F4D34E7} = {6F70CA70-E53E-4109-92E7-265D98D548BE}
+ {7D094640-D749-4446-9BC3-F6BC0FA431CE} = {8DF060FB-76A9-43D6-85DD-1BEA7F4D34E7}
+ {8C08780C-A0D6-4957-A375-ABC625462D26} = {7D094640-D749-4446-9BC3-F6BC0FA431CE}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {E417B42F-4058-46CD-83CA-C981FA714F7C}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/CompanionFiles/Skyline DataMiner/AboutThisFolder.md b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/CompanionFiles/Skyline DataMiner/AboutThisFolder.md
new file mode 100644
index 0000000..a7fc8db
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/CompanionFiles/Skyline DataMiner/AboutThisFolder.md
@@ -0,0 +1 @@
+This folder can contain any file you would like to add under the Skyline DataMiner folder while installing the Automation scripts.
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Directory.Build.props b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Directory.Build.props
new file mode 100644
index 0000000..5c71c5b
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Directory.Build.props
@@ -0,0 +1,20 @@
+
+
+ x86
+ true
+
+
+
+ Properties\stylecop.json
+
+
+ Properties\.editorconfig
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Dlls/ABOUT.md b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Dlls/ABOUT.md
new file mode 100644
index 0000000..a3170b3
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Dlls/ABOUT.md
@@ -0,0 +1 @@
+This folder contains DLL files that should be placed under the ProtocolScripts folder of DataMiner for this solution to work correctly.
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Documentation/ABOUT.md b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Documentation/ABOUT.md
new file mode 100644
index 0000000..a150545
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Documentation/ABOUT.md
@@ -0,0 +1 @@
+Looking for README.md? Check your Solution Root folder. This folder can be used to add documentation related to this solution.
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Internal/.editorconfig b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Internal/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Internal/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Internal/Code Analysis/qaction-debug.ruleset b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Internal/Code Analysis/qaction-debug.ruleset
new file mode 100644
index 0000000..26e7d46
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Internal/Code Analysis/qaction-debug.ruleset
@@ -0,0 +1,355 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Internal/Code Analysis/qaction-release.ruleset b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Internal/Code Analysis/qaction-release.ruleset
new file mode 100644
index 0000000..de0890a
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Internal/Code Analysis/qaction-release.ruleset
@@ -0,0 +1,484 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Internal/Code Analysis/stylecop.json b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Internal/Code Analysis/stylecop.json
new file mode 100644
index 0000000..b2d519d
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Internal/Code Analysis/stylecop.json
@@ -0,0 +1,74 @@
+{
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "indentation": {
+ "useTabs": true,
+ "tabSize": 4
+ },
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/README.md b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/README.md
new file mode 100644
index 0000000..f325b14
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/README.md
@@ -0,0 +1 @@
+# SRM_References
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/SRM_References.xml b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/SRM_References.xml
new file mode 100644
index 0000000..9700ca2
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/SRM_References.xml
@@ -0,0 +1,26 @@
+
+
+ SRM_References
+
+ Automation
+ SKYLINE2\XXX
+ FALSE
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/SRM_References_1/SRM_References_1.cs b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/SRM_References_1/SRM_References_1.cs
new file mode 100644
index 0000000..4c6d345
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/SRM_References_1/SRM_References_1.cs
@@ -0,0 +1,74 @@
+/*
+****************************************************************************
+* Copyright (c) 2024, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+09/01/2024 1.0.0.1 XXX, Skyline Initial version
+****************************************************************************
+*/
+
+namespace SRM_References_1
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Text;
+ using Skyline.DataMiner.Automation;
+
+ ///
+ /// Represents a DataMiner Automation script.
+ ///
+ public class Script
+ {
+ ///
+ /// The script entry point.
+ ///
+ /// Link with SLAutomation process.
+ public void Run(IEngine engine)
+ {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/SRM_References_1/SRM_References_1.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/SRM_References_1/SRM_References_1.csproj
new file mode 100644
index 0000000..105a39f
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/SRM_References_1/SRM_References_1.csproj
@@ -0,0 +1,28 @@
+
+
+ net462
+ Skyline Communications
+ © Skyline Communications
+ true
+
+
+ full
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+
+
+ pdbonly
+ ..\Internal\Code Analysis\qaction-release.ruleset
+
+
+ $(DefineConstants);DCFv1;DBInfo;ALARM_SQUASHING
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Solution9.sln b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Solution9.sln
new file mode 100644
index 0000000..9018e75
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/Solution9/Solution9.sln
@@ -0,0 +1,73 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33502.453
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{A87088A1-0B35-4491-909D-187087198E1B}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\.editorconfig = Internal\.editorconfig
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{6F70CA70-E53E-4109-92E7-265D98D548BE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{471BB13E-D62E-407F-9F53-B3EA4653F9BD}"
+ ProjectSection(SolutionItems) = preProject
+ Dlls\ABOUT.md = Dlls\ABOUT.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CompanionFiles", "CompanionFiles", "{26FCFCA0-71B5-4026-B097-AA5A17659EC0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Skyline DataMiner", "Skyline DataMiner", "{5032461D-2741-41E8-B247-27EBBA68E05E}"
+ ProjectSection(SolutionItems) = preProject
+ CompanionFiles\Skyline DataMiner\AboutThisFolder.md = CompanionFiles\Skyline DataMiner\AboutThisFolder.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{B3274593-F594-45F2-932A-16488B459B5B}"
+ ProjectSection(SolutionItems) = preProject
+ Documentation\ABOUT.md = Documentation\ABOUT.md
+ README.md = README.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{F8938D60-51A0-4880-9CFC-19C66379BB5D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code Analysis", "Code Analysis", "{EE32BE80-C8BB-4815-B894-A5C78DD4E4E1}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\Code Analysis\qaction-debug.ruleset = Internal\Code Analysis\qaction-debug.ruleset
+ Internal\Code Analysis\qaction-release.ruleset = Internal\Code Analysis\qaction-release.ruleset
+ Internal\Code Analysis\stylecop.json = Internal\Code Analysis\stylecop.json
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SRM_References", "SRM_References", "{8DF060FB-76A9-43D6-85DD-1BEA7F4D34E7}"
+ ProjectSection(SolutionItems) = preProject
+ SRM_References.xml = SRM_References.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{7D094640-D749-4446-9BC3-F6BC0FA431CE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SRM_References_1", "SRM_References_1\SRM_References_1.csproj", "{8C08780C-A0D6-4957-A375-ABC625462D26}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8C08780C-A0D6-4957-A375-ABC625462D26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8C08780C-A0D6-4957-A375-ABC625462D26}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8C08780C-A0D6-4957-A375-ABC625462D26}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8C08780C-A0D6-4957-A375-ABC625462D26}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {5032461D-2741-41E8-B247-27EBBA68E05E} = {26FCFCA0-71B5-4026-B097-AA5A17659EC0}
+ {EE32BE80-C8BB-4815-B894-A5C78DD4E4E1} = {A87088A1-0B35-4491-909D-187087198E1B}
+ {8DF060FB-76A9-43D6-85DD-1BEA7F4D34E7} = {6F70CA70-E53E-4109-92E7-265D98D548BE}
+ {7D094640-D749-4446-9BC3-F6BC0FA431CE} = {8DF060FB-76A9-43D6-85DD-1BEA7F4D34E7}
+ {8C08780C-A0D6-4957-A375-ABC625462D26} = {7D094640-D749-4446-9BC3-F6BC0FA431CE}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {E417B42F-4058-46CD-83CA-C981FA714F7C}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/AutomationScript.sln b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/AutomationScript.sln
new file mode 100644
index 0000000..a65093d
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/AutomationScript.sln
@@ -0,0 +1,58 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.1684
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{E7D3511B-D22F-4DBD-B2C2-7A8C727B3C0F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{48D8F878-FAEF-4765-B4CF-80FF2639D521}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{DB881A31-8F8F-47B9-8FAE-4CF141CF9587}"
+ ProjectSection(SolutionItems) = preProject
+ Dlls\readme.txt = Dlls\readme.txt
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{C7CE0082-E626-4AAC-B896-FA9633E802DD}"
+ ProjectSection(SolutionItems) = preProject
+ Documentation\readme.txt = Documentation\readme.txt
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code Analysis", "Code Analysis", "{B48FAA81-E887-4C35-8C4D-0C22E76AD7D7}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\Code Analysis\SonarLint-QuickActions-Active.ruleset = Internal\Code Analysis\SonarLint-QuickActions-Active.ruleset
+ Internal\Code Analysis\SonarLint-QuickActions-Inactive.ruleset = Internal\Code Analysis\SonarLint-QuickActions-Inactive.ruleset
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NewNugetTest", "NewNugetTest", "{A9C49E31-C166-481A-82F8-1884440C9A1A}"
+ ProjectSection(SolutionItems) = preProject
+ NewNugetTest.xml = NewNugetTest.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{46AAC8F1-FF8D-43BC-BA59-E8E52C22BAF7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NewNugetTest_1", "NewNugetTest_1\NewNugetTest_1.csproj", "{6CD1E51A-B664-48D4-8A51-8E6D987774F2}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6CD1E51A-B664-48D4-8A51-8E6D987774F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6CD1E51A-B664-48D4-8A51-8E6D987774F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6CD1E51A-B664-48D4-8A51-8E6D987774F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6CD1E51A-B664-48D4-8A51-8E6D987774F2}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {B48FAA81-E887-4C35-8C4D-0C22E76AD7D7} = {E7D3511B-D22F-4DBD-B2C2-7A8C727B3C0F}
+ {A9C49E31-C166-481A-82F8-1884440C9A1A} = {48D8F878-FAEF-4765-B4CF-80FF2639D521}
+ {46AAC8F1-FF8D-43BC-BA59-E8E52C22BAF7} = {A9C49E31-C166-481A-82F8-1884440C9A1A}
+ {6CD1E51A-B664-48D4-8A51-8E6D987774F2} = {46AAC8F1-FF8D-43BC-BA59-E8E52C22BAF7}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {9769F039-DCCE-4887-8816-3C2B8E219941}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest.xml b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest.xml
new file mode 100644
index 0000000..5041371
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest.xml
@@ -0,0 +1,26 @@
+
+
+ NewNugetTest
+
+ Automation
+ SKYLINE2\Pedro
+ FALSE
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/.editorconfig b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/NewNugetTest_1.cs b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/NewNugetTest_1.cs
new file mode 100644
index 0000000..00ecbff
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/NewNugetTest_1.cs
@@ -0,0 +1,9 @@
+using Skyline.DataMiner.Automation;
+
+public class Script
+{
+ public void Run(Engine engine)
+ {
+ engine.GenerateInformation("test ›");
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/NewNugetTest_1.csproj b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/NewNugetTest_1.csproj
new file mode 100644
index 0000000..0afdb1c
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/NewNugetTest_1.csproj
@@ -0,0 +1,83 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {6CD1E51A-B664-48D4-8A51-8E6D987774F2}
+ Library
+ Properties
+ NewNugetTest_1
+ NewNugetTest_1
+ v4.6.2
+ 512
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\SonarLint-QuickActions-Active.ruleset
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\SonarLint-QuickActions-Inactive.ruleset
+
+
+ None
+
+
+
+
+ C:\Skyline DataMiner\Files\SLManagedAutomation.dll
+
+
+ C:\Skyline DataMiner\Files\SLNetTypes.dll
+
+
+
+ C:\Skyline DataMiner\Files\Skyline.DataMiner.Storage.Types.dll
+
+
+ C:\Skyline DataMiner\ProtocolScripts\SLLoggerUtil.dll
+
+
+
+
+
+
+
+
+
+
+ 0.1.0
+
+
+ 1.0.2
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/Properties/AssemblyInfo.cs b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a4785c2
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("NewNugetTest_1")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("NewNugetTest_1")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("61EDA42D-AB3D-40AA-9D1C-EBC5AEEB2C67")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/Settings.StyleCop b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/Settings.StyleCop
new file mode 100644
index 0000000..341ff75
--- /dev/null
+++ b/Assemblers.AutomationTests/TestFiles/Solutions/SpecialChar/NewNugetTest_1/Settings.StyleCop
@@ -0,0 +1,301 @@
+
+
+ NoMerge
+
+
+
+
+
+
+ False
+
+
+
+
+
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+
+ ab
+ ac
+ ad
+ af
+ ai
+ al
+ ao
+ as
+ ax
+ b
+ by
+ c
+ d
+ dt
+ e
+ f
+ hs
+ i
+ ip
+ is
+ l
+ lb
+ lc
+ ld
+ lf
+ li
+ ll
+ lo
+ ls
+ lx
+ no
+ o
+ qb
+ qc
+ qd
+ qf
+ qi
+ ql
+ qo
+ qs
+ qx
+ rx
+ s
+ sb
+ sc
+ sd
+ sf
+ sh
+ si
+ sl
+ so
+ ss
+ sx
+ to
+ ts
+ tx
+ ui
+ ul
+ x
+
+
+
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ True
+
+
+
+
+ True
+
+
+
+
+ True
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.Common/AssemblerException.cs b/Assemblers.Common/AssemblerException.cs
new file mode 100644
index 0000000..19f5d50
--- /dev/null
+++ b/Assemblers.Common/AssemblerException.cs
@@ -0,0 +1,45 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Common
+{
+ using System;
+ using System.Runtime.Serialization;
+
+ ///
+ /// The exception that is thrown when the DataMiner item could not be assembled.
+ ///
+ [Serializable]
+ public class AssemblerException : Exception
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public AssemblerException()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class with a specified error message..
+ ///
+ /// The message that describes the error.
+ public AssemblerException(string message) : base(message)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception.
+ ///
+ /// The error message that explains the reason for the exception.
+ /// The exception that is the cause of the current exception. If the inner parameter is not null, the current exception is raised in a catch block that handles the inner exception.
+ public AssemblerException(string message, Exception inner) : base(message, inner)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class with serialized data.
+ ///
+ /// The object that holds the serialized object data.
+ /// The contextual information about the source or destination.
+ protected AssemblerException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
+ }
+}
diff --git a/Assemblers.Common/Assemblers.Common.csproj b/Assemblers.Common/Assemblers.Common.csproj
new file mode 100644
index 0000000..57c95f3
--- /dev/null
+++ b/Assemblers.Common/Assemblers.Common.csproj
@@ -0,0 +1,39 @@
+
+
+
+ netstandard2.0
+ Skyline.DataMiner.CICD.Assemblers.Common
+ Skyline.DataMiner.CICD.Assemblers.Common
+ True
+ True
+ SkylineCommunications
+ Skyline Communications
+ LICENSE.txt
+ True
+ icon.png
+ https://skyline.be/
+ Skyline;DataMiner;CICD
+ Library providing common methods for converting Visual Studio DIS Solutions to individual DataMiner artifacts (e.g. xml, dlls,...).
+ README.md
+ https://github.com/SkylineCommunications/Skyline.DataMiner.CICD.Packages
+ git
+ 0.0.2-local
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Assemblers.Common/BuildResultItems.cs b/Assemblers.Common/BuildResultItems.cs
new file mode 100644
index 0000000..750abd7
--- /dev/null
+++ b/Assemblers.Common/BuildResultItems.cs
@@ -0,0 +1,36 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Common
+{
+ using System.Collections.Generic;
+
+ ///
+ /// Represents the result items of a build.
+ ///
+ public class BuildResultItems
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public BuildResultItems()
+ {
+ Assemblies = new List();
+ DllAssemblies = new List();
+ }
+
+ ///
+ /// Gets or sets the protocol or Automation script XML content.
+ ///
+ /// The protocol or Automation script XML content.
+ public string Document { get; set; }
+
+ ///
+ /// Gets the assemblies of the used NuGet packages.
+ ///
+ /// The assemblies of the used NuGet packages.
+ public ICollection Assemblies { get; }
+
+ ///
+ /// Gets the assemblies of the used DLLs (non-NuGet packages).
+ ///
+ public ICollection DllAssemblies { get; }
+ }
+}
diff --git a/Assemblers.Common/CSharpCodeCombiner.cs b/Assemblers.Common/CSharpCodeCombiner.cs
new file mode 100644
index 0000000..911eac6
--- /dev/null
+++ b/Assemblers.Common/CSharpCodeCombiner.cs
@@ -0,0 +1,92 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Common
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+
+ using Microsoft.CodeAnalysis.CSharp;
+ using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+ using Skyline.DataMiner.CICD.Parsers.Common.VisualStudio.Projects;
+
+ ///
+ /// Combines code of multiple C# code files into a single file.
+ ///
+ public static class CSharpCodeCombiner
+ {
+ ///
+ /// Combines the code of the specified C# code files into a single file.
+ ///
+ /// The C# code files to combine.
+ /// The string that contains the combined code.
+ /// is null.
+ public static string CombineFiles(IList files)
+ {
+ if (files == null)
+ {
+ throw new ArgumentNullException(nameof(files));
+ }
+
+ StringBuilder newCode = new StringBuilder();
+
+ if (files.Count > 1)
+ {
+ var syntaxTrees = files.Select(f => CSharpSyntaxTree.ParseText(f.Content, path: f.Name)).ToList();
+ var compilationUnitRoots = syntaxTrees.Where(t => t.HasCompilationUnitRoot).Select(t => t.GetCompilationUnitRoot()).ToList();
+
+ var usings = GetCombinedUsings(compilationUnitRoots);
+ newCode.AppendLine(SyntaxFactory.List(usings).ToFullString());
+
+ for (int i = 0; i < compilationUnitRoots.Count; i++)
+ {
+ var root = compilationUnitRoots[i];
+
+ if (i != 0)
+ {
+ newCode.AppendLine();
+ }
+
+ newCode.AppendLine("//---------------------------------");
+ newCode.AppendLine("// " + root.SyntaxTree.FilePath);
+ newCode.AppendLine("//---------------------------------");
+
+ string code = root.Members.ToFullString();
+
+ newCode.Append(code);
+ }
+ }
+ else if (files.Count > 0)
+ {
+ newCode.Append(files[0].Content);
+ }
+ else
+ {
+ // No files.
+ }
+
+ return newCode.ToString();
+ }
+
+ private static IEnumerable GetCombinedUsings(IList compilationUnitRoots)
+ {
+ var usings = new HashSet<(string, string)>();
+
+ foreach (var r in compilationUnitRoots)
+ {
+ foreach (var u in r.Usings)
+ {
+ string name = u.Name.ToString();
+ string alias = u.Alias?.Name?.ToString();
+
+ if (!usings.Add((alias, name)))
+ {
+ continue;
+ }
+
+ yield return u;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.Common/DllAssemblyReference.cs b/Assemblers.Common/DllAssemblyReference.cs
new file mode 100644
index 0000000..dec9b39
--- /dev/null
+++ b/Assemblers.Common/DllAssemblyReference.cs
@@ -0,0 +1,64 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Common
+{
+ ///
+ /// Represents an assembly reference of a local DLL.
+ ///
+ public class DllAssemblyReference
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The import value for the QAction@dllImport attribute or Exe/Param element.
+ /// The assembly file path.
+ public DllAssemblyReference(string dllImport, string assemblyPath)
+ {
+ DllImport = dllImport;
+ AssemblyPath = assemblyPath;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The import value for the QAction@dllImport attribute or Exe/Param element.
+ /// The assembly file path.
+ /// Determine if this is a package of the Files folder.
+ public DllAssemblyReference(string dllImport, string assemblyPath, bool isFilesPackage) : this(dllImport, assemblyPath)
+ {
+ IsFilesPackage = isFilesPackage;
+ }
+
+ ///
+ /// Gets the dllImport value.
+ ///
+ /// The dllImport value.
+ ///
+ ///
+ /// -
+ /// This is the value after C:\Skyline DataMiner\ProtocolScripts\.
+ ///
+ ///
+ ///
+ public string DllImport { get; }
+
+ ///
+ /// Gets the Local path for the reference.
+ ///
+ /// The Local path for the reference.
+ public string AssemblyPath { get; }
+
+ ///
+ /// Defines if this reference should be located in the Files a 'Skyline.DataMiner.Files' package.
+ ///
+ public bool IsFilesPackage { get; }
+
+ ///
+ /// Returns a string that represents the current object, including the values of the DllImport, AssemblyPath,
+ /// and IsFilesPackage properties.
+ ///
+ /// A string containing the DllImport, AssemblyPath, and IsFilesPackage values separated by vertical bars (|).
+ public override string ToString()
+ {
+ return $"{DllImport}|{AssemblyPath}|{IsFilesPackage}";
+ }
+ }
+}
diff --git a/Assemblers.Common/NuGetHelper.cs b/Assemblers.Common/NuGetHelper.cs
new file mode 100644
index 0000000..079479f
--- /dev/null
+++ b/Assemblers.Common/NuGetHelper.cs
@@ -0,0 +1,42 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Common
+{
+ using System.Collections.Generic;
+ using System.Linq;
+
+ using Skyline.DataMiner.CICD.Common.NuGet;
+
+ internal static class NuGetHelper
+ {
+ public static readonly IReadOnlyDictionary CustomNuGetPackages = new Dictionary
+ {
+ ["Skyline.DataMiner.Core.SRM"] = (@"SRM\SLSRMLibrary.dll", true),
+ ["Skyline.DataMiner.Core.SRM.Utils.Dijkstra"] = (@"SRM\SLDijkstraSearch.dll", true),
+ ["Skyline.DataMiner.Core.SRM.Utils.IAS"] = (@"SRM\Skyline.DataMiner.Core.SRM.Utils.IAS.dll", true)
+ };
+
+ public static bool IsDevPackNuGetPackage(string packageId)
+ {
+ return DevPackHelper.DevPackNuGetPackages.Contains(packageId) || packageId.StartsWith(DevPackHelper.FilesPrefix);
+ }
+
+ public static bool SkipPackageDependencies(string packageId)
+ {
+ return CustomNuGetPackages.ContainsKey(packageId) || IsSolutionLibraryNuGetPackage(packageId, out _);
+ }
+
+ public static bool IsSolutionLibraryNuGetPackage(string packageId, out string name)
+ {
+ // Solution 'devpacks' (like MediaOps)
+ const string prefix = "Skyline.DataMiner.Dev.Utils.";
+
+ if (packageId.StartsWith(prefix))
+ {
+ name = packageId.Substring(prefix.Length);
+ return true;
+ }
+
+ name = null;
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.Common/NuGetPackageAssemblyData.cs b/Assemblers.Common/NuGetPackageAssemblyData.cs
new file mode 100644
index 0000000..7b01a42
--- /dev/null
+++ b/Assemblers.Common/NuGetPackageAssemblyData.cs
@@ -0,0 +1,136 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Common
+{
+ using System.Collections.Generic;
+ using System.Text;
+
+ ///
+ /// Represents NuGet package assembly data.
+ ///
+ public class NuGetPackageAssemblyData
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public NuGetPackageAssemblyData()
+ {
+ DllImportNugetAssemblyReferences = new List();
+ DllImportFrameworkAssemblyReferences = new HashSet();
+ DllImportDirectoryReferences = new HashSet();
+ DllImportDirectoryReferencesAssembly = new Dictionary();
+
+ ImplicitDllImportDirectoryReferences = new HashSet();
+
+ NugetAssemblies = new List();
+
+ ProcessedAssemblies = new HashSet();
+ }
+
+ ///
+ /// Gets all the NuGet package assemblies that need to be provided in the protocol package.
+ ///
+ /// The NuGet package assemblies that need to be provided in the protocol package.
+ public IList NugetAssemblies { get; }
+
+ ///
+ /// Gets the NuGet package assemblies that need to be provided in the dllImportAttribute.
+ ///
+ /// The NuGet package assemblies that need to be provided in the dllImportAttribute.
+ public IList DllImportNugetAssemblyReferences { get; }
+
+ ///
+ /// Gets the framework assemblies that need to be provided in the dllImport attribute.
+ ///
+ /// The framework assemblies that need to be provided in the dllImport attribute.
+ public ISet DllImportFrameworkAssemblyReferences { get; }
+
+ ///
+ /// Gets the directory paths that need to be added to the dllImport attribute.
+ /// This is always windows style.
+ ///
+ /// The directory paths that need to be added to the dllImport attribute.
+ public ISet DllImportDirectoryReferences { get; }
+
+ ///
+ /// Gets a map of a folder and an assembly that resides in that folder.
+ ///
+ /// A map of a folder and an assembly that resides in that folder.
+ /// For Automation scripts, providing a directory is not supported. Therefore, a DLL of that exists in the specified folder must be provided. This map stores the name of an assembly that exists in the specified folder.
+ public IDictionary DllImportDirectoryReferencesAssembly { get; }
+
+ ///
+ /// Gets the directory paths that are implicitly already covered because an assembly from this folder has already been added to the dllImport attribute.
+ ///
+ /// The directory paths that are implicitly already covered because an assembly from this folder has already been added to the dllImport attribute.
+ public ISet ImplicitDllImportDirectoryReferences { get; }
+
+ ///
+ /// Gets the names of all assemblies that have been processed.
+ ///
+ /// The names of all assemblies that have been processed.
+ public ISet ProcessedAssemblies { get; }
+
+ ///
+ /// Returns a string that provides a detailed, multi-line summary of the current assembly and reference
+ /// collections managed by this instance.
+ ///
+ /// The returned string is intended for diagnostic or debugging purposes and includes all
+ /// relevant reference collections tracked by the instance. The format may change if the structure of the
+ /// collections changes.
+ /// A formatted string containing counts and lists of NuGet assemblies, DllImport references, directory
+ /// references, and processed assemblies. Each collection is displayed on a separate line for readability.
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.AppendLine($"NuGetAssemblies: {NugetAssemblies.Count}");
+ foreach (PackageAssemblyReference reference in NugetAssemblies)
+ {
+ sb.AppendLine($"\t{reference}");
+ }
+
+ sb.AppendLine();
+ sb.AppendLine($"DllImportNugetAssemblyReferences: {DllImportNugetAssemblyReferences.Count}");
+ foreach (PackageAssemblyReference reference in DllImportNugetAssemblyReferences)
+ {
+ sb.AppendLine($"\t{reference}");
+ }
+
+ sb.AppendLine();
+ sb.AppendLine($"DllImportFrameworkAssemblyReferences: {DllImportFrameworkAssemblyReferences.Count}");
+ foreach (string reference in DllImportFrameworkAssemblyReferences)
+ {
+ sb.AppendLine($"\t{reference}");
+ }
+
+ sb.AppendLine();
+ sb.AppendLine($"DllImportDirectoryReferences: {DllImportDirectoryReferences.Count}");
+ foreach (string reference in DllImportDirectoryReferences)
+ {
+ sb.AppendLine($"\t{reference}");
+ }
+
+ sb.AppendLine();
+ sb.AppendLine($"DllImportDirectoryReferencesAssembly: {DllImportDirectoryReferencesAssembly.Count}");
+ foreach (var pair in DllImportDirectoryReferencesAssembly)
+ {
+ sb.AppendLine($"\t{pair.Key}|{pair.Value}");
+ }
+
+ sb.AppendLine();
+ sb.AppendLine($"ImplicitDllImportDirectoryReferences: {ImplicitDllImportDirectoryReferences.Count}");
+ foreach (string reference in ImplicitDllImportDirectoryReferences)
+ {
+ sb.AppendLine($"\t{reference}");
+ }
+
+ sb.AppendLine();
+ sb.AppendLine($"ProcessedAssemblies: {ProcessedAssemblies.Count}");
+ foreach (string processedAssembly in ProcessedAssemblies)
+ {
+ sb.AppendLine($"\t{processedAssembly}");
+ }
+
+ return sb.ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.Common/PackageAssemblyReference.cs b/Assemblers.Common/PackageAssemblyReference.cs
new file mode 100644
index 0000000..de6ed73
--- /dev/null
+++ b/Assemblers.Common/PackageAssemblyReference.cs
@@ -0,0 +1,64 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Common
+{
+ ///
+ /// Represents an assembly reference of a NuGet package.
+ ///
+ public class PackageAssemblyReference
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The import value for the QAction@dllImport attribute or Exe/Param element.
+ /// The assembly file path.
+ public PackageAssemblyReference(string dllImport, string assemblyPath)
+ {
+ DllImport = dllImport;
+ AssemblyPath = assemblyPath;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The import value for the QAction@dllImport attribute or Exe/Param element.
+ /// The assembly file path.
+ /// Determine if this is a package of the Files folder.
+ public PackageAssemblyReference(string dllImport, string assemblyPath, bool isFilesPackage) : this(dllImport, assemblyPath)
+ {
+ IsFilesPackage = isFilesPackage;
+ }
+
+ ///
+ /// Gets the dllImport value.
+ ///
+ /// The dllImport value.
+ ///
+ ///
+ /// -
+ /// This is the value after C:\Skyline DataMiner\ProtocolScripts\DllImport\.
+ ///
+ ///
+ ///
+ public string DllImport { get; }
+
+ ///
+ /// Gets the Local path for the reference.
+ ///
+ /// The Local path for the reference.
+ public string AssemblyPath { get; }
+
+ ///
+ /// Defines if this references is a 'Skyline.DataMiner.Files' package.
+ ///
+ public bool IsFilesPackage { get; }
+
+ ///
+ /// Returns a string that represents the current object, including the values of DllImport, AssemblyPath, and
+ /// IsFilesPackage.
+ ///
+ /// A string containing the DllImport, AssemblyPath, and IsFilesPackage values separated by vertical bars ("|").
+ public override string ToString()
+ {
+ return $"{DllImport}|{AssemblyPath}|{IsFilesPackage}";
+ }
+ }
+}
diff --git a/Assemblers.Common/PackageReferenceProcessor.cs b/Assemblers.Common/PackageReferenceProcessor.cs
new file mode 100644
index 0000000..3ac778d
--- /dev/null
+++ b/Assemblers.Common/PackageReferenceProcessor.cs
@@ -0,0 +1,725 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Common
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading;
+ using System.Threading.Tasks;
+
+ using NuGet.Common;
+ using NuGet.Configuration;
+ using NuGet.Frameworks;
+ using NuGet.Packaging;
+ using NuGet.Packaging.Core;
+ using NuGet.Packaging.Signing;
+ using NuGet.Protocol;
+ using NuGet.Protocol.Core.Types;
+ using NuGet.Resolver;
+ using NuGet.Versioning;
+
+ using Skyline.DataMiner.CICD.Common.NuGet;
+ using Skyline.DataMiner.CICD.FileSystem;
+ using Skyline.DataMiner.CICD.Loggers;
+
+ ///
+ /// Determines all references required for a specific NuGet package.
+ ///
+ public class PackageReferenceProcessor
+ {
+ private readonly ILogCollector logCollector;
+ private readonly ISettings settings;
+ private readonly ILogger nuGetLogger;
+ private readonly ICollection repositories;
+ private readonly SourceRepository rootRepository;
+
+ // V3 package path resolver
+ private readonly VersionFolderPathResolver versionFolderPathResolver;
+ private readonly FrameworkReducer frameworkReducer;
+ private readonly SourceRepositoryProvider sourceRepositoryProvider;
+ private readonly ClientPolicyContext clientPolicyContext;
+
+ private readonly IFileSystem _fileSystem = FileSystem.Instance;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ [Obsolete("Use the constructor with the directory path to be able to read out the nuget.config.")]
+ public PackageReferenceProcessor() : this(directoryForNuGetConfig: null)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Directory path (to find the NuGet.config)
+ public PackageReferenceProcessor(string directoryForNuGetConfig)
+ {
+ nuGetLogger = NullLogger.Instance;
+
+ // Start with the lowest settings. It will automatically look at the other NuGet.config files it can find on the default locations
+ settings = Settings.LoadDefaultSettings(root: directoryForNuGetConfig);
+
+ clientPolicyContext = ClientPolicyContext.GetClientPolicy(settings, nuGetLogger);
+
+ var provider = new PackageSourceProvider(settings);
+ sourceRepositoryProvider = new SourceRepositoryProvider(provider, Repository.Provider.GetCoreV3());
+
+ NuGetRootPath = SettingsUtility.GetGlobalPackagesFolder(settings);
+
+ // Add global packages to be the first repository as it speeds up everything when reading from disk then via internet.
+ var repos = sourceRepositoryProvider.GetRepositories().ToList();
+ rootRepository = new SourceRepository(new PackageSource(NuGetRootPath), Repository.Provider.GetCoreV3());
+ repos.Insert(0, rootRepository);
+ repositories = repos;
+
+ // https://docs.microsoft.com/en-us/nuget/consume-packages/managing-the-global-packages-and-cache-folders
+ versionFolderPathResolver = new VersionFolderPathResolver(NuGetRootPath);
+
+ frameworkReducer = new FrameworkReducer();
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The log collector.
+ /// is .
+ [Obsolete("Use the constructor with the solution directory path to be able to read out the nuget.config from the solution.")]
+ public PackageReferenceProcessor(ILogCollector logCollector) : this(logCollector, directoryForNuGetConfig: null)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The log collector.
+ /// Directory path (to find the NuGet.config)
+ /// is .
+ public PackageReferenceProcessor(ILogCollector logCollector, string directoryForNuGetConfig) : this(directoryForNuGetConfig)
+ {
+ this.logCollector = logCollector ?? throw new ArgumentNullException(nameof(logCollector));
+
+ foreach (SourceRepository sourceRepository in repositories)
+ {
+ LogDebug($"Source: [{sourceRepository.PackageSource?.Name}] {sourceRepository.PackageSource?.Source}");
+ }
+
+ LogDebug($"NuGet Root Path: {NuGetRootPath}");
+ }
+
+ ///
+ /// Gets the NuGet root path.
+ ///
+ /// The NuGet root path.
+ public string NuGetRootPath { get; }
+
+ ///
+ /// Processes the NuGet packages.
+ ///
+ /// The NuGet packages referenced by the project.
+ /// The target framework moniker.
+ /// The assembly info of the processed packages.
+ /// Cannot find the package with the identity.
+ public async Task ProcessAsync(IList projectPackages, string targetFrameworkMoniker)
+ {
+ return await ProcessAsync(projectPackages, targetFrameworkMoniker, new List());
+ }
+
+ ///
+ /// Processes the NuGet packages.
+ ///
+ /// The NuGet packages referenced by the project.
+ /// The target framework moniker.
+ /// Specifies the NuGet package IDs that are included by default.
+ /// The assembly info of the processed packages.
+ /// Cannot find the package with the identity.
+ public async Task ProcessAsync(IList projectPackages, string targetFrameworkMoniker, IReadOnlyCollection defaultIncludedFilesNuGetPackages)
+ {
+ var cancellationToken = CancellationToken.None;
+
+ var provider = DefaultFrameworkNameProvider.Instance;
+ NuGetFramework nugetFramework = NuGetFramework.ParseFrameworkName(targetFrameworkMoniker, provider);
+
+ using (var cacheContext = new SourceCacheContext())
+ {
+ cacheContext.MaxAge = DateTimeOffset.UtcNow;
+
+ var allDependenciesPackageInfos = new HashSet(PackageIdentityComparer.Default);
+
+ var filteredProjectPackages = new List();
+ foreach (var projectPackage in projectPackages)
+ {
+ // Verify whether the specified package version actually is available.
+ var packageIdentity = await GetPackageIdentityAsync(projectPackage, cacheContext, cancellationToken).ConfigureAwait(false);
+
+ if (packageIdentity is null)
+ {
+ throw new InvalidOperationException($"Cannot find package {projectPackage.Id}, version {projectPackage.Version}.");
+ }
+
+ if (DevPackHelper.DevPackNuGetPackages.Contains(packageIdentity.Id) || defaultIncludedFilesNuGetPackages.Contains(packageIdentity.Id))
+ {
+ continue;
+ }
+
+ filteredProjectPackages.Add(packageIdentity);
+
+ await AddPackagesAndDependenciesAsync(packageIdentity, cacheContext, nugetFramework, nuGetLogger, repositories, allDependenciesPackageInfos, cancellationToken).ConfigureAwait(false);
+ }
+
+ var unifiedPackages = GetResolvedPackages(sourceRepositoryProvider, nuGetLogger, filteredProjectPackages, allDependenciesPackageInfos);
+
+ var references = await ProcessPackagesAsync(unifiedPackages, allDependenciesPackageInfos, nugetFramework, defaultIncludedFilesNuGetPackages);
+
+ return references;
+ }
+ }
+
+ ///
+ /// Determines which packages to install after resolving.
+ ///
+ /// Source repository provider.
+ /// The NuGet Logger
+ /// The NuGet packages.
+ /// All top level packages and their dependencies.
+ /// The resolved NuGet packages.
+ private static IEnumerable GetResolvedPackages(ISourceRepositoryProvider sourceRepositoryProvider,
+ ILogger logger, IList extensions,
+ HashSet allPackagesAndDependencies)
+ {
+ if (allPackagesAndDependencies.Count == 0)
+ {
+ // If no dependencies, then return the main package(s) at least.
+ return extensions;
+ }
+
+ // Create a package resolver context (this is used to help figure out which actual package versions to install).
+ var resolverContext = new PackageResolverContext(
+ DependencyBehavior.Lowest,
+ extensions.Select(identity => identity.Id).Distinct(),
+ Enumerable.Empty(),
+ Enumerable.Empty(),
+ Enumerable.Empty(),
+ allPackagesAndDependencies,
+ sourceRepositoryProvider.GetRepositories().Select(s => s.PackageSource),
+ logger);
+
+ var resolver = new PackageResolver();
+
+ // Work out the actual set of packages to install.
+ IEnumerable packagesToInstall = resolver.Resolve(resolverContext, CancellationToken.None)
+ .Select(identity => allPackagesAndDependencies.Single(info => PackageIdentityComparer.Default.Equals(info, identity)));
+
+ return packagesToInstall;
+ }
+
+ private async Task ProcessPackagesAsync(IEnumerable resolvedPackages, HashSet filteredAllPackages, NuGetFramework nugetFramework, IReadOnlyCollection defaultIncludedFilesNuGetPackages)
+ {
+ var nugetPackageAssemblies = new NuGetPackageAssemblyData();
+
+ if (resolvedPackages == null || !resolvedPackages.Any())
+ {
+ return nugetPackageAssemblies;
+ }
+
+ HashSet processedPackages = new HashSet();
+
+ // Resolved Packages are top level NuGet Packages
+ await ProcessResolvedPackagesAsync(resolvedPackages, nugetPackageAssemblies, processedPackages, nugetFramework, defaultIncludedFilesNuGetPackages);
+
+ // Remaining Packages are Dependencies
+ await ProcessRemainingPackagesAsync(filteredAllPackages, nugetPackageAssemblies, processedPackages, nugetFramework);
+
+ return nugetPackageAssemblies;
+ }
+
+ ///
+ /// Processes the resolved/unified packages.
+ ///
+ /// The resolved packages.
+ /// The NuGet package assemblies.
+ /// The processed packages.
+ /// The NuGet framework.
+ /// The default NuGet "Skyline.DataMiner.Files." NuGet packages that are already referenced by default.
+ private async Task ProcessResolvedPackagesAsync(IEnumerable resolvedPackages, NuGetPackageAssemblyData nugetPackageAssemblies, ISet processedPackages, NuGetFramework nugetFramework, IReadOnlyCollection defaultIncludedFilesNuGetPackages)
+ {
+ // For all assemblies in the resolved package list we provide the reference to the assembly.
+ foreach (var resolvedPackage in resolvedPackages)
+ {
+ string packageKey = resolvedPackage.Id.ToLower() + "\\" + resolvedPackage.Version.ToString().ToLower();
+ processedPackages.Add(packageKey);
+
+ using (PackageReaderBase packageReader = GetPackageReader(resolvedPackage))
+ {
+ if (packageReader.GetDevelopmentDependency() || (NuGetHelper.IsDevPackNuGetPackage(resolvedPackage.Id) && defaultIncludedFilesNuGetPackages.Contains(resolvedPackage.Id)))
+ {
+ continue;
+ }
+
+ var libItems = packageReader.GetLibItems().ToList();
+
+ var nearestLibItems = frameworkReducer.GetNearest(nugetFramework, libItems.Select(x => x.TargetFramework));
+ var filteredLibItems = (await ExtractPrimaryAssembliesAsync(libItems, nearestLibItems, packageReader)).ToList();
+
+ if (filteredLibItems.Any())
+ {
+ // Lib items corresponding to the nuspec file.
+ // See: https://docs.microsoft.com/en-us/nuget/reference/nuspec#including-assembly-files
+ foreach (var filteredLibItem in filteredLibItems)
+ {
+ string assemblyName = _fileSystem.Path.GetFileName(filteredLibItem);
+ string dllImportDirectory = packageKey + "\\" + _fileSystem.Path.GetDirectoryName(filteredLibItem).Replace("/", "\\");
+
+ nugetPackageAssemblies.ProcessedAssemblies.Add(assemblyName);
+
+ if (!resolvedPackage.Id.StartsWith(DevPackHelper.FilesPrefix))
+ {
+ nugetPackageAssemblies.ImplicitDllImportDirectoryReferences.Add(dllImportDirectory);
+ }
+
+ string fullPath = null;
+ string dllImportValue;
+ bool isFilePackage = false;
+ bool dontAddToPackageToInstall = false;
+
+ if (resolvedPackage.Id.StartsWith(DevPackHelper.FilesPrefix))
+ {
+ // Full path is not set as it should not be included.
+ dllImportValue = assemblyName;
+ isFilePackage = true;
+ dontAddToPackageToInstall = true;
+ }
+ else if (NuGetHelper.CustomNuGetPackages.TryGetValue(resolvedPackage.Id, out (string Path, bool InDllImportDirectory) info))
+ {
+ dllImportValue = info.Path;
+ isFilePackage = !info.InDllImportDirectory;
+ dontAddToPackageToInstall = true;
+ }
+ else if (NuGetHelper.IsSolutionLibraryNuGetPackage(resolvedPackage.Id, out string name))
+ {
+ // Use the name of the solution library as the folder name. Everything after 'Skyline.DataMiner.Dev.Utils.' is considered the name.
+ dllImportValue = $"SolutionLibraries\\{name}\\{assemblyName}";
+ dontAddToPackageToInstall = true;
+ }
+ else
+ {
+ fullPath = _fileSystem.Path.GetFullPath(_fileSystem.Path.Combine(NuGetRootPath, resolvedPackage.Id.ToLower(), resolvedPackage.Version.ToString().ToLower(), filteredLibItem));
+ dllImportValue = dllImportDirectory + "\\" + assemblyName; // fileInfo.Name
+ }
+
+ var packageAssemblyReference = new PackageAssemblyReference(dllImportValue, fullPath, isFilePackage);
+
+ // Needs to be added as a reference in the dllImport attribute/script references.
+ nugetPackageAssemblies.DllImportNugetAssemblyReferences.Add(packageAssemblyReference);
+
+ if (dontAddToPackageToInstall)
+ {
+ // Should not be provided in the package to install.
+ continue;
+ }
+
+ nugetPackageAssemblies.NugetAssemblies.Add(packageAssemblyReference);
+ }
+ }
+
+ // Frameworkitems are items that are that are part of the targeted .NET framework. These are specified in the nuspec file.
+ // See: https://docs.microsoft.com/en-us/nuget/reference/nuspec#framework-assembly-references
+ var frameworkItems = packageReader.GetFrameworkItems().ToList();
+ var nearestFramework = frameworkReducer.GetNearest(nugetFramework, frameworkItems.Select(x => x.TargetFramework));
+
+ var filteredFrameworkItems = frameworkItems
+ .Where(x => x.TargetFramework.Equals(nearestFramework))
+ .SelectMany(x => x.Items)
+ .Select(x => x + ".dll")
+ .ToList();
+
+ nugetPackageAssemblies.ProcessedAssemblies.AddRange(filteredFrameworkItems);
+ nugetPackageAssemblies.DllImportFrameworkAssemblyReferences.AddRange(filteredFrameworkItems);
+ }
+ }
+ }
+
+ private static async Task> ExtractPrimaryAssembliesAsync(List libItems, NuGetFramework nearestVersion, PackageReaderBase packageReader)
+ {
+ if (nearestVersion == null)
+ {
+ return Array.Empty();
+ }
+
+ var nearestLibItems = libItems.FirstOrDefault(x => x.TargetFramework.Equals(nearestVersion));
+
+ if (nearestLibItems?.Items == null || !nearestLibItems.Items.Any())
+ {
+ return Array.Empty();
+ }
+
+ // Determine short folder name as follows because nearestVersion.GetShortFolderName(); could give a different result (e.g. net40) compared to what is used in the actual package (e.g. net4).
+ var firstItem = nearestLibItems.Items.First();
+ var firstItemParts = firstItem.Split('/');
+
+ string shortFolderName = null;
+
+ if (firstItemParts.Length > 1)
+ {
+ shortFolderName = firstItemParts[1];
+ }
+
+ if (shortFolderName == null)
+ {
+ return Array.Empty();
+ }
+
+ var filteredLibItems = new List();
+ foreach (var libItem in nearestLibItems.Items)
+ {
+ if (!libItem.EndsWith(".dll"))
+ {
+ // Only process DLL files.
+ continue;
+ }
+
+ string prefix = "lib/" + shortFolderName + '/';
+
+ // Safeguard.
+ if (!libItem.StartsWith(prefix))
+ {
+ continue;
+ }
+
+ string subPath = libItem.Substring(prefix.Length);
+ int subfolderNameIndex = subPath.IndexOf('/');
+
+ if (subfolderNameIndex != -1)
+ {
+ string subfolderName = subPath.Substring(0, subfolderNameIndex);
+
+ // Verify whether the assembly is a satellite assembly.
+ // If it is a satellite assembly, do not include it.
+ // For more info about satellite assemblies, refer to https://learn.microsoft.com/en-us/dotnet/core/extensions/create-satellite-assemblies.
+ var satelliteAssemblies = await packageReader.GetSatelliteFilesAsync(subfolderName, CancellationToken.None);
+ var satelliteAssembliesList = satelliteAssemblies.ToList();
+
+ if (satelliteAssembliesList.ToList().Count == 0 || !satelliteAssembliesList.Contains(libItem))
+ {
+ filteredLibItems.Add(libItem);
+ }
+ }
+ else
+ {
+ // Root item, cannot be a satellite assembly.
+ filteredLibItems.Add(libItem);
+ }
+ }
+
+ return filteredLibItems;
+ }
+
+ ///
+ /// Processes the remaining packages skipping the ones that are already processes.
+ ///
+ /// All packages.
+ /// The NuGet package assemblies.
+ /// The processed packages.
+ /// The NuGet framework.
+ private async Task ProcessRemainingPackagesAsync(HashSet allPackages, NuGetPackageAssemblyData nugetPackageAssemblies, ICollection processedPackages, NuGetFramework nugetFramework)
+ {
+ // For all assemblies that are not in the resolved package list, we provide the folder where the assembly can be found.
+ foreach (var packageToInstall in allPackages)
+ {
+ string packageKey = packageToInstall.Id.ToLower() + "\\" + packageToInstall.Version.ToString().ToLower();
+ if (processedPackages.Contains(packageKey))
+ {
+ continue;
+ }
+
+ using (PackageReaderBase packageReader = GetPackageReader(packageToInstall))
+ {
+ if (packageReader.GetDevelopmentDependency() || NuGetHelper.IsDevPackNuGetPackage(packageToInstall.Id))
+ {
+ continue;
+ }
+
+ var libItems = packageReader.GetLibItems().ToList();
+ var nearestLibItems = frameworkReducer.GetNearest(nugetFramework, libItems.Select(x => x.TargetFramework));
+ var filteredLibItems = (await ExtractPrimaryAssembliesAsync(libItems, nearestLibItems, packageReader)).ToList();
+
+ if (filteredLibItems.Any())
+ {
+ var firstFilteredLibItem = filteredLibItems.First();
+ string dllImportDirectory = packageKey + "\\" + _fileSystem.Path.GetDirectoryName(firstFilteredLibItem).Replace("/", "\\");
+
+ // Add the directory to be added to the dllImport attribute so the assembly can be found at runtime.
+ if (!nugetPackageAssemblies.ImplicitDllImportDirectoryReferences.Contains(dllImportDirectory))
+ {
+ nugetPackageAssemblies.DllImportDirectoryReferences.Add(dllImportDirectory + "\\");
+
+ // For Automation scripts we cannot provide a path, so instead the first assembly is provided (as this will result in the path of that assembly to be used as a hint path as well).
+ nugetPackageAssemblies.DllImportDirectoryReferencesAssembly.Add(dllImportDirectory + "\\", dllImportDirectory + "\\" + _fileSystem.Path.GetFileName(firstFilteredLibItem));
+ }
+
+ // Add all assemblies so these get included in the dllImports folder to be loaded at runtime.
+ foreach (var filteredLibItem in filteredLibItems)
+ {
+ var fullPath = _fileSystem.Path.Combine(NuGetRootPath, packageToInstall.Id.ToLower(), packageToInstall.Version.ToString().ToLower(), filteredLibItem);
+ var dllImportValue = dllImportDirectory + "\\" + _fileSystem.Path.GetFileName(filteredLibItem);
+
+ nugetPackageAssemblies.NugetAssemblies.Add(new PackageAssemblyReference(dllImportValue, fullPath));
+ }
+ }
+
+ var frameworkItems = packageReader.GetFrameworkItems().ToList();
+ var nearestFramework = frameworkReducer.GetNearest(nugetFramework, frameworkItems.Select(x => x.TargetFramework));
+
+ var filteredFrameworkItems = frameworkItems
+ .Where(x => x.TargetFramework.Equals(nearestFramework))
+ .SelectMany(x => x.Items)
+ .Select(x => x + ".dll");
+
+ nugetPackageAssemblies.ProcessedAssemblies.AddRange(filteredFrameworkItems);
+ }
+ }
+ }
+
+ private PackageReaderBase GetPackageReader(PackageIdentity packageToInstall)
+ {
+ var installedPath = versionFolderPathResolver.GetInstallPath(packageToInstall.Id, packageToInstall.Version);
+
+ PackageReaderBase packageReader = new PackageFolderReader(installedPath);
+
+ return packageReader;
+ }
+
+ ///
+ /// Retrieves the package.
+ ///
+ /// The package for which the identity should be retrieved.
+ /// The cache.
+ /// A cancellation token.
+ /// The package identity.
+ private async Task GetPackageIdentityAsync(
+ PackageIdentity nugetPackage, SourceCacheContext cache, CancellationToken cancelToken)
+ {
+ if (nugetPackage.HasVersion)
+ {
+ return nugetPackage;
+ }
+
+ foreach (var sourceRepository in repositories)
+ {
+ if (cancelToken.IsCancellationRequested)
+ {
+ break;
+ }
+
+ FindPackageByIdResource findPackageResource = await sourceRepository.GetResourceAsync(cancelToken).ConfigureAwait(false);
+ var allVersions = await findPackageResource.GetAllVersionsAsync(nugetPackage.Id, cache, nuGetLogger, cancelToken).ConfigureAwait(false);
+
+ // No version; choose the latest, allow pre-release if configured.
+ NuGetVersion selected = allVersions.LastOrDefault();
+
+ if (selected == null)
+ {
+ // No versions found in this source.
+ continue;
+ }
+
+ return new PackageIdentity(nugetPackage.Id, selected);
+ }
+
+ return null;
+ }
+
+ ///
+ /// Searches the package dependency graph for the chain of all packages to install.
+ ///
+ private async Task AddPackagesAndDependenciesAsync(PackageIdentity package, SourceCacheContext cacheContext, NuGetFramework framework, ILogger logger, ICollection repositories, ISet allPackages, CancellationToken cancellationToken)
+ {
+ if (allPackages.Contains(package))
+ {
+ // Package was already processed.
+ return;
+ }
+
+ await InstallPackageIfNotFound(package, cacheContext, cancellationToken);
+
+ if (NuGetHelper.SkipPackageDependencies(package.Id))
+ {
+ // Add it to the allPackages as the PackageResolver later on needs it (in case there would be multiple versions).
+ SourceRepository packageSourceRepository = null;
+ foreach (var sourceRepository in repositories)
+ {
+ FindPackageByIdResource findPackageResource = await sourceRepository.GetResourceAsync(cancellationToken).ConfigureAwait(false);
+ var exists = await findPackageResource.DoesPackageExistAsync(package.Id, package.Version, cacheContext, nuGetLogger, cancellationToken).ConfigureAwait(false);
+
+ if (exists)
+ {
+ packageSourceRepository = sourceRepository;
+ break;
+ }
+ }
+
+ if (packageSourceRepository == null)
+ {
+ logCollector?.ReportError($"PackageReferenceProcessor|InstallPackageIfNotFound|Unable to find package '{package.Id}' with version '{package.Version}");
+ return;
+ }
+
+ allPackages.Add(new SourcePackageDependencyInfo(package.Id, package.Version, Array.Empty(), true,
+ packageSourceRepository));
+ return;
+ }
+
+ foreach (var sourceRepository in repositories)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ break;
+ }
+
+ // Get the dependency info for the package.
+ var dependencyInfoResource = await sourceRepository.GetResourceAsync(cancellationToken).ConfigureAwait(false);
+ var dependencyInfo = await dependencyInfoResource.ResolvePackage(
+ package,
+ framework,
+ cacheContext,
+ logger,
+ cancellationToken).ConfigureAwait(false);
+
+ if (dependencyInfo == null)
+ {
+ continue;
+ }
+
+ var filteredDependencyInfo = dependencyInfo.Dependencies.Where(d => !NuGetHelper.IsDevPackNuGetPackage(d.Id));
+
+ var filteredDependencies = new SourcePackageDependencyInfo(dependencyInfo.Id, dependencyInfo.Version, filteredDependencyInfo, dependencyInfo.Listed, dependencyInfo.Source);
+
+ allPackages.Add(filteredDependencies);
+
+ // Process dependencies of dependency.
+ foreach (var dependency in dependencyInfo.Dependencies)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ break;
+ }
+
+ if (NuGetHelper.IsDevPackNuGetPackage(dependency.Id))
+ {
+ continue;
+ }
+
+ await AddPackagesAndDependenciesAsync(
+ new PackageIdentity(dependency.Id, dependency.VersionRange.MinVersion),
+ cacheContext,
+ framework,
+ logger,
+ repositories,
+ allPackages,
+ cancellationToken).ConfigureAwait(false);
+ }
+
+ break;
+ }
+ }
+
+ private async Task InstallPackageIfNotFound(PackageIdentity packageToInstall, SourceCacheContext cacheContext, CancellationToken cancelToken)
+ {
+ var existsResource = await rootRepository.GetResourceAsync(cancelToken);
+ if (existsResource.Exists(packageToInstall, nuGetLogger, cancelToken))
+ {
+ // Package is already installed.
+ return;
+ }
+
+ LogDebug($"InstallPackageIfNotFound|Installing package: {packageToInstall.Id} - {packageToInstall.Version}");
+
+ PackageSource packageSource = null;
+ // Figure out which packageSource is needed
+ foreach (var sourceRepository in repositories)
+ {
+ FindPackageByIdResource findPackageResource = await sourceRepository.GetResourceAsync(cancelToken).ConfigureAwait(false);
+ var exists = await findPackageResource.DoesPackageExistAsync(packageToInstall.Id, packageToInstall.Version, cacheContext, nuGetLogger, cancelToken).ConfigureAwait(false);
+
+ if (exists)
+ {
+ packageSource = sourceRepository.PackageSource;
+ break;
+ }
+ }
+
+ if (packageSource == null)
+ {
+ logCollector?.ReportError($"PackageReferenceProcessor|InstallPackageIfNotFound|Unable to find package '{packageToInstall.Id}' with version '{packageToInstall.Version}");
+ return;
+ }
+
+ var repository = Repository.Factory.GetCoreV3(packageSource);
+ var resource = await repository.GetResourceAsync(cancelToken);
+
+ try
+ {
+ using (DownloadResourceResult downloadResourceResult = await resource.GetDownloadResourceResultAsync(
+ packageToInstall,
+ new PackageDownloadContext(cacheContext),
+ SettingsUtility.GetGlobalPackagesFolder(settings),
+ nuGetLogger,
+ cancelToken))
+ {
+ // Add it to the global package folder
+ using (DownloadResourceResult result = await GlobalPackagesFolderUtility.AddPackageAsync(
+ packageSource.Source,
+ packageToInstall,
+ downloadResourceResult.PackageStream,
+ NuGetRootPath,
+ Guid.Empty,
+ clientPolicyContext,
+ nuGetLogger,
+ CancellationToken.None))
+ {
+ LogDebug($"InstallPackageIfNotFound|Finished installing package {packageToInstall.Id} - {packageToInstall.Version} with status: " + result?.Status);
+ }
+ }
+ }
+ catch
+ {
+ LogDebug("Retrying to add package without caching");
+ string tempDir = FileSystem.Instance.Directory.CreateTemporaryDirectory();
+
+ try
+ {
+ // Retrying without cache
+ using (DownloadResourceResult downloadResourceResult = await resource.GetDownloadResourceResultAsync(
+ packageToInstall,
+ new PackageDownloadContext(cacheContext, tempDir, true),
+ SettingsUtility.GetGlobalPackagesFolder(settings),
+ nuGetLogger,
+ cancelToken))
+ {
+ // Add it to the global package folder
+ using (DownloadResourceResult result = await GlobalPackagesFolderUtility.AddPackageAsync(
+ packageSource.Source,
+ packageToInstall,
+ downloadResourceResult.PackageStream,
+ NuGetRootPath,
+ Guid.Empty,
+ clientPolicyContext,
+ nuGetLogger,
+ CancellationToken.None))
+ {
+ LogDebug($"InstallPackageIfNotFound|Finished installing package {packageToInstall.Id} - {packageToInstall.Version} with status: " + result?.Status);
+ }
+ }
+ }
+ finally
+ {
+ FileSystem.Instance.Directory.DeleteDirectory(tempDir);
+ }
+ }
+ }
+
+ private void LogDebug(string message)
+ {
+ logCollector?.ReportDebug($"PackageReferenceProcessor|{message}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.CommonTests/Assemblers.CommonTests.csproj b/Assemblers.CommonTests/Assemblers.CommonTests.csproj
new file mode 100644
index 0000000..2369db3
--- /dev/null
+++ b/Assemblers.CommonTests/Assemblers.CommonTests.csproj
@@ -0,0 +1,21 @@
+
+
+
+ net48;net8.0
+ false
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
diff --git a/Assemblers.CommonTests/CSharpCodeCombinerTests.cs b/Assemblers.CommonTests/CSharpCodeCombinerTests.cs
new file mode 100644
index 0000000..0912a7e
--- /dev/null
+++ b/Assemblers.CommonTests/CSharpCodeCombinerTests.cs
@@ -0,0 +1,209 @@
+namespace Assemblers.CommonTests
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+
+ using FluentAssertions;
+
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ using Skyline.DataMiner.CICD.Assemblers.Common;
+ using Skyline.DataMiner.CICD.Parsers.Common.VisualStudio.Projects;
+
+ [TestClass]
+ public class CSharpCodeCombinerTests
+ {
+ [TestMethod]
+ public void CombineFiles_Null_ExpectedArgumentNullException()
+ {
+ // Arrange
+
+ // Act
+ Action act = () => CSharpCodeCombiner.CombineFiles(null);
+
+ // Assert
+ act.Should().ThrowExactly();
+ }
+
+ [TestMethod]
+ public void CombineFiles_EmptyList()
+ {
+ // Arrange
+
+ // Act
+ var result = CSharpCodeCombiner.CombineFiles(new List(0));
+
+ // Assert
+ result.Should().BeEmpty();
+ }
+
+ [TestMethod]
+ public void CombineFiles_SingleFile()
+ {
+ // Arrange
+ const string content = "ABC";
+ List files = new List
+ {
+ new ProjectFile("MyProjectFile", content)
+ };
+
+ // Act
+ var result = CSharpCodeCombiner.CombineFiles(files);
+
+ // Assert
+ result.Should().BeEquivalentTo(content);
+ }
+
+ [TestMethod]
+ public void CombineFiles_MultipleFiles_RandomText()
+ {
+ // Arrange
+ const string contentFile1 = "ABC";
+ const string contentFile2 = "DEF";
+ List files = new List
+ {
+ new ProjectFile("MyProjectFile1", contentFile1),
+ new ProjectFile("MyProjectFile2", contentFile2)
+ };
+
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine() // usings but there aren't any
+ .AppendLine("//---------------------------------")
+ .AppendLine("// MyProjectFile1")
+ .AppendLine("//---------------------------------")
+ .AppendLine(contentFile1)
+ .AppendLine("//---------------------------------")
+ .AppendLine("// MyProjectFile2")
+ .AppendLine("//---------------------------------")
+ .Append(contentFile2);
+ string expectedResult = sb.ToString();
+
+ // Act
+ var result = CSharpCodeCombiner.CombineFiles(files);
+
+ // Assert
+ result.Should().BeEquivalentTo(expectedResult);
+ }
+
+ [TestMethod]
+ public void CombineFiles_MultipleFiles_ActualCSharp_WithoutNamespaces()
+ {
+ // Arrange
+ const string contentFile1 = @"using System;
+
+public static class MyExtensions
+{
+ public static string MyMethod()
+ {
+ return String.Empty;
+ }
+}
+";
+ const string contentFile2 = @"using System;
+using System.IO;
+
+public static class MyOtherExtensions
+{
+ public static bool MyOtherMethod(string path)
+ {
+ return Path.HasExtension(path);
+ }
+}";
+ List files = new List
+ {
+ new ProjectFile("MyProjectFile1", contentFile1),
+ new ProjectFile("MyProjectFile2", contentFile2)
+ };
+
+ const string expectedContentFile1 = @"public static class MyExtensions
+{
+ public static string MyMethod()
+ {
+ return String.Empty;
+ }
+}
+";
+ const string expectedContentFile2 = @"public static class MyOtherExtensions
+{
+ public static bool MyOtherMethod(string path)
+ {
+ return Path.HasExtension(path);
+ }
+}";
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine("using System;" + Environment.NewLine + "using System.IO;")
+ .AppendLine()
+ .AppendLine("//---------------------------------")
+ .AppendLine("// MyProjectFile1")
+ .AppendLine("//---------------------------------")
+ .AppendLine()
+ .AppendLine(expectedContentFile1)
+ .AppendLine("//---------------------------------")
+ .AppendLine("// MyProjectFile2")
+ .AppendLine("//---------------------------------")
+ .AppendLine()
+ .Append(expectedContentFile2);
+ string expectedResult = sb.ToString();
+
+ // Act
+ var result = CSharpCodeCombiner.CombineFiles(files);
+
+ // Assert
+ result.Should().BeEquivalentTo(expectedResult);
+ }
+
+ [TestMethod]
+ public void CombineFiles_MultipleFiles_ActualCSharp_WithNamespaces()
+ {
+ // Arrange
+ const string contentFile1 = @"namespace Skyline.Protocol
+{
+ using System;
+
+ public static class MyExtensions
+ {
+ public static string MyMethod()
+ {
+ return String.Empty;
+ }
+ }
+}";
+ const string contentFile2 = @"namespace Skyline.Protocol.Files
+{
+ using System.IO;
+
+ public static class MyOtherExtensions
+ {
+ public static bool MyOtherMethod(string path)
+ {
+ return Path.HasExtension(path);
+ }
+ }
+}";
+ List files = new List
+ {
+ new ProjectFile("MyProjectFile1", contentFile1),
+ new ProjectFile("MyProjectFile2", contentFile2)
+ };
+
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine()
+ .AppendLine("//---------------------------------")
+ .AppendLine("// MyProjectFile1")
+ .AppendLine("//---------------------------------")
+ .AppendLine(contentFile1)
+ .AppendLine("//---------------------------------")
+ .AppendLine("// MyProjectFile2")
+ .AppendLine("//---------------------------------")
+ .Append(contentFile2);
+ string expectedResult = sb.ToString();
+
+ // Act
+ var result = CSharpCodeCombiner.CombineFiles(files);
+
+ // Assert
+ result.Should().BeEquivalentTo(expectedResult);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.CommonTests/PackageReferenceProcessorTests.cs b/Assemblers.CommonTests/PackageReferenceProcessorTests.cs
new file mode 100644
index 0000000..6afe61e
--- /dev/null
+++ b/Assemblers.CommonTests/PackageReferenceProcessorTests.cs
@@ -0,0 +1,440 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Common.Tests
+{
+ using System.Collections.Generic;
+ using System.Threading.Tasks;
+
+ using FluentAssertions;
+ using FluentAssertions.Equivalency;
+
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ using NuGet.Packaging.Core;
+ using NuGet.Versioning;
+
+ using Skyline.DataMiner.CICD.Common.NuGet;
+
+ [TestClass]
+ public class PackageReferenceProcessorTests
+ {
+ [TestMethod]
+ public async Task ProcessAsyncTest_FilesNuGet_OnlyReturnsAssemblyName_Protocol()
+ {
+ var packageReferenceProcessor = new PackageReferenceProcessor(directoryForNuGetConfig: null);
+
+ IList projectPackages = new List
+ {
+ new PackageIdentity("Skyline.DataMiner.Dev.Protocol", new NuGetVersion("10.3.4.1")),
+ new PackageIdentity("Skyline.DataMiner.Files.SLManagedAutomation", new NuGetVersion("10.3.4.1")),
+ new PackageIdentity("Skyline.DataMiner.Files.SLMediationSnippets", new NuGetVersion("10.3.4.1"))
+ };
+
+ string targetFrameworkMoniker = ".NETFramework,Version=v4.6.2";
+
+ var result = await packageReferenceProcessor.ProcessAsync(projectPackages, targetFrameworkMoniker, DevPackHelper.ProtocolDevPackNuGetDependenciesIncludingTransitive);
+
+ Assert.IsNotNull(result);
+ Assert.IsEmpty(result.ImplicitDllImportDirectoryReferences);
+ Assert.IsEmpty(result.DllImportFrameworkAssemblyReferences);
+ Assert.IsEmpty(result.DllImportDirectoryReferences);
+ Assert.IsEmpty(result.DllImportDirectoryReferencesAssembly);
+
+ Assert.IsEmpty(result.NugetAssemblies); // Assembly must not be included in package, only needs to be added to dllImport.
+ Assert.HasCount(2, result.DllImportNugetAssemblyReferences);
+
+ Assert.HasCount(2, result.ProcessedAssemblies);
+ }
+
+ [TestMethod]
+ public async Task ProcessAsyncTest_FilesNuGet_OnlyReturnsAssemblyName_Automation()
+ {
+ var packageReferenceProcessor = new PackageReferenceProcessor(directoryForNuGetConfig: null);
+
+ IList projectPackages = new List
+ {
+ new PackageIdentity("Skyline.DataMiner.Dev.Automation", new NuGetVersion("10.3.4.1")),
+ new PackageIdentity("Skyline.DataMiner.Files.SLManagedScripting", new NuGetVersion("10.3.4.1")),
+ new PackageIdentity("Skyline.DataMiner.Files.SLMediationSnippets", new NuGetVersion("10.3.4.1"))
+ };
+
+ string targetFrameworkMoniker = ".NETFramework,Version=v4.6.2";
+
+ var result = await packageReferenceProcessor.ProcessAsync(projectPackages, targetFrameworkMoniker, DevPackHelper.AutomationDevPackNuGetDependenciesIncludingTransitive);
+
+ Assert.IsNotNull(result);
+ Assert.IsEmpty(result.ImplicitDllImportDirectoryReferences);
+ Assert.IsEmpty(result.DllImportFrameworkAssemblyReferences);
+ Assert.IsEmpty(result.DllImportDirectoryReferences);
+ Assert.IsEmpty(result.DllImportDirectoryReferencesAssembly);
+
+ Assert.IsEmpty(result.NugetAssemblies); // Assembly must not be included in package, only needs to be added to dllImport.
+ Assert.HasCount(2, result.DllImportNugetAssemblyReferences);
+
+ Assert.HasCount(2, result.ProcessedAssemblies);
+ }
+
+ [TestMethod]
+ public async Task ProcessAsyncTest_CommonScenario()
+ {
+ // Arrange
+ var packageReferenceProcessor = new PackageReferenceProcessor(directoryForNuGetConfig: null);
+
+ IList projectPackages = new List
+ {
+ new PackageIdentity("Skyline.DataMiner.Dev.Automation", new NuGetVersion("10.3.4.1")),
+ new PackageIdentity("Newtonsoft.Json", new NuGetVersion("13.0.3")),
+ new PackageIdentity("Skyline.DataMiner.Utils.ExportImport", new NuGetVersion("1.0.0")),
+ };
+
+ const string targetFrameworkMoniker = ".NETFramework,Version=v4.6.2";
+
+ const string pathJson = "newtonsoft.json\\13.0.3\\lib\\net45";
+ const string pathExportImport = "skyline.dataminer.utils.exportimport\\1.0.0\\lib\\netstandard2.0";
+ var expectedResult = new NuGetPackageAssemblyData
+ {
+ ImplicitDllImportDirectoryReferences =
+ {
+ pathJson,
+ pathExportImport,
+ },
+ DllImportNugetAssemblyReferences =
+ {
+ new PackageAssemblyReference(pathJson + "\\Newtonsoft.Json.dll", null, false),
+ new PackageAssemblyReference(pathExportImport + "\\Skyline.DataMiner.Utils.ExportImport.dll", null, false),
+ },
+ NugetAssemblies =
+ {
+ new PackageAssemblyReference(pathJson + "\\Newtonsoft.Json.dll", null, false),
+ new PackageAssemblyReference(pathExportImport + "\\Skyline.DataMiner.Utils.ExportImport.dll", null, false),
+ },
+ ProcessedAssemblies =
+ {
+ "Newtonsoft.Json.dll",
+ "Skyline.DataMiner.Utils.ExportImport.dll",
+ }
+ };
+
+ // Act
+ var result = await packageReferenceProcessor.ProcessAsync(projectPackages, targetFrameworkMoniker);
+
+ // Assert
+ result.Should().BeEquivalentTo(expectedResult, ExcludeAssemblyPath);
+ }
+
+ [TestMethod]
+ public async Task ProcessAsyncTest_UseOfOtherDevPackFile()
+ {
+ // Arrange
+ var packageReferenceProcessor = new PackageReferenceProcessor(directoryForNuGetConfig: null);
+
+ IList projectPackages = new List
+ {
+ new PackageIdentity("Skyline.DataMiner.Dev.Automation", new NuGetVersion("10.3.4.1")),
+ new PackageIdentity("Skyline.DataMiner.Files.SLManagedScripting", new NuGetVersion("10.3.4.1")),
+ new PackageIdentity("Newtonsoft.Json", new NuGetVersion("13.0.3")),
+ new PackageIdentity("Skyline.DataMiner.Utils.ExportImport", new NuGetVersion("1.0.0")),
+ };
+
+ const string targetFrameworkMoniker = ".NETFramework,Version=v4.6.2";
+
+ const string pathJson = "newtonsoft.json\\13.0.3\\lib\\net45";
+ const string pathExportImport = "skyline.dataminer.utils.exportimport\\1.0.0\\lib\\netstandard2.0";
+ var expectedResult = new NuGetPackageAssemblyData
+ {
+ ImplicitDllImportDirectoryReferences =
+ {
+ pathJson,
+ pathExportImport,
+ },
+ DllImportNugetAssemblyReferences =
+ {
+ new PackageAssemblyReference(pathJson + "\\Newtonsoft.Json.dll", null, false),
+ new PackageAssemblyReference(pathExportImport + "\\Skyline.DataMiner.Utils.ExportImport.dll", null, false),
+
+ // Is a files package
+ new PackageAssemblyReference("SLManagedScripting.dll", null, true),
+ },
+ NugetAssemblies =
+ {
+ new PackageAssemblyReference(pathJson + "\\Newtonsoft.Json.dll", null, false),
+ new PackageAssemblyReference(pathExportImport + "\\Skyline.DataMiner.Utils.ExportImport.dll", null, false),
+ },
+ ProcessedAssemblies =
+ {
+ "Newtonsoft.Json.dll",
+ "Skyline.DataMiner.Utils.ExportImport.dll",
+
+ "SLManagedScripting.dll"
+ }
+ };
+
+ // Act
+ var result = await packageReferenceProcessor.ProcessAsync(projectPackages, targetFrameworkMoniker);
+
+ // Assert
+ result.Should().BeEquivalentTo(expectedResult, ExcludeAssemblyPath);
+ }
+
+ [TestMethod]
+ public async Task ProcessAsyncTest_UnitTestScenario()
+ {
+ // Arrange
+ var packageReferenceProcessor = new PackageReferenceProcessor(directoryForNuGetConfig: null);
+
+ IList projectPackages = new List
+ {
+ new PackageIdentity("Skyline.DataMiner.Dev.Automation", new NuGetVersion("10.3.4.1")),
+ new PackageIdentity("Newtonsoft.Json", new NuGetVersion("13.0.3")),
+ new PackageIdentity("Skyline.DataMiner.Utils.ExportImport", new NuGetVersion("1.0.0")),
+ new PackageIdentity("Moq", new NuGetVersion("4.18.4"))
+ };
+
+ const string targetFrameworkMoniker = ".NETFramework,Version=v4.6.2";
+
+ const string pathJson = "newtonsoft.json\\13.0.3\\lib\\net45";
+ const string pathExportImport = "skyline.dataminer.utils.exportimport\\1.0.0\\lib\\netstandard2.0";
+ const string pathMoq = "moq\\4.18.4\\lib\\net462";
+ const string pathCastleCore = "castle.core\\5.1.1\\lib\\net462";
+ const string pathThreading = "system.threading.tasks.extensions\\4.5.4\\lib\\net461";
+ const string pathCompiler = "system.runtime.compilerservices.unsafe\\4.5.3\\lib\\net461";
+ var expectedResult = new NuGetPackageAssemblyData
+ {
+ ImplicitDllImportDirectoryReferences =
+ {
+ pathJson,
+ pathExportImport,
+ pathMoq,
+ pathCastleCore,
+ pathThreading,
+ pathCompiler,
+ },
+ DllImportNugetAssemblyReferences =
+ {
+ new PackageAssemblyReference(pathJson + "\\Newtonsoft.Json.dll", null, false),
+ new PackageAssemblyReference(pathExportImport + "\\Skyline.DataMiner.Utils.ExportImport.dll", null, false),
+ new PackageAssemblyReference(pathMoq + "\\Moq.dll", null, false),
+
+ // Dependencies from Moq
+ new PackageAssemblyReference(pathCastleCore + "\\Castle.Core.dll", null, false),
+ new PackageAssemblyReference(pathThreading + "\\System.Threading.Tasks.Extensions.dll", null, false),
+
+ // Dependencies from System.Threading.Tasks.Extensions
+ new PackageAssemblyReference(pathCompiler + "\\System.Runtime.CompilerServices.Unsafe.dll", null, false),
+ },
+ NugetAssemblies =
+ {
+ new PackageAssemblyReference(pathJson + "\\Newtonsoft.Json.dll", null, false),
+ new PackageAssemblyReference(pathExportImport + "\\Skyline.DataMiner.Utils.ExportImport.dll", null, false),
+ new PackageAssemblyReference(pathMoq + "\\Moq.dll", null, false),
+
+ // Dependencies from Moq
+ new PackageAssemblyReference(pathCastleCore + "\\Castle.Core.dll", null, false),
+ new PackageAssemblyReference(pathThreading + "\\System.Threading.Tasks.Extensions.dll", null, false),
+
+ // Dependencies from System.Threading.Tasks.Extensions
+ new PackageAssemblyReference(pathCompiler + "\\System.Runtime.CompilerServices.Unsafe.dll", null, false),
+ },
+ ProcessedAssemblies =
+ {
+ "Newtonsoft.Json.dll",
+ "Skyline.DataMiner.Utils.ExportImport.dll",
+ "Moq.dll",
+
+ // Dependencies from Moq
+ "Castle.Core.dll",
+ "System.Threading.Tasks.Extensions.dll",
+
+ // Dependencies from System.Threading.Tasks.Extensions
+ "System.Runtime.CompilerServices.Unsafe.dll",
+
+ "System.Configuration.dll",
+ "mscorlib.dll",
+ },
+ DllImportFrameworkAssemblyReferences =
+ {
+ "System.Configuration.dll",
+ "mscorlib.dll",
+ },
+ };
+
+ // Act
+ var result = await packageReferenceProcessor.ProcessAsync(projectPackages, targetFrameworkMoniker);
+
+ // Assert
+ result.Should().BeEquivalentTo(expectedResult, ExcludeAssemblyPath);
+ }
+
+ [TestMethod]
+ public async Task ProcessAsyncTest_UnitTestScenario_Yle_Library()
+ {
+ // Arrange
+ var packageReferenceProcessor = new PackageReferenceProcessor(directoryForNuGetConfig: null);
+
+ IList projectPackages = new List
+ {
+ new PackageIdentity("Skyline.DataMiner.Dev.Automation", new NuGetVersion("10.3.5")),
+ new PackageIdentity("Newtonsoft.Json", new NuGetVersion("13.0.3")),
+ new PackageIdentity("NPOI", new NuGetVersion("2.4.1")),
+ new PackageIdentity("Skyline.DataMiner.ConnectorAPI.EVS.IPD-VIA", new NuGetVersion("1.0.0.4-Test1")),
+ new PackageIdentity("Skyline.DataMiner.ConnectorAPI.YLE.OrderManager", new NuGetVersion("1.0.0.2-Test1")),
+ new PackageIdentity("Skyline.DataMiner.Utils.InteractiveAutomationScriptToolkit", new NuGetVersion("6.1.0")),
+ new PackageIdentity("Skyline.DataMiner.Utils.YLE.Integrations", new NuGetVersion("1.0.1.6-Test1")),
+ };
+
+ const string targetFrameworkMoniker = ".NETFramework,Version=v4.7.2";
+
+ const string pathJson = "newtonsoft.json\\13.0.3\\lib\\net45";
+ const string pathJsonOld = "newtonsoft.json\\13.0.2\\lib\\net45";
+ const string pathSharpZipLib = "sharpziplib\\1.0.0\\lib\\net45";
+ const string pathNpoi = "npoi\\2.4.1\\lib\\net45";
+ const string pathCoreDmsCommonNew = "skyline.dataminer.core.dataminersystem.common\\1.1.0.5\\lib\\net462";
+ const string pathCoreDmsCommonOld = "skyline.dataminer.core.dataminersystem.common\\1.0.0.2\\lib\\net462";
+ const string pathCoreInterApp = "skyline.dataminer.core.interappcalls.common\\1.0.0.2\\lib\\net462";
+ const string pathEvs = "skyline.dataminer.connectorapi.evs.ipd-via\\1.0.0.4-test1\\lib\\net472";
+ const string pathOrder = "skyline.dataminer.connectorapi.yle.ordermanager\\1.0.0.2-test1\\lib\\net472";
+ const string pathToolkit = "skyline.dataminer.utils.interactiveautomationscripttoolkit\\6.1.0\\lib\\net462";
+ const string pathIntegrations = "skyline.dataminer.utils.yle.integrations\\1.0.1.6-test1\\lib\\net472";
+ var expectedResult = new NuGetPackageAssemblyData
+ {
+ ImplicitDllImportDirectoryReferences =
+ {
+ pathJson,
+ pathSharpZipLib,
+ pathNpoi,
+ pathCoreDmsCommonNew,
+ pathCoreInterApp,
+ pathEvs,
+ pathOrder,
+ pathToolkit,
+ pathIntegrations
+ },
+ DllImportNugetAssemblyReferences =
+ {
+ new PackageAssemblyReference(pathJson + "\\Newtonsoft.Json.dll", null, false),
+ new PackageAssemblyReference(pathSharpZipLib + "\\ICSharpCode.SharpZipLib.dll", null, false),
+ new PackageAssemblyReference(pathNpoi + "\\NPOI.dll", null, false),
+ new PackageAssemblyReference(pathNpoi + "\\NPOI.OOXML.dll", null, false),
+ new PackageAssemblyReference(pathNpoi + "\\NPOI.OpenXml4Net.dll", null, false),
+ new PackageAssemblyReference(pathNpoi + "\\NPOI.OpenXmlFormats.dll", null, false),
+ new PackageAssemblyReference(pathCoreDmsCommonNew + "\\Skyline.DataMiner.Core.DataMinerSystem.Common.dll", null, false),
+ new PackageAssemblyReference(pathCoreInterApp + "\\Skyline.DataMiner.Core.InterAppCalls.Common.dll", null, false),
+ new PackageAssemblyReference(pathEvs + "\\Skyline.DataMiner.ConnectorAPI.EVS.IPD-VIA.dll", null, false),
+ new PackageAssemblyReference(pathOrder + "\\Skyline.DataMiner.ConnectorAPI.YLE.OrderManager.dll", null, false),
+ new PackageAssemblyReference(pathToolkit + "\\Skyline.DataMiner.Utils.InteractiveAutomationScriptToolkit.dll", null, false),
+ new PackageAssemblyReference(pathIntegrations + "\\Skyline.DataMiner.Utils.YLE.Integrations.dll", null, false),
+ },
+ NugetAssemblies =
+ {
+ new PackageAssemblyReference(pathJson + "\\Newtonsoft.Json.dll", null, false),
+ new PackageAssemblyReference(pathSharpZipLib + "\\ICSharpCode.SharpZipLib.dll", null, false),
+ new PackageAssemblyReference(pathNpoi + "\\NPOI.dll", null, false),
+ new PackageAssemblyReference(pathNpoi + "\\NPOI.OOXML.dll", null, false),
+ new PackageAssemblyReference(pathNpoi + "\\NPOI.OpenXml4Net.dll", null, false),
+ new PackageAssemblyReference(pathNpoi + "\\NPOI.OpenXmlFormats.dll", null, false),
+ new PackageAssemblyReference(pathCoreDmsCommonNew + "\\Skyline.DataMiner.Core.DataMinerSystem.Common.dll", null, false),
+ new PackageAssemblyReference(pathCoreInterApp + "\\Skyline.DataMiner.Core.InterAppCalls.Common.dll", null, false),
+ new PackageAssemblyReference(pathEvs + "\\Skyline.DataMiner.ConnectorAPI.EVS.IPD-VIA.dll", null, false),
+ new PackageAssemblyReference(pathOrder + "\\Skyline.DataMiner.ConnectorAPI.YLE.OrderManager.dll", null, false),
+ new PackageAssemblyReference(pathToolkit + "\\Skyline.DataMiner.Utils.InteractiveAutomationScriptToolkit.dll", null, false),
+ new PackageAssemblyReference(pathIntegrations + "\\Skyline.DataMiner.Utils.YLE.Integrations.dll", null, false),
+ new PackageAssemblyReference(pathCoreDmsCommonOld + "\\Skyline.DataMiner.Core.DataMinerSystem.Common.dll", null, false),
+ new PackageAssemblyReference(pathJsonOld + "\\Newtonsoft.Json.dll", null, false),
+ },
+ ProcessedAssemblies =
+ {
+ "Newtonsoft.Json.dll",
+ "ICSharpCode.SharpZipLib.dll",
+
+ "NPOI.dll",
+
+ // Dependencies of NPOI
+ "NPOI.OOXML.dll",
+ "NPOI.OpenXml4Net.dll",
+ "NPOI.OpenXmlFormats.dll",
+
+ "Skyline.DataMiner.Core.DataMinerSystem.Common.dll",
+ "Skyline.DataMiner.Core.InterAppCalls.Common.dll",
+ "Skyline.DataMiner.ConnectorAPI.EVS.IPD-VIA.dll",
+ "Skyline.DataMiner.ConnectorAPI.YLE.OrderManager.dll",
+ "Skyline.DataMiner.Utils.InteractiveAutomationScriptToolkit.dll",
+ "Skyline.DataMiner.Utils.YLE.Integrations.dll",
+ },
+ DllImportDirectoryReferencesAssembly =
+ {
+ [pathCoreDmsCommonOld + "\\"] = pathCoreDmsCommonOld + "\\Skyline.DataMiner.Core.DataMinerSystem.Common.dll",
+ [pathJsonOld + "\\"] = pathJsonOld + "\\Newtonsoft.Json.dll",
+ },
+ DllImportDirectoryReferences =
+ {
+ pathCoreDmsCommonOld + "\\",
+ pathJsonOld + "\\",
+ }
+ };
+
+ // Act
+ var result = await packageReferenceProcessor.ProcessAsync(projectPackages, targetFrameworkMoniker);
+
+ // Assert
+ result.Should().BeEquivalentTo(expectedResult, ExcludeAssemblyPath);
+ }
+
+ [TestMethod]
+ public async Task ProcessAsyncTest_SolutionLibraries()
+ {
+ // Arrange
+ var packageReferenceProcessor = new PackageReferenceProcessor(directoryForNuGetConfig: null);
+
+ IList projectPackages = new List
+ {
+ new PackageIdentity("Skyline.DataMiner.Dev.Automation", new NuGetVersion("10.3.5")),
+ new PackageIdentity("Newtonsoft.Json", new NuGetVersion("13.0.3")),
+ new PackageIdentity("Skyline.DataMiner.Dev.Utils.ModSolutionLib", new NuGetVersion("1.0.0")),
+ };
+
+ const string targetFrameworkMoniker = ".NETFramework,Version=v4.8";
+
+ const string pathJson = "newtonsoft.json\\13.0.3\\lib\\net45";
+ const string pathSolutionLib = "skyline.dataminer.dev.utils.modsolutionlib\\1.0.0\\lib\\netstandard2.0";
+ var expectedResult = new NuGetPackageAssemblyData
+ {
+ ImplicitDllImportDirectoryReferences =
+ {
+ pathJson,
+ pathSolutionLib,
+ },
+ DllImportNugetAssemblyReferences =
+ {
+ new PackageAssemblyReference(pathJson + "\\Newtonsoft.Json.dll", null, false),
+ new PackageAssemblyReference("SolutionLibraries\\ModSolutionLib\\Skyline.DataMiner.Dev.Utils.ModSolutionLib.dll", null, false),
+ },
+ NugetAssemblies =
+ {
+ new PackageAssemblyReference(pathJson + "\\Newtonsoft.Json.dll", null, false),
+ },
+ ProcessedAssemblies =
+ {
+ "Newtonsoft.Json.dll",
+
+ "Skyline.DataMiner.Dev.Utils.ModSolutionLib.dll",
+ },
+ DllImportDirectoryReferencesAssembly =
+ {
+ },
+ DllImportDirectoryReferences =
+ {
+ }
+ };
+
+ // Act
+ var result = await packageReferenceProcessor.ProcessAsync(projectPackages, targetFrameworkMoniker);
+
+ // Assert
+ result.Should().BeEquivalentTo(expectedResult, ExcludeAssemblyPath);
+ }
+
+ private static EquivalencyAssertionOptions ExcludeAssemblyPath(EquivalencyAssertionOptions arg)
+ {
+ arg.Excluding(x => x.Path.EndsWith("AssemblyPath"));
+ return arg;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.Protocol/AsciiTable.cs b/Assemblers.Protocol/AsciiTable.cs
new file mode 100644
index 0000000..d968052
--- /dev/null
+++ b/Assemblers.Protocol/AsciiTable.cs
@@ -0,0 +1,80 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Protocol
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+
+ internal class AsciiTable
+ {
+ private readonly List rows = new List();
+ const int spacing = 4;
+
+ public void AddRow(params string[] fields)
+ {
+ rows.Add(fields);
+ }
+
+ private IDictionary CalculateColumnOffsets()
+ {
+ var result = new Dictionary();
+
+ int offset = 0;
+ result.Add(0, offset);
+
+ if (rows.Count > 0)
+ {
+ int numColumns = rows.Max(r => r.Length);
+
+ for (int col = 0; col < numColumns; col++)
+ {
+ int maxLength = 0;
+
+ foreach (var row in rows)
+ {
+ if (row.Length > col && row[col] != null)
+ {
+ maxLength = Math.Max(row[col].Length, maxLength);
+ }
+ }
+
+ offset += maxLength + spacing;
+
+ result.Add(col + 1, offset);
+ }
+ }
+
+ return result;
+ }
+
+ public override string ToString()
+ {
+ var columnOffsets = CalculateColumnOffsets();
+
+ StringBuilder sb = new StringBuilder();
+
+ foreach (var row in rows)
+ {
+ for (int col = 0; col < row.Length; col++)
+ {
+ string field = row[col] ?? "";
+ sb.Append(field);
+
+ if (col != row.Length - 1)
+ {
+ int offset = columnOffsets[col];
+ int nextOffset = columnOffsets[col + 1];
+ int width = nextOffset - offset;
+
+ int spaces = width - field.Length;
+ sb.Append(new String(' ', spaces));
+ }
+ }
+
+ sb.AppendLine();
+ }
+
+ return sb.ToString();
+ }
+ }
+}
diff --git a/Assemblers.Protocol/Assemblers.Protocol.csproj b/Assemblers.Protocol/Assemblers.Protocol.csproj
new file mode 100644
index 0000000..daa1c0c
--- /dev/null
+++ b/Assemblers.Protocol/Assemblers.Protocol.csproj
@@ -0,0 +1,40 @@
+
+
+ netstandard2.0
+ Skyline.DataMiner.CICD.Assemblers.Protocol
+ Skyline.DataMiner.CICD.Assemblers.Protocol
+ True
+ True
+ SkylineCommunications
+ Skyline Communications
+ LICENSE.txt
+ True
+ icon.png
+ https://skyline.be/
+ Skyline;DataMiner;CICD
+ Library providing methods for converting Visual Studio DIS connector solutions to individual DataMiner connector artifacts (e.g. XML, DLLs,...).
+ README.md
+ https://github.com/SkylineCommunications/Skyline.DataMiner.CICD.Packages
+ git
+ 0.0.1-local
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Assemblers.Protocol/AssemblyFilter.cs b/Assemblers.Protocol/AssemblyFilter.cs
new file mode 100644
index 0000000..cdb761d
--- /dev/null
+++ b/Assemblers.Protocol/AssemblyFilter.cs
@@ -0,0 +1,204 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Protocol
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Reflection;
+ using System.Threading.Tasks;
+
+ using NuGet.Packaging.Core;
+
+ using Skyline.DataMiner.CICD.Assemblers.Common;
+ using Skyline.DataMiner.CICD.FileSystem;
+
+ ///
+ /// Provides functionality to filter assemblies based on target framework, package references, and build result items.
+ ///
+ public static class AssemblyFilter
+ {
+ ///
+ /// Filters assemblies based on the specified criteria.
+ ///
+ /// The target framework moniker.
+ /// The package reference processor.
+ /// The build result items.
+ /// A set of DLL imports.
+ /// A list of package identities.
+ /// The filtered NuGet package assembly data.
+ public static async Task FilterAsync(string targetFrameworkMoniker, PackageReferenceProcessor packageReferenceProcessor, BuildResultItems buildResultItems, HashSet dllImports, IList packageIdentities)
+ {
+ var nugetAssemblyData = await packageReferenceProcessor.ProcessAsync(packageIdentities, targetFrameworkMoniker,
+ Skyline.DataMiner.CICD.Common.NuGet.DevPackHelper.ProtocolDevPackNuGetDependenciesIncludingTransitive).ConfigureAwait(false);
+
+ ProcessFrameworkAssemblies(dllImports, nugetAssemblyData);
+ ProcessLibAssemblies(buildResultItems, dllImports, nugetAssemblyData);
+
+ return nugetAssemblyData;
+ }
+
+ ///
+ /// Adds a new DLL import to the set if it does not already contain an import with the same name.
+ ///
+ /// A set of DLL imports.
+ /// The new import to add.
+ private static bool AddToDllImport(HashSet dllImports, string newImport)
+ {
+ if (!dllImports.Select(FileSystem.Instance.Path.GetFileName).Contains(FileSystem.Instance.Path.GetFileName(newImport)))
+ {
+ dllImports.Add(newImport);
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Processes NuGet assembly references for DLL import and updates the set of DLL imports and directory references accordingly.
+ ///
+ /// A set of DLL imports.
+ /// The NuGet package assembly data.
+ private static void ProcessDllImportNuGetAssemblyReferences(HashSet dllImports, NuGetPackageAssemblyData nugetAssemblyData)
+ {
+ if (nugetAssemblyData.DllImportNugetAssemblyReferences.Count <= 0)
+ {
+ return;
+ }
+
+ var directoriesWithExplicitDllImport = new HashSet();
+ var potentialRemainingDirectoryImports = new List();
+ var assemblies = new Dictionary>();
+
+ foreach (var libItem in nugetAssemblyData.DllImportNugetAssemblyReferences)
+ {
+ string assemblyName = FileSystem.Instance.Path.GetFileName(libItem.DllImport);
+
+ if (assemblies.TryGetValue(assemblyName, out var entries))
+ {
+ entries.Add(libItem);
+ }
+ else
+ {
+ assemblies[assemblyName] = new List { libItem };
+ }
+ }
+
+ foreach (var assembly in assemblies)
+ {
+ var packagesContainingAssembly = assembly.Value;
+
+ if (packagesContainingAssembly.Count == 1)
+ {
+ var libItem = packagesContainingAssembly[0];
+ if (AddToDllImport(dllImports, libItem.DllImport))
+ {
+ directoriesWithExplicitDllImport.Add(libItem.DllImport.Substring(0, libItem.DllImport.Length - assembly.Key.Length));
+ }
+ else
+ {
+ potentialRemainingDirectoryImports.Add(FileSystem.Instance.Path.GetDirectoryName(libItem.DllImport) + "\\");
+ }
+ }
+ else
+ {
+ PackageAssemblyReference mostRecentLibItem = SelectMostRecentVersion(packagesContainingAssembly);
+ if (mostRecentLibItem == null)
+ {
+ continue;
+ }
+
+ if (AddToDllImport(dllImports, mostRecentLibItem.DllImport))
+ {
+ directoriesWithExplicitDllImport.Add(mostRecentLibItem.DllImport.Substring(0, mostRecentLibItem.DllImport.Length - assembly.Key.Length));
+ }
+ else
+ {
+ potentialRemainingDirectoryImports.Add(FileSystem.Instance.Path.GetDirectoryName(mostRecentLibItem.DllImport) + "\\");
+ }
+
+ foreach (var libItem in packagesContainingAssembly)
+ {
+ if (libItem != mostRecentLibItem)
+ {
+ string directoryPath = libItem.DllImport.Substring(0, libItem.DllImport.Length - assembly.Key.Length);
+ potentialRemainingDirectoryImports.Add(directoryPath);
+ }
+ }
+ }
+ }
+
+ foreach (var directoryPath in potentialRemainingDirectoryImports)
+ {
+ if (!directoriesWithExplicitDllImport.Contains(directoryPath))
+ {
+ nugetAssemblyData.DllImportDirectoryReferences.Add(directoryPath);
+ }
+ }
+ }
+
+ ///
+ /// Processes framework assemblies and adds them to the set of DLL imports if not already present.
+ ///
+ /// A set of DLL imports.
+ /// The NuGet package assembly data.
+ private static void ProcessFrameworkAssemblies(HashSet dllImports, NuGetPackageAssemblyData nugetAssemblyData)
+ {
+ foreach (var frameworkAssembly in nugetAssemblyData.DllImportFrameworkAssemblyReferences)
+ {
+ if (!Helper.QActionDefaultImportDLLs.Any(a => String.Equals(a, frameworkAssembly, StringComparison.OrdinalIgnoreCase)))
+ {
+ dllImports.Add(frameworkAssembly);
+ }
+ }
+ }
+
+ ///
+ /// Processes library assemblies and updates the build result items and DLL imports accordingly.
+ ///
+ /// The build result items.
+ /// A set of DLL imports.
+ /// The NuGet package assembly data.
+ private static void ProcessLibAssemblies(BuildResultItems buildResultItems, HashSet dllImports, NuGetPackageAssemblyData nugetAssemblyData)
+ {
+ ProcessDllImportNuGetAssemblyReferences(dllImports, nugetAssemblyData);
+
+ foreach (var dir in nugetAssemblyData.DllImportDirectoryReferences)
+ {
+ if (!Helper.QActionDefaultImportDLLs.Any(d => String.Equals(d, dir, StringComparison.OrdinalIgnoreCase)))
+ {
+ dllImports.Add(dir);
+ }
+ }
+
+ foreach (var libItem in nugetAssemblyData.NugetAssemblies)
+ {
+ if (!dllImports.Contains(FileSystem.Instance.Path.GetFileName(libItem.AssemblyPath)) && buildResultItems.Assemblies.FirstOrDefault(b => b.AssemblyPath == libItem.AssemblyPath) == null)
+ {
+ buildResultItems.Assemblies.Add(libItem);
+ }
+ }
+ }
+
+ ///
+ /// Selects the most recent version of a package assembly reference from a list.
+ ///
+ /// The list of package assembly references.
+ /// The most recent package assembly reference, or null if the list is empty.
+ private static PackageAssemblyReference SelectMostRecentVersion(List packagesContainingAssembly)
+ {
+ PackageAssemblyReference mostRecentLibItem = null;
+ Version mostRecentVersion = null;
+
+ foreach (var libItem in packagesContainingAssembly)
+ {
+ var version = AssemblyName.GetAssemblyName(libItem.AssemblyPath).Version;
+ if (mostRecentVersion == null || version > mostRecentVersion)
+ {
+ mostRecentVersion = version;
+ mostRecentLibItem = libItem;
+ }
+ }
+
+ return mostRecentLibItem;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.Protocol/AttachedBehavior.cs b/Assemblers.Protocol/AttachedBehavior.cs
new file mode 100644
index 0000000..547a453
--- /dev/null
+++ b/Assemblers.Protocol/AttachedBehavior.cs
@@ -0,0 +1,13 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Protocol
+{
+ using System.Collections.Generic;
+ using System.Linq;
+
+ internal static class AttachedBehavior
+ {
+ public static IEnumerable OrEmptyIfNull(this IEnumerable source)
+ {
+ return source ?? Enumerable.Empty();
+ }
+ }
+}
diff --git a/Assemblers.Protocol/DevPackHelper.cs b/Assemblers.Protocol/DevPackHelper.cs
new file mode 100644
index 0000000..4cee006
--- /dev/null
+++ b/Assemblers.Protocol/DevPackHelper.cs
@@ -0,0 +1,28 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Protocol
+{
+ using System;
+ using System.Collections.Generic;
+
+ using Skyline.DataMiner.CICD.Parsers.Common.VisualStudio.Projects;
+
+ internal static class DevPackHelper
+ {
+ private const string CommonDevPackName = "Skyline.DataMiner.Dev.Common";
+
+ private static readonly HashSet DevPackDllsToIgnore = new HashSet
+ {
+ "ICSharpCode.SharpZipLib.dll",
+ "Newtonsoft.Json.dll",
+ "protobuf-net.dll",
+ "SLProtoBufLibrary.dll",
+ };
+
+ public static bool IsDevPackDllReference(Reference reference)
+ {
+ string referenceDllName = reference.GetDllName();
+
+ return DevPackDllsToIgnore.Contains(referenceDllName) &&
+ (reference.HintPath == null || reference.HintPath.Contains(CommonDevPackName));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.Protocol/Helper.cs b/Assemblers.Protocol/Helper.cs
new file mode 100644
index 0000000..ed613ca
--- /dev/null
+++ b/Assemblers.Protocol/Helper.cs
@@ -0,0 +1,50 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Protocol
+{
+ using System;
+ using System.Collections.Generic;
+
+ using Skyline.DataMiner.CICD.Parsers.Common.VisualStudio.Projects;
+ using Skyline.DataMiner.CICD.Parsers.Protocol.Xml.QActions;
+
+ ///
+ /// Protocol assembler helper class.
+ ///
+ public static class Helper
+ {
+ ///
+ /// Defines the assemblies that are referenced by default in DataMiner when a QAction is compiled.
+ ///
+ public static readonly IReadOnlyList QActionDefaultImportDLLs = new List()
+ {
+ "Interop.SLDms.dll",
+ "mscorlib.dll",
+ "QactionHelperBaseClasses.dll",
+ "Skyline.DataMiner.Storage.Types.dll",
+ "SLLoggerUtil.dll",
+ "SLManagedScripting.dll",
+ "SLNetTypes.dll",
+ "System.dll",
+ "System.Xml.dll",
+ "System.Core.dll",
+ };
+
+ ///
+ /// Retrieves the ID of the specified QAction project reference. A return value indicates whether the operation succeeded.
+ ///
+ /// The project reference.
+ /// The ID of the specified QAction project reference
+ /// true if the ID was successfully retrieved; otherwise, false.
+ public static bool TryGetQActionId(ProjectReference reference, out int id)
+ {
+ var m = QAction.RegexExtractQActionID.Match(reference.Name);
+ if (m.Success)
+ {
+ id = Convert.ToInt32(m.Groups["id"].Value);
+ return true;
+ }
+
+ id = default(int);
+ return false;
+ }
+ }
+}
diff --git a/Assemblers.Protocol/ProtocolBuilder.cs b/Assemblers.Protocol/ProtocolBuilder.cs
new file mode 100644
index 0000000..f7f0411
--- /dev/null
+++ b/Assemblers.Protocol/ProtocolBuilder.cs
@@ -0,0 +1,564 @@
+namespace Skyline.DataMiner.CICD.Assemblers.Protocol
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using System.Reflection;
+ using System.Text;
+ using System.Threading.Tasks;
+
+ using NuGet.Packaging.Core;
+ using NuGet.Versioning;
+
+ using Skyline.DataMiner.CICD.Assemblers.Common;
+ using Skyline.DataMiner.CICD.FileSystem;
+ using Skyline.DataMiner.CICD.Loggers;
+ using Skyline.DataMiner.CICD.Models.Protocol.Enums;
+ using Skyline.DataMiner.CICD.Models.Protocol.Read;
+ using Skyline.DataMiner.CICD.Models.Protocol.Read.Interfaces;
+ using Skyline.DataMiner.CICD.Parsers.Common.VisualStudio.Projects;
+ using Skyline.DataMiner.CICD.Parsers.Common.Xml;
+ using Skyline.DataMiner.CICD.Parsers.Protocol.VisualStudio;
+
+ using EditXml = Skyline.DataMiner.CICD.Parsers.Common.XmlEdit;
+ using ProtocolDocumentEdit = Skyline.DataMiner.CICD.Models.Protocol.Edit.ProtocolDocumentEdit;
+ using QActionsQAction = Skyline.DataMiner.CICD.Models.Protocol.Edit.QActionsQAction;
+
+ ///
+ /// Protocol builder.
+ ///
+ public class ProtocolBuilder
+ {
+ private readonly ILogCollector logCollector;
+
+ ///
+ /// Initializes a new instance of the class using the specified protocol solution.
+ ///
+ /// The protocol solution.
+ /// is .
+ public ProtocolBuilder(ProtocolSolution solution)
+ {
+ if (solution == null)
+ {
+ throw new ArgumentNullException(nameof(solution));
+ }
+
+ Document = solution.ProtocolDocument;
+ Model = new ProtocolModel(Document);
+
+ Projects = new Dictionary();
+
+ foreach (var p in solution.Projects)
+ {
+ Projects[p.Name] = solution.LoadProject(p);
+ }
+ }
+
+ ///
+ /// Initializes a new instance of the class using the specified protocol solution.
+ ///
+ /// The protocol solution.
+ /// The log collector.
+ /// is .
+ public ProtocolBuilder(ProtocolSolution solution, ILogCollector logCollector)
+ : this(solution)
+ {
+ this.logCollector = logCollector;
+ }
+
+ ///
+ /// Initializes a new instance of the class using the specified protocol solution.
+ ///
+ /// The protocol solution.
+ /// The log collector.
+ /// Version that will be used to override the version in the protocol itself.
+ /// is .
+ /// is , empty or whitespace.
+ public ProtocolBuilder(ProtocolSolution solution, ILogCollector logCollector, string overrideVersion)
+ : this(solution, logCollector)
+ {
+ if (String.IsNullOrWhiteSpace(overrideVersion))
+ {
+ throw new ArgumentException(nameof(overrideVersion));
+ }
+
+ var edit = new EditXml.XmlDocument(solution.ProtocolDocument);
+ var version = edit.Root.Element["Version"];
+ if (version == null)
+ {
+ throw new AssemblerException("Protocol does not contain a Version tag.");
+ }
+
+ version.InnerText = overrideVersion;
+
+ // Override the Document & Model as it now has the overridden version.
+ Document = XmlDocument.Parse(edit.GetXml());
+ Model = new ProtocolModel(Document);
+ }
+
+ ///
+ /// Initializes a new instance of the class using the specified document and projects.
+ ///
+ /// The protocol XML document.
+ /// The project dictionary.
+ /// Version that will be used to override the version in the protocol itself.
+ /// , or is .
+ internal ProtocolBuilder(XmlDocument document, IDictionary projects, string overrideVersion = null)
+ {
+ if (document is null)
+ {
+ throw new ArgumentNullException(nameof(document));
+ }
+
+ if (!String.IsNullOrWhiteSpace(overrideVersion))
+ {
+ var edit = new EditXml.XmlDocument(document);
+ var version = edit.Root.Element["Version"];
+ if (version == null)
+ {
+ throw new AssemblerException("Protocol does not contain a Version tag.");
+ }
+
+ version.InnerText = overrideVersion;
+
+ Document = XmlDocument.Parse(edit.GetXml());
+ }
+ else
+ {
+ Document = document;
+ }
+
+ Model = new ProtocolModel(Document);
+ Projects = projects ?? throw new ArgumentNullException(nameof(projects));
+ }
+
+ ///
+ /// Gets the XML document of the protocol.
+ ///
+ /// The protocol model.
+ public XmlDocument Document { get; }
+
+ ///
+ /// Gets the protocol model/
+ ///
+ /// The protocol model.
+ public IProtocolModel Model { get; }
+
+ ///
+ /// Gets the projects dictionary.
+ ///
+ /// The projects dictionary.
+ public IDictionary Projects { get; }
+
+ ///
+ /// Builds the protocol assembling the protocol document and projects into the full protocol XML document and assemblies of NuGet packages.
+ ///
+ /// The build result items.
+ /// Project with name '{projectName}' could not be found -or-
+ /// No code files found for QAction -or-
+ /// File could not be found in project -or-
+ /// Cannot replace QAction, because the target XML node is not empty.
+ public async Task BuildAsync()
+ {
+ logCollector?.ReportStatus("Building the protocol.");
+ var protocolEdit = new ProtocolDocumentEdit(Document, Model);
+ return await BuildResultsAsync(protocolEdit).ConfigureAwait(false);
+ }
+
+ ///
+ /// Combines all the cs files in the project into a single string.
+ ///
+ /// Project.
+ /// String with all the code from the cs files.
+ /// No code files found in specified project.
+ public static string CombineProjectFiles(Project project)
+ {
+ var files = GetRelevantCodeFilesSorted(project);
+
+ if (files.Count == 0)
+ {
+ throw new AssemblerException($"No code files found in project '{project.AssemblyName}'");
+ }
+
+ return CSharpCodeCombiner.CombineFiles(files);
+ }
+
+ ///
+ /// Retrieves the C# files (.cs) of the QAction project in sorted order.
+ ///
+ /// The QAction project.
+ /// The C# files (.cs) of the QAction project in sorted order.
+ /// This method excludes any AssemblyInfo.cs file present in the project.
+ /// is .
+ public static IList GetRelevantCodeFilesSorted(Project project)
+ {
+ if (project == null)
+ {
+ throw new ArgumentNullException(nameof(project));
+ }
+
+ var files = project.Files
+ .Where(x => x.Name.EndsWith(".cs") && !x.Name.EndsWith("AssemblyInfo.cs"))
+ .OrderByDescending(x => x.Name.StartsWith("QAction_"))
+ .ThenBy(x => x.Name)
+ .ToList();
+
+ return files;
+ }
+
+ private async Task BuildResultsAsync(ProtocolDocumentEdit protocolEdit)
+ {
+ BuildResultItems buildResultItems = new BuildResultItems();
+
+ await BuildQActions(protocolEdit, buildResultItems, Model?.Protocol?.Compliancies).ConfigureAwait(false);
+ BuildVersionHistoryComment(protocolEdit, Model);
+ buildResultItems.Document = protocolEdit.Document.GetXml();
+
+ return buildResultItems;
+ }
+
+ private async Task BuildQActions(ProtocolDocumentEdit protocolEdit, BuildResultItems buildResultItems, ICompliancies compliancies)
+ {
+ logCollector?.ReportDebug("Building QActions");
+ var packageReferenceProcessor = new PackageReferenceProcessor(directoryForNuGetConfig: null);
+
+ var qactions = protocolEdit.Protocol?.QActions;
+ if (qactions != null)
+ {
+ foreach (var qa in qactions)
+ {
+ await BuildQAction(qa, qactions.Read, packageReferenceProcessor, buildResultItems, compliancies).ConfigureAwait(false);
+ }
+ }
+ }
+
+ private async Task BuildQAction(QActionsQAction qa, IQActions allQActions, PackageReferenceProcessor packageReferenceProcessor, BuildResultItems buildResultItems, ICompliancies compliancies)
+ {
+ if (qa.Encoding?.Value != EnumQActionEncoding.Csharp)
+ {
+ // skip JScript etc..
+ return;
+ }
+
+ var qaId = qa.Id?.Value;
+
+ string projectName = $"QAction_{qaId}";
+ if (!Projects.TryGetValue(projectName, out var project))
+ {
+ throw new AssemblerException($"Project with name '{projectName}' could not be found!");
+ }
+
+ // replace code
+ var hasQActionCodeChanges = BuildQActionCode(qa, project, qaId);
+
+ // DLL imports
+ var hasDllImportChanges = await BuildQActionDllImports(qa, project, allQActions, packageReferenceProcessor, buildResultItems, compliancies).ConfigureAwait(false);
+
+ // format
+ if (hasQActionCodeChanges || hasDllImportChanges)
+ {
+ qa.EditNode.Format();
+ }
+ }
+
+ private static bool BuildQActionCode(QActionsQAction qa, Project project, uint? qaId)
+ {
+ bool hasChanges = false;
+
+ string newCode = CombineProjectFiles(project);
+ if (!String.IsNullOrWhiteSpace(newCode))
+ {
+ if (!String.IsNullOrWhiteSpace(qa.Code) && !String.Equals(qa.Code, newCode))
+ {
+ throw new AssemblerException($"Cannot replace QAction {qaId}, because the target XML node is not empty!");
+ }
+
+ qa.Code = newCode;
+ hasChanges = true;
+ }
+
+ return hasChanges;
+ }
+
+ private static async Task BuildQActionDllImports(QActionsQAction qa, Project project, IQActions allQActions, PackageReferenceProcessor packageReferenceProcessor, BuildResultItems buildResultItems, ICompliancies compliancies)
+ {
+ bool hasChanges = false;
+
+ var dllImports = new HashSet(StringComparer.OrdinalIgnoreCase);
+
+ string dllsFolder = null;
+ if (project.Path != null)
+ {
+ dllsFolder = FileSystem.Instance.Path.Combine(FileSystem.Instance.Directory.GetParentDirectory(FileSystem.Instance.Path.GetDirectoryName(project.Path)), @"Dlls\");
+ }
+
+ NuGetPackageAssemblyData nugetAssemblyData = await ProcessPackageReferences(project, packageReferenceProcessor, buildResultItems, dllImports);
+ ProcessReferences(project, packageReferenceProcessor, compliancies, nugetAssemblyData, dllsFolder, dllImports, buildResultItems);
+ ProcessProjectReferences(project, allQActions, dllImports);
+
+ // Edit QAction@dllImport
+ if (dllImports.Count > 0)
+ {
+ qa.DllImport = String.Join(";", dllImports);
+ hasChanges = true;
+ }
+
+ return hasChanges;
+ }
+
+ private static async Task ProcessPackageReferences(Project project, PackageReferenceProcessor packageReferenceProcessor,
+ BuildResultItems buildResultItems, HashSet dllImports)
+ {
+ if (project.PackageReferences == null)
+ {
+ return null;
+ }
+
+ List packageIdentities = GetPackageIdentities(project);
+
+ if (packageIdentities.Count <= 0)
+ {
+ return null;
+ }
+
+ NuGetPackageAssemblyData nugetAssemblyData = await AssemblyFilter.FilterAsync(project.TargetFrameworkMoniker, packageReferenceProcessor, buildResultItems, dllImports, packageIdentities).ConfigureAwait(false);
+
+ return nugetAssemblyData;
+ }
+
+ private static List GetPackageIdentities(Project project)
+ {
+ var packageIdentities = new List();
+
+ foreach (var packageReference in project.PackageReferences)
+ {
+ var packageIdentity = new PackageIdentity(packageReference.Name, NuGetVersion.Parse(packageReference.Version));
+ packageIdentities.Add(packageIdentity);
+ }
+
+ return packageIdentities;
+ }
+
+ private static void ProcessProjectReferences(Project project, IQActions allQActions, HashSet dllImports)
+ {
+ if (project.ProjectReferences != null)
+ {
+ foreach (var r in project.ProjectReferences)
+ {
+ if (r.Name == "QAction_ClassLibrary")
+ {
+ // Do nothing (no longer supported).
+ }
+ else if (r.Name == "QAction_Helper")
+ {
+ // Do nothing.
+ }
+ else if (Helper.TryGetQActionId(r, out int id))
+ {
+ var refQA = allQActions.FirstOrDefault(q => q.Id?.Value == id);
+ if (refQA != null)
+ {
+ string dll;
+
+ var options = refQA.GetOptions();
+ if (!String.IsNullOrWhiteSpace(options?.CustomDllName))
+ {
+ dll = $"[ProtocolName].[ProtocolVersion].{options.CustomDllName}";
+ }
+ else
+ {
+ dll = $"[ProtocolName].[ProtocolVersion].QAction.{id}.dll";
+ }
+
+ dllImports.Add(dll);
+ }
+ }
+ else if (!String.IsNullOrWhiteSpace(r.Name))
+ {
+ dllImports.Add($"{r.Name}.dll");
+ }
+ }
+ }
+ }
+
+ private static void ProcessReferences(Project project, PackageReferenceProcessor packageReferenceProcessor, ICompliancies compliancies,
+ NuGetPackageAssemblyData nugetAssemblyData, string dllsFolder, HashSet dllImports, BuildResultItems buildResultItems)
+ {
+ if (project.References == null)
+ {
+ return;
+ }
+
+ foreach (Reference r in project.References)
+ {
+ string dllName = r.GetDllName();
+
+ if (IsDllDefaultInQAction(dllName, compliancies) || DevPackHelper.IsDevPackDllReference(r) ||
+ (nugetAssemblyData != null && nugetAssemblyData.ProcessedAssemblies.Contains(dllName)))
+ {
+ continue;
+ }
+
+ if (r.HintPath?.Contains(packageReferenceProcessor.NuGetRootPath) == true)
+ {
+ // DLL is from a NuGet but is transitive from precompile or other project reference.
+ // These can be ignored.
+ continue;
+ }
+
+ if (r.HintPath != null && FileSystem.Instance.Path.IsPathRooted(r.HintPath))
+ {
+ string absolutePath = r.HintPath;
+
+ if (absolutePath.StartsWith(@"C:\Skyline DataMiner\ProtocolScripts\DllImport\"))
+ {
+ dllName = absolutePath.Substring(47);
+ }
+ else if (absolutePath.StartsWith(@"C:\Skyline DataMiner\ProtocolScripts\"))
+ {
+ dllName = absolutePath.Substring(37);
+ }
+ else if (absolutePath.StartsWith(@"C:\Skyline DataMiner\Files\"))
+ {
+ dllName = absolutePath.Substring(27);
+ }
+ else if (dllsFolder != null && absolutePath.StartsWith(dllsFolder))
+ {
+ dllName = absolutePath.Substring(dllsFolder.Length);
+ }
+ }
+
+ dllImports.Add(dllName);
+
+ // If custom DLL
+ if (r.HintPath != null && project.ProjectStyle == ProjectStyle.Sdk)
+ {
+ string dllPath = FileSystem.Instance.Path.GetFullPath(FileSystem.Instance.Path.Combine(project.ProjectDirectory, r.HintPath));
+
+ buildResultItems.DllAssemblies.Add(new DllAssemblyReference(dllName, dllPath));
+ }
+ }
+ }
+
+ private static bool IsDllDefaultInQAction(string dllName, ICompliancies compliancies)
+ {
+ if (dllName.Equals("System.Xml.dll", StringComparison.OrdinalIgnoreCase))
+ {
+ string minimumRequiredVersion = compliancies?.MinimumRequiredVersion?.Value ?? String.Empty;
+ string[] versionParts = minimumRequiredVersion.Split('.');
+
+ // See RN 19494.
+ if (!Int32.TryParse(versionParts[0], out int major) || major >= 10)
+ {
+ return true;
+ }
+ }
+ else if (Helper.QActionDefaultImportDLLs.Any(d => String.Equals(d, dllName, StringComparison.OrdinalIgnoreCase)))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private void BuildVersionHistoryComment(ProtocolDocumentEdit protocolEdit, IProtocolModel model)
+ {
+ logCollector?.ReportDebug("Building version history comment");
+ var versionHistory = model.Protocol?.VersionHistory;
+ if (versionHistory == null)
+ {
+ return;
+ }
+
+ var xmlEdit = protocolEdit.Document;
+ var xmlProtocol = xmlEdit.TryFindNode(model.Protocol.ReadNode);
+
+ var firstXmlComment = xmlEdit.Children.OfType().FirstOrDefault();
+ if (firstXmlComment == null || xmlEdit.Children.IndexOf(firstXmlComment) > xmlEdit.Children.IndexOf(xmlProtocol))
+ {
+ firstXmlComment = new EditXml.XmlComment("");
+ xmlEdit.Children.InsertBefore(xmlProtocol, firstXmlComment);
+ xmlEdit.Children.InsertBefore(xmlProtocol, new EditXml.XmlText("\r\n"));
+ }
+
+ firstXmlComment.InnerText += "\r\n\r\n" + BuildVersionHistoryComment(versionHistory);
+ }
+
+ private static string BuildVersionHistoryComment(IVersionHistory versionHistory)
+ {
+ if (versionHistory is null)
+ {
+ throw new ArgumentNullException(nameof(versionHistory));
+ }
+
+ AsciiTable table = new AsciiTable();
+
+ void appendComment(string datetime, string version, string author, string comment)
+ {
+ var commentLines = GetLines(comment).ToList();
+
+ table.AddRow(datetime, version, author, commentLines.Count > 0 ? commentLines[0] : "");
+
+ for (int i = 1; i < commentLines.Count; i++)
+ {
+ table.AddRow("", "", "", commentLines[i]);
+ }
+ }
+
+ table.AddRow("DATE", "VERSION", "AUTHOR", "COMMENTS");
+ table.AddRow();
+
+ foreach (var branch in versionHistory.Branches.OrEmptyIfNull().OrderBy(x => x.Id?.Value))
+ {
+ foreach (var systemVersion in branch.SystemVersions.OrEmptyIfNull().OrderBy(x => x.Id?.Value))
+ {
+ foreach (var majorVersion in systemVersion.MajorVersions.OrEmptyIfNull().OrderBy(x => x.Id?.Value))
+ {
+ foreach (var minorVersion in majorVersion.MinorVersions.OrEmptyIfNull().OrderBy(x => x.Id?.Value))
+ {
+ string date = minorVersion.Date?.Value?.ToString("dd/MM/yyyy");
+ string version = String.Join(".", branch.Id?.Value, systemVersion.Id?.Value, majorVersion.Id?.Value, minorVersion.Id?.Value);
+ string author = $"{minorVersion.Provider?.Author?.Value}, {minorVersion.Provider?.Company?.Value}";
+
+ StringBuilder sbComment = new StringBuilder();
+
+ foreach (var change in minorVersion.Changes)
+ {
+ switch (change)
+ {
+ case IVersionHistoryBranchesBranchSystemVersionsSystemVersionMajorVersionsMajorVersionMinorVersionsMinorVersionChangesNewFeature nf:
+ sbComment.AppendLine("NF: " + nf.Value);
+ break;
+ case IVersionHistoryBranchesBranchSystemVersionsSystemVersionMajorVersionsMajorVersionMinorVersionsMinorVersionChangesFix f:
+ sbComment.AppendLine("Fix: " + f.Value);
+ break;
+ case IVersionHistoryBranchesBranchSystemVersionsSystemVersionMajorVersionsMajorVersionMinorVersionsMinorVersionChangesChange c:
+ sbComment.AppendLine("Change: " + c.Value);
+ break;
+ }
+ }
+
+ string comment = sbComment.ToString().Trim();
+
+ appendComment(date, version, author, comment);
+ }
+ }
+ }
+ }
+
+ return "Revision History (auto generated):\r\n\r\n" + table.ToString();
+ }
+
+ private static IEnumerable GetLines(string s)
+ {
+ StringReader sr = new StringReader(s);
+
+ string line;
+ while ((line = sr.ReadLine()) != null)
+ {
+ yield return line;
+ }
+ }
+ }
+}
diff --git a/Assemblers.ProtocolTests/Assemblers.ProtocolTests.csproj b/Assemblers.ProtocolTests/Assemblers.ProtocolTests.csproj
new file mode 100644
index 0000000..8e34d0d
--- /dev/null
+++ b/Assemblers.ProtocolTests/Assemblers.ProtocolTests.csproj
@@ -0,0 +1,34 @@
+
+
+
+ net48;net8.0
+ false
+ disable
+ disable
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
diff --git a/Assemblers.ProtocolTests/Logging.cs b/Assemblers.ProtocolTests/Logging.cs
new file mode 100644
index 0000000..cb44970
--- /dev/null
+++ b/Assemblers.ProtocolTests/Logging.cs
@@ -0,0 +1,44 @@
+namespace Assemblers.ProtocolTests
+{
+ using System;
+
+ using Skyline.DataMiner.CICD.Loggers;
+
+ internal class Logging : ILogCollector
+ {
+ private readonly bool debug;
+
+ public Logging(bool debug)
+ {
+ this.debug = debug;
+ }
+
+ public void ReportError(string error)
+ {
+ ReportLog($"ERROR|{error}");
+ }
+
+ public void ReportStatus(string status)
+ {
+ ReportLog($"STATUS|{status}");
+ }
+
+ public void ReportWarning(string warning)
+ {
+ ReportLog($"WARNING|{warning}");
+ }
+
+ public void ReportDebug(string debug)
+ {
+ ReportLog($"DEBUG|{debug}");
+ }
+
+ public void ReportLog(string message)
+ {
+ if (debug)
+ {
+ Console.WriteLine(message);
+ }
+ }
+ }
+}
diff --git a/Assemblers.ProtocolTests/ProcessAssembliesTests.cs b/Assemblers.ProtocolTests/ProcessAssembliesTests.cs
new file mode 100644
index 0000000..9a73549
--- /dev/null
+++ b/Assemblers.ProtocolTests/ProcessAssembliesTests.cs
@@ -0,0 +1,71 @@
+namespace Assemblers.ProtocolTests
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Threading.Tasks;
+
+ using FluentAssertions;
+
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ using NuGet.Packaging.Core;
+ using NuGet.Versioning;
+
+ using Skyline.DataMiner.CICD.Assemblers.Common;
+ using Skyline.DataMiner.CICD.Assemblers.Protocol;
+ using Skyline.DataMiner.CICD.Loggers;
+
+ [TestClass]
+ public class AssemblyFilterTests
+ {
+ [TestMethod]
+ public async Task ProcessAsyncTest_DuplicateFrameworkScenario()
+ {
+ // Arrange
+ var packageReferenceProcessor = new PackageReferenceProcessor(directoryForNuGetConfig: null);
+
+ IList projectPackages = new List
+ {
+ new PackageIdentity("microsoft.extensions.http", new NuGetVersion("6.0.0")),
+ new PackageIdentity("nats.client", new NuGetVersion("1.1.0")),
+ };
+
+ const string targetFrameworkMoniker = ".NETFramework,Version=v4.6.2";
+
+ BuildResultItems buildResultItems = new BuildResultItems();
+ HashSet dllImports = new HashSet();
+
+ // Act
+ var result = await AssemblyFilter.FilterAsync(targetFrameworkMoniker, packageReferenceProcessor, buildResultItems, dllImports,
+ projectPackages);
+
+ // Assert
+ // Make sure there is only one System.Net.Http.dll
+ // NuGetAssemblies and NetFramework cannot both have System.Net.Http which causes incorrect behavior down the line.
+ // BuildResultItems
+ // AssemblyPath: c:\Users\{user}\.nuget\packages\system.net.http\4.3.4\lib\net46\System.Net.Http.dll
+ // dllImports: system.net.http\4.3.4\lib\net46\System.Net.Http.dll
+ // dllImports hashset:
+ // System.Net.Http.dll
+
+ result.Should().NotBeNull();
+ // dllImports needs priority
+ dllImports.Should().Contain("System.Net.Http.dll");
+ // buildResultItems should not have system.net.http
+ // dllImports should not have duplicate system.net.http
+ dllImports.Should().NotContain(@"system.net.http\4.3.4\lib\net46\System.Net.Http.dll");
+
+ // dllImports should still have added the folder, in order to access other dll's from the same nuget
+ dllImports.Should().Contain(@"system.net.http\4.3.4\lib\net46\");
+
+ var unexpectedPackageReference =
+ new PackageAssemblyReference(@"system.net.http\4.3.4\lib\net46\System.Net.Http.dll", String.Empty, false);
+ buildResultItems.Assemblies.Should().NotContainEquivalentOf(unexpectedPackageReference,
+ options => options.Excluding(reference => reference.AssemblyPath));
+
+ // Best effort to save time.
+ dllImports.Count.Should().Be(26);
+ buildResultItems.Assemblies.Count.Should().Be(22);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/ProtocolBuilderTests.cs b/Assemblers.ProtocolTests/ProtocolBuilderTests.cs
new file mode 100644
index 0000000..b76d5b8
--- /dev/null
+++ b/Assemblers.ProtocolTests/ProtocolBuilderTests.cs
@@ -0,0 +1,832 @@
+namespace Assemblers.ProtocolTests
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Reflection;
+ using System.Threading.Tasks;
+
+ using FluentAssertions;
+
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ using Org.XmlUnit.Builder;
+ using Org.XmlUnit.Diff;
+
+ using Skyline.DataMiner.CICD.Assemblers.Common;
+ using Skyline.DataMiner.CICD.Assemblers.Protocol;
+ using Skyline.DataMiner.CICD.FileSystem;
+ using Skyline.DataMiner.CICD.Parsers.Common.VisualStudio.Projects;
+ using Skyline.DataMiner.CICD.Parsers.Common.Xml;
+ using Skyline.DataMiner.CICD.Parsers.Protocol.VisualStudio;
+
+ [TestClass]
+ public class ProtocolBuilderTests
+ {
+ [TestMethod]
+ public async Task ProtocolBuilder_BuildAsync_IgnoreSatelliteAssemblies()
+ {
+ var logCollector = new Logging(true);
+
+ var baseDir = FileSystem.Instance.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ var dir = FileSystem.Instance.Path.GetFullPath(FileSystem.Instance.Path.Combine(baseDir, @"TestFiles\Solutions\Solution2"));
+ var solutionFilePath = FileSystem.Instance.Path.Combine(dir, "protocol.sln");
+
+ ProtocolSolution solution = ProtocolSolution.Load(solutionFilePath, logCollector);
+ ProtocolBuilder protocolBuilder = new ProtocolBuilder(solution, logCollector);
+
+ var buildResultItems = await protocolBuilder.BuildAsync();
+
+ Assert.IsNotNull(buildResultItems.Assemblies);
+ Assert.HasCount(1, buildResultItems.Assemblies);
+ Assert.AreEqual(@"microsoft.visualstudio.validation\17.8.8\lib\netstandard2.0\Microsoft.VisualStudio.Validation.dll", buildResultItems.Assemblies.First().DllImport);
+ }
+
+ [TestMethod]
+ public async Task ProtocolBuilder_BuildAsync_KeepReferenceAssemblies()
+ {
+ var logCollector = new Logging(true);
+
+ var baseDir = FileSystem.Instance.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ var dir = FileSystem.Instance.Path.GetFullPath(FileSystem.Instance.Path.Combine(baseDir, @"TestFiles\Solutions\Solution3"));
+ var solutionFilePath = FileSystem.Instance.Path.Combine(dir, "protocol.sln");
+
+ ProtocolSolution solution = ProtocolSolution.Load(solutionFilePath, logCollector);
+ ProtocolBuilder protocolBuilder = new ProtocolBuilder(solution, logCollector);
+
+ var buildResultItems = await protocolBuilder.BuildAsync();
+
+ Assert.IsNotNull(buildResultItems.Assemblies);
+ Assert.HasCount(18, buildResultItems.Assemblies);
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_BasicAsync()
+ {
+ string originalProtocol = @"
+
+
+
+";
+
+ string expected = @"
+
+
+
+
+
+";
+
+ var projects = new Dictionary()
+ {
+ { "QAction_1", new Project("QAction_1", new[]{ new ProjectFile("QAction_1.cs", "using System;") }) },
+ };
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_MultipleQActionsAsync()
+ {
+ string originalProtocol = @"
+
+
+
+
+";
+
+ string expected = @"
+
+
+
+
+
+
+
+
+";
+
+ var projects = new Dictionary()
+ {
+ { "QAction_1", new Project("QAction_1", new[]{ new ProjectFile("QAction_1.cs", "using System;") }) },
+ { "QAction_2", new Project("QAction_2", new[]{ new ProjectFile("QAction_2.cs", "using System.Xml;") }) },
+ };
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_VersionHistoryAsync()
+ {
+ string originalProtocol = @"
+
+
+
+
+
+
+
+
+
+
+
+ Change1
+ Fix1
+ NewFeature1
+
+ 2020-01-02
+
+ TWA
+ Skyline Communications
+
+
+
+
+ Change2
+
+ 2020-01-03
+
+ TWA
+ Skyline Communications
+
+
+
+
+ 2020-01-04
+
+ TWA
+ Skyline Communications
+
+
+
+
+
+
+
+
+
+
+";
+
+ string expected = @"
+
+
+
+
+
+
+
+
+
+
+
+
+ Change1
+ Fix1
+ NewFeature1
+
+ 2020-01-02
+
+ TWA
+ Skyline Communications
+
+
+
+
+ Change2
+
+ 2020-01-03
+
+ TWA
+ Skyline Communications
+
+
+
+
+ 2020-01-04
+
+ TWA
+ Skyline Communications
+
+
+
+
+
+
+
+
+
+
+";
+
+ var projects = new Dictionary();
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_MultipleFilesAsync()
+ {
+ string originalProtocol = @"
+
+
+
+";
+
+ string expected = @"
+
+
+
+
+
+";
+
+ var projects = new Dictionary()
+ {
+ { "QAction_3", new Project("QAction_3", new[]{
+ new ProjectFile("QAction_3.cs", "using System;"),
+ new ProjectFile("Class1.cs", "using System; class Class1 {}")
+ }) },
+ };
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public void ProtocolCompiler_ProtocolBuilder_TargetNotEmpty()
+ {
+ string originalProtocol = @"
+
+
+
+
+
+";
+
+ var projects = new Dictionary()
+ {
+ { "QAction_1", new Project("QAction_1", new[]{ new ProjectFile("QAction_1.cs", "using System.Xml;") }) },
+ };
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ var exception = Assert.Throws(() => builder.BuildAsync().Result);
+
+ Assert.IsNotNull(exception.InnerException);
+ Assert.IsInstanceOfType(exception.InnerException, typeof(AssemblerException));
+ Assert.AreEqual("Cannot replace QAction 1, because the target XML node is not empty!", exception.InnerException.Message);
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_DllImportsAsync()
+ {
+ string originalProtocol = @"
+
+
+
+";
+
+ string expected = @"
+
+
+
+
+
+";
+
+ var projectFiles = new[] { new ProjectFile("QAction_1.cs", "using System;") };
+ var references = new[] { new Reference("System.Data.dll"), new Reference("System.Xml.dll") };
+ var project1 = new Project("QAction_1", projectFiles: projectFiles, references: references);
+
+ var projects = new Dictionary()
+ {
+ { "QAction_1", project1 },
+ };
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_DllImports_NoDuplicateAsync()
+ {
+ string originalProtocol = @"
+
+
+
+";
+
+ string expected = @"
+
+
+
+
+
+";
+
+ var projectFiles = new[] { new ProjectFile("QAction_1.cs", "using System;") };
+ var references = new[] { new Reference("System.Data.dll"), new Reference("System.Xml.dll") };
+ var project1 = new Project("QAction_1", projectFiles: projectFiles, references: references);
+
+ var projects = new Dictionary()
+ {
+ { "QAction_1", project1 },
+ };
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_DllImports_ProjectReference()
+ {
+ string originalProtocol = @"
+
+
+
+";
+
+ string expected = @"
+
+
+
+
+
+";
+
+ var projectFiles = new[] { new ProjectFile("QAction_1.cs", "using System;") };
+ var projectReferences = new[] { new ProjectReference("MyLibrary") };
+ var project1 = new Project("QAction_1", projectFiles: projectFiles, projectReferences: projectReferences);
+
+ var projects = new Dictionary()
+ {
+ { "QAction_1", project1 },
+ };
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_ClassLibraryAsync()
+ {
+ string originalProtocol = @"
+
+
+
+
+";
+
+ string expected = @"
+
+
+
+
+
+
+
+
+";
+
+ var project63000 = new Project("QAction_63000", new[] { new ProjectFile("QAction_63000.cs", "namespace Skyline.DataMiner.Library { }") });
+
+ var projectFiles = new[] { new ProjectFile("QAction_1.cs", "using System;") };
+ var references = new[] { new Reference("System.Data.dll"), new Reference("System.Xml.dll") };
+ var projectReferences = new[] { new ProjectReference("QAction_63000") };
+ var project1 = new Project("QAction_1", projectFiles: projectFiles, projectReferences: projectReferences, references: references);
+
+ var projects = new Dictionary()
+ {
+ { "QAction_63000", project63000 },
+ { "QAction_1", project1 },
+ };
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_ReferencedQActionAsync()
+ {
+ string originalProtocol = @"
+
+
+
+
+";
+
+ string expected = @"
+
+
+
+
+
+
+
+
+";
+
+ var project1 = new Project("QAction_1", new[] { new ProjectFile("QAction_1.cs", "using System;") });
+
+ var projectReferences = new[] { new ProjectReference("QAction_1") };
+ var project2 = new Project("QAction_2", projectFiles: new[] { new ProjectFile("QAction_2.cs", "using System;") }, projectReferences: projectReferences);
+
+ var projects = new Dictionary()
+ {
+ { "QAction_1", project1 },
+ { "QAction_2", project2 },
+ };
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_ReferencedQActionWithCustomNameAsync()
+ {
+ string originalProtocol = @"
+
+
+
+
+";
+
+ string expected = @"
+
+
+
+
+
+
+
+
+";
+
+ var project1 = new Project("QAction_1", new[] { new ProjectFile("QAction_1.cs", "using System;") });
+
+ var projectReferences = new[] { new ProjectReference("QAction_1") };
+ var project2 = new Project("QAction_2", projectFiles: new[] { new ProjectFile("QAction_2.cs", "using System;") }, projectReferences: projectReferences);
+
+ var projects = new Dictionary()
+ {
+ { "QAction_1", project1 },
+ { "QAction_2", project2 },
+ };
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public void ProtocolCompiler_ProtocolBuilder_MissingQAction()
+ {
+ string originalProtocol = @"
+
+
+
+";
+
+ var projects = new Dictionary();
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+ var exception = Assert.Throws(() => builder.BuildAsync().Result);
+
+ Assert.IsNotNull(exception.InnerException);
+ Assert.IsInstanceOfType(exception.InnerException, typeof(AssemblerException));
+ Assert.AreEqual("Project with name 'QAction_1' could not be found!", exception.InnerException.Message);
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_MissingNameAsync()
+ {
+ string originalProtocol = @"
+
+
+
+";
+
+ string expected = @"
+
+
+
+
+
+";
+
+ var projects = new Dictionary()
+ {
+ { "QAction_1", new Project("QAction_1", new[]{ new ProjectFile("QAction_1.cs", "using System;") }) },
+ };
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_JScriptQActionAsync()
+ {
+ string originalProtocol = @"
+
+
+
+
+
+";
+
+ string expected = @"
+
+
+
+
+
+";
+
+ var projects = new Dictionary();
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_SpecialCharactersAsync()
+ {
+ string originalProtocol = @"
+
+
+
+";
+
+ string expected = @"
+
+
+
+
+
+";
+
+ var projects = new Dictionary()
+ {
+ { "QAction_1", new Project("QAction_1", new[]{ new ProjectFile("QAction_1.cs", "using Characterø;") }) },
+ };
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects);
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_Solution_Build()
+ {
+ // arrange
+ var baseDir = FileSystem.Instance.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ var dir = FileSystem.Instance.Path.GetFullPath(FileSystem.Instance.Path.Combine(baseDir, @"TestFiles\Solutions\Solution1"));
+ var path = FileSystem.Instance.Path.Combine(dir, "Protocol.sln");
+
+ var solution = ProtocolSolution.Load(path);
+
+ // act
+ ProtocolBuilder builder = new ProtocolBuilder(solution);
+ var buildResultItems = await builder.BuildAsync().ConfigureAwait(false);
+
+ string result = buildResultItems.Document;
+
+ // check
+ string expected = @"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+";
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public async Task ProtocolCompiler_ProtocolBuilder_OverrideVersion()
+ {
+ string originalProtocol = @"
+ 1.0.0.1
+";
+
+ string expected = @"
+ 1.0.0.1_DIS
+";
+
+ var projects = new Dictionary(0);
+
+ ProtocolBuilder builder = new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects, "1.0.0.1_DIS");
+
+ string result = (await builder.BuildAsync().ConfigureAwait(false)).Document;
+
+ Diff d = DiffBuilder.Compare(Input.FromString(expected))
+ .WithTest(Input.FromString(result)).Build();
+
+ Assert.IsFalse(d.HasDifferences(), d.ToString());
+ }
+
+ [TestMethod]
+ public void ProtocolCompiler_ProtocolBuilder_OverrideVersion_MissingVersionTag()
+ {
+ string originalProtocol = @"
+";
+
+ var projects = new Dictionary(0);
+
+ Assert.Throws(() => new ProtocolBuilder(XmlDocument.Parse(originalProtocol), projects, "1.0.0.1_DIS"));
+ }
+
+ [TestMethod]
+ public async Task ProtocolSolution_BuildAsync_SolutionLibraries()
+ {
+ // Arrange
+ var baseDir = FileSystem.Instance.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ var dir = FileSystem.Instance.Path.GetFullPath(FileSystem.Instance.Path.Combine(baseDir, @"TestFiles\Solutions\Solution4"));
+ var path = FileSystem.Instance.Path.Combine(dir, "Protocol.sln");
+
+ var solution = ProtocolSolution.Load(path);
+
+ // Act
+ ProtocolBuilder builder = new ProtocolBuilder(solution);
+ var result = await builder.BuildAsync().ConfigureAwait(false);
+
+ // Assert
+ result.Should().NotBeNull();
+ result.Document.Should()
+ .ContainEquivalentOf(
+ "dllImport=\"SolutionLibraries\\ModSolutionLib\\Skyline.DataMiner.Dev.Utils.ModSolutionLib.dll\"");
+
+ // Only needs to be referenced, shouldn't be part of the script itself
+ result.Assemblies.Should().BeEmpty();
+ result.DllAssemblies.Should().BeEmpty();
+ }
+ }
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/Protocol.sln b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/Protocol.sln
new file mode 100644
index 0000000..5b9de86
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/Protocol.sln
@@ -0,0 +1,65 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33414.496
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{13998E16-2F02-4D47-BEB1-4ED034DD72D8}"
+ ProjectSection(SolutionItems) = preProject
+ protocol.xml = protocol.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "QActions", "QActions", "{F32C5E72-BF2C-45CF-AAB1-DADCC040E51C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QAction_1", "QAction_1\QAction_1.csproj", "{20481214-4655-4C51-97AA-5DA92296CBCF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QAction_2", "QAction_2\QAction_2.csproj", "{B5ED3E0A-72ED-42ED-8375-65925907F2D9}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{07EA3993-AA2E-4C59-9110-BF25DB8450BE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QAction_Helper", "QAction_Helper\QAction_Helper.csproj", "{31B1EF6A-2E94-4F70-9B05-F297AB3B6C69}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QAction_63000", "QAction_63000\QAction_63000.csproj", "{113FC56A-2732-420E-B365-3915558AFD45}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QAction_3", "QAction_3\QAction_3.csproj", "{35F7A839-1F8D-4932-8850-D6B9FD17A2E8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {20481214-4655-4C51-97AA-5DA92296CBCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {20481214-4655-4C51-97AA-5DA92296CBCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {20481214-4655-4C51-97AA-5DA92296CBCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {20481214-4655-4C51-97AA-5DA92296CBCF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B5ED3E0A-72ED-42ED-8375-65925907F2D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B5ED3E0A-72ED-42ED-8375-65925907F2D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B5ED3E0A-72ED-42ED-8375-65925907F2D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B5ED3E0A-72ED-42ED-8375-65925907F2D9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {31B1EF6A-2E94-4F70-9B05-F297AB3B6C69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {31B1EF6A-2E94-4F70-9B05-F297AB3B6C69}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {31B1EF6A-2E94-4F70-9B05-F297AB3B6C69}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {31B1EF6A-2E94-4F70-9B05-F297AB3B6C69}.Release|Any CPU.Build.0 = Release|Any CPU
+ {113FC56A-2732-420E-B365-3915558AFD45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {113FC56A-2732-420E-B365-3915558AFD45}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {113FC56A-2732-420E-B365-3915558AFD45}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {113FC56A-2732-420E-B365-3915558AFD45}.Release|Any CPU.Build.0 = Release|Any CPU
+ {35F7A839-1F8D-4932-8850-D6B9FD17A2E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {35F7A839-1F8D-4932-8850-D6B9FD17A2E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {35F7A839-1F8D-4932-8850-D6B9FD17A2E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {35F7A839-1F8D-4932-8850-D6B9FD17A2E8}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {20481214-4655-4C51-97AA-5DA92296CBCF} = {F32C5E72-BF2C-45CF-AAB1-DADCC040E51C}
+ {B5ED3E0A-72ED-42ED-8375-65925907F2D9} = {F32C5E72-BF2C-45CF-AAB1-DADCC040E51C}
+ {31B1EF6A-2E94-4F70-9B05-F297AB3B6C69} = {07EA3993-AA2E-4C59-9110-BF25DB8450BE}
+ {113FC56A-2732-420E-B365-3915558AFD45} = {F32C5E72-BF2C-45CF-AAB1-DADCC040E51C}
+ {35F7A839-1F8D-4932-8850-D6B9FD17A2E8} = {F32C5E72-BF2C-45CF-AAB1-DADCC040E51C}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {58942BE7-5A68-461B-8F90-E06699C84F5C}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_1/Class1.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_1/Class1.cs
new file mode 100644
index 0000000..e486b61
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_1/Class1.cs
@@ -0,0 +1,6 @@
+namespace QAction_1
+{
+ public class Class1
+ {
+ }
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_1/Properties/AssemblyInfo.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_1/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1b24379
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_1/Properties/AssemblyInfo.cs
@@ -0,0 +1,5 @@
+using System.Reflection;
+
+
+[assembly: AssemblyTitle("QAction_1")]
+[assembly: AssemblyDescription("")]
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_1/QAction_1.csproj b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_1/QAction_1.csproj
new file mode 100644
index 0000000..7752adb
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_1/QAction_1.csproj
@@ -0,0 +1,59 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {20481214-4655-4C51-97AA-5DA92296CBCF}
+ Library
+ Properties
+ QAction_1
+ QAction_1
+ v4.6
+ 512
+ 7.3
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ None
+
+
+
+ ..\..\..\..\..\..\..\..\..\..\..\Skyline DataMiner\ProtocolScripts\Newtonsoft.Json.dll
+
+
+
+
+
+
+
+
+
+
+ {113fc56a-2732-420e-b365-3915558afd45}
+ QAction_63000
+
+
+ {31b1ef6a-2e94-4f70-9b05-f297ab3b6c69}
+ QAction_Helper
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_2/QAction_2.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_2/QAction_2.cs
new file mode 100644
index 0000000..b2bd68b
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_2/QAction_2.cs
@@ -0,0 +1,6 @@
+namespace QAction_2
+{
+ public class QAction_2
+ {
+ }
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_2/QAction_2.csproj b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_2/QAction_2.csproj
new file mode 100644
index 0000000..700ba66
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_2/QAction_2.csproj
@@ -0,0 +1,58 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {B5ED3E0A-72ED-42ED-8375-65925907F2D9}
+ Library
+ Properties
+ QAction_2
+ QAction_2
+ v4.6
+ 512
+ 7.3
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ None
+
+
+
+
+
+
+
+
+
+ {20481214-4655-4c51-97aa-5da92296cbcf}
+ QAction_1
+
+
+ {113fc56a-2732-420e-b365-3915558afd45}
+ QAction_63000
+
+
+ {31b1ef6a-2e94-4f70-9b05-f297ab3b6c69}
+ QAction_Helper
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_3/Class1.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_3/Class1.cs
new file mode 100644
index 0000000..228673c
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_3/Class1.cs
@@ -0,0 +1,6 @@
+namespace QAction_3
+{
+ public class Class1
+ {
+ }
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_3/QAction_3.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_3/QAction_3.cs
new file mode 100644
index 0000000..e19b113
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_3/QAction_3.cs
@@ -0,0 +1,6 @@
+namespace QAction_3
+{
+ public class QAction_3
+ {
+ }
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_3/QAction_3.csproj b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_3/QAction_3.csproj
new file mode 100644
index 0000000..8b77711
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_3/QAction_3.csproj
@@ -0,0 +1,58 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {35F7A839-1F8D-4932-8850-D6B9FD17A2E8}
+ Library
+ Properties
+ QAction_3
+ QAction_3
+ v4.6.2
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+ {113fc56a-2732-420e-b365-3915558afd45}
+ QAction_63000
+
+
+ {31b1ef6a-2e94-4f70-9b05-f297ab3b6c69}
+ QAction_Helper
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_3/SubDir/Class2.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_3/SubDir/Class2.cs
new file mode 100644
index 0000000..1959565
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_3/SubDir/Class2.cs
@@ -0,0 +1,6 @@
+namespace QAction_3
+{
+ public class Class2
+ {
+ }
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_63000/QAction_63000.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_63000/QAction_63000.cs
new file mode 100644
index 0000000..0bb2afc
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_63000/QAction_63000.cs
@@ -0,0 +1,6 @@
+namespace QAction_63000
+{
+ public class QAction_63000
+ {
+ }
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_63000/QAction_63000.csproj b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_63000/QAction_63000.csproj
new file mode 100644
index 0000000..58a2e21
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_63000/QAction_63000.csproj
@@ -0,0 +1,46 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {113FC56A-2732-420E-B365-3915558AFD45}
+ Library
+ Properties
+ QAction_63000
+ QAction_63000
+ v4.6
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+ {31b1ef6a-2e94-4f70-9b05-f297ab3b6c69}
+ QAction_Helper
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_ClassLibrary/QAction_ClassLibrary.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_ClassLibrary/QAction_ClassLibrary.cs
new file mode 100644
index 0000000..b936d2f
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_ClassLibrary/QAction_ClassLibrary.cs
@@ -0,0 +1,5 @@
+// This is auto-generated code by DIS. Do not modify.
+namespace Skyline.DataMiner.Library
+{
+
+}
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_ClassLibrary/QAction_ClassLibrary.csproj b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_ClassLibrary/QAction_ClassLibrary.csproj
new file mode 100644
index 0000000..312b0ed
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_ClassLibrary/QAction_ClassLibrary.csproj
@@ -0,0 +1,42 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {08EC67C1-11E7-4BEC-B22B-63F115216912}
+ Library
+ Properties
+ QAction_ClassLibrary
+ QAction_ClassLibrary
+ v4.6
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_Helper/QAction_Helper.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_Helper/QAction_Helper.cs
new file mode 100644
index 0000000..fd0ea5a
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_Helper/QAction_Helper.cs
@@ -0,0 +1 @@
+// This is auto-generated code by DIS. Do not modify.
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_Helper/QAction_Helper.csproj b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_Helper/QAction_Helper.csproj
new file mode 100644
index 0000000..a7eb9ac
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/QAction_Helper/QAction_Helper.csproj
@@ -0,0 +1,42 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {31B1EF6A-2E94-4F70-9B05-F297AB3B6C69}
+ Library
+ Properties
+ QAction_Helper
+ QAction_Helper
+ v4.6
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/protocol.xml b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/protocol.xml
new file mode 100644
index 0000000..2d254da
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution1/protocol.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/DefaultTemplates/ABOUT.md b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/DefaultTemplates/ABOUT.md
new file mode 100644
index 0000000..8041bec
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/DefaultTemplates/ABOUT.md
@@ -0,0 +1,5 @@
+This folder contains default templates to be used by the protocol.
+Allowed names:
+"Template_Alarm_Default.xml"
+"Trending_Template_Default.xml"
+"Information_Template_Default.xml"
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Directory.Build.props b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Directory.Build.props
new file mode 100644
index 0000000..4cb446b
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Directory.Build.props
@@ -0,0 +1,31 @@
+
+
+ x86
+ true
+
+
+ $(DefineConstants);DCFv1;DBInfo;ALARM_SQUASHING
+
+
+ full
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+
+
+ pdbonly
+ ..\Internal\Code Analysis\qaction-release.ruleset
+
+
+
+ Properties\stylecop.json
+
+
+ Properties\.editorconfig
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Directory.Build.targets b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Directory.Build.targets
new file mode 100644
index 0000000..6de23bf
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Directory.Build.targets
@@ -0,0 +1,5 @@
+
+
+ $(AssemblySearchPaths);$(ReferencePath)
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Dlls/ABOUT.md b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Dlls/ABOUT.md
new file mode 100644
index 0000000..a3170b3
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Dlls/ABOUT.md
@@ -0,0 +1 @@
+This folder contains DLL files that should be placed under the ProtocolScripts folder of DataMiner for this solution to work correctly.
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Documentation/ABOUT.md b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Documentation/ABOUT.md
new file mode 100644
index 0000000..a150545
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Documentation/ABOUT.md
@@ -0,0 +1 @@
+Looking for README.md? Check your Solution Root folder. This folder can be used to add documentation related to this solution.
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Internal/.editorconfig b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Internal/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Internal/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Internal/Code Analysis/qaction-debug.ruleset b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Internal/Code Analysis/qaction-debug.ruleset
new file mode 100644
index 0000000..26e7d46
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Internal/Code Analysis/qaction-debug.ruleset
@@ -0,0 +1,355 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Internal/Code Analysis/qaction-release.ruleset b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Internal/Code Analysis/qaction-release.ruleset
new file mode 100644
index 0000000..de0890a
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Internal/Code Analysis/qaction-release.ruleset
@@ -0,0 +1,484 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Internal/Code Analysis/stylecop.json b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Internal/Code Analysis/stylecop.json
new file mode 100644
index 0000000..b2d519d
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/Internal/Code Analysis/stylecop.json
@@ -0,0 +1,74 @@
+{
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "indentation": {
+ "useTabs": true,
+ "tabSize": 4
+ },
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_2/QAction_2.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_2/QAction_2.cs
new file mode 100644
index 0000000..a25b12f
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_2/QAction_2.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+
+using Skyline.DataMiner.Scripting;
+
+///
+/// DataMiner QAction Class: After Startup.
+///
+public static class QAction
+{
+ ///
+ /// The QAction entry point.
+ ///
+ /// Link with SLProtocol process.
+ public static void Run(SLProtocol protocol)
+ {
+ try
+ {
+
+ }
+ catch (Exception ex)
+ {
+ protocol.Log($"QA{protocol.QActionID}|{protocol.GetTriggerParameter()}|Run|Exception thrown:{Environment.NewLine}{ex}", LogType.Error, LogLevel.NoLogging);
+ }
+ }
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_2/QAction_2.csproj b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_2/QAction_2.csproj
new file mode 100644
index 0000000..28172a6
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_2/QAction_2.csproj
@@ -0,0 +1,20 @@
+
+
+ net48
+ Skyline Communications
+ © Skyline Communications
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_Helper/Directory.Build.props b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_Helper/Directory.Build.props
new file mode 100644
index 0000000..60bd6c1
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_Helper/Directory.Build.props
@@ -0,0 +1,5 @@
+
+
+ x86
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_Helper/QAction_Helper.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_Helper/QAction_Helper.cs
new file mode 100644
index 0000000..9f7efe0
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_Helper/QAction_Helper.cs
@@ -0,0 +1,38 @@
+// This is auto-generated code by DIS. Do not modify.
+using System.ComponentModel;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Skyline.DataMiner.Scripting
+{
+public static class Parameter
+{
+ public class Write
+ {
+ }
+}
+public class WriteParameters
+{
+ public SLProtocolExt Protocol;
+ public WriteParameters(SLProtocolExt protocol)
+ {
+ Protocol = protocol;
+ }
+}
+public interface SLProtocolExt : SLProtocol
+{
+ object Afterstartup_dummy { get; set; }
+ WriteParameters Write { get; set; }
+}
+public class ConcreteSLProtocolExt : ConcreteSLProtocol, SLProtocolExt
+{
+ /// PID: 2 | Type: dummy
+ public System.Object Afterstartup_dummy {get { return GetParameter(2); }set { SetParameter(2, value); }}
+ public WriteParameters Write { get; set; }
+ public ConcreteSLProtocolExt()
+ {
+ Write = new WriteParameters(this);
+ }
+}
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_Helper/QAction_Helper.csproj b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_Helper/QAction_Helper.csproj
new file mode 100644
index 0000000..9e697ba
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/QAction_Helper/QAction_Helper.csproj
@@ -0,0 +1,21 @@
+
+
+ net48
+ Skyline Communications
+ © Skyline Communications
+ 0
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/protocol.sln b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/protocol.sln
new file mode 100644
index 0000000..0dc095f
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/protocol.sln
@@ -0,0 +1,72 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33502.453
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{AFFAB0B4-ADBE-4678-83A7-431B9D259E0D}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\.editorconfig = Internal\.editorconfig
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "QActions", "QActions", "{9DB1E2EC-F575-479D-AFDF-D9A72E22145A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{41343ECD-5C88-49A3-905D-FC1F24C3EFC6}"
+ ProjectSection(SolutionItems) = preProject
+ Dlls\ABOUT.md = Dlls\ABOUT.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DefaultTemplates", "DefaultTemplates", "{F2683535-3B81-4454-9E99-120E5016BBCE}"
+ ProjectSection(SolutionItems) = preProject
+ DefaultTemplates\ABOUT.md = DefaultTemplates\ABOUT.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{791FA0C3-E691-4665-B01C-BCC3E296E58D}"
+ ProjectSection(SolutionItems) = preProject
+ Documentation\ABOUT.md = Documentation\ABOUT.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{ECB3E466-EA84-4A9B-80CF-2AAFD7C59525}"
+ ProjectSection(SolutionItems) = preProject
+ protocol.xml = protocol.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D9DACB40-405B-41C9-8AB9-035344C5485B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code Analysis", "Code Analysis", "{C6502079-007F-40F4-B435-7395410F5D02}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\Code Analysis\qaction-debug.ruleset = Internal\Code Analysis\qaction-debug.ruleset
+ Internal\Code Analysis\qaction-release.ruleset = Internal\Code Analysis\qaction-release.ruleset
+ Internal\Code Analysis\stylecop.json = Internal\Code Analysis\stylecop.json
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAction_Helper", "QAction_Helper\QAction_Helper.csproj", "{46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAction_2", "QAction_2\QAction_2.csproj", "{EC10A547-508B-44BD-8146-72A3BC06E0F6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {C6502079-007F-40F4-B435-7395410F5D02} = {AFFAB0B4-ADBE-4678-83A7-431B9D259E0D}
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C} = {AFFAB0B4-ADBE-4678-83A7-431B9D259E0D}
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6} = {9DB1E2EC-F575-479D-AFDF-D9A72E22145A}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {25C201FA-8CE6-4789-B8EB-E99CC4EE1AA3}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/protocol.xml b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/protocol.xml
new file mode 100644
index 0000000..0aa6aba
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution2/protocol.xml
@@ -0,0 +1,169 @@
+
+
+
+
+ natsconnectortest
+ natsconnectortest DataMiner connector
+ 1.0.0.1
+ DMS-DRV-
+ Skyline Communications
+
+ 1.3.6.1.4.1.8813.2.
+
+ auto
+
+ virtual
+
+
+
+ true
+ 10.2.0.0 - 12603
+
+
+
+
+ AfterStartup
+ After Startup
+ dummy
+
+
+
+
+
+
+
+
+
+ After Startup
+ After Startup
+ poll action
+
+ 2
+
+
+
+
+
+
+ After Startup
+ protocol
+
+ action
+
+ 1
+
+
+
+
+
+
+ After Startup Group
+ group
+ execute next
+
+
+ After Startup QAction
+ parameter
+ run actions
+
+
+
+
+
+ Fast Timer (10s)
+
+ 75
+
+
+
+
+ Medium Timer (1m)
+
+ 75
+
+
+
+
+ Slow Timer (1h)
+
+ 75
+
+
+
+
+
+
+
+
+
+
+
+ Main Branch
+
+
+
+
+
+
+ 2025-01-03
+
+ XXX
+ Skyline Communications
+
+
+ Initial version
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/DefaultTemplates/ABOUT.md b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/DefaultTemplates/ABOUT.md
new file mode 100644
index 0000000..8041bec
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/DefaultTemplates/ABOUT.md
@@ -0,0 +1,5 @@
+This folder contains default templates to be used by the protocol.
+Allowed names:
+"Template_Alarm_Default.xml"
+"Trending_Template_Default.xml"
+"Information_Template_Default.xml"
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Directory.Build.props b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Directory.Build.props
new file mode 100644
index 0000000..4cb446b
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Directory.Build.props
@@ -0,0 +1,31 @@
+
+
+ x86
+ true
+
+
+ $(DefineConstants);DCFv1;DBInfo;ALARM_SQUASHING
+
+
+ full
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+
+
+ pdbonly
+ ..\Internal\Code Analysis\qaction-release.ruleset
+
+
+
+ Properties\stylecop.json
+
+
+ Properties\.editorconfig
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Directory.Build.targets b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Directory.Build.targets
new file mode 100644
index 0000000..6de23bf
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Directory.Build.targets
@@ -0,0 +1,5 @@
+
+
+ $(AssemblySearchPaths);$(ReferencePath)
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Dlls/ABOUT.md b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Dlls/ABOUT.md
new file mode 100644
index 0000000..a3170b3
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Dlls/ABOUT.md
@@ -0,0 +1 @@
+This folder contains DLL files that should be placed under the ProtocolScripts folder of DataMiner for this solution to work correctly.
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Documentation/ABOUT.md b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Documentation/ABOUT.md
new file mode 100644
index 0000000..a150545
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Documentation/ABOUT.md
@@ -0,0 +1 @@
+Looking for README.md? Check your Solution Root folder. This folder can be used to add documentation related to this solution.
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Internal/.editorconfig b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Internal/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Internal/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Internal/Code Analysis/qaction-debug.ruleset b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Internal/Code Analysis/qaction-debug.ruleset
new file mode 100644
index 0000000..26e7d46
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Internal/Code Analysis/qaction-debug.ruleset
@@ -0,0 +1,355 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Internal/Code Analysis/qaction-release.ruleset b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Internal/Code Analysis/qaction-release.ruleset
new file mode 100644
index 0000000..de0890a
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Internal/Code Analysis/qaction-release.ruleset
@@ -0,0 +1,484 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Internal/Code Analysis/stylecop.json b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Internal/Code Analysis/stylecop.json
new file mode 100644
index 0000000..b2d519d
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/Internal/Code Analysis/stylecop.json
@@ -0,0 +1,74 @@
+{
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "indentation": {
+ "useTabs": true,
+ "tabSize": 4
+ },
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_2/QAction_2.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_2/QAction_2.cs
new file mode 100644
index 0000000..a25b12f
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_2/QAction_2.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+
+using Skyline.DataMiner.Scripting;
+
+///
+/// DataMiner QAction Class: After Startup.
+///
+public static class QAction
+{
+ ///
+ /// The QAction entry point.
+ ///
+ /// Link with SLProtocol process.
+ public static void Run(SLProtocol protocol)
+ {
+ try
+ {
+
+ }
+ catch (Exception ex)
+ {
+ protocol.Log($"QA{protocol.QActionID}|{protocol.GetTriggerParameter()}|Run|Exception thrown:{Environment.NewLine}{ex}", LogType.Error, LogLevel.NoLogging);
+ }
+ }
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_2/QAction_2.csproj b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_2/QAction_2.csproj
new file mode 100644
index 0000000..2af835e
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_2/QAction_2.csproj
@@ -0,0 +1,20 @@
+
+
+ net48
+ Skyline Communications
+ © Skyline Communications
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_Helper/Directory.Build.props b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_Helper/Directory.Build.props
new file mode 100644
index 0000000..60bd6c1
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_Helper/Directory.Build.props
@@ -0,0 +1,5 @@
+
+
+ x86
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_Helper/QAction_Helper.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_Helper/QAction_Helper.cs
new file mode 100644
index 0000000..9f7efe0
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_Helper/QAction_Helper.cs
@@ -0,0 +1,38 @@
+// This is auto-generated code by DIS. Do not modify.
+using System.ComponentModel;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Skyline.DataMiner.Scripting
+{
+public static class Parameter
+{
+ public class Write
+ {
+ }
+}
+public class WriteParameters
+{
+ public SLProtocolExt Protocol;
+ public WriteParameters(SLProtocolExt protocol)
+ {
+ Protocol = protocol;
+ }
+}
+public interface SLProtocolExt : SLProtocol
+{
+ object Afterstartup_dummy { get; set; }
+ WriteParameters Write { get; set; }
+}
+public class ConcreteSLProtocolExt : ConcreteSLProtocol, SLProtocolExt
+{
+ /// PID: 2 | Type: dummy
+ public System.Object Afterstartup_dummy {get { return GetParameter(2); }set { SetParameter(2, value); }}
+ public WriteParameters Write { get; set; }
+ public ConcreteSLProtocolExt()
+ {
+ Write = new WriteParameters(this);
+ }
+}
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_Helper/QAction_Helper.csproj b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_Helper/QAction_Helper.csproj
new file mode 100644
index 0000000..9e697ba
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/QAction_Helper/QAction_Helper.csproj
@@ -0,0 +1,21 @@
+
+
+ net48
+ Skyline Communications
+ © Skyline Communications
+ 0
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/protocol.sln b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/protocol.sln
new file mode 100644
index 0000000..0dc095f
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/protocol.sln
@@ -0,0 +1,72 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33502.453
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{AFFAB0B4-ADBE-4678-83A7-431B9D259E0D}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\.editorconfig = Internal\.editorconfig
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "QActions", "QActions", "{9DB1E2EC-F575-479D-AFDF-D9A72E22145A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{41343ECD-5C88-49A3-905D-FC1F24C3EFC6}"
+ ProjectSection(SolutionItems) = preProject
+ Dlls\ABOUT.md = Dlls\ABOUT.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DefaultTemplates", "DefaultTemplates", "{F2683535-3B81-4454-9E99-120E5016BBCE}"
+ ProjectSection(SolutionItems) = preProject
+ DefaultTemplates\ABOUT.md = DefaultTemplates\ABOUT.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{791FA0C3-E691-4665-B01C-BCC3E296E58D}"
+ ProjectSection(SolutionItems) = preProject
+ Documentation\ABOUT.md = Documentation\ABOUT.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{ECB3E466-EA84-4A9B-80CF-2AAFD7C59525}"
+ ProjectSection(SolutionItems) = preProject
+ protocol.xml = protocol.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D9DACB40-405B-41C9-8AB9-035344C5485B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code Analysis", "Code Analysis", "{C6502079-007F-40F4-B435-7395410F5D02}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\Code Analysis\qaction-debug.ruleset = Internal\Code Analysis\qaction-debug.ruleset
+ Internal\Code Analysis\qaction-release.ruleset = Internal\Code Analysis\qaction-release.ruleset
+ Internal\Code Analysis\stylecop.json = Internal\Code Analysis\stylecop.json
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAction_Helper", "QAction_Helper\QAction_Helper.csproj", "{46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAction_2", "QAction_2\QAction_2.csproj", "{EC10A547-508B-44BD-8146-72A3BC06E0F6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {C6502079-007F-40F4-B435-7395410F5D02} = {AFFAB0B4-ADBE-4678-83A7-431B9D259E0D}
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C} = {AFFAB0B4-ADBE-4678-83A7-431B9D259E0D}
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6} = {9DB1E2EC-F575-479D-AFDF-D9A72E22145A}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {25C201FA-8CE6-4789-B8EB-E99CC4EE1AA3}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/protocol.xml b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/protocol.xml
new file mode 100644
index 0000000..0aa6aba
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution3/protocol.xml
@@ -0,0 +1,169 @@
+
+
+
+
+ natsconnectortest
+ natsconnectortest DataMiner connector
+ 1.0.0.1
+ DMS-DRV-
+ Skyline Communications
+
+ 1.3.6.1.4.1.8813.2.
+
+ auto
+
+ virtual
+
+
+
+ true
+ 10.2.0.0 - 12603
+
+
+
+
+ AfterStartup
+ After Startup
+ dummy
+
+
+
+
+
+
+
+
+
+ After Startup
+ After Startup
+ poll action
+
+ 2
+
+
+
+
+
+
+ After Startup
+ protocol
+
+ action
+
+ 1
+
+
+
+
+
+
+ After Startup Group
+ group
+ execute next
+
+
+ After Startup QAction
+ parameter
+ run actions
+
+
+
+
+
+ Fast Timer (10s)
+
+ 75
+
+
+
+
+ Medium Timer (1m)
+
+ 75
+
+
+
+
+ Slow Timer (1h)
+
+ 75
+
+
+
+
+
+
+
+
+
+
+
+ Main Branch
+
+
+
+
+
+
+ 2025-01-03
+
+ XXX
+ Skyline Communications
+
+
+ Initial version
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/DefaultTemplates/ABOUT.md b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/DefaultTemplates/ABOUT.md
new file mode 100644
index 0000000..8041bec
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/DefaultTemplates/ABOUT.md
@@ -0,0 +1,5 @@
+This folder contains default templates to be used by the protocol.
+Allowed names:
+"Template_Alarm_Default.xml"
+"Trending_Template_Default.xml"
+"Information_Template_Default.xml"
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Directory.Build.props b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Directory.Build.props
new file mode 100644
index 0000000..4cb446b
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Directory.Build.props
@@ -0,0 +1,31 @@
+
+
+ x86
+ true
+
+
+ $(DefineConstants);DCFv1;DBInfo;ALARM_SQUASHING
+
+
+ full
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+
+
+ pdbonly
+ ..\Internal\Code Analysis\qaction-release.ruleset
+
+
+
+ Properties\stylecop.json
+
+
+ Properties\.editorconfig
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Directory.Build.targets b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Directory.Build.targets
new file mode 100644
index 0000000..6de23bf
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Directory.Build.targets
@@ -0,0 +1,5 @@
+
+
+ $(AssemblySearchPaths);$(ReferencePath)
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Dlls/ABOUT.md b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Dlls/ABOUT.md
new file mode 100644
index 0000000..a3170b3
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Dlls/ABOUT.md
@@ -0,0 +1 @@
+This folder contains DLL files that should be placed under the ProtocolScripts folder of DataMiner for this solution to work correctly.
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Documentation/ABOUT.md b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Documentation/ABOUT.md
new file mode 100644
index 0000000..a150545
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Documentation/ABOUT.md
@@ -0,0 +1 @@
+Looking for README.md? Check your Solution Root folder. This folder can be used to add documentation related to this solution.
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Internal/.editorconfig b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Internal/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Internal/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Internal/Code Analysis/qaction-debug.ruleset b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Internal/Code Analysis/qaction-debug.ruleset
new file mode 100644
index 0000000..26e7d46
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Internal/Code Analysis/qaction-debug.ruleset
@@ -0,0 +1,355 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Internal/Code Analysis/qaction-release.ruleset b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Internal/Code Analysis/qaction-release.ruleset
new file mode 100644
index 0000000..de0890a
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Internal/Code Analysis/qaction-release.ruleset
@@ -0,0 +1,484 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Internal/Code Analysis/stylecop.json b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Internal/Code Analysis/stylecop.json
new file mode 100644
index 0000000..b2d519d
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/Internal/Code Analysis/stylecop.json
@@ -0,0 +1,74 @@
+{
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "indentation": {
+ "useTabs": true,
+ "tabSize": 4
+ },
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_2/QAction_2.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_2/QAction_2.cs
new file mode 100644
index 0000000..a25b12f
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_2/QAction_2.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+
+using Skyline.DataMiner.Scripting;
+
+///
+/// DataMiner QAction Class: After Startup.
+///
+public static class QAction
+{
+ ///
+ /// The QAction entry point.
+ ///
+ /// Link with SLProtocol process.
+ public static void Run(SLProtocol protocol)
+ {
+ try
+ {
+
+ }
+ catch (Exception ex)
+ {
+ protocol.Log($"QA{protocol.QActionID}|{protocol.GetTriggerParameter()}|Run|Exception thrown:{Environment.NewLine}{ex}", LogType.Error, LogLevel.NoLogging);
+ }
+ }
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_2/QAction_2.csproj b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_2/QAction_2.csproj
new file mode 100644
index 0000000..17b6fa2
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_2/QAction_2.csproj
@@ -0,0 +1,20 @@
+
+
+ net48
+ Skyline Communications
+ © Skyline Communications
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_Helper/Directory.Build.props b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_Helper/Directory.Build.props
new file mode 100644
index 0000000..60bd6c1
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_Helper/Directory.Build.props
@@ -0,0 +1,5 @@
+
+
+ x86
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_Helper/QAction_Helper.cs b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_Helper/QAction_Helper.cs
new file mode 100644
index 0000000..9f7efe0
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_Helper/QAction_Helper.cs
@@ -0,0 +1,38 @@
+// This is auto-generated code by DIS. Do not modify.
+using System.ComponentModel;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Skyline.DataMiner.Scripting
+{
+public static class Parameter
+{
+ public class Write
+ {
+ }
+}
+public class WriteParameters
+{
+ public SLProtocolExt Protocol;
+ public WriteParameters(SLProtocolExt protocol)
+ {
+ Protocol = protocol;
+ }
+}
+public interface SLProtocolExt : SLProtocol
+{
+ object Afterstartup_dummy { get; set; }
+ WriteParameters Write { get; set; }
+}
+public class ConcreteSLProtocolExt : ConcreteSLProtocol, SLProtocolExt
+{
+ /// PID: 2 | Type: dummy
+ public System.Object Afterstartup_dummy {get { return GetParameter(2); }set { SetParameter(2, value); }}
+ public WriteParameters Write { get; set; }
+ public ConcreteSLProtocolExt()
+ {
+ Write = new WriteParameters(this);
+ }
+}
+}
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_Helper/QAction_Helper.csproj b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_Helper/QAction_Helper.csproj
new file mode 100644
index 0000000..9e697ba
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/QAction_Helper/QAction_Helper.csproj
@@ -0,0 +1,21 @@
+
+
+ net48
+ Skyline Communications
+ © Skyline Communications
+ 0
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/protocol.sln b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/protocol.sln
new file mode 100644
index 0000000..0dc095f
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/protocol.sln
@@ -0,0 +1,72 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33502.453
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{AFFAB0B4-ADBE-4678-83A7-431B9D259E0D}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\.editorconfig = Internal\.editorconfig
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "QActions", "QActions", "{9DB1E2EC-F575-479D-AFDF-D9A72E22145A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{41343ECD-5C88-49A3-905D-FC1F24C3EFC6}"
+ ProjectSection(SolutionItems) = preProject
+ Dlls\ABOUT.md = Dlls\ABOUT.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DefaultTemplates", "DefaultTemplates", "{F2683535-3B81-4454-9E99-120E5016BBCE}"
+ ProjectSection(SolutionItems) = preProject
+ DefaultTemplates\ABOUT.md = DefaultTemplates\ABOUT.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{791FA0C3-E691-4665-B01C-BCC3E296E58D}"
+ ProjectSection(SolutionItems) = preProject
+ Documentation\ABOUT.md = Documentation\ABOUT.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{ECB3E466-EA84-4A9B-80CF-2AAFD7C59525}"
+ ProjectSection(SolutionItems) = preProject
+ protocol.xml = protocol.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D9DACB40-405B-41C9-8AB9-035344C5485B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code Analysis", "Code Analysis", "{C6502079-007F-40F4-B435-7395410F5D02}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\Code Analysis\qaction-debug.ruleset = Internal\Code Analysis\qaction-debug.ruleset
+ Internal\Code Analysis\qaction-release.ruleset = Internal\Code Analysis\qaction-release.ruleset
+ Internal\Code Analysis\stylecop.json = Internal\Code Analysis\stylecop.json
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAction_Helper", "QAction_Helper\QAction_Helper.csproj", "{46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QAction_2", "QAction_2\QAction_2.csproj", "{EC10A547-508B-44BD-8146-72A3BC06E0F6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {C6502079-007F-40F4-B435-7395410F5D02} = {AFFAB0B4-ADBE-4678-83A7-431B9D259E0D}
+ {46E09E96-CAAD-43DC-A5ED-1E2FDB4C217C} = {AFFAB0B4-ADBE-4678-83A7-431B9D259E0D}
+ {EC10A547-508B-44BD-8146-72A3BC06E0F6} = {9DB1E2EC-F575-479D-AFDF-D9A72E22145A}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {25C201FA-8CE6-4789-B8EB-E99CC4EE1AA3}
+ EndGlobalSection
+EndGlobal
diff --git a/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/protocol.xml b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/protocol.xml
new file mode 100644
index 0000000..0aa6aba
--- /dev/null
+++ b/Assemblers.ProtocolTests/TestFiles/Solutions/Solution4/protocol.xml
@@ -0,0 +1,169 @@
+
+
+
+
+ natsconnectortest
+ natsconnectortest DataMiner connector
+ 1.0.0.1
+ DMS-DRV-
+ Skyline Communications
+
+ 1.3.6.1.4.1.8813.2.
+
+ auto
+
+ virtual
+
+
+
+ true
+ 10.2.0.0 - 12603
+
+
+
+
+ AfterStartup
+ After Startup
+ dummy
+
+
+
+
+
+
+
+
+
+ After Startup
+ After Startup
+ poll action
+
+ 2
+
+
+
+
+
+
+ After Startup
+ protocol
+
+ action
+
+ 1
+
+
+
+
+
+
+ After Startup Group
+ group
+ execute next
+
+
+ After Startup QAction
+ parameter
+ run actions
+
+
+
+
+
+ Fast Timer (10s)
+
+ 75
+
+
+
+
+ Medium Timer (1m)
+
+ 75
+
+
+
+
+ Slow Timer (1h)
+
+ 75
+
+
+
+
+
+
+
+
+
+
+
+ Main Branch
+
+
+
+
+
+
+ 2025-01-03
+
+ XXX
+ Skyline Communications
+
+
+ Initial version
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DMApp.Automation/AppPackageCreatorForAutomation.cs b/DMApp.Automation/AppPackageCreatorForAutomation.cs
index e2aabe9..33924be 100644
--- a/DMApp.Automation/AppPackageCreatorForAutomation.cs
+++ b/DMApp.Automation/AppPackageCreatorForAutomation.cs
@@ -35,7 +35,7 @@ private AppPackageCreatorForAutomation(IFileSystem fileSystem, ILogCollector log
/// The package builder to which the items should be added to.
/// The package creator.
/// is .
- /// No solution (.sln) file was detected or multiple solutions were detected.
+ /// No solution (.sln or .slnx) file was detected or multiple solutions were detected.
public override async Task AddItemsAsync(AppPackage.AppPackageBuilder appPackageBuilder)
{
if (appPackageBuilder == null)
@@ -44,12 +44,14 @@ public override async Task AddItemsAsync(AppPackage.AppPackageBuilder appPackage
}
LogCollector.ReportStatus("Using Workspace: " + RepositoryPath);
- string[] files = FileSystem.Directory.GetFiles(RepositoryPath, "*.sln", SearchOption.TopDirectoryOnly);
+ string[] files = FileSystem.Directory.GetFiles(RepositoryPath, "*.sln", SearchOption.TopDirectoryOnly)
+ .Concat(FileSystem.Directory.GetFiles(RepositoryPath, "*.slnx", SearchOption.AllDirectories))
+ .ToArray();
if (files.Length == 0)
- throw new InvalidOperationException("No solution file (.sln) detected in " + RepositoryPath + ".");
+ throw new InvalidOperationException("No solution file (.sln or .slnx) detected in " + RepositoryPath + ".");
if (files.Length > 1)
- throw new InvalidOperationException("More than one solution file (.sln) detected in " + RepositoryPath + ".");
+ throw new InvalidOperationException("More than one solution file (.sln or .slnx) detected in " + RepositoryPath + ".");
HashSet namesOfScriptsToInclude = null;
diff --git a/DMApp.Automation/DMApp.Automation.csproj b/DMApp.Automation/DMApp.Automation.csproj
index 034078e..ffc2b9c 100644
--- a/DMApp.Automation/DMApp.Automation.csproj
+++ b/DMApp.Automation/DMApp.Automation.csproj
@@ -29,10 +29,7 @@
-
-
-
-
+
diff --git a/DMApp.AutomationTests/AppPackageCreatorForAutomationTests.cs b/DMApp.AutomationTests/AppPackageCreatorForAutomationTests.cs
index 2e1e176..6f32e55 100644
--- a/DMApp.AutomationTests/AppPackageCreatorForAutomationTests.cs
+++ b/DMApp.AutomationTests/AppPackageCreatorForAutomationTests.cs
@@ -30,7 +30,7 @@ public async Task AddItemsAsync_ExpectedArgumentNullException()
Task Act() => creator.AddItemsAsync(null);
// Assert
- await Assert.ThrowsExceptionAsync(Act);
+ await Assert.ThrowsAsync(Act);
}
}
}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/AssemblyInitialize.cs b/DMApp.AutomationTests/AssemblyInitialize.cs
deleted file mode 100644
index 655549f..0000000
--- a/DMApp.AutomationTests/AssemblyInitialize.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-namespace DMApp.AutomationTests
-{
- using System.IO;
- using System.IO.Compression;
- using System.Reflection;
-
- using Microsoft.VisualStudio.TestTools.UnitTesting;
-
- [TestClass]
- public class AssemblyInitialize
- {
- [AssemblyInitialize]
- public static void AssemblyInit(TestContext context)
- {
- // This is needed because certain tools will look at all csproj files in the entire repository.
-
- var baseDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
-
- foreach (var zipFile in Directory.GetFiles(baseDir, "*.zip", SearchOption.AllDirectories))
- {
- string dir = Path.Combine(Path.GetDirectoryName(zipFile), "TestFiles");
-
- ZipFile.ExtractToDirectory(zipFile, dir);
- }
- }
-
- [AssemblyCleanup]
- public static void AssemblyCleanup()
- {
- var baseDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
-
- foreach (var testFilesDirectories in Directory.GetDirectories(baseDir, "TestFiles", SearchOption.AllDirectories))
- {
- Directory.Delete(testFilesDirectories, true);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/DMApp.AutomationTests.csproj b/DMApp.AutomationTests/DMApp.AutomationTests.csproj
index 11658e0..e23f151 100644
--- a/DMApp.AutomationTests/DMApp.AutomationTests.csproj
+++ b/DMApp.AutomationTests/DMApp.AutomationTests.csproj
@@ -1,4 +1,4 @@
-
+
net48;net8.0
@@ -8,7 +8,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -21,9 +21,13 @@
-
- Always
-
+
+
+
+
+
+ PreserveNewest
+
diff --git a/DMApp.AutomationTests/FactoryTests.cs b/DMApp.AutomationTests/FactoryTests.cs
index d490460..e11184b 100644
--- a/DMApp.AutomationTests/FactoryTests.cs
+++ b/DMApp.AutomationTests/FactoryTests.cs
@@ -75,7 +75,7 @@ public async Task FromRepositorySolution1ReturnsPackageWith2Scripts()
var package = await creator.BuildPackageAsync();
// Assert.
- Assert.AreEqual(2, package.AutomationScripts.Count);
+ Assert.HasCount(2, package.AutomationScripts);
var scriptNames = package.AutomationScripts.Select(s => s.Name).ToList();
scriptNames.Should().BeEquivalentTo(new List { "Script_1", "Script_2" });
}
@@ -93,7 +93,7 @@ public async Task FromRepositorySolution1WithSelectedScriptReturnsPackageWithSin
var package = await creator.BuildPackageAsync();
// Assert.
- Assert.AreEqual(1, package.AutomationScripts.Count);
+ Assert.HasCount(1, package.AutomationScripts);
var scriptNames = package.AutomationScripts.Select(s => s.Name).ToList();
scriptNames.Should().Equal(new List { "Script_1" });
}
@@ -144,7 +144,7 @@ public async Task FromRepositorySolution3WithSharedProject()
string scriptContent = Encoding.UTF8.GetString(automationScript.ScriptContent);
- Assert.IsTrue(scriptContent.Contains("public bool TestSharedCall()"));
+ Assert.Contains("public bool TestSharedCall()", scriptContent);
}
[TestMethod]
@@ -162,7 +162,7 @@ public async Task FromRepositorySolution2WithCustomDllResultsInPackageWithCustom
// Assert.
var automationScript = package.AutomationScripts.FirstOrDefault(a => a.Name == "Script_1");
Assert.IsNotNull(automationScript);
- Assert.AreEqual(1, automationScript.Assemblies.Count);
+ Assert.HasCount(1, automationScript.Assemblies);
var includedAssembly = automationScript.Assemblies.FirstOrDefault();
Assert.IsNotNull(includedAssembly);
diff --git a/DMApp.AutomationTests/TestFiles.zip b/DMApp.AutomationTests/TestFiles.zip
deleted file mode 100644
index 04f37da..0000000
Binary files a/DMApp.AutomationTests/TestFiles.zip and /dev/null differ
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent.xml b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent.xml
new file mode 100644
index 0000000..f1d1224
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent.xml
@@ -0,0 +1,24 @@
+
+
+ AddEvent
+ Script 1.0.1.77
+ Automation
+ SKYLINE2\ThomasRE
+ FALSE
+ YLE/Customer UI
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate.xml b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate.xml
new file mode 100644
index 0000000..eba8d50
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate.xml
@@ -0,0 +1,28 @@
+
+
+ AddEventFromTemplate
+ Script 1.0.1.77
+ Automation
+ SKYLINE2\thomasre
+ FALSE
+ YLE/Customer UI
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/.editorconfig b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/AddEventFromTemplate_1.csproj b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/AddEventFromTemplate_1.csproj
new file mode 100644
index 0000000..97e815a
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/AddEventFromTemplate_1.csproj
@@ -0,0 +1,102 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {880203DF-F9E6-4888-9978-A2FBE22BD25A}
+ Library
+ Properties
+ AddEventFromTemplate_1
+ AddEventFromTemplate_1
+ v4.7.2
+ 512
+
+
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\AddEventFromTemplate_1.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\AddEventFromTemplate_1.xml
+
+
+ None
+
+
+
+ ..\Dlls\SLMediationSnippets.dll
+
+
+ ..\Dlls\SLSRMLibrary.dll
+ C:\Skyline DataMiner\Files\SLSRMLibrary.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.3.5
+
+
+ 7.0.1
+
+
+ 1.0.1.12
+
+
+
+
+ {121dd302-df4b-4f49-b6f9-b3ad358bd842}
+ Library_1
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/Properties/AssemblyInfo.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..7f2402d
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("AddEventFromTemplate_1")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("AddEventFromTemplate_1")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("20BF2FA4-97FD-46BA-AAA4-9181E06A423C")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/Script.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/Script.cs
new file mode 100644
index 0000000..5dcfaf7
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/Script.cs
@@ -0,0 +1,400 @@
+/*
+****************************************************************************
+* Copyright (c) 2021, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+16/07/2021 1.0.0.1 TRE, Skyline Initial version
+****************************************************************************
+*/
+
+namespace AddEventFromTemplate_1
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using Skyline.DataMiner.Automation;
+ using Skyline.DataMiner.Utils.InteractiveAutomationScript;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Contracts;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Event;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Locking;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Order;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Order.OrderManagerElement;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Events;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+ using Skyline.DataMiner.Utils.YLE.Integrations.Ceiton;
+ using Status = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Event.Status;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Configuration;
+
+ public class Script : IDisposable
+ {
+ private InteractiveController app;
+
+ private UserInfo userInfo;
+ private UseEventTemplateDialog useEventTemplateDialog;
+ private AddOrUpdateEventDialog eventDialog;
+ private EditTemplateDialog editTemplateDialog;
+ private AddEventTemplateDialog addEventTemplateDialog;
+ private Helpers helpers;
+
+ private System.Threading.Tasks.Task scriptTask;
+ private int timeOutResult;
+ private bool disposedValue;
+
+ ///
+ /// The Script entry point.
+ /// Engine.ShowUI();
+ ///
+ /// Link with SLScripting process.
+ public void Run(Engine engine)
+ {
+ scriptTask = System.Threading.Tasks.Task.Factory.StartNew(() =>
+ {
+ try
+ {
+ Initialize(engine);
+
+ userInfo = helpers.ContractManager.GetUserInfo(engine.UserLoginName);
+ Dialog dialog;
+ if (userInfo.GetEventTemplates().Any())
+ {
+ dialog = InitUseEventTemplateDialog();
+ }
+ else
+ {
+ MessageDialog messageDialog = new MessageDialog(engine, "You don't have access to any Event Templates.") { Title = "No Templates Available" };
+ messageDialog.OkButton.Pressed += (s, a) => engine.ExitSuccess("No Event Templates");
+
+ dialog = messageDialog;
+ }
+
+ if (app.IsRunning) app.ShowDialog(dialog);
+ else app.Run(dialog);
+ }
+ catch (ScriptAbortException)
+ {
+ // Do nothing
+ }
+ catch (InteractiveUserDetachedException)
+ {
+ // Do nothing
+ }
+ catch (Exception e)
+ {
+ if (timeOutResult != -1)
+ {
+ helpers.Log(nameof(Script), nameof(Run), "Something went wrong: " + e);
+ ShowExceptionDialog(engine, e);
+ }
+ }
+ finally
+ {
+ Dispose();
+ }
+ });
+
+ timeOutResult = System.Threading.Tasks.Task.WaitAny(new[] { scriptTask }, new TimeSpan(9, 59, 40));
+ }
+
+ private Dialog InitUseEventTemplateDialog()
+ {
+ var eventTemplates = new List();
+ foreach (string templateName in userInfo.GetEventTemplates())
+ {
+ if (!helpers.ContractManager.TryGetEventTemplate(templateName, out EventTemplate template))
+ {
+ helpers.Log(nameof(Script), nameof(InitUseEventTemplateDialog), $"Unable to retrieve Event Template: {templateName}");
+ continue;
+ }
+
+ eventTemplates.Add(template);
+ }
+
+ useEventTemplateDialog = new UseEventTemplateDialog(helpers, eventTemplates, userInfo);
+ useEventTemplateDialog.ContinueButton.Pressed += UseEventTemplateButton_Pressed;
+ useEventTemplateDialog.EditSelectedTemplateButton.Pressed += (o, e) => EditTemplate();
+
+ return useEventTemplateDialog;
+ }
+
+ private void Initialize(Engine engine)
+ {
+ engine.SetFlag(RunTimeFlags.NoKeyCaching);
+ engine.SetFlag(RunTimeFlags.NoInformationEvents);
+ engine.Timeout = TimeSpan.FromHours(10);
+
+ helpers = new Helpers(engine, Scripts.AddEventFromTemplate);
+
+ app = new InteractiveController(engine);
+ }
+
+ private void UseEventTemplateButton_Pressed(object sender, EventArgs e)
+ {
+ if (!useEventTemplateDialog.IsValid) return;
+
+ try
+ {
+ if (useEventTemplateDialog.EventSubType == EventSubType.Normal)
+ {
+ var @event = useEventTemplateDialog.SelectedEvent;
+ @event.Start = new[] { useEventTemplateDialog.StartTime, @event.Start }.Min();
+ @event.End = new[] { useEventTemplateDialog.EndTime, @event.End }.Max();
+
+ LockInfo lockInfo = new LockInfo(true, String.Empty, Guid.Empty.ToString(), TimeSpan.Zero);
+ eventDialog = new AddOrUpdateEventDialog(helpers, userInfo, @event, lockInfo);
+ eventDialog.SaveAsTemplateButton.Text = "Edit Template";
+ eventDialog.SavePreliminaryEventButton.Pressed += (s, a) => SaveEvent(Status.Preliminary);
+ eventDialog.SavePlannedEventButton.Pressed += (s, a) => SaveEvent(Status.Planned);
+ eventDialog.SaveButton.Pressed += (s, a) => SaveEvent(Status.Confirmed);
+ eventDialog.SaveAsTemplateButton.Pressed += (s, a) => EditTemplate();
+
+ app.ShowDialog(eventDialog);
+ }
+ else
+ {
+ SaveEvent(Status.Planned);
+ }
+ }
+ catch(Exception ex)
+ {
+ helpers.Log(nameof(Script), nameof(UseEventTemplateButton_Pressed), $"Exception occurred: {ex}");
+ throw;
+ }
+ }
+
+ private void SaveEvent(Status status)
+ {
+ try
+ {
+ Event eventInfo = null;
+
+ if (eventDialog != null)
+ {
+ if (!eventDialog.IsValid()) return;
+
+ eventInfo = eventDialog.GetUpdatedEvent();
+ }
+ else if (useEventTemplateDialog != null)
+ {
+ if (!useEventTemplateDialog.IsValid) return;
+
+ eventInfo = useEventTemplateDialog.SelectedEvent;
+ }
+ else
+ {
+ return;
+ }
+
+ var progressDialog = new ProgressDialog(helpers.Engine) { Title = "Saving New Event" };
+ progressDialog.OkButton.Pressed += (send, args) => helpers.Engine.ExitSuccess(eventInfo.Id.ToString());
+
+ app.ShowDialog(progressDialog);
+
+ eventInfo.Status = status;
+ helpers.EventManager.AddOrUpdateEvent(eventInfo);
+
+ // If a project number is defined, the project should be polled from Ceiton.
+ // If Ceiton has any information, the Ceiton Integration will update this Event.
+ if (!string.IsNullOrWhiteSpace(eventInfo.ProjectNumber))
+ {
+ var orderManagerElement = new OrderManagerElement(helpers);
+ var ceiton = new CeitonElement(orderManagerElement.CeitonElement);
+ ceiton.PollProject(eventInfo.ProjectNumber);
+ }
+
+ AddOrUpdateLinkedOrders(status, eventInfo, progressDialog);
+
+ progressDialog.Finish();
+ app.ShowDialog(progressDialog);
+ }
+ catch (Exception exception)
+ {
+ ShowExceptionDialog((Engine)helpers.Engine, exception);
+ }
+ }
+
+ private void AddOrUpdateLinkedOrders(Status status, Event eventInfo, ProgressDialog progressDialog)
+ {
+ var linkedOrders = useEventTemplateDialog.SelectedTemplateLinkedOrders.Any() ? useEventTemplateDialog.SelectedTemplateLinkedOrders : useEventTemplateDialog.CreateLinkedOrders(eventInfo);
+ foreach (var order in linkedOrders)
+ {
+ helpers.ProgressReported += (send, args) => progressDialog.AddProgressLine(args.Progress);
+
+ order.Event = eventInfo;
+ order.Company = eventInfo.Company;
+ order.Contract = eventInfo.Contract;
+ order.IsInternal = eventInfo.IsInternal;
+ order.Status = useEventTemplateDialog.DetermineOrderStatus(order, status);
+ order.AddOrUpdate(helpers, userInfo.IsMcrUser);
+ }
+ }
+
+ private void EditTemplate()
+ {
+ Event @event = null;
+ Dialog dialogLinkToBackButton = null;
+ if (useEventTemplateDialog.EventSubType == EventSubType.Normal)
+ {
+ if (!eventDialog.IsValid()) return;
+
+ @event = eventDialog.GetUpdatedEvent();
+ dialogLinkToBackButton = eventDialog;
+ }
+ else
+ {
+ @event = useEventTemplateDialog.SelectedEvent;
+ dialogLinkToBackButton = useEventTemplateDialog;
+ }
+
+ editTemplateDialog = new EditTemplateDialog((Engine)helpers.Engine);
+ editTemplateDialog.BackButton.Pressed += (s, a) => app.ShowDialog(dialogLinkToBackButton);
+ editTemplateDialog.CreateNewTemplateButton.Pressed += (s, a) => CreateNewTemplate(@event);
+ editTemplateDialog.UpdateTemplateButton.Pressed += (s, a) => UpdateTemplate(@event, useEventTemplateDialog.SelectedTemplate);
+ editTemplateDialog.DeleteTemplateButton.Pressed += (s, a) => DeleteTemplate(useEventTemplateDialog.SelectedTemplate);
+
+ app.ShowDialog(editTemplateDialog);
+ }
+
+ private void CreateNewTemplate(Event @event)
+ {
+ addEventTemplateDialog = new AddEventTemplateDialog(helpers, @event, userInfo);
+ addEventTemplateDialog.BackButton.Pressed += (s, args) => app.ShowDialog(editTemplateDialog);
+ addEventTemplateDialog.SaveTemplateButton.Pressed += (s, args) => SaveNewEventTemplate(@event, addEventTemplateDialog.TemplateName, addEventTemplateDialog.SelectedUserGroups.ToArray());
+
+ app.ShowDialog(addEventTemplateDialog);
+ }
+
+ private void SaveNewEventTemplate(Event @event, string templateName, string[] userGroups)
+ {
+ if (!addEventTemplateDialog.IsValid) return;
+
+ MessageDialog messageDialog;
+ if (helpers.ContractManager.TryAddEventTemplate(templateName, userGroups, @event, new Order[0]))
+ {
+ messageDialog = new MessageDialog(helpers.Engine, "The template was successfully saved");
+ }
+ else
+ {
+ messageDialog = new MessageDialog(helpers.Engine, "Unable to save the template");
+ }
+
+ messageDialog.OkButton.Pressed += (s, args) => helpers.Engine.ExitSuccess("OK");
+ app.ShowDialog(messageDialog);
+ }
+
+ private void UpdateTemplate(Event @event, EventTemplate selectedTemplate)
+ {
+ addEventTemplateDialog = new AddEventTemplateDialog(helpers, @event, userInfo);
+ List linkedOrderTemplates = helpers.ContractManager.GetLinkedOrderTemplates(selectedTemplate.Id);
+ addEventTemplateDialog.Init(selectedTemplate, linkedOrderTemplates, userInfo);
+
+ addEventTemplateDialog.BackButton.Pressed += (s, args) => app.ShowDialog(editTemplateDialog);
+ addEventTemplateDialog.SaveTemplateButton.Pressed += (s, args) => SaveUpdatedEventTemplate(@event, selectedTemplate, addEventTemplateDialog.TemplateName, addEventTemplateDialog.SelectedUserGroups.ToArray(), addEventTemplateDialog.GetLinkedOrderTemplatesToKeep(), addEventTemplateDialog.NewOrderTemplates, addEventTemplateDialog.NewOrderTemplateOffsets);
+
+ app.ShowDialog(addEventTemplateDialog);
+ }
+
+ private void SaveUpdatedEventTemplate(Event @event, EventTemplate selectedTemplate, string templateName, string[] userGroups, IReadOnlyList linkedOrderTemplatesToKeep, IReadOnlyList newOrderTemplates, Dictionary newOrderTemplateOffsets)
+ {
+ if (!addEventTemplateDialog.IsValid) return;
+
+ MessageDialog messageDialog;
+ if (helpers.ContractManager.TryEditEventTemplate(@event, selectedTemplate, templateName, userGroups, linkedOrderTemplatesToKeep, newOrderTemplates, newOrderTemplateOffsets))
+ {
+ messageDialog = new MessageDialog(helpers.Engine, "The template was successfully saved");
+ }
+ else
+ {
+ messageDialog = new MessageDialog(helpers.Engine, "Unable to save the template");
+ }
+
+ messageDialog.OkButton.Pressed += (s, args) => helpers.Engine.ExitSuccess("OK");
+ app.ShowDialog(messageDialog);
+ }
+
+ private void DeleteTemplate(EventTemplate selectedTemplate)
+ {
+ MessageDialog messageDialog;
+ if (helpers.ContractManager.TryDeleteEventTemplate(selectedTemplate.Name))
+ {
+ messageDialog = new MessageDialog(helpers.Engine, "The template was successfully removed");
+ }
+ else
+ {
+ messageDialog = new MessageDialog(helpers.Engine, "Unable to remove the template");
+ }
+
+ messageDialog.OkButton.Pressed += (s, args) => helpers.Engine.ExitSuccess("OK");
+ app.ShowDialog(messageDialog);
+ }
+
+ private void ShowExceptionDialog(Engine engine, Exception exception)
+ {
+ ExceptionDialog dialog = new ExceptionDialog(engine, exception);
+ dialog.OkButton.Pressed += (sender, args) => engine.ExitSuccess("Something went wrong during the creation of the new event.");
+ if (app.IsRunning) app.ShowDialog(dialog); else app.Run(dialog);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ helpers.Dispose();
+ }
+
+ disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/app.config b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/app.config
new file mode 100644
index 0000000..a5d0f75
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/app.config
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/stylecop.json b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEventFromTemplate_1/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/.editorconfig b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/.editorconfig
new file mode 100644
index 0000000..de5a35c
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/.editorconfig
@@ -0,0 +1,83 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
+csharp_indent_labels = one_less_than_current
+csharp_using_directive_placement = outside_namespace:silent
+csharp_prefer_simple_using_statement = true:suggestion
+csharp_prefer_braces = true:silent
+csharp_style_namespace_declarations = block_scoped:silent
+csharp_style_expression_bodied_methods = false:silent
+csharp_style_expression_bodied_constructors = false:silent
+csharp_style_expression_bodied_operators = false:silent
+csharp_style_expression_bodied_properties = true:silent
+csharp_style_expression_bodied_indexers = true:silent
+csharp_style_expression_bodied_accessors = true:silent
+csharp_style_expression_bodied_lambdas = true:silent
+csharp_style_expression_bodied_local_functions = false:silent
+[*.{cs,vb}]
+#### Naming styles ####
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+# Naming styles
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+dotnet_style_prefer_auto_properties = true:silent
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
+dotnet_style_prefer_conditional_expression_over_assignment = true:silent
+dotnet_style_prefer_conditional_expression_over_return = true:silent
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/AddEvent_2.csproj b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/AddEvent_2.csproj
new file mode 100644
index 0000000..c9b5619
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/AddEvent_2.csproj
@@ -0,0 +1,85 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {8EBFE2CE-07A1-45F6-85AC-8023014A0A8A}
+ Library
+ Properties
+ AddEvent_2
+ AddEvent_2
+ v4.7.2
+ 512
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\AddEvent_2.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\AddEvent_2.xml
+
+
+ None
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.3.5
+
+
+ 7.0.1
+
+
+ 1.0.1.12
+
+
+
+
+ {121dd302-df4b-4f49-b6f9-b3ad358bd842}
+ Library_1
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/Properties/AssemblyInfo.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..51e9d17
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("AddEvent_2")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("AddEvent_2")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("9BD33446-3515-4DD2-9406-F4856BCCC669")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/Script.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/Script.cs
new file mode 100644
index 0000000..4bfc135
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/Script.cs
@@ -0,0 +1,210 @@
+/*
+****************************************************************************
+* Copyright (c) 2019, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+dd/mm/2019 1.0.0.1 XXX, Skyline Initial Version
+****************************************************************************
+*/
+
+namespace AddEvent_2
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Timers;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Configuration;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Event;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Order;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Order.OrderManagerElement;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Tasks.EventTasks;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Events;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.LoadingScreens;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Reports;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+ using Skyline.DataMiner.Utils.InteractiveAutomationScript;
+ using Skyline.DataMiner.Utils.YLE.Integrations.Ceiton;
+ using Status = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Event.Status;
+ using Task = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Tasks.Task;
+
+ ///
+ /// DataMiner Script Class.
+ ///
+ public class Script : YleInteractiveScript
+ {
+ private LoadAddOrUpdateEventDialog loadAddOrUpdateEventDialog;
+ private AddOrUpdateEventDialog eventDialog;
+ private AddEventTemplateDialog addEventTemplateDialog;
+
+ private readonly Timer extendLocksTimer = new Timer();
+
+ protected override Scripts ScriptName => Scripts.AddEvent;
+
+ protected override TimeSpan? TimeOut => TimeSpan.FromHours(9);
+
+ protected override void InternalRun()
+ {
+ loadAddOrUpdateEventDialog = new LoadAddOrUpdateEventDialog(helpers, extendLocksTimer);
+
+ if (loadAddOrUpdateEventDialog.Execute()) ShowAddEventDialog();
+ else app.Run(loadAddOrUpdateEventDialog);
+ }
+
+ protected override void EngineShowUiInComments()
+ {
+ //engine.ShowUI()
+ }
+
+ private void ShowAddEventDialog()
+ {
+ eventDialog = loadAddOrUpdateEventDialog.AddOrUpdateEventDialog;
+ eventDialog.SavePreliminaryEventButton.Pressed += (sender, args) => SaveEvent(Status.Preliminary);
+ eventDialog.SavePlannedEventButton.Pressed += (sender, args) => SaveEvent(Status.Planned);
+ eventDialog.SaveAsTemplateButton.Pressed += (sender, args) => ShowAddEventTemplateDialog();
+
+ if (app.IsRunning) app.ShowDialog(eventDialog);
+ else app.Run(eventDialog);
+ }
+
+ private void SaveEvent(Status status)
+ {
+ try
+ {
+ if (!eventDialog.IsValid()) return;
+
+ var eventInfo = eventDialog.GetUpdatedEvent();
+
+ var reportDialog = new AddOrUpdateReportDialog(helpers);
+ reportDialog.OkButton.Pressed += (o, args) => { helpers.LockManager.ReleaseLocks(); helpers.Engine.ExitSuccess("Successfully updated the service"); };
+ app.ShowDialog(reportDialog);
+
+ eventInfo.Status = status;
+
+ List tasks = new List();
+ var addOrUpdateEventTask = new AddOrUpdateEventTask(helpers, eventInfo);
+ tasks.Add(addOrUpdateEventTask);
+
+ if (!addOrUpdateEventTask.Execute())
+ {
+ helpers.Log(nameof(AddEvent_2.Script), nameof(SaveEvent), $"Add or update event task failed for event: {eventInfo.Name}");
+ }
+
+ // If a project number is defined, the project should be polled from Ceiton.
+ // If Ceiton has any information, the Ceiton Integration will update this Event.
+ if (!string.IsNullOrWhiteSpace(eventInfo.ProjectNumber))
+ {
+ OrderManagerElement orderManagerElement = new OrderManagerElement(helpers);
+ var ceiton = new CeitonElement(orderManagerElement.CeitonElement);
+ ceiton.PollProject(eventInfo.ProjectNumber);
+ }
+
+ reportDialog.Finish(tasks);
+ app.ShowDialog(reportDialog);
+ }
+ catch (Exception exception)
+ {
+ ShowExceptionDialog(exception);
+ }
+ }
+
+ protected override void HandleException(Exception e)
+ {
+ ShowExceptionDialog(e);
+ }
+
+ private void ShowAddEventTemplateDialog()
+ {
+ var @event = eventDialog.GetUpdatedEvent();
+ var userInfo = loadAddOrUpdateEventDialog.UserInfo;
+
+ addEventTemplateDialog = new AddEventTemplateDialog(helpers, @event, userInfo);
+ addEventTemplateDialog.BackButton.Pressed += (s, args) => app.ShowDialog(eventDialog);
+ addEventTemplateDialog.SaveTemplateButton.Pressed += (s, args) => SaveEventTemplate();
+
+ app.ShowDialog(addEventTemplateDialog);
+ }
+
+ private void SaveEventTemplate()
+ {
+ if (!addEventTemplateDialog.IsValid) return;
+
+ string templateName = addEventTemplateDialog.TemplateName;
+ string[] userGroups = addEventTemplateDialog.SelectedUserGroups.ToArray();
+ Event @event = addEventTemplateDialog.Event;
+
+ MessageDialog messageDialog;
+ if (helpers.ContractManager.TryAddEventTemplate(templateName, userGroups, @event, new Order[0]))
+ {
+ messageDialog = new MessageDialog(helpers.Engine, "The template was successfully saved");
+ }
+ else
+ {
+ messageDialog = new MessageDialog(helpers.Engine, "Unable to save the template");
+ }
+
+ messageDialog.OkButton.Pressed += (s, args) => helpers.Engine.ExitSuccess("OK");
+ app.ShowDialog(messageDialog);
+ }
+
+ #region IDisposable Support
+ private bool isDisposed;
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ if (!isDisposed)
+ {
+ if (disposing)
+ {
+ extendLocksTimer.Dispose();
+ }
+
+ isDisposed = true;
+ }
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/app.config b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/app.config
new file mode 100644
index 0000000..fda1974
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/app.config
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/stylecop.json b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddEvent_2/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote.xml b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote.xml
new file mode 100644
index 0000000..d5a8b76
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote.xml
@@ -0,0 +1,30 @@
+
+ AddNote
+ Script 1.0.1.77
+ Automation
+ SKYLINE2\VSC
+ FALSE
+ YLE/Customer UI
+
+
+
+
+
+
+
+
+
+ Page
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/.editorconfig b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/AddNote_2.csproj b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/AddNote_2.csproj
new file mode 100644
index 0000000..2b9e5b5
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/AddNote_2.csproj
@@ -0,0 +1,102 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {E5C344F3-4239-4F98-BF5B-642646B0A68A}
+ Library
+ Properties
+ AddNote_2
+ AddNote_2
+ v4.7.2
+ 512
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\AddNote_2.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\AddNote_2.xml
+
+
+ None
+
+
+
+ ..\Dlls\SLMediationSnippets.dll
+
+
+ ..\Dlls\SLSRMLibrary.dll
+ C:\Skyline DataMiner\Files\SLSRMLibrary.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.3.5
+
+
+ 7.0.1
+
+
+
+
+ {121dd302-df4b-4f49-b6f9-b3ad358bd842}
+ Library_1
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/Properties/AssemblyInfo.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1168f94
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("AddNote_2")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("AddNote_2")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("8CB3E2CB-7D6C-44B2-9F55-5E3B076B41C7")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/Script.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/Script.cs
new file mode 100644
index 0000000..73aaa55
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/Script.cs
@@ -0,0 +1,168 @@
+/*
+****************************************************************************
+* Copyright (c) 2020, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+03/02/2020 1.0.0.1 JVT, Skyline Initial version
+****************************************************************************
+*/
+
+namespace AddNote_2
+{
+ using System;
+ using System.Threading.Tasks;
+ using Skyline.DataMiner.Automation;
+ using Skyline.DataMiner.Utils.InteractiveAutomationScript;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Notes;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Notes;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+ using ExceptionDialog = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Reports.ExceptionDialog;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Configuration;
+
+ internal class Script : IDisposable
+ {
+ private Helpers helpers;
+ private InteractiveController app;
+ private AddOrUpdateNoteDialog dialog;
+
+ private Task scriptTask;
+ private int timeOutResult;
+ private bool disposedValue;
+
+ public void Run(Engine engine)
+ {
+ scriptTask = Task.Factory.StartNew(() =>
+ {
+ try
+ {
+ string paramValue = engine.GetScriptParam(1).Value;
+
+ var page = EnumExtensions.GetEnumValueFromDescription(paramValue);
+
+ //engine.ShowUI();
+ engine.Timeout = TimeSpan.FromHours(10);
+ helpers = new Helpers(engine, Scripts.AddNote);
+ this.app = new InteractiveController(engine);
+
+ dialog = new AddOrUpdateNoteDialog(engine, page);
+ dialog.ConfirmButton.Pressed += Dialog_ConfirmButton_Pressed;
+
+ app.Run(dialog);
+ }
+ catch (ScriptAbortException)
+ {
+ throw;
+ }
+ catch (Exception e)
+ {
+ if (timeOutResult != -1)
+ {
+ engine.Log("Run|Something went wrong: " + e);
+ ShowExceptionDialog(engine, e);
+ }
+ }
+ finally
+ {
+ helpers?.Dispose();
+ }
+ });
+
+ timeOutResult = Task.WaitAny(new[] { scriptTask }, new TimeSpan(9, 59, 40));
+ }
+
+ private void Dialog_ConfirmButton_Pressed(object sender, EventArgs e)
+ {
+ var updatedNote = dialog.Note;
+ if (!TryCheckValidityAndUpdateNote(updatedNote)) return;
+
+ ShowMessageDialog((Engine)helpers.Engine, "Successfully added note", "Add Note");
+ }
+
+ private bool TryCheckValidityAndUpdateNote(Note updatedNote)
+ {
+ if (!dialog.IsValid()) return false;
+
+ helpers.NoteManager.AddOrUpdateNote(updatedNote, out string fullTicketId);
+
+ return true;
+ }
+
+ private void ShowExceptionDialog(Engine engine, Exception exception)
+ {
+ ExceptionDialog exceptionDialog = new ExceptionDialog(engine, exception);
+ exceptionDialog.OkButton.Pressed += (sender, args) => engine.ExitSuccess("Something went wrong during adding the Note.");
+ app.ShowDialog(exceptionDialog);
+ }
+
+ private void ShowMessageDialog(Engine engine, string message, string title)
+ {
+ MessageDialog messageDialog = new MessageDialog(engine, message) { Title = title };
+ messageDialog.OkButton.Pressed += (sender, args) => engine.ExitSuccess(message);
+
+ if (app.IsRunning) app.ShowDialog(messageDialog);
+ else app.Run(messageDialog);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ helpers.Dispose();
+ }
+
+ disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/app.config b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/app.config
new file mode 100644
index 0000000..fda1974
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/app.config
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/stylecop.json b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddNote_2/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder.xml b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder.xml
new file mode 100644
index 0000000..6df676b
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder.xml
@@ -0,0 +1,30 @@
+
+ AddOrUpdateNonLiveOrder
+ Script 1.0.1.77
+ Automation
+ SKYLINE2\Joey
+ FALSE
+ YLE/Customer UI
+
+
+
+
+
+
+
+
+
+ ticketId
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/.editorconfig b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/AddOrUpdateNonLiveOrder_2.csproj b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/AddOrUpdateNonLiveOrder_2.csproj
new file mode 100644
index 0000000..f1f1b39
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/AddOrUpdateNonLiveOrder_2.csproj
@@ -0,0 +1,102 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {CD8CA3A7-2D4D-416A-BB82-76279B1843C2}
+ Library
+ Properties
+ AddOrUpdateNonLiveOrder_2
+ AddOrUpdateNonLiveOrder_2
+ v4.7.2
+ 512
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\AddOrUpdateNonLiveOrder_2.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\AddOrUpdateNonLiveOrder_2.xml
+
+
+ None
+
+
+
+ ..\Dlls\SLMediationSnippets.dll
+
+
+ ..\Dlls\SLSRMLibrary.dll
+ C:\Skyline DataMiner\Files\SLSRMLibrary.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.3.5
+
+
+ 7.0.1
+
+
+
+
+ {121dd302-df4b-4f49-b6f9-b3ad358bd842}
+ Library_1
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/Properties/AssemblyInfo.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..3f6c9b6
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("AddOrUpdateNonLiveOrder_2")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("AddOrUpdateNonLiveOrder_2")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("87B4351F-CAE3-4BE2-82F4-97D9C3EDA5CA")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/Script.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/Script.cs
new file mode 100644
index 0000000..982a825
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/Script.cs
@@ -0,0 +1,208 @@
+/*
+****************************************************************************
+* Copyright (c) 2020, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+18/03/2021 1.0.0.1 TRE, Skyline Updated edit rights for Non-MCR users
+06/04/2021 1.0.0.2 TRE, Skyline Allow multiple file selection.
+****************************************************************************
+*/
+
+namespace AddOrUpdateNonLiveOrder_2
+{
+ using System;
+ using System.Threading.Tasks;
+ using Skyline.DataMiner.Automation;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Configuration;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.LoadingScreens;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.NonLive;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+ using Skyline.DataMiner.Utils.InteractiveAutomationScript;
+ using ExceptionDialog = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Reports.ExceptionDialog;
+
+ internal class Script : IDisposable
+ {
+ private InteractiveController app;
+
+ private LoadNonLiveOrderFormDialog loadNonLiveOrderFormDialog;
+ private MainDialog nonLiveOrderForm;
+ private NonLiveRejectionDialog rejectionDialog;
+ private Helpers helpers;
+
+ private int timeOutResult;
+ private bool disposedValue;
+
+ public void Run(Engine engine)
+ {
+ var scriptTask = Task.Factory.StartNew(() =>
+ {
+ try
+ {
+ Initialize(engine);
+
+ loadNonLiveOrderFormDialog = new LoadNonLiveOrderFormDialog(helpers, LoadNonLiveOrderFormDialog.ScriptAction.AddOrUpdate);
+
+ if (loadNonLiveOrderFormDialog.Execute()) ShowNonLiveOrderForm();
+ else app.Run(loadNonLiveOrderFormDialog);
+ }
+ catch (InteractiveUserDetachedException)
+ {
+ // Do Nothing
+ }
+ catch (ScriptAbortException)
+ {
+ // Do Nothing
+ }
+ catch (Exception e)
+ {
+ if (timeOutResult != -1)
+ {
+ helpers.Log(nameof(Script), nameof(Run), "Something went wrong: " + e);
+ ShowExceptionDialog(e);
+ }
+ }
+ finally
+ {
+ Dispose();
+ }
+ });
+
+ timeOutResult = Task.WaitAny(new[] { scriptTask }, new TimeSpan(9, 59, 40));
+ }
+
+ private void Initialize(Engine engine)
+ {
+ engine.Timeout = TimeSpan.FromHours(10);
+ //engine.ShowUI();
+
+ helpers = new Helpers(engine, Scripts.AddOrUpdateNonLiveOrder);
+ app = new InteractiveController(engine);
+ }
+
+ private void ShowNonLiveOrderForm()
+ {
+ nonLiveOrderForm = loadNonLiveOrderFormDialog.NonLiveOrderFormDialog;
+ nonLiveOrderForm.CancelButton.Pressed += Dialog_CancelButton_Pressed;
+ nonLiveOrderForm.BookOrSaveFinished += NonLiveOrderForm_BookOrSaveFinished;
+ nonLiveOrderForm.RejectOrderButton.Pressed += Dialog_RejectOrderButton_Pressed;
+
+ if (app.IsRunning) app.ShowDialog(nonLiveOrderForm);
+ else app.Run(nonLiveOrderForm);
+ }
+
+ private void NonLiveOrderForm_BookOrSaveFinished(object sender, Library_1.EventArguments.StringEventArgs e)
+ {
+ ShowMessageDialog(e.Value, "Add or Update Non-Live Order finished");
+ }
+
+ private void ShowExceptionDialog(Exception exception)
+ {
+ ExceptionDialog exceptionDialog = new ExceptionDialog((Engine)helpers.Engine, exception);
+ exceptionDialog.OkButton.Pressed += (sender, args) => helpers.Engine.ExitSuccess("Something went wrong during the creation of the new Order.");
+ if (app.IsRunning) app.ShowDialog(exceptionDialog); else app.Run(exceptionDialog);
+ }
+
+ private void ShowMessageDialog(string message, string title)
+ {
+ MessageDialog dialog = new MessageDialog(helpers.Engine, message) { Title = title };
+ dialog.OkButton.Pressed += (sender, args) => helpers.Engine.ExitSuccess(message);
+
+ if (app.IsRunning) app.ShowDialog(dialog);
+ else app.Run(dialog);
+ }
+
+ private void Dialog_CancelButton_Pressed(object sender, EventArgs e)
+ {
+ helpers.NonLiveOrderManager.CancelNonLiveOrder(nonLiveOrderForm.NonLiveOrder, loadNonLiveOrderFormDialog.UserInfo.User);
+
+ ShowMessageDialog("Order successfully canceled", "Cancel Non Live Order");
+ }
+
+ private void Dialog_RejectOrderButton_Pressed(object sender, EventArgs e)
+ {
+ rejectionDialog = new NonLiveRejectionDialog(helpers.Engine);
+ rejectionDialog.CancelButton.Pressed += RejectionDialog_CancelButton_Pressed;
+ rejectionDialog.RejectButton.Pressed += RejectionDialog_RejectButton_Pressed;
+
+ app.ShowDialog(rejectionDialog);
+ }
+
+ private void RejectionDialog_RejectButton_Pressed(object sender, EventArgs e)
+ {
+ if (!rejectionDialog.IsValid()) return;
+
+ rejectionDialog.UpdateNonLiveOrder(nonLiveOrderForm.NonLiveOrder);
+
+ helpers.NonLiveOrderManager.SetNonLiveOrderToChangeRequested(nonLiveOrderForm.NonLiveOrder, loadNonLiveOrderFormDialog.UserInfo.User);
+
+ ShowMessageDialog("Order successfully rejected", "Reject Non Live Order");
+ }
+
+ private void RejectionDialog_CancelButton_Pressed(object sender, EventArgs e)
+ {
+ app.ShowDialog(nonLiveOrderForm);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ helpers.Dispose();
+ }
+
+ disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/app.config b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/app.config
new file mode 100644
index 0000000..fda1974
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/app.config
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/stylecop.json b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddOrUpdateNonLiveOrder_2/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService.xml b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService.xml
new file mode 100644
index 0000000..0782020
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService.xml
@@ -0,0 +1,32 @@
+
+
+ AddService
+ Script 1.0.1.77
+ Automation
+ SKYLINE2\VictorSC
+ FALSE
+ YLE/Customer UI
+
+
+
+
+
+
+
+
+
+ ServiceId
+
+
+ Action
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/.editorconfig b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/AddService_1.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/AddService_1.cs
new file mode 100644
index 0000000..183c80d
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/AddService_1.cs
@@ -0,0 +1,308 @@
+/*
+****************************************************************************
+* Copyright (c) 2022, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+dd/mm/2022 1.0.0.1 XXX, Skyline Initial version
+****************************************************************************
+*/
+
+namespace AddService_1
+{
+
+
+ using System;
+ using System.Linq;
+ using System.Timers;
+ using Skyline.DataMiner.Automation;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Configuration;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Contracts;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Order;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Order;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Order.Dialogs;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Reports;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.YleWidgets;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+ using Skyline.DataMiner.Utils.InteractiveAutomationScript;
+ using ExceptionDialog = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Reports.ExceptionDialog;
+ using TaskStatus = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Tasks.Status;
+
+ ///
+ /// DataMiner Script Class.
+ ///
+ internal class Script : IDisposable
+ {
+ private readonly Timer extendLocksTimer = new Timer();
+
+ private Helpers helpers;
+ private InteractiveController app;
+
+ private ReportDialog rollbackReportDialog;
+ private LoadAddServiceDialog loadEditOrderDialog;
+ private LiveOrderFormDialog editOrderDialog;
+ private ReportDialog reportDialog;
+
+ private LiveOrderFormAction scriptAction;
+ private readonly string selectedOrderIdForExiting = Guid.Empty.ToString();
+ private UserInfo userInfo;
+
+ ///
+ /// The Script entry point.
+ ///
+ /// Link with SLAutomation process.
+ public void Run(Engine engine)
+ {
+ int timeOutResult = 0;
+ var scriptTask = System.Threading.Tasks.Task.Factory.StartNew(() =>
+ {
+ try
+ {
+ Initialize(engine);
+
+ loadEditOrderDialog = new LoadAddServiceDialog(helpers, extendLocksTimer);
+
+ if (loadEditOrderDialog.Execute()) ShowDialog();
+ else app.Run(loadEditOrderDialog);
+ }
+ catch (InteractiveUserDetachedException)
+ {
+ Dispose();
+ }
+ catch (ScriptAbortException)
+ {
+ Dispose();
+ throw;
+ }
+ catch (Exception e)
+ {
+ if (timeOutResult != -1)
+ {
+ helpers.Log(nameof(Script), nameof(Run), $"Something went wrong: {e}");
+
+ Dispose();
+
+ ShowExceptionDialog(engine, e);
+ }
+ }
+ });
+
+ timeOutResult = System.Threading.Tasks.Task.WaitAny(new System.Threading.Tasks.Task[] { scriptTask }, new TimeSpan(9, 59, 40));
+ if (timeOutResult == -1) Dispose();
+ }
+
+ private void ShowDialog()
+ {
+ scriptAction = loadEditOrderDialog.ScriptAction;
+ userInfo = loadEditOrderDialog.UserInfo;
+
+ editOrderDialog = loadEditOrderDialog.EditOrderDialog;
+
+ editOrderDialog.BookOrderButton.Pressed += OrderForm_BookButton_Pressed;
+ editOrderDialog.ExitButton.Pressed += (s, e) => helpers.Engine.ExitSuccess("no changes");
+
+ app.Run(editOrderDialog);
+ }
+
+ private void Initialize(Engine engine)
+ {
+ engine.SetFlag(RunTimeFlags.NoInformationEvents);
+ engine.SetFlag(RunTimeFlags.NoKeyCaching);
+ engine.SetFlag(RunTimeFlags.NoCheckingSets);
+ engine.Timeout = TimeSpan.FromHours(10);
+ //engine.ShowUI();
+
+ helpers = new Helpers(engine, Scripts.AddService);
+
+ app = new InteractiveController(engine);
+ }
+
+ private void OrderForm_BookButton_Pressed(object sender, YleValueWidgetChangedEventArgs e)
+ {
+ helpers.LogMethodStart(nameof(Script), nameof(OrderForm_BookButton_Pressed), out var stopwatch);
+
+ try
+ {
+ if (!editOrderDialog.IsValid(saveOrder: false, confirmOrder: false, requestEventLock: true))
+ {
+ helpers.LogMethodCompleted(nameof(Script), nameof(OrderForm_BookButton_Pressed), null, stopwatch);
+ return;
+ }
+
+ AddOrUpdateOrder(OrderAction.Book);
+ }
+ catch (Exception exception)
+ {
+ ShowExceptionDialog(helpers.Engine, exception);
+ }
+
+ helpers.LogMethodCompleted(nameof(Script), nameof(OrderForm_BookButton_Pressed), null, stopwatch);
+ }
+
+ private void AddOrUpdateOrder(OrderAction orderAction)
+ {
+ reportDialog = new AddOrUpdateReportDialog(helpers, userInfo.IsMcrUser) { Title = "Updating Order" };
+
+ reportDialog.OkButton.Pressed += ReportDialog_OkButton_Pressed;
+ reportDialog.RollBackButton.Pressed += ReportDialog_RollbackButton_Pressed;
+ app.ShowDialog(reportDialog);
+
+ var tasks = editOrderDialog.Finish(orderAction).Tasks;
+
+ if (tasks.Any())
+ {
+ reportDialog.Finish(tasks);
+
+ // release the locks if all tasks were successful
+ if (tasks.All(t => t.Status == TaskStatus.Ok)) helpers.LockManager.ReleaseLocks();
+
+ app.ShowDialog(reportDialog);
+ }
+ else ShowMessageDialog(helpers.Engine, "No changes made", "No Changes made");
+
+ helpers.Log(nameof(Script), nameof(AddOrUpdateOrder), $"Order Updated");
+ }
+
+ private void ReportDialog_RollbackButton_Pressed(object sender, EventArgs e)
+ {
+ RollBackTasks();
+
+ helpers.LockManager.ReleaseLocks();
+ }
+
+ private void ReportDialog_OkButton_Pressed(object sender, EventArgs e)
+ {
+ helpers.LockManager.ReleaseLocks();
+
+ if (reportDialog.TasksWereSuccessful)
+ {
+ helpers.Engine.ExitSuccess(selectedOrderIdForExiting);
+ }
+ else if (reportDialog.ShouldRollback)
+ {
+ RollBackTasks();
+ }
+ else
+ {
+ // Exit script when the user chooses to ignore the failed tasks
+ helpers.Engine.ExitSuccess(scriptAction == LiveOrderFormAction.Add ? "Unable to create the new Order." : "Unable to update the existing Order.");
+ }
+ }
+
+ private void RollBackTasks()
+ {
+ // Roll back tasks - Only roll back tasks that were successful
+ rollbackReportDialog = new RollBackReportDialog(helpers) { Title = scriptAction == LiveOrderFormAction.Edit ? "Roll back Order update" : "Roll back Order creation" };
+ rollbackReportDialog.OkButton.Pressed += (s, e) => helpers.Engine.ExitSuccess(rollbackReportDialog.TasksWereSuccessful ? "Successfully rolled back " : "Failed to roll back");
+
+
+ app.ShowDialog(rollbackReportDialog);
+
+ // Only roll back tasks that were successful
+ var rollbackTasks = reportDialog.UpdateResults.SelectMany(ur => ur.Tasks).Where(t => t.Status == TaskStatus.Ok).Select(t => t.CreateRollbackTask()).Where(t => t != null).Reverse().ToList();
+
+ foreach (var rollbackTask in rollbackTasks)
+ {
+ if (!rollbackTask.Execute())
+ {
+ helpers.Log(nameof(Script), nameof(RollBackTasks), "Rolling back " + rollbackTask.Description + "failed: " + rollbackTask.Exception);
+ break;
+ }
+ }
+
+ rollbackReportDialog.Finish(rollbackTasks);
+ app.ShowDialog(rollbackReportDialog);
+ }
+
+
+ private void ShowMessageDialog(IEngine engine, string message, string title)
+ {
+ var dialog = new MessageDialog((Engine)engine, message) { Title = title };
+ dialog.OkButton.Pressed += (sender, args) => engine.ExitSuccess(message);
+
+ if (app.IsRunning) app.ShowDialog(dialog);
+ else app.Run(dialog);
+ }
+
+ private void ShowExceptionDialog(IEngine engine, Exception exception)
+ {
+ ExceptionDialog exceptionDialog = new ExceptionDialog(engine, exception);
+ exceptionDialog.OkButton.Pressed += (sender, args) => engine.ExitSuccess("Something went wrong during adding a new service.");
+
+ if (app.IsRunning) app.ShowDialog(exceptionDialog);
+ else app.Run(exceptionDialog);
+ }
+
+ #region IDisposable Support
+ private bool disposedValue;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue && disposing)
+ {
+ helpers.Dispose();
+
+ helpers.LockManager.ReleaseLocks();
+
+ extendLocksTimer.Stop();
+ extendLocksTimer.Dispose();
+ }
+
+ disposedValue = true;
+ }
+
+ ~Script()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/AddService_1.csproj b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/AddService_1.csproj
new file mode 100644
index 0000000..5812351
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/AddService_1.csproj
@@ -0,0 +1,104 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {CB5B8A98-2204-4F53-A8A8-B6BB32E85F64}
+ Library
+ Properties
+ AddService_1
+ AddService_1
+ v4.7.2
+ 512
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\AddService_1.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\AddService_1.xml
+
+
+ None
+
+
+
+ ..\Dlls\SLMediationSnippets.dll
+
+
+ ..\Dlls\SLSRMLibrary.dll
+ C:\Skyline DataMiner\Files\SLSRMLibrary.dll
+
+
+
+
+
+
+ False
+ ..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Net.Http.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.3.5
+
+
+ 7.0.1
+
+
+
+
+ {121dd302-df4b-4f49-b6f9-b3ad358bd842}
+ Library_1
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/LoadAddServiceDialog.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/LoadAddServiceDialog.cs
new file mode 100644
index 0000000..630802f
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/LoadAddServiceDialog.cs
@@ -0,0 +1,166 @@
+namespace AddService_1
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Timers;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Notifications;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Order;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Service;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Tasks.LoadingScreenTasks;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Tasks.OrderTasks;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Tasks.ServiceTasks;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.LoadingScreens;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Order;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Order.Dialogs;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Service;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+
+ public class LoadAddServiceDialog : LoadingDialog
+ {
+ private string serviceId;
+ private Service service;
+
+ private readonly Timer extendLocksTimer;
+ private int attemptsExtendLocking = 1;
+
+ public LoadAddServiceDialog(Helpers helpers, Timer extendLocksTimer) : base(helpers)
+ {
+ this.extendLocksTimer = extendLocksTimer;
+ }
+
+ public Order Order { get; private set; }
+
+ public LiveOrderFormDialog EditOrderDialog { get; private set; }
+
+ public EditSharedSourceDialog EditSharedSourceDialog { get; private set; }
+
+ public LiveOrderFormAction ScriptAction { get; private set; }
+
+ protected override void GetScriptInput()
+ {
+ serviceId = Helpers.Engine.GetScriptParam("ServiceId").Value;
+ ScriptAction = Helpers.Engine.GetScriptParam("Action").Value.GetEnumValue();
+ }
+
+ protected override void CollectActions()
+ {
+ methodsToExecute.Add(GetService);
+ methodsToExecute.Add(InitializeOrderLogger);
+ methodsToExecute.Add(GetOrder);
+ methodsToExecute.Add(GetLockInfo);
+ methodsToExecute.Add(GetUserInfo);
+ methodsToExecute.Add(ConstructForm);
+ }
+
+ protected override void SendReportButton_Pressed(object sender, EventArgs e)
+ {
+ string title = "Exception while loading Update Service [" + DateTime.Now + "]";
+
+ string message = $"Order(s): '{Order.Name}'
Order ID(s): {Order.Id}
Service: '{service?.Name}'
Service ID: {serviceId}
User: {Helpers.Engine.UserLoginName}
Timestamp: {DateTime.Now}
Exception: {informationMessageLabel.Text.Replace(" at ", "
at ")}";
+
+ NotificationManager.SendMailToSkylineDevelopers(Helpers, title, message);
+
+ reportSuccessfullySentLabel.IsVisible = true;
+ }
+
+ private void GetService()
+ {
+ var getServiceTask = new GetServiceTask(Helpers, serviceId);
+ Tasks.Add(getServiceTask);
+
+ IsSuccessful &= getServiceTask.Execute();
+
+ if (!IsSuccessful) return;
+
+ service = getServiceTask.Service;
+ }
+
+ private void InitializeOrderLogger()
+ {
+ Helpers.AddOrderReferencesForLogging(service.OrderReferences.ToArray());
+ }
+
+ private void GetOrder()
+ {
+ if (service.TryGetLinkedOrders(Helpers, out List linkedOrders) && linkedOrders.Count == 1)
+ {
+ // there can only be 1 order linked to a Destination or Transmission
+ Order = linkedOrders.Single();
+
+ Order.AcceptChanges();
+ }
+ else
+ {
+ IsSuccessful &= false;
+ }
+
+ if (Order.Subtype == OrderSubType.Vizrem)
+ {
+ PrepareUiForManualMessage("Editing Vizrem orders is currently not supported.");
+ IsSuccessful = false;
+ }
+ }
+
+ private void GetLockInfo()
+ {
+ var getLockInfoTask = new GetOrderLockTask(Helpers, Order.Id);
+ Tasks.Add(getLockInfoTask);
+
+ IsSuccessful &= getLockInfoTask.Execute();
+
+ if (!IsSuccessful) return;
+
+ LockInfos.Add(getLockInfoTask.LockInfo);
+
+ if (LockInfos.Single().IsLockGranted)
+ {
+ extendLocksTimer.Elapsed += ExtendLocksTimer_Elapsed;
+ extendLocksTimer.Interval = LockInfos.Single().ReleaseLocksAfter.TotalMilliseconds;
+ extendLocksTimer.AutoReset = true;
+ extendLocksTimer.Enabled = true;
+ }
+ }
+
+ private void GetUserInfo()
+ {
+ var getUserInfoTask = new GetUserInfoTask(Helpers);
+ Tasks.Add(getUserInfoTask);
+
+ IsSuccessful &= getUserInfoTask.Execute();
+
+ if (!IsSuccessful) return;
+
+ UserInfo = getUserInfoTask.UserInfo;
+ }
+
+ private void ConstructForm()
+ {
+ var constructAddServiceDialogTask = new ConstructLiveOrderFormTask(Helpers, Order, null, LockInfos.Single(), UserInfo, ScriptAction);
+ Tasks.Add(constructAddServiceDialogTask);
+
+ IsSuccessful &= constructAddServiceDialogTask.Execute();
+ if (!IsSuccessful) return;
+
+ EditOrderDialog = constructAddServiceDialogTask.EditOrderDialog;
+ }
+
+ private void ExtendLocksTimer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ if (attemptsExtendLocking >= 10)
+ {
+ extendLocksTimer.Stop();
+ extendLocksTimer.Dispose();
+ return;
+ }
+
+ var orderLockInfo = Helpers.LockManager.RequestOrderLock(Order.Id, extendLock: true);
+ if (orderLockInfo.LockUsername.Contains("error"))
+ {
+ Helpers.Log(nameof(LoadAddServiceDialog), nameof(ExtendLocksTimer_Elapsed), $"Something went wrong when extending the order lock: {Order.Id}", Order.Name);
+ }
+
+ attemptsExtendLocking++;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/Properties/AssemblyInfo.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..79272e2
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("AddService_1")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("AddService_1")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("A9896034-2C14-41E6-A4B0-D064F2ACE9B8")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/app.config b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/app.config
new file mode 100644
index 0000000..b8ffc0f
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/app.config
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/stylecop.json b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AddService_1/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics.xml b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics.xml
new file mode 100644
index 0000000..ce2bc52
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics.xml
@@ -0,0 +1,32 @@
+
+
+ AggregateMetrics
+ Script 1.0.1.77
+ Automation
+ SKYLINE2\VictorSC
+ FALSE
+ YLE/Tools
+
+
+
+
+
+
+
+
+
+ pushToQaPortal
+
+
+ DaysToRemainMetricFiles
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/.editorconfig b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/AggregateMetrics_1.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/AggregateMetrics_1.cs
new file mode 100644
index 0000000..c3b2aff
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/AggregateMetrics_1.cs
@@ -0,0 +1,281 @@
+/*
+****************************************************************************
+* Copyright (c) 2022, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+dd/mm/2022 1.0.0.1 XXX, Skyline Initial version
+****************************************************************************
+*/
+
+namespace AggregateMetrics_1
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using Newtonsoft.Json;
+ using Skyline.DataMiner.Automation;
+ using Skyline.DataMiner.Core.DataMinerSystem.Common;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Configuration;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Metrics;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Metrics.Files;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+ using Skyline.DataMiner.Library.Automation;
+ using Skyline.DataMiner.Net.Messages;
+
+ ///
+ /// DataMiner Script Class.
+ ///
+ public class Script : IDisposable
+ {
+ private const string MetricLoggingDirectory = @"C:\Skyline_Data\MetricLogging";
+
+ private Helpers helpers;
+ private MetricAggregator aggregator;
+ private bool pushToQaPortal;
+ private bool disposedValue;
+
+ ///
+ /// The Script entry point.
+ ///
+ /// Link with SLAutomation process.
+ public void Run(Engine engine)
+ {
+ try
+ {
+ Initialize(engine);
+
+ var summary = aggregator.GetMetricsSummary(MetricLoggingDirectory, out var filesToRemove, out var amountOfProcessedFiles, DateTime.Now.AddDays(-1));
+ RemoveProcessedFiles(filesToRemove);
+
+ if (pushToQaPortal)
+ {
+ MergeMetricsSummariesFromOtherAgents(summary);
+ PushMetricsToQaPortal(summary);
+ }
+ else
+ {
+ AddSummaryToScriptOutput(engine, summary);
+ }
+ }
+ catch (Exception e)
+ {
+ helpers.Log(nameof(Script), nameof(Run), $"Exception occurred: {e}");
+ throw;
+ }
+ finally
+ {
+ Dispose();
+ }
+ }
+
+ private static void RemoveProcessedFiles(List files)
+ {
+ foreach (var processedFile in files)
+ {
+ File.Delete(processedFile);
+ }
+ }
+
+ private static void AddSummaryToScriptOutput(Engine engine, MetricsSummary summary)
+ {
+ //var settings = new JsonSerializerSettings();
+ //settings.TypeNameHandling = TypeNameHandling.All;
+ //var serializedSummary = JsonConvert.SerializeObject(summary, Formatting.None, settings);
+
+ var serializedSummary = JsonConvert.SerializeObject(summary, Formatting.None);
+
+ engine.AddOrUpdateScriptOutput("summary", serializedSummary);
+ }
+
+ private void Initialize(Engine engine)
+ {
+ engine.Timeout = TimeSpan.FromHours(10);
+ engine.SetFlag(RunTimeFlags.NoInformationEvents);
+
+ pushToQaPortal = Convert.ToBoolean(engine.GetScriptParam("pushToQaPortal").Value);
+ int daysToRemainMetricFiles = Convert.ToInt32(engine.GetScriptParam("DaysToRemainMetricFiles").Value);
+
+ helpers = new Helpers(engine, Scripts.AggregateMetrics);
+ aggregator = new MetricAggregator(helpers, daysToRemainMetricFiles);
+ }
+
+ private void MergeMetricsSummariesFromOtherAgents(MetricsSummary summary)
+ {
+ var thisAgentId = Engine.SLNetRaw.ServerDetails.AgentID;
+
+ var dms = Engine.SLNetRaw.GetDms();
+ foreach (var agentId in dms.GetAgents().Where(a => a.State == Skyline.DataMiner.Core.DataMinerSystem.Common.AgentState.Running).Select(a => a.Id))
+ {
+ if (agentId == thisAgentId) continue;
+
+ var summaryForAgent = GetMetricsSummaryFromAgent(agentId);
+ if (summaryForAgent != null)
+ {
+ summary.Merge(summaryForAgent);
+ }
+ }
+ }
+
+ private MetricsSummary GetMetricsSummaryFromAgent(int agentId)
+ {
+ var executeScriptMessage = new ExecuteScriptMessage
+ {
+ ScriptName = "AggregateMetrics",
+ DataMinerID = agentId,
+ HostingDataMinerID = agentId,
+ Options = new SA(new[]
+ {
+ "DEFER:FALSE",
+ "PARAMETERBYNAME:pushToQaPortal:False",
+ $"PARAMETERBYNAME:DaysToRemainMetricFiles:{aggregator.DaysToRemainMetricFiles}"
+ })
+ };
+
+ try
+ {
+ var response = (ExecuteScriptResponseMessage)helpers.Engine.SendSLNetSingleResponseMessage(executeScriptMessage);
+
+ var output = response.ScriptOutput;
+ return GetSummaryFromScriptOutput(output, agentId);
+ }
+ catch (Exception e)
+ {
+ helpers.Log(nameof(Script), nameof(GetMetricsSummaryFromAgent), $"Exception retrieving metrics summary from agent {agentId}: {e}");
+ return null;
+ }
+ }
+
+ private MetricsSummary GetSummaryFromScriptOutput(Dictionary output, int agentId)
+ {
+ if (output == null || !output.TryGetValue("summary", out var summary))
+ {
+ helpers.Log(nameof(Script), nameof(GetSummaryFromScriptOutput), $"No metrics summary results received from agent {agentId}");
+ return null;
+ }
+
+ if (String.IsNullOrEmpty(summary))
+ {
+ helpers.Log(nameof(Script), nameof(GetSummaryFromScriptOutput), $"Empty metrics summary results received from agent {agentId}");
+ return null;
+ }
+
+ helpers.Log(nameof(Script), nameof(GetSummaryFromScriptOutput), $"Summary from {agentId}: {summary}");
+
+ //var settings = new JsonSerializerSettings();
+ //settings.TypeNameHandling = TypeNameHandling.All;
+ //return JsonConvert.DeserializeObject(summary, settings);
+
+ return JsonConvert.DeserializeObject(summary);
+ }
+
+ private void PushMetricsToQaPortal(MetricsSummary summary)
+ {
+ //var allStartTimes = summary.ScriptExecutionMetricSummaries.Values.SelectMany(s => s).Select(x => x.StartTime).Where(s => s != null).ToList();
+
+ var allStartTimes = summary.ScriptMetricSummaries.SelectMany(s => s.GetStartTimes()).Where(s => s != null).ToList();
+
+ var earliestStartTime = allStartTimes.Min();
+ var latestEndTime = allStartTimes.Max();
+
+ // Temporary method additions, goal is to make something generic to gather and push method results.
+ var fixedMethodNameList = new[] { "GetEvent", "Event", "GetEventByName", "AddOrUpdateOrderReservation", "AddOrUpdateServiceReservation" };
+ var methodSummeriesToPush = summary.MethodCallSummaries.Where(mcs => fixedMethodNameList.Contains(mcs.MethodName)).ToList();
+
+ foreach (var methodSummary in methodSummeriesToPush)
+ {
+ if (methodSummary is null) continue;
+
+ string extraInfo = $"Value aggregated from {methodSummary.AmountOfExecutions} executions from {earliestStartTime} until {latestEndTime}";
+
+ helpers.QAPortalHelper.PublishPerformanceTestResult(methodSummary.QaPortalTestNameForAverage, methodSummary.AverageExecutionTime, extraInfo);
+ helpers.QAPortalHelper.PublishPerformanceTestResult(methodSummary.QaPortalTestNameForHighest, methodSummary.HighestExecutionTime, extraInfo);
+ }
+
+ foreach (var scriptSummary in summary.ScriptMetricSummaries)
+ {
+ if (String.IsNullOrWhiteSpace(scriptSummary.ScriptName)) continue;
+ if (!scriptSummary.ScriptExecutionMetricSummaries.Any()) continue;
+
+ string extraInfo = $"Value aggregated from {scriptSummary.AmountOfExecutions} executions from {earliestStartTime} until {latestEndTime}";
+
+ helpers.QAPortalHelper.PublishPerformanceTestResult(scriptSummary.QaPortalTestNameForAverage, scriptSummary.AverageExecutionTime, extraInfo);
+ helpers.QAPortalHelper.PublishPerformanceTestResult(scriptSummary.QaPortalTestNameForHighest, scriptSummary.HighestExecutionTime, extraInfo);
+ }
+
+ foreach (var dataMinerInterfaceMethodSummary in summary.DataMinerInterfaceMethodCallSummaries)
+ {
+ if (String.IsNullOrWhiteSpace(dataMinerInterfaceMethodSummary.ClassName) ||
+ String.IsNullOrWhiteSpace(dataMinerInterfaceMethodSummary.MethodName)) continue;
+ if (!dataMinerInterfaceMethodSummary.ExecutionTimes.Any()) continue;
+
+ string extraInfo = $"Value aggregated from {dataMinerInterfaceMethodSummary.AmountOfExecutions} executions from {earliestStartTime} until {latestEndTime}";
+
+ helpers.QAPortalHelper.PublishPerformanceTestResult(dataMinerInterfaceMethodSummary.QaPortalTestNameForAverage, dataMinerInterfaceMethodSummary.AverageExecutionTime, extraInfo);
+ helpers.QAPortalHelper.PublishPerformanceTestResult(dataMinerInterfaceMethodSummary.QaPortalTestNameForHighest, dataMinerInterfaceMethodSummary.HighestExecutionTime, extraInfo);
+ }
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ helpers.Dispose();
+ }
+
+ disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/AggregateMetrics_1.csproj b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/AggregateMetrics_1.csproj
new file mode 100644
index 0000000..a63f601
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/AggregateMetrics_1.csproj
@@ -0,0 +1,101 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {8F19C132-61E2-4351-AC47-4653E86D7456}
+ Library
+ Properties
+ AggregateMetrics_1
+ AggregateMetrics_1
+ v4.7.2
+ 512
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\AggregateMetrics_1.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\AggregateMetrics_1.xml
+
+
+ None
+
+
+
+ ..\Dlls\SLMediationSnippets.dll
+
+
+ ..\Dlls\SLSRMLibrary.dll
+ C:\Skyline DataMiner\Files\SLSRMLibrary.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.1.0.5
+
+
+ 10.3.5
+
+
+ 7.0.1
+
+
+
+
+ {121dd302-df4b-4f49-b6f9-b3ad358bd842}
+ Library_1
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/Properties/AssemblyInfo.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a125c62
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("AggregateMetrics_1")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("AggregateMetrics_1")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("38656200-E291-4E4E-B6E8-4A7A6BD11F5B")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/app.config b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/app.config
new file mode 100644
index 0000000..fda1974
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/app.config
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/stylecop.json b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AggregateMetrics_1/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources.xml b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources.xml
new file mode 100644
index 0000000..edff934
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources.xml
@@ -0,0 +1,31 @@
+
+
+ AssignRecordingResources
+ Script 1.0.1.77
+ Automation
+ SKYLINE2\GillesVH
+ FALSE
+ YLE/SRM
+
+
+
+
+
+
+
+
+
+ BookingID
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/.editorconfig b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/AssignRecordingResources_2.csproj b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/AssignRecordingResources_2.csproj
new file mode 100644
index 0000000..ab98c5b
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/AssignRecordingResources_2.csproj
@@ -0,0 +1,101 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {61FCF96E-F3D6-4609-9D75-78D9582E692D}
+ Library
+ Properties
+ AssignRecordingResources_2
+ AssignRecordingResources_2
+ v4.7.2
+ 512
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\AssignRecordingResources_2.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\AssignRecordingResources_2.xml
+
+
+ None
+
+
+
+ ..\Dlls\SLMediationSnippets.dll
+
+
+ ..\Dlls\SLSRMLibrary.dll
+ C:\Skyline DataMiner\Files\SLSRMLibrary.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.3.5
+
+
+ 7.0.1
+
+
+
+
+ {121dd302-df4b-4f49-b6f9-b3ad358bd842}
+ Library_1
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/ConfirmAssignDialog.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/ConfirmAssignDialog.cs
new file mode 100644
index 0000000..6d17acb
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/ConfirmAssignDialog.cs
@@ -0,0 +1,36 @@
+namespace AssignRecordingResources_2
+{
+ using Skyline.DataMiner.Automation;
+ using Skyline.DataMiner.Utils.InteractiveAutomationScript;
+
+ public class ConfirmAssignDialog : Dialog
+ {
+ private readonly Label messageLabel = new Label("Are you sure that you want to assign the resource of this service reservation?");
+
+ public ConfirmAssignDialog(Engine engine) : base(engine)
+ {
+ this.Title = "Confirm Assign";
+
+ YesButton = new Button("Yes") { Width = 200 };
+ NoButton = new Button("No") { Width = 200 };
+
+ GenerateUi();
+ }
+
+ public Button YesButton { get; private set; }
+
+ public Button NoButton { get; private set; }
+
+ private void GenerateUi()
+ {
+ int row = -1;
+
+ AddWidget(messageLabel, ++row, 0, 1, 2);
+
+ AddWidget(new WhiteSpace(), new WidgetLayout(++row, 0));
+
+ AddWidget(YesButton, ++row, 0, 1, 1);
+ AddWidget(NoButton, row, 1, 1, 1);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/Properties/AssemblyInfo.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..19f7581
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("AssignRecordingResources_2")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("AssignRecordingResources_2")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("A09BD0C0-047F-4253-818B-FB8BB5D1A624")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/Script.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/Script.cs
new file mode 100644
index 0000000..e73f88a
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/Script.cs
@@ -0,0 +1,239 @@
+/*
+****************************************************************************
+* Copyright (c) 2021, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+13/04/2021 1.0.0.1 GVH, Skyline Initial version
+****************************************************************************
+*/
+
+namespace AssignRecordingResources_2
+{
+ using System;
+ using System.Linq;
+ using Skyline.DataMiner.Automation;
+ using Skyline.DataMiner.Utils.InteractiveAutomationScript;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Tasks;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Functions;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.LoadingScreens;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Reports;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+ using ExceptionDialog = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Reports.ExceptionDialog;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Configuration;
+
+ ///
+ /// DataMiner Script Class.
+ ///
+ public class Script : IDisposable
+ {
+ private Helpers helpers;
+ private InteractiveController app;
+
+ private LoadAssignReleaseResourceDialog loadAssignRecordingResourceDialog;
+ private AssignReleaseResourceDialog assignResourceDialog;
+ private ReportDialog reportDialog;
+ private bool disposedValue;
+
+ ///
+ /// The Script entry point.
+ ///
+ /// Link with SLScripting process.
+ public void Run(Engine engine)
+ {
+ try
+ {
+ Initialize(engine);
+
+ loadAssignRecordingResourceDialog = new LoadAssignReleaseResourceDialog(helpers, ResourceScriptAction.Assign);
+
+ if (loadAssignRecordingResourceDialog.Execute()) ShowAssignResourceDialog();
+ else app.Run(loadAssignRecordingResourceDialog);
+ }
+ catch (InteractiveUserDetachedException)
+ {
+ helpers.Log(nameof(Script), "STOP SCRIPT", "Assign Recording Resource");
+ helpers.LockManager.ReleaseLocks();
+ }
+ catch (ScriptAbortException)
+ {
+ helpers.Log(nameof(Script), "STOP SCRIPT", "Assign Recording Resource");
+ helpers.LockManager.ReleaseLocks();
+ throw;
+ }
+ catch (Exception e)
+ {
+ helpers.Log(nameof(Script), "STOP SCRIPT", "Assign Recording Resource");
+ engine.Log("Run|Something went wrong: " + e);
+ ShowExceptionDialog(engine, e);
+ }
+ finally
+ {
+ Dispose();
+ }
+ }
+
+ private void Initialize(Engine engine)
+ {
+ // engine.ShowUI();
+ engine.Timeout = TimeSpan.FromHours(10);
+ engine.SetFlag(RunTimeFlags.NoInformationEvents);
+
+ helpers = new Helpers(engine, Scripts.AssignRecordingResources);
+
+ app = new InteractiveController(engine);
+ }
+
+ private void ShowAssignResourceDialog()
+ {
+ assignResourceDialog = loadAssignRecordingResourceDialog.AssignReleaseResourceDialog;
+ assignResourceDialog.AssignButton.Pressed += AssignButton_Pressed;
+
+ if (app.IsRunning) app.ShowDialog(assignResourceDialog);
+ else app.Run(assignResourceDialog);
+ }
+
+ private void AssignButton_Pressed(object sender, EventArgs e)
+ {
+ ConfirmAssignDialog confirmAssignDialog = new ConfirmAssignDialog((Engine)helpers.Engine);
+ confirmAssignDialog.NoButton.Pressed += (o, args) => app.ShowDialog(assignResourceDialog);
+ confirmAssignDialog.YesButton.Pressed += ConfirmAssignDialog_YesButton_Pressed;
+
+ app.ShowDialog(confirmAssignDialog);
+ }
+
+ private void ConfirmAssignDialog_YesButton_Pressed(object sender, EventArgs e)
+ {
+ try
+ {
+ reportDialog = new AddOrUpdateReportDialog(helpers);
+ reportDialog.OkButton.Pressed += (o, args) => { helpers.LockManager.ReleaseLocks(); helpers.Engine.ExitSuccess("Successfully updated the recording service"); };
+ reportDialog.RollBackButton.Pressed += (o, args) => RollBackTasks();
+ app.ShowDialog(reportDialog);
+
+ var tasks = assignResourceDialog.Finish().Tasks.ToList();
+
+ if (tasks.Any())
+ {
+ reportDialog.Finish(tasks);
+
+ // release the locks if all tasks were successful
+ if (tasks.All(t => t.Status == Status.Ok)) helpers.LockManager.ReleaseLocks();
+
+ app.ShowDialog(reportDialog);
+ }
+ else ShowMessageDialog((Engine)helpers.Engine, "No changes made", "No Changes made");
+
+ }
+ catch (Exception ex)
+ {
+ ShowExceptionDialog((Engine)helpers.Engine, ex);
+ }
+ }
+
+ private void RollBackTasks()
+ {
+ // Roll back tasks - Only roll back tasks that were successful
+ var rollbackReportDialog = new RollBackReportDialog(helpers) { Title = "Roll back service update" };
+ rollbackReportDialog.OkButton.Pressed += (o, e) => helpers.Engine.ExitSuccess("Successfully rolled back the service update");
+
+ app.ShowDialog(rollbackReportDialog);
+
+ // Only roll back tasks that were successful
+ var rollbackTasks = reportDialog.UpdateResults.SelectMany(ur => ur.Tasks).Where(t => t.Status == Status.Ok).Select(t => t.CreateRollbackTask()).Where(t => t != null).Reverse().ToList();
+
+ foreach (var rollbackTask in rollbackTasks)
+ {
+ if (!rollbackTask.Execute())
+ {
+ helpers.Log(nameof(Script), nameof(RollBackTasks), "Rolling back " + rollbackTask.Description + "failed: " + rollbackTask.Exception);
+ break;
+ }
+ }
+
+ rollbackReportDialog.Finish(rollbackTasks);
+
+ helpers.LockManager.ReleaseLocks();
+
+ app.ShowDialog(rollbackReportDialog);
+ }
+
+ private void ShowMessageDialog(Engine engine, string message, string title)
+ {
+ MessageDialog dialog = new MessageDialog(engine, message) { Title = title };
+ dialog.OkButton.Pressed += (sender, args) => engine.ExitSuccess(message);
+
+ if (app.IsRunning) app.ShowDialog(dialog);
+ else app.Run(dialog);
+ }
+
+ private void ShowExceptionDialog(Engine engine, Exception exception)
+ {
+ ExceptionDialog dialog = new ExceptionDialog(engine, exception);
+ dialog.OkButton.Pressed += (sender, args) => engine.ExitFail("Something went wrong during the handling of resource assigning");
+ if (!app.IsRunning) app.Run(dialog);
+ else app.ShowDialog(dialog);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ helpers.Dispose();
+ }
+
+ disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/app.config b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/app.config
new file mode 100644
index 0000000..fda1974
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/app.config
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/stylecop.json b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignRecordingResources_2/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe.xml b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe.xml
new file mode 100644
index 0000000..5668443
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe.xml
@@ -0,0 +1,31 @@
+
+
+ AssignTicketToMe
+ Script 1.0.1.77
+ Automation
+ SKYLINE2\VictorSC
+ FALSE
+ YLE/Customer UI
+
+
+
+
+
+
+
+
+
+ TicketId
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/.editorconfig b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/AssignTicketToMe_2.csproj b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/AssignTicketToMe_2.csproj
new file mode 100644
index 0000000..98a9bc3
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/AssignTicketToMe_2.csproj
@@ -0,0 +1,100 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {6846E9D4-264E-4FFD-876D-88BFBDAFE69F}
+ Library
+ Properties
+ AssignTicketToMe_2
+ AssignTicketToMe_2
+ v4.7.2
+ 512
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\AssignTicketToMe_2.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\AssignTicketToMe_2.xml
+
+
+ None
+
+
+
+ ..\Dlls\SLMediationSnippets.dll
+
+
+ ..\Dlls\SLSRMLibrary.dll
+ C:\Skyline DataMiner\Files\SLSRMLibrary.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.3.5
+
+
+ 7.0.1
+
+
+
+
+ {121dd302-df4b-4f49-b6f9-b3ad358bd842}
+ Library_1
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/Properties/AssemblyInfo.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..71682f3
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("AssignTicketToMe_2")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("AssignTicketToMe_2")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("6B970F92-99A9-455F-951B-3298412F6FB3")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/Script.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/Script.cs
new file mode 100644
index 0000000..bb1ae7b
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/Script.cs
@@ -0,0 +1,178 @@
+/*
+****************************************************************************
+* Copyright (c) 2021, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+dd/mm/2021 1.0.0.1 XXX, Skyline Initial version
+
+22/03/2021 1.0.0.2 GVH, Skyline Linking between user tasks and non live orders
+****************************************************************************
+*/
+
+namespace AssignTicketToMe_2
+{
+ using System;
+ using System.Linq;
+ using Skyline.DataMiner.Automation;
+ using Skyline.DataMiner.Utils.InteractiveAutomationScript;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Contracts;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.IngestExport;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UserTasks;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+ using ExceptionDialog = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Reports.ExceptionDialog;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UserTasks.NonLiveUserTasks;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Configuration;
+
+ ///
+ /// DataMiner Script Class.
+ ///
+ class Script : IDisposable
+ {
+ private Helpers helpers;
+ private InteractiveController app;
+ private User user;
+ private bool disposedValue;
+
+ ///
+ /// The Script entry point.
+ ///
+ /// Link with SLScripting process.
+ public void Run(Engine engine)
+ {
+ try
+ {
+ Initialize(engine);
+
+ string scriptParameter = engine.GetScriptParam(1).Value;
+
+ int[] dmaAndTicketId = Array.ConvertAll(scriptParameter.Split(new[] { '/' }).Select(item => item.Trim('"', '[', ']')).ToArray(), Convert.ToInt32);
+
+ if (helpers.NonLiveOrderManager.TryGetNonLiveOrder(dmaAndTicketId[0], dmaAndTicketId[1], out var nonLiveOrder))
+ {
+ helpers.NonLiveOrderManager.AssignNonLiveOrderTo(nonLiveOrder, user);
+ }
+ else if (helpers.UserTaskManager.TryGetUserTask(scriptParameter, out var userTask))
+ {
+ userTask.Owner = engine.UserDisplayName;
+ userTask.AddOrUpdate(helpers);
+
+ bool assignToMe = true;
+ if (userTask is NonLiveUserTask nonLiveUserTask && !helpers.NonLiveOrderManager.TryUpdateNonLiveOrderStatusBasedOnUserTask(helpers.NonLiveUserTaskManager, nonLiveUserTask, user, assignToMe))
+ {
+ helpers.Log(nameof(Script), nameof(Run), $"Non live order failed while updating the status");
+ }
+ }
+ else
+ {
+ helpers.Log(nameof(Script), nameof(Run), $"Ticket with ID {scriptParameter} is not a non-live order nor a user task.");
+
+ ShowMessageDialog(engine, $"Assigning the ticket to you failed because the system was unable to convert the ticket with ID {scriptParameter} to a non-live order or user task.", "Error");
+ }
+ }
+ catch (ScriptAbortException)
+ {
+ // ignore
+ }
+ catch (Exception e)
+ {
+ helpers.Log(nameof(Script), nameof(Run), $"Something went wrong: {e}");
+ ShowExceptionDialog(engine, e);
+ }
+ finally
+ {
+ helpers.Log(nameof(Script), "STOP SCRIPT", "AssignTicketToMe");
+ Dispose();
+ }
+ }
+
+ private void Initialize(Engine engine)
+ {
+ //engine.ShowUI();
+ helpers = new Helpers(engine, Scripts.AssignTicketToMe);
+
+ app = new InteractiveController(engine);
+
+ user = helpers.ContractManager.GetBaseUserInfo(engine.UserLoginName).User;
+ }
+
+ private void ShowMessageDialog(Engine engine, string message, string title)
+ {
+ MessageDialog dialog = new MessageDialog(engine, message) { Title = title };
+ dialog.OkButton.Pressed += (sender, args) => engine.ExitSuccess(message);
+
+ if (app.IsRunning) app.ShowDialog(dialog);
+ else app.Run(dialog);
+ }
+
+ private void ShowExceptionDialog(Engine engine, Exception exception)
+ {
+ ExceptionDialog exceptionDialog = new ExceptionDialog(engine, exception);
+ exceptionDialog.OkButton.Pressed += (o, e) => engine.ExitSuccess("Something went wrong during the execution of Assign Ticket to me");
+
+ if (app.IsRunning) app.ShowDialog(exceptionDialog);
+ else app.Run(exceptionDialog);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ helpers.Dispose();
+ }
+
+ disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/app.config b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/app.config
new file mode 100644
index 0000000..fda1974
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/app.config
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/stylecop.json b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AssignTicketToMe_2/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AutomationScript.sln b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AutomationScript.sln
new file mode 100644
index 0000000..1423722
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/AutomationScript.sln
@@ -0,0 +1,1457 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32407.343
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{B8F1F599-6153-4506-BA3A-C68123D23987}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dlls", "Dlls", "{EC5443D2-2D8E-411C-A52D-1F5E14895874}"
+ ProjectSection(SolutionItems) = preProject
+ Dlls\readme.txt = Dlls\readme.txt
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{8162A277-32E5-4B70-981B-16BD1FBC49C0}"
+ ProjectSection(SolutionItems) = preProject
+ Documentation\readme.txt = Documentation\readme.txt
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddEvent", "AddEvent", "{0A0FBC87-CC98-42F9-9A0A-8E9BA7BFFCD5}"
+ ProjectSection(SolutionItems) = preProject
+ AddEvent.xml = AddEvent.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{ACC68C00-F79A-4901-AD56-56608A4ED459}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddEvent_2", "AddEvent_2\AddEvent_2.csproj", "{8EBFE2CE-07A1-45F6-85AC-8023014A0A8A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddEventFromTemplate", "AddEventFromTemplate", "{AAAB9A5A-635B-436F-8C37-EC7AEC4E2CD6}"
+ ProjectSection(SolutionItems) = preProject
+ AddEventFromTemplate.xml = AddEventFromTemplate.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{021CDAC2-FA64-47D4-B135-BE88307070F3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddEventFromTemplate_1", "AddEventFromTemplate_1\AddEventFromTemplate_1.csproj", "{880203DF-F9E6-4888-9978-A2FBE22BD25A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddNote", "AddNote", "{8CA3AB2F-92C6-4C50-8D9E-CA2B47C2C3D8}"
+ ProjectSection(SolutionItems) = preProject
+ AddNote.xml = AddNote.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{E538F135-D7F1-4D06-B4FA-42CC9B2045C0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddNote_2", "AddNote_2\AddNote_2.csproj", "{E5C344F3-4239-4F98-BF5B-642646B0A68A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddOrUpdateNonLiveOrder", "AddOrUpdateNonLiveOrder", "{F2457324-04D1-4703-91D4-30CB9046C94F}"
+ ProjectSection(SolutionItems) = preProject
+ AddOrUpdateNonLiveOrder.xml = AddOrUpdateNonLiveOrder.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{D54F9F07-8ED9-4511-A572-57AA57D7ABEE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddOrUpdateNonLiveOrder_2", "AddOrUpdateNonLiveOrder_2\AddOrUpdateNonLiveOrder_2.csproj", "{CD8CA3A7-2D4D-416A-BB82-76279B1843C2}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AssignTicketToMe", "AssignTicketToMe", "{D6AA01DF-D60F-497E-A29D-28268B164B8D}"
+ ProjectSection(SolutionItems) = preProject
+ AssignTicketToMe.xml = AssignTicketToMe.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{E20DDD90-B221-4873-A9F9-7F831F17FF95}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssignTicketToMe_2", "AssignTicketToMe_2\AssignTicketToMe_2.csproj", "{6846E9D4-264E-4FFD-876D-88BFBDAFE69F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BookMultipleOrders", "BookMultipleOrders", "{42DE3F58-875F-49A2-8BB3-AE9ABB6ABD98}"
+ ProjectSection(SolutionItems) = preProject
+ BookMultipleOrders.xml = BookMultipleOrders.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{EB2D434B-1053-42C1-95B0-3A1C8112DA49}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookMultipleOrders_2", "BookMultipleOrders_2\BookMultipleOrders_2.csproj", "{E10BD658-9B0E-4A95-97B7-C288C429C094}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CancelMultipleOrders", "CancelMultipleOrders", "{5A7E4CE3-E5F2-46FB-80F8-AAF2EA16D5E4}"
+ ProjectSection(SolutionItems) = preProject
+ CancelMultipleOrders.xml = CancelMultipleOrders.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{FAA052F2-328B-41A2-9A2B-CCD32A7517A3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CancelMultipleOrders_2", "CancelMultipleOrders_2\CancelMultipleOrders_2.csproj", "{CFA4A2CE-A230-4303-83B1-677B23B66266}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ConfirmOrders", "ConfirmOrders", "{2FCA2E8E-D20D-421A-8F6B-4641DF47CF84}"
+ ProjectSection(SolutionItems) = preProject
+ ConfirmOrders.xml = ConfirmOrders.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{7BBC9237-2D49-4C6F-BDC6-0B495FD43FB6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfirmOrders_5", "ConfirmOrders_5\ConfirmOrders_5.csproj", "{7F6A3EC0-1B12-4F2A-B0F8-1EBA1C113460}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DeleteEvent", "DeleteEvent", "{96FD05B9-272B-4AC4-81AB-A8D411823A37}"
+ ProjectSection(SolutionItems) = preProject
+ DeleteEvent.xml = DeleteEvent.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{D5E91541-FE1E-48BB-BCA2-EF80BF0F4381}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeleteEvent_2", "DeleteEvent_2\DeleteEvent_2.csproj", "{E69808C1-8776-4055-8385-05CCE596C4E5}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DeleteNonLiveOrder", "DeleteNonLiveOrder", "{5C85A61A-EED6-4A1D-9BA0-245900C0B493}"
+ ProjectSection(SolutionItems) = preProject
+ DeleteNonLiveOrder.xml = DeleteNonLiveOrder.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{91324E15-E4A3-4C49-9385-7F311012AB3D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeleteNonLiveOrder_2", "DeleteNonLiveOrder_2\DeleteNonLiveOrder_2.csproj", "{98F1FA3D-7B10-4178-A6A4-41F6958CCBE5}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DuplicateNonLiveOrder", "DuplicateNonLiveOrder", "{985ED6EE-AC9D-4BD4-88D7-06CC4740ACD1}"
+ ProjectSection(SolutionItems) = preProject
+ DuplicateNonLiveOrder.xml = DuplicateNonLiveOrder.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{D9C0DE7D-885D-4CB3-80FA-2A653026A28E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DuplicateNonLiveOrder_2", "DuplicateNonLiveOrder_2\DuplicateNonLiveOrder_2.csproj", "{A90B225A-0F85-416B-9CE8-EEBDF2929BC4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LiveOrderForm", "LiveOrderForm", "{2A8BDC9C-C864-46B7-98A0-ECC9BA0ECDFF}"
+ ProjectSection(SolutionItems) = preProject
+ LiveOrderForm.xml = LiveOrderForm.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{5B9A381F-95C5-4879-BB11-67E7FE333C45}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LiveOrderForm_6", "LiveOrderForm_6\LiveOrderForm_6.csproj", "{48F1B70D-8C96-49BA-B4A2-957377393EEF}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MergeEvents", "MergeEvents", "{F2100C68-99AA-437E-8B6F-569CFF60319A}"
+ ProjectSection(SolutionItems) = preProject
+ MergeEvents.xml = MergeEvents.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{D277FFE9-E342-4D8F-9EEA-ACB984B3F20E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MergeEvents_2", "MergeEvents_2\MergeEvents_2.csproj", "{C11D6283-7A34-4CDD-8C27-65F8499E5CFE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SendOrderDebugReport", "SendOrderDebugReport", "{E3A38228-9D83-4287-BB40-3B37105327C3}"
+ ProjectSection(SolutionItems) = preProject
+ SendOrderDebugReport.xml = SendOrderDebugReport.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{0A6E4D7B-7E46-4428-B8A2-04670F4AE4E8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SendOrderDebugReport_2", "SendOrderDebugReport_2\SendOrderDebugReport_2.csproj", "{C37BA915-33E8-48C6-9098-6681EE54884D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UpdateComments", "UpdateComments", "{263ABDC6-0FF9-4CEF-BADE-AF910A4CD06E}"
+ ProjectSection(SolutionItems) = preProject
+ UpdateComments.xml = UpdateComments.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{55BA7DED-599D-4518-BE9A-EF537FF15FD5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateComments_2", "UpdateComments_2\UpdateComments_2.csproj", "{2C70A6EE-70B7-42C0-8C0B-66C690AB8C87}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UpdateEvent", "UpdateEvent", "{4FBDE444-8013-449D-829B-1A10E5C84ED2}"
+ ProjectSection(SolutionItems) = preProject
+ UpdateEvent.xml = UpdateEvent.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{81C41B64-01DB-4B74-ACC0-E3FC9EBCC8F1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateEvent_2", "UpdateEvent_2\UpdateEvent_2.csproj", "{F44EB030-BD0E-42AB-82BD-5E7E0F530A24}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UpdateNote", "UpdateNote", "{3C7B03EF-F829-4183-8447-5FFAAB41736D}"
+ ProjectSection(SolutionItems) = preProject
+ UpdateNote.xml = UpdateNote.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{504632B3-C3E0-4AEE-BB19-4B83AB67EE98}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateNote_2", "UpdateNote_2\UpdateNote_2.csproj", "{96C98AA8-D5D5-4F3D-AC36-DFB044A10283}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UpdateService", "UpdateService", "{CF5E9E32-F322-427D-9282-75D9241B01A9}"
+ ProjectSection(SolutionItems) = preProject
+ UpdateService.xml = UpdateService.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{36D4B481-06AB-4B67-8794-E9CFB5502973}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateService_4", "UpdateService_4\UpdateService_4.csproj", "{D3966891-3616-427F-BC24-CEBAD4B3B6BE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UpdateTicketStatus", "UpdateTicketStatus", "{F15D5FFF-2C08-4EB8-B2D7-A1DD8162F5AF}"
+ ProjectSection(SolutionItems) = preProject
+ UpdateTicketStatus.xml = UpdateTicketStatus.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{BBB2D930-94EA-4246-8455-237671065539}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateTicketStatus_4", "UpdateTicketStatus_4\UpdateTicketStatus_4.csproj", "{FAFEE1DA-438D-4D7F-91B1-9BB2444DB30E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ExecuteFeenixStopCommand", "ExecuteFeenixStopCommand", "{6E2CC07F-56CA-40F3-B3F3-3DA8AE603896}"
+ ProjectSection(SolutionItems) = preProject
+ ExecuteFeenixStopCommand.xml = ExecuteFeenixStopCommand.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{C6A58830-B745-41A4-90D2-DA163CF2BB67}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExecuteFeenixStopCommand_2", "ExecuteFeenixStopCommand_2\ExecuteFeenixStopCommand_2.csproj", "{DA97B418-6D04-4FA2-8214-6FE3113E02C7}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PollCeitonResources", "PollCeitonResources", "{A3BE5D15-F8AA-4EDB-8E75-E1F37924CEF6}"
+ ProjectSection(SolutionItems) = preProject
+ PollCeitonResources.xml = PollCeitonResources.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{8E528AAF-4A6F-4829-B806-EDBD5C30F355}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PollCeitonResources_1", "PollCeitonResources_1\PollCeitonResources_1.csproj", "{DD92F97D-EA78-4377-8DB7-63D1C6048670}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ShowCeitonDetails", "ShowCeitonDetails", "{4D2D22C2-B933-495B-9846-811D5907A57D}"
+ ProjectSection(SolutionItems) = preProject
+ ShowCeitonDetails.xml = ShowCeitonDetails.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{929BA453-227D-46A5-BDD7-0A19825BE5E5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShowCeitonDetails_2", "ShowCeitonDetails_2\ShowCeitonDetails_2.csproj", "{891D09C7-E16C-4467-BDEE-BDAAB5552B7A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ShowEBUDetails", "ShowEBUDetails", "{269FF747-D5E0-40D8-B049-6E4C4964ADA6}"
+ ProjectSection(SolutionItems) = preProject
+ ShowEBUDetails.xml = ShowEBUDetails.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{2E90B124-81A7-4537-927F-8DB160C1FE80}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShowEBUDetails_2", "ShowEBUDetails_2\ShowEBUDetails_2.csproj", "{A3B23699-5387-4266-B784-C7AE207E6923}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ShowFeenixDetails", "ShowFeenixDetails", "{9101C64B-D96D-473D-B675-3774012104DA}"
+ ProjectSection(SolutionItems) = preProject
+ ShowFeenixDetails.xml = ShowFeenixDetails.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{35EB5074-E17E-414B-9057-2E26E4C43D5B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShowFeenixDetails_2", "ShowFeenixDetails_2\ShowFeenixDetails_2.csproj", "{BA41DE74-F49C-4C07-A83D-2317566E7808}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ShowPebbleBeachDetails", "ShowPebbleBeachDetails", "{3F4A40BF-90D0-4F0B-A8E7-4353FAC34D4C}"
+ ProjectSection(SolutionItems) = preProject
+ ShowPebbleBeachDetails.xml = ShowPebbleBeachDetails.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{E78D409D-0A8E-4A95-9E03-165B01A953BF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShowPebbleBeachDetails_2", "ShowPebbleBeachDetails_2\ShowPebbleBeachDetails_2.csproj", "{80B82340-D9C3-431F-9B22-947F6DDAE0F6}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ShowPlasmaDetails", "ShowPlasmaDetails", "{044CF8A5-7174-45AD-A429-BFAE3DC59B3B}"
+ ProjectSection(SolutionItems) = preProject
+ ShowPlasmaDetails.xml = ShowPlasmaDetails.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{2924AEED-876E-4AFA-A233-B34229F73BE4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShowPlasmaDetails_2", "ShowPlasmaDetails_2\ShowPlasmaDetails_2.csproj", "{74B56470-25B2-4846-810D-53560F6EB5F1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TriggerPebbleBeachIntegrationUpdate", "TriggerPebbleBeachIntegrationUpdate", "{DB05923D-5D5E-4630-AF81-386E8FD267A6}"
+ ProjectSection(SolutionItems) = preProject
+ TriggerPebbleBeachIntegrationUpdate.xml = TriggerPebbleBeachIntegrationUpdate.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{AABB6D87-3D71-4E9B-964C-C2327BE60CFA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TriggerPebbleBeachIntegrationUpdate_2", "TriggerPebbleBeachIntegrationUpdate_2\TriggerPebbleBeachIntegrationUpdate_2.csproj", "{5C73EE37-B28D-476A-825E-4EF73D0F6D80}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AssignRecordingResources", "AssignRecordingResources", "{25A7010F-FAAF-47FB-85F4-CBA5803D29FB}"
+ ProjectSection(SolutionItems) = preProject
+ AssignRecordingResources.xml = AssignRecordingResources.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{C430C499-9B05-46D5-A3F8-5BA3FB0FEC97}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssignRecordingResources_2", "AssignRecordingResources_2\AssignRecordingResources_2.csproj", "{61FCF96E-F3D6-4609-9D75-78D9582E692D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ClearReservations", "ClearReservations", "{7856E480-B1CB-4658-A2FB-ABA0C201A41F}"
+ ProjectSection(SolutionItems) = preProject
+ ClearReservations.xml = ClearReservations.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{0819B57C-7DC1-4766-88DE-2E6EE93100B8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClearReservations_2", "ClearReservations_2\ClearReservations_2.csproj", "{BF317DEB-2946-49C4-A6D2-3A0B4175AF64}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ClearExpiredServices", "ClearExpiredServices", "{8A254CA8-A07F-4729-9D33-0494853B734B}"
+ ProjectSection(SolutionItems) = preProject
+ ClearExpiredServices.xml = ClearExpiredServices.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{48443654-8823-499D-9FDA-B95460C5307C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClearExpiredServices_1", "ClearExpiredServices_1\ClearExpiredServices_1.csproj", "{951F433D-47BB-46CD-9577-38DC2EEF38F1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debug", "Debug", "{0EE07F7A-DE9B-4C55-A697-3A17B5D3E0B4}"
+ ProjectSection(SolutionItems) = preProject
+ Debug.xml = Debug.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{92896FB4-C0F8-4387-858D-A290CD242622}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Debug_2", "Debug_2\Debug_2.csproj", "{92B8FAFF-3EBC-4C12-91AB-71A8B6E0EC1C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DecodingResourceCapabilityUpdates", "DecodingResourceCapabilityUpdates", "{2EBD7821-313E-4099-B11E-A64208AF5828}"
+ ProjectSection(SolutionItems) = preProject
+ DecodingResourceCapabilityUpdates.xml = DecodingResourceCapabilityUpdates.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{D7AF3953-4C0F-4D48-9B9B-41CC9030C3CC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DecodingResourceCapabilityUpdates_1", "DecodingResourceCapabilityUpdates_1\DecodingResourceCapabilityUpdates_1.csproj", "{6C8B2D4E-6B4E-4F71-AA72-BF0BB37D6DAD}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DeleteIntegrationOrders", "DeleteIntegrationOrders", "{916C4EA8-832B-4A46-87E0-B7E791370E40}"
+ ProjectSection(SolutionItems) = preProject
+ DeleteIntegrationOrders.xml = DeleteIntegrationOrders.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{59C0DA6D-19D4-4558-99E4-214E303A4577}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeleteIntegrationOrders_1", "DeleteIntegrationOrders_1\DeleteIntegrationOrders_1.csproj", "{66B48A43-2EA8-4463-81B5-D842A49DBD73}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DeleteReservationsForCertainResource", "DeleteReservationsForCertainResource", "{B980A4D6-935E-4EBC-B2EA-6CCA456F7A58}"
+ ProjectSection(SolutionItems) = preProject
+ DeleteReservationsForCertainResource.xml = DeleteReservationsForCertainResource.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{5D0E2857-73F0-4629-8E2E-AE0697AD80D1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeleteReservationsForCertainResource_1", "DeleteReservationsForCertainResource_1\DeleteReservationsForCertainResource_1.csproj", "{30536342-FF9E-4B4E-8679-55DDF1583BCE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DeleteUnusedReservations", "DeleteUnusedReservations", "{BE0926CC-9242-4907-B7D9-DD44FA3DB846}"
+ ProjectSection(SolutionItems) = preProject
+ DeleteUnusedReservations.xml = DeleteUnusedReservations.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{483EBECF-595C-41E1-9133-F6823CAEAD21}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeleteUnusedReservations_1", "DeleteUnusedReservations_1\DeleteUnusedReservations_1.csproj", "{1A694B8E-C1E4-4BC2-A5F3-F658EB733EDB}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ForceDeleteOrder", "ForceDeleteOrder", "{2C0EA586-4767-4FD7-B994-7FD140C88410}"
+ ProjectSection(SolutionItems) = preProject
+ ForceDeleteOrder.xml = ForceDeleteOrder.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{921533E6-BAEC-4661-81D4-93379BC098C5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ForceDeleteOrder_1", "ForceDeleteOrder_1\ForceDeleteOrder_1.csproj", "{86177A39-B69B-40BC-AAA4-E5DDDCE80B54}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HandleEventAction", "HandleEventAction", "{6FE112DA-68F4-4478-B3D4-0998C796B069}"
+ ProjectSection(SolutionItems) = preProject
+ HandleEventAction.xml = HandleEventAction.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{9A6E6002-400C-4E20-B720-98E4C6C08C91}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HandleEventAction_3", "HandleEventAction_3\HandleEventAction_3.csproj", "{3FF581CD-E646-48CE-8611-159999784EDB}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HandleOrderAction", "HandleOrderAction", "{E08F12C4-FC31-46E7-8929-D588E0516D1E}"
+ ProjectSection(SolutionItems) = preProject
+ HandleOrderAction.xml = HandleOrderAction.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{A6FAE91B-BC05-4231-9B18-B77861456554}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HandleOrderAction_1", "HandleOrderAction_1\HandleOrderAction_1.csproj", "{6BDE17DC-A368-4EB8-9BA5-222E2E8469D1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HandleOrderStartFailure", "HandleOrderStartFailure", "{FB1CC579-E541-4CB9-B1B8-4F5DF7E9AC14}"
+ ProjectSection(SolutionItems) = preProject
+ HandleOrderStartFailure.xml = HandleOrderStartFailure.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{78A1EE8A-2B3C-48C5-B604-A769436714D6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HandleOrderStartFailure_1", "HandleOrderStartFailure_1\HandleOrderStartFailure_1.csproj", "{24C6898B-ACF8-4406-8767-4EB388950D3B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HandleRecurringOrderAction", "HandleRecurringOrderAction", "{B3B19CA3-CA80-4010-98E6-C175AA88B8CC}"
+ ProjectSection(SolutionItems) = preProject
+ HandleRecurringOrderAction.xml = HandleRecurringOrderAction.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{99767C82-2DC7-41C7-92F8-C92C28985A87}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HandleRecurringOrderAction_2", "HandleRecurringOrderAction_2\HandleRecurringOrderAction_2.csproj", "{2F80BDCE-7606-4F23-99CE-B980E1E8C70E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HandleServiceAction", "HandleServiceAction", "{3085F22A-78A0-4BF2-AF0D-5E2A0EC3B1FD}"
+ ProjectSection(SolutionItems) = preProject
+ HandleServiceAction.xml = HandleServiceAction.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{805B67FD-07D3-4B16-85E6-EA8039FE0C51}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HandleServiceAction_1", "HandleServiceAction_1\HandleServiceAction_1.csproj", "{C5A5B136-224B-43B4-B220-C677BF4D8294}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HandleServiceStartFailure", "HandleServiceStartFailure", "{1DC7633F-5218-4A44-963F-730CA81B66E2}"
+ ProjectSection(SolutionItems) = preProject
+ HandleServiceStartFailure.xml = HandleServiceStartFailure.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{E4806DB9-88E3-4192-8077-90047B8DD2A1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HandleServiceStartFailure_1", "HandleServiceStartFailure_1\HandleServiceStartFailure_1.csproj", "{DB1D40BF-6C1B-4565-B629-4647834B8F40}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LocalBackup", "LocalBackup", "{CF2C3F58-8A1E-48C4-ACA7-7D540DBEDD80}"
+ ProjectSection(SolutionItems) = preProject
+ LocalBackup.xml = LocalBackup.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{B34807AE-1728-48FE-8B3A-4FCC4DD8D40C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalBackup_1", "LocalBackup_1\LocalBackup_1.csproj", "{316025D1-B4C1-4053-87E4-34DC46FF7B23}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MatrixOutputLbandResourceCapabilityUpdates", "MatrixOutputLbandResourceCapabilityUpdates", "{CACFA014-FC77-4B94-827C-2B59DE04BE16}"
+ ProjectSection(SolutionItems) = preProject
+ MatrixOutputLbandResourceCapabilityUpdates.xml = MatrixOutputLbandResourceCapabilityUpdates.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{96787B73-62AA-4C09-B688-823A4E4FB6E2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixOutputLbandResourceCapabilityUpdates_1", "MatrixOutputLbandResourceCapabilityUpdates_1\MatrixOutputLbandResourceCapabilityUpdates_1.csproj", "{7808E16E-87A9-4D8C-82A5-BFBABBDD2C3C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ReleaseRecordingResources", "ReleaseRecordingResources", "{C6AEDC14-DF11-4B52-BB08-6FF557237010}"
+ ProjectSection(SolutionItems) = preProject
+ ReleaseRecordingResources.xml = ReleaseRecordingResources.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{F425D415-34EF-4A22-B010-F250131034F6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReleaseRecordingResources_2", "ReleaseRecordingResources_2\ReleaseRecordingResources_2.csproj", "{DD1FEF33-10CA-4DF2-872A-D8879A8302DA}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ResourceProvisioning", "ResourceProvisioning", "{C5965E3E-F9B7-457D-976B-FF198E971AEE}"
+ ProjectSection(SolutionItems) = preProject
+ ResourceProvisioning.xml = ResourceProvisioning.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{BC476C0E-2947-47EE-B395-69D71D46C179}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceProvisioning_1", "ResourceProvisioning_1\ResourceProvisioning_1.csproj", "{1098672C-C215-4912-AB71-906E6176A4AA}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UpdateOrdersAfterUserTaskStatusChange", "UpdateOrdersAfterUserTaskStatusChange", "{4254A869-193E-4AD5-B403-AA628B30E75D}"
+ ProjectSection(SolutionItems) = preProject
+ UpdateOrdersAfterUserTaskStatusChange.xml = UpdateOrdersAfterUserTaskStatusChange.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{5C8BC972-E212-4ACD-BF34-AC11F29372F2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateOrdersAfterUserTaskStatusChange_4", "UpdateOrdersAfterUserTaskStatusChange_4\UpdateOrdersAfterUserTaskStatusChange_4.csproj", "{F932902B-7C87-4E8A-B43D-FEAABBB1AB2A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UpdateVisibilityRights", "UpdateVisibilityRights", "{AEA3EB59-34FB-455C-AD80-C93186A5BE8D}"
+ ProjectSection(SolutionItems) = preProject
+ UpdateVisibilityRights.xml = UpdateVisibilityRights.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{7E3CABB1-B098-486F-BBF9-93138E58E1B6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateVisibilityRights_1", "UpdateVisibilityRights_1\UpdateVisibilityRights_1.csproj", "{21DD38E0-3B0C-4F3E-B7B2-77869FB5471D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NonLiveLocalBackup", "NonLiveLocalBackup", "{EEA6E326-AAF9-4772-B4C1-AECF9FADAA19}"
+ ProjectSection(SolutionItems) = preProject
+ NonLiveLocalBackup.xml = NonLiveLocalBackup.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{BAA404DB-39D2-41E4-AC87-4DE55BE7B346}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NonLiveLocalBackup_1", "NonLiveLocalBackup_1\NonLiveLocalBackup_1.csproj", "{096D90EF-4ABC-40B4-85D1-E813969C40D1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UI", "UI", "{E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Integrations", "Integrations", "{000361F4-B47A-430A-A0C2-0A7086A31436}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SRM", "SRM", "{1387AD44-A709-427B-8B95-2262C0284BE5}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{67FCA1BE-D816-4972-9138-F74F39F3A158}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HandleIntegrationUpdate", "HandleIntegrationUpdate", "{50BD1A91-4AE4-4595-A3E5-C3CCB29C222A}"
+ ProjectSection(SolutionItems) = preProject
+ HandleIntegrationUpdate.xml = HandleIntegrationUpdate.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{6BFD42BE-5AB6-484B-9751-18184B4602A1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HandleIntegrationUpdate_4", "HandleIntegrationUpdate_4\HandleIntegrationUpdate_4.csproj", "{10DE679A-E842-4227-8120-AB0D91F02C3B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Configure Ticketing Colors", "Configure Ticketing Colors", "{08A830E5-212D-4BB4-8ABA-0C22368496AC}"
+ ProjectSection(SolutionItems) = preProject
+ Configure Ticketing Colors.xml = Configure Ticketing Colors.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{0485686F-900D-4D21-9ED6-60CB21E3F0D4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Configure Ticketing Colors_1", "Configure Ticketing Colors_1\Configure Ticketing Colors_1.csproj", "{161D23AA-B910-4826-984E-5F71E6115F3C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AggregateMetrics", "AggregateMetrics", "{704C4816-BDEA-47B7-94A7-00F3E19BD47E}"
+ ProjectSection(SolutionItems) = preProject
+ AggregateMetrics.xml = AggregateMetrics.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{7467768D-4858-4847-9A5B-97ECB096EFE8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AggregateMetrics_1", "AggregateMetrics_1\AggregateMetrics_1.csproj", "{8F19C132-61E2-4351-AC47-4653E86D7456}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RunLogCollector", "RunLogCollector", "{8E9348FF-4214-4BFE-953F-E564A2C01DFD}"
+ ProjectSection(SolutionItems) = preProject
+ RunLogCollector.xml = RunLogCollector.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{7D0320C0-C6C2-45F5-8F14-EA15BB063A90}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RunLogCollector_1", "RunLogCollector_1\RunLogCollector_1.csproj", "{CE704EE3-FC1E-48D5-A9FF-13ACB9C2E529}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UpdateServiceStatus", "UpdateServiceStatus", "{01B3171D-AF96-4796-8388-8649053CF04E}"
+ ProjectSection(SolutionItems) = preProject
+ UpdateServiceStatus.xml = UpdateServiceStatus.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{313BAE04-DBEC-4EE2-ACF3-D85D8C8798C5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateServiceStatus_1", "UpdateServiceStatus_1\UpdateServiceStatus_1.csproj", "{15344920-AE73-4C0A-AEB2-7D75748B791E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UpdateOrderStatus", "UpdateOrderStatus", "{DE565C75-358D-43AF-82FA-0A70925FFFB4}"
+ ProjectSection(SolutionItems) = preProject
+ UpdateOrderStatus.xml = UpdateOrderStatus.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{1CDBE1A6-3E5B-4FBE-B98F-5705633BFE9C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateOrderStatus_1", "UpdateOrderStatus_1\UpdateOrderStatus_1.csproj", "{39664900-A87E-4A6D-8BFA-EAC97F5892ED}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UpdateOrderServiceDefinitionActions", "UpdateOrderServiceDefinitionActions", "{F9D1F2B5-1B82-4B5F-A65A-18EA75F38457}"
+ ProjectSection(SolutionItems) = preProject
+ UpdateOrderServiceDefinitionActions.xml = UpdateOrderServiceDefinitionActions.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{93D303A0-945B-403E-82D4-AC8E2CA4463F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateOrderServiceDefinitionActions_1", "UpdateOrderServiceDefinitionActions_1\UpdateOrderServiceDefinitionActions_1.csproj", "{EBDF3AD9-BE1C-43B3-ADE4-2336DE09355E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ExportServiceDefinitions", "ExportServiceDefinitions", "{471F09E3-9BA6-43AB-A8F1-359D797FD136}"
+ ProjectSection(SolutionItems) = preProject
+ ExportServiceDefinitions.xml = ExportServiceDefinitions.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{DCB5C4A9-9AA5-413D-A4AA-CBBB66A0262E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExportServiceDefinitions_1", "ExportServiceDefinitions_1\ExportServiceDefinitions_1.csproj", "{54B5632D-C113-4383-913E-2701501D951D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ExportProfileDefinitions", "ExportProfileDefinitions", "{1DC34F9A-8397-4B6D-8B13-175A850DECFB}"
+ ProjectSection(SolutionItems) = preProject
+ ExportProfileDefinitions.xml = ExportProfileDefinitions.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{E98FBEDE-0103-4D38-8A72-92FAE634C67E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExportProfileDefinitions_1", "ExportProfileDefinitions_1\ExportProfileDefinitions_1.csproj", "{54742C48-894C-4B28-B0D6-BF4F6CE7E76B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ExportResourcePools", "ExportResourcePools", "{6D68EB04-A8B4-4843-A20E-5BFC4F07923B}"
+ ProjectSection(SolutionItems) = preProject
+ ExportResourcePools.xml = ExportResourcePools.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{477D4BB3-CA8F-4CB3-AD08-CD84CBF4215E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExportResourcePools_1", "ExportResourcePools_1\ExportResourcePools_1.csproj", "{60637559-5F48-44A1-B1F6-16AEA6B1BA01}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LoggingCleanup", "LoggingCleanup", "{4EB973CF-9705-442F-AA83-7DBE73B010D0}"
+ ProjectSection(SolutionItems) = preProject
+ LoggingCleanup.xml = LoggingCleanup.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{86C29745-85F2-4F63-9CBB-EF0F364E3633}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoggingCleanup_1", "LoggingCleanup_1\LoggingCleanup_1.csproj", "{A4619E76-5B45-4B85-B305-FD99A80EAAFF}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RemoveOldServices", "RemoveOldServices", "{E12EF30F-3FD3-4A97-8BBD-FC008108298D}"
+ ProjectSection(SolutionItems) = preProject
+ RemoveOldServices.xml = RemoveOldServices.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{77EB4E23-F3B6-4259-8A37-68ADDEC79FA3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoveOldServices_1", "RemoveOldServices_1\RemoveOldServices_1.csproj", "{A0D587EC-3860-41A7-A648-ABDE1DBB2B01}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ViewTicket", "ViewTicket", "{FA0D3054-CC09-4B44-BE75-A4BBA43CF568}"
+ ProjectSection(SolutionItems) = preProject
+ ViewTicket.xml = ViewTicket.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{FE9B754D-0964-43E7-B284-E5BFCE219339}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ViewTicket_1", "ViewTicket_1\ViewTicket_1.csproj", "{AEDA5B3F-0DD4-4F00-AD27-9C74E7B58E4A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MigrateResourcesYLE", "MigrateResourcesYLE", "{761F0B1D-C5E2-4B7F-9757-2569DE22242C}"
+ ProjectSection(SolutionItems) = preProject
+ MigrateResourcesYLE.xml = MigrateResourcesYLE.xml
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MigrateResourcesYLE_1", "MigrateResourcesYLE_1\MigrateResourcesYLE_1.csproj", "{1346E39C-2A3C-45F3-B3F1-7BC486BC6C3F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{7CE65D69-9B3F-4CA8-9837-75BCB4E3F083}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RemoveIntegrationOrders", "RemoveIntegrationOrders", "{44497CF8-959A-44C6-A40B-E517BC2376A6}"
+ ProjectSection(SolutionItems) = preProject
+ RemoveIntegrationOrders.xml = RemoveIntegrationOrders.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{9357F636-7980-46DF-8AE1-967D9B52D4C7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoveIntegrationOrders_1", "RemoveIntegrationOrders_1\RemoveIntegrationOrders_1.csproj", "{136DFCD0-EEC3-4856-88FC-875549E69567}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ForceDeleteResource", "ForceDeleteResource", "{AA4DF06F-0801-4132-8993-A5BED221A9F2}"
+ ProjectSection(SolutionItems) = preProject
+ ForceDeleteResource.xml = ForceDeleteResource.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{D73D3AA8-4D8A-4820-B62C-9BB9F0C0CB3A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ForceDeleteResource_1", "ForceDeleteResource_1\ForceDeleteResource_1.csproj", "{BB6E867B-D3C5-4EB8-8A08-919A8E530753}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SendNonLiveDeletionReminders", "SendNonLiveDeletionReminders", "{8564D43C-9FD5-4B61-86F6-5F1DE20B072E}"
+ ProjectSection(SolutionItems) = preProject
+ SendNonLiveDeletionReminders.xml = SendNonLiveDeletionReminders.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{CC2F9BCC-C904-4EC8-A7D6-B45B3FC6946E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SendNonLiveDeletionReminders_1", "SendNonLiveDeletionReminders_1\SendNonLiveDeletionReminders_1.csproj", "{1BE80F2C-F652-4E36-8DA3-EFFD46BEC8AA}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HandleNonLiveFolderDeletion", "HandleNonLiveFolderDeletion", "{21586975-5E83-42BD-BDB0-B34FCD5B734A}"
+ ProjectSection(SolutionItems) = preProject
+ HandleNonLiveFolderDeletion.xml = HandleNonLiveFolderDeletion.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{0B90312C-7E10-4C6F-B3EC-C580BAD0FFE9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HandleNonLiveFolderDeletion_1", "HandleNonLiveFolderDeletion_1\HandleNonLiveFolderDeletion_1.csproj", "{650813DD-F043-4C38-B235-4F2986B96DF4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UpdateNonLiveUserTask", "UpdateNonLiveUserTask", "{653A4FE9-34F5-4248-AD24-2113A58731B4}"
+ ProjectSection(SolutionItems) = preProject
+ UpdateNonLiveUserTask.xml = UpdateNonLiveUserTask.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{6E66E383-08AD-49AD-AE98-062EF74A2D0A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateNonLiveUserTask_1", "UpdateNonLiveUserTask_1\UpdateNonLiveUserTask_1.csproj", "{E064C30A-5B7D-4253-B3F2-A2172F4DBF7D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibraryTests", "UnitTestProject\LibraryTests.csproj", "{F4511D97-994D-4393-BE3D-178C0DC1301A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ShowOrderHistory", "ShowOrderHistory", "{83AD0011-B9F9-41CE-993A-C82BEC443354}"
+ ProjectSection(SolutionItems) = preProject
+ ShowOrderHistory.xml = ShowOrderHistory.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{B16C0689-BE91-4470-867C-29CD41BECBE3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShowOrderHistory_1", "ShowOrderHistory_1\ShowOrderHistory_1.csproj", "{E340800D-3FCB-4389-8E95-39454110F40A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CustomerUiLauncher", "CustomerUiLauncher", "{5658AB3B-3A50-4586-B407-D028CA678ADE}"
+ ProjectSection(SolutionItems) = preProject
+ CustomerUiLauncher.xml = CustomerUiLauncher.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{FB7BBE6E-9121-415B-ACAC-FE412DF3CE41}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CreateInvoiceReport", "CreateInvoiceReport", "{450B0EA2-2AFF-4CBF-9ED0-B3F230C33621}"
+ ProjectSection(SolutionItems) = preProject
+ CreateInvoiceReport.xml = CreateInvoiceReport.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{AD67A5A6-BA20-4F9E-83C7-1D0AFB9091C2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreateInvoiceReport_1", "CreateInvoiceReport_1\CreateInvoiceReport_1.csproj", "{8262B019-389D-4E9A-9EE4-606D3F2023FC}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AddService", "AddService", "{FA87E4AC-AFBE-4811-848E-EF6AED874F59}"
+ ProjectSection(SolutionItems) = preProject
+ AddService.xml = AddService.xml
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddService_1", "AddService_1\AddService_1.csproj", "{CB5B8A98-2204-4F53-A8A8-B6BB32E85F64}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{AA75ECB6-3554-4CD6-A240-53637B392904}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{ED714ADB-432F-456C-B767-06576666A43B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Code Analysis", "Code Analysis", "{B572C23F-1A8A-4514-A785-CF1C717691EB}"
+ ProjectSection(SolutionItems) = preProject
+ Internal\Code Analysis\qaction-debug.ruleset = Internal\Code Analysis\qaction-debug.ruleset
+ Internal\Code Analysis\qaction-release.ruleset = Internal\Code Analysis\qaction-release.ruleset
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ReprocessOrders", "ReprocessOrders", "{31293883-B73F-4DA8-9BA2-4A9930B44AA2}"
+ ProjectSection(SolutionItems) = preProject
+ ReprocessOrders.xml = ReprocessOrders.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{35CDF4F0-89D5-463D-B3BA-628F032DDCDC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReprocessOrders_1", "ReprocessOrders_1\ReprocessOrders_1.csproj", "{C99CFF53-B1BD-4FAA-A285-3C149CACE44F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StopOrder", "StopOrder", "{06C10087-A052-40BD-8101-18DB37909B14}"
+ ProjectSection(SolutionItems) = preProject
+ StopOrder.xml = StopOrder.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{19D8C4FC-AE55-436B-BC9A-EDBB80B27822}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomerUI_Launcher_2", "CustomerUI_Launcher_2\CustomerUI_Launcher_2.csproj", "{AE455D02-0572-43BA-B213-4D6BF8EDD37B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MigrateResourcesInBulkYLE", "MigrateResourcesInBulkYLE", "{83888528-487F-4071-8605-151E4F586C78}"
+ ProjectSection(SolutionItems) = preProject
+ MigrateResourcesInBulkYLE.xml = MigrateResourcesInBulkYLE.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{5A8BECBC-089B-4425-BE29-AB6F2750DAC6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MigrateResourcesInBulkYLE_1", "MigrateResourcesInBulkYLE_1\MigrateResourcesInBulkYLE_1.csproj", "{CE011088-8685-47FC-8274-2141025946D2}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ProfileLoadScripts", "ProfileLoadScripts", "{2D9E833E-0229-4DA6-BC6C-2A039E925176}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PLS_EricssonRX8200_Decoding", "PLS_EricssonRX8200_Decoding", "{7E38EF2C-F2CD-40A4-9052-F5472E30CBDC}"
+ ProjectSection(SolutionItems) = preProject
+ PLS_EricssonRX8200_Decoding.xml = PLS_EricssonRX8200_Decoding.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{F85E1F14-3D62-4F7A-BEB2-B73AA16BB2F8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PLS_EricssonRX8200_Decoding_1", "PLS_EricssonRX8200_Decoding_1\PLS_EricssonRX8200_Decoding_1.csproj", "{40244095-2B04-407C-AF92-CED881D0429D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PLS_EricssonRX8200_Demodulating", "PLS_EricssonRX8200_Demodulating", "{197C8362-EB09-4F2C-A70B-2D29E5F04D21}"
+ ProjectSection(SolutionItems) = preProject
+ PLS_EricssonRX8200_Demodulating.xml = PLS_EricssonRX8200_Demodulating.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{4B4DE002-28B5-4E4A-AD2F-837DF34D5F2F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PLS_EricssonRX8200_Demodulating_1", "PLS_EricssonRX8200_Demodulating_1\PLS_EricssonRX8200_Demodulating_1.csproj", "{BAB2ACB4-1914-48FB-B141-A52C85FBDDC1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ExportSrm", "ExportSrm", "{CA1F8B6F-2EA4-4A7C-B468-190B7C76E97B}"
+ ProjectSection(SolutionItems) = preProject
+ ExportSrm.xml = ExportSrm.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{F623050B-10E1-407E-91F4-0AE24EE144FB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExportSrm_1", "ExportSrm_1\ExportSrm_1.csproj", "{E6720C0D-274D-4AEF-A45E-897EBDCE0911}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StopOrder", "StopOrder_1\StopOrder.csproj", "{CEBDD8CA-8AC5-41B2-95CE-21EDA9D38AFF}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{57375AE4-BFE0-4D8A-8D76-27AF0FA5479E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EditOrderTemplate", "EditOrderTemplate", "{644EE9B7-3883-4C1A-900C-0A3217CD5122}"
+ ProjectSection(SolutionItems) = preProject
+ EditOrderTemplate.xml = EditOrderTemplate.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{5EF9AA74-6CD0-4FC4-8D8F-19BECE6D5041}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EditOrderTemplate_1", "EditOrderTemplate_1\EditOrderTemplate_1.csproj", "{3BCB9CBC-A3EE-4493-B605-6EBE559F295A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ConfigureContractManager", "ConfigureContractManager", "{C66C3B0F-2B02-414E-A02C-20E40E4323CA}"
+ ProjectSection(SolutionItems) = preProject
+ ConfigureContractManager.xml = ConfigureContractManager.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{38F41597-6448-4CB2-A73B-457C53354FD6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfigureContractManager_1", "ConfigureContractManager_1\ConfigureContractManager_1.csproj", "{5D786C6B-2A75-440B-A1FB-C077E8B8B898}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SetElementCustomProperty", "SetElementCustomProperty", "{BBF714D6-0319-4D28-B531-BD06728F5E4F}"
+ ProjectSection(SolutionItems) = preProject
+ SetElementCustomProperty.xml = SetElementCustomProperty.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{09CDBAFA-14B3-4C0D-A604-56AB25627D75}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SetElementCustomProperty_1", "SetElementCustomProperty_1\SetElementCustomProperty_1.csproj", "{9F5AFB87-3F4F-40A9-A76F-BFC6C78BD59B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NonLiveOrderAndNotesCleanup", "NonLiveOrderAndNotesCleanup", "{ECD7B20D-BB60-447D-9379-CB231CED783D}"
+ ProjectSection(SolutionItems) = preProject
+ NonLiveOrderAndNotesCleanup.xml = NonLiveOrderAndNotesCleanup.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{99DE7371-2C7F-49CB-BE2D-03C2C6DB4ABB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NonLiveOrderAndNotesCleanup_1", "NonLiveOrderAndNotesCleanup_1\NonLiveOrderAndNotesCleanup_1.csproj", "{394C3304-3228-4F16-AD8A-06D7B32A3D46}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Library", "Library", "{6337C220-C88D-40F6-8430-5D587AAAA6E1}"
+ ProjectSection(SolutionItems) = preProject
+ Library.xml = Library.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{1A8EC1C6-6712-4C84-9495-1E6B9C7C0695}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Library_1", "Library_1\Library_1.csproj", "{121DD302-DF4B-4F49-B6F9-B3AD358BD842}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnassignTicket", "UnassignTicket", "{9184AD19-8580-4A8F-8220-8A679639C57F}"
+ ProjectSection(SolutionItems) = preProject
+ UnassignTicket.xml = UnassignTicket.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{D1E71180-9B7B-40BB-831D-48BB98F0A834}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnassignTicket_1", "UnassignTicket_1\UnassignTicket_1.csproj", "{033DCC6B-9081-4119-8F9E-F51B834992CC}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NonLiveUserTasksBulkUpdate", "NonLiveUserTasksBulkUpdate", "{A1466055-9F55-4B87-8D6F-323E4F0EA85C}"
+ ProjectSection(SolutionItems) = preProject
+ NonLiveUserTasksBulkUpdate.xml = NonLiveUserTasksBulkUpdate.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{06F7B8FB-7357-4F31-93CF-E76050F07224}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NonLiveUserTasksBulkUpdate_1", "NonLiveUserTasksBulkUpdate_1\NonLiveUserTasksBulkUpdate_1.csproj", "{4AC66D72-FD8B-40B3-9236-C76F97FFD487}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PLS_NovelsatNS2000_Demodulating", "PLS_NovelsatNS2000_Demodulating", "{72128F4D-352C-4DEF-BA5A-DAB4A2A7CC93}"
+ ProjectSection(SolutionItems) = preProject
+ PLS_NovelsatNS2000_Demodulating.xml = PLS_NovelsatNS2000_Demodulating.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{B257C040-9707-4DF4-93BB-F7151D0C0702}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PLS_NovelsatNS2000_Demodulating_1", "PLS_NovelsatNS2000_Demodulating_1\PLS_NovelsatNS2000_Demodulating_1.csproj", "{130FBF70-7031-4F7C-92AC-2C616442F18D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileRetrieval", "FileRetrieval", "{50494B33-0532-42E6-AF1F-05BA2F7B8D81}"
+ ProjectSection(SolutionItems) = preProject
+ FileRetrieval.xml = FileRetrieval.xml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actions", "Actions", "{B7B98608-DFC0-47A9-AA5A-760D948D7DE1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileRetrieval_1", "FileRetrieval_1\FileRetrieval_1.csproj", "{56BC6E17-FC0B-4AB5-BFB2-B92344E707FA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8EBFE2CE-07A1-45F6-85AC-8023014A0A8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8EBFE2CE-07A1-45F6-85AC-8023014A0A8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8EBFE2CE-07A1-45F6-85AC-8023014A0A8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8EBFE2CE-07A1-45F6-85AC-8023014A0A8A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {880203DF-F9E6-4888-9978-A2FBE22BD25A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {880203DF-F9E6-4888-9978-A2FBE22BD25A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {880203DF-F9E6-4888-9978-A2FBE22BD25A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {880203DF-F9E6-4888-9978-A2FBE22BD25A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E5C344F3-4239-4F98-BF5B-642646B0A68A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E5C344F3-4239-4F98-BF5B-642646B0A68A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E5C344F3-4239-4F98-BF5B-642646B0A68A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E5C344F3-4239-4F98-BF5B-642646B0A68A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CD8CA3A7-2D4D-416A-BB82-76279B1843C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CD8CA3A7-2D4D-416A-BB82-76279B1843C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CD8CA3A7-2D4D-416A-BB82-76279B1843C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CD8CA3A7-2D4D-416A-BB82-76279B1843C2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6846E9D4-264E-4FFD-876D-88BFBDAFE69F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6846E9D4-264E-4FFD-876D-88BFBDAFE69F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6846E9D4-264E-4FFD-876D-88BFBDAFE69F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6846E9D4-264E-4FFD-876D-88BFBDAFE69F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E10BD658-9B0E-4A95-97B7-C288C429C094}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E10BD658-9B0E-4A95-97B7-C288C429C094}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E10BD658-9B0E-4A95-97B7-C288C429C094}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E10BD658-9B0E-4A95-97B7-C288C429C094}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CFA4A2CE-A230-4303-83B1-677B23B66266}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CFA4A2CE-A230-4303-83B1-677B23B66266}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CFA4A2CE-A230-4303-83B1-677B23B66266}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CFA4A2CE-A230-4303-83B1-677B23B66266}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7F6A3EC0-1B12-4F2A-B0F8-1EBA1C113460}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7F6A3EC0-1B12-4F2A-B0F8-1EBA1C113460}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7F6A3EC0-1B12-4F2A-B0F8-1EBA1C113460}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7F6A3EC0-1B12-4F2A-B0F8-1EBA1C113460}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E69808C1-8776-4055-8385-05CCE596C4E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E69808C1-8776-4055-8385-05CCE596C4E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E69808C1-8776-4055-8385-05CCE596C4E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E69808C1-8776-4055-8385-05CCE596C4E5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {98F1FA3D-7B10-4178-A6A4-41F6958CCBE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {98F1FA3D-7B10-4178-A6A4-41F6958CCBE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {98F1FA3D-7B10-4178-A6A4-41F6958CCBE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {98F1FA3D-7B10-4178-A6A4-41F6958CCBE5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A90B225A-0F85-416B-9CE8-EEBDF2929BC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A90B225A-0F85-416B-9CE8-EEBDF2929BC4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A90B225A-0F85-416B-9CE8-EEBDF2929BC4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A90B225A-0F85-416B-9CE8-EEBDF2929BC4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {48F1B70D-8C96-49BA-B4A2-957377393EEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {48F1B70D-8C96-49BA-B4A2-957377393EEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {48F1B70D-8C96-49BA-B4A2-957377393EEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {48F1B70D-8C96-49BA-B4A2-957377393EEF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C11D6283-7A34-4CDD-8C27-65F8499E5CFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C11D6283-7A34-4CDD-8C27-65F8499E5CFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C11D6283-7A34-4CDD-8C27-65F8499E5CFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C11D6283-7A34-4CDD-8C27-65F8499E5CFE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C37BA915-33E8-48C6-9098-6681EE54884D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C37BA915-33E8-48C6-9098-6681EE54884D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C37BA915-33E8-48C6-9098-6681EE54884D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C37BA915-33E8-48C6-9098-6681EE54884D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2C70A6EE-70B7-42C0-8C0B-66C690AB8C87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2C70A6EE-70B7-42C0-8C0B-66C690AB8C87}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2C70A6EE-70B7-42C0-8C0B-66C690AB8C87}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2C70A6EE-70B7-42C0-8C0B-66C690AB8C87}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F44EB030-BD0E-42AB-82BD-5E7E0F530A24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F44EB030-BD0E-42AB-82BD-5E7E0F530A24}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F44EB030-BD0E-42AB-82BD-5E7E0F530A24}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F44EB030-BD0E-42AB-82BD-5E7E0F530A24}.Release|Any CPU.Build.0 = Release|Any CPU
+ {96C98AA8-D5D5-4F3D-AC36-DFB044A10283}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {96C98AA8-D5D5-4F3D-AC36-DFB044A10283}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {96C98AA8-D5D5-4F3D-AC36-DFB044A10283}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {96C98AA8-D5D5-4F3D-AC36-DFB044A10283}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D3966891-3616-427F-BC24-CEBAD4B3B6BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D3966891-3616-427F-BC24-CEBAD4B3B6BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D3966891-3616-427F-BC24-CEBAD4B3B6BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D3966891-3616-427F-BC24-CEBAD4B3B6BE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FAFEE1DA-438D-4D7F-91B1-9BB2444DB30E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FAFEE1DA-438D-4D7F-91B1-9BB2444DB30E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FAFEE1DA-438D-4D7F-91B1-9BB2444DB30E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FAFEE1DA-438D-4D7F-91B1-9BB2444DB30E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DA97B418-6D04-4FA2-8214-6FE3113E02C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DA97B418-6D04-4FA2-8214-6FE3113E02C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DA97B418-6D04-4FA2-8214-6FE3113E02C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DA97B418-6D04-4FA2-8214-6FE3113E02C7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DD92F97D-EA78-4377-8DB7-63D1C6048670}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DD92F97D-EA78-4377-8DB7-63D1C6048670}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DD92F97D-EA78-4377-8DB7-63D1C6048670}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DD92F97D-EA78-4377-8DB7-63D1C6048670}.Release|Any CPU.Build.0 = Release|Any CPU
+ {891D09C7-E16C-4467-BDEE-BDAAB5552B7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {891D09C7-E16C-4467-BDEE-BDAAB5552B7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {891D09C7-E16C-4467-BDEE-BDAAB5552B7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {891D09C7-E16C-4467-BDEE-BDAAB5552B7A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A3B23699-5387-4266-B784-C7AE207E6923}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A3B23699-5387-4266-B784-C7AE207E6923}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A3B23699-5387-4266-B784-C7AE207E6923}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A3B23699-5387-4266-B784-C7AE207E6923}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BA41DE74-F49C-4C07-A83D-2317566E7808}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BA41DE74-F49C-4C07-A83D-2317566E7808}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BA41DE74-F49C-4C07-A83D-2317566E7808}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BA41DE74-F49C-4C07-A83D-2317566E7808}.Release|Any CPU.Build.0 = Release|Any CPU
+ {80B82340-D9C3-431F-9B22-947F6DDAE0F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {80B82340-D9C3-431F-9B22-947F6DDAE0F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {80B82340-D9C3-431F-9B22-947F6DDAE0F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {80B82340-D9C3-431F-9B22-947F6DDAE0F6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {74B56470-25B2-4846-810D-53560F6EB5F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {74B56470-25B2-4846-810D-53560F6EB5F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {74B56470-25B2-4846-810D-53560F6EB5F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {74B56470-25B2-4846-810D-53560F6EB5F1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5C73EE37-B28D-476A-825E-4EF73D0F6D80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5C73EE37-B28D-476A-825E-4EF73D0F6D80}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5C73EE37-B28D-476A-825E-4EF73D0F6D80}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5C73EE37-B28D-476A-825E-4EF73D0F6D80}.Release|Any CPU.Build.0 = Release|Any CPU
+ {61FCF96E-F3D6-4609-9D75-78D9582E692D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {61FCF96E-F3D6-4609-9D75-78D9582E692D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {61FCF96E-F3D6-4609-9D75-78D9582E692D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {61FCF96E-F3D6-4609-9D75-78D9582E692D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BF317DEB-2946-49C4-A6D2-3A0B4175AF64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BF317DEB-2946-49C4-A6D2-3A0B4175AF64}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BF317DEB-2946-49C4-A6D2-3A0B4175AF64}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BF317DEB-2946-49C4-A6D2-3A0B4175AF64}.Release|Any CPU.Build.0 = Release|Any CPU
+ {951F433D-47BB-46CD-9577-38DC2EEF38F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {951F433D-47BB-46CD-9577-38DC2EEF38F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {951F433D-47BB-46CD-9577-38DC2EEF38F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {951F433D-47BB-46CD-9577-38DC2EEF38F1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {92B8FAFF-3EBC-4C12-91AB-71A8B6E0EC1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {92B8FAFF-3EBC-4C12-91AB-71A8B6E0EC1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {92B8FAFF-3EBC-4C12-91AB-71A8B6E0EC1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {92B8FAFF-3EBC-4C12-91AB-71A8B6E0EC1C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6C8B2D4E-6B4E-4F71-AA72-BF0BB37D6DAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6C8B2D4E-6B4E-4F71-AA72-BF0BB37D6DAD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6C8B2D4E-6B4E-4F71-AA72-BF0BB37D6DAD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6C8B2D4E-6B4E-4F71-AA72-BF0BB37D6DAD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {66B48A43-2EA8-4463-81B5-D842A49DBD73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {66B48A43-2EA8-4463-81B5-D842A49DBD73}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {66B48A43-2EA8-4463-81B5-D842A49DBD73}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {66B48A43-2EA8-4463-81B5-D842A49DBD73}.Release|Any CPU.Build.0 = Release|Any CPU
+ {30536342-FF9E-4B4E-8679-55DDF1583BCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {30536342-FF9E-4B4E-8679-55DDF1583BCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {30536342-FF9E-4B4E-8679-55DDF1583BCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {30536342-FF9E-4B4E-8679-55DDF1583BCE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1A694B8E-C1E4-4BC2-A5F3-F658EB733EDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1A694B8E-C1E4-4BC2-A5F3-F658EB733EDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1A694B8E-C1E4-4BC2-A5F3-F658EB733EDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1A694B8E-C1E4-4BC2-A5F3-F658EB733EDB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {86177A39-B69B-40BC-AAA4-E5DDDCE80B54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {86177A39-B69B-40BC-AAA4-E5DDDCE80B54}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {86177A39-B69B-40BC-AAA4-E5DDDCE80B54}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {86177A39-B69B-40BC-AAA4-E5DDDCE80B54}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3FF581CD-E646-48CE-8611-159999784EDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3FF581CD-E646-48CE-8611-159999784EDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3FF581CD-E646-48CE-8611-159999784EDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3FF581CD-E646-48CE-8611-159999784EDB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6BDE17DC-A368-4EB8-9BA5-222E2E8469D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6BDE17DC-A368-4EB8-9BA5-222E2E8469D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6BDE17DC-A368-4EB8-9BA5-222E2E8469D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6BDE17DC-A368-4EB8-9BA5-222E2E8469D1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {24C6898B-ACF8-4406-8767-4EB388950D3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {24C6898B-ACF8-4406-8767-4EB388950D3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {24C6898B-ACF8-4406-8767-4EB388950D3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {24C6898B-ACF8-4406-8767-4EB388950D3B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2F80BDCE-7606-4F23-99CE-B980E1E8C70E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2F80BDCE-7606-4F23-99CE-B980E1E8C70E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2F80BDCE-7606-4F23-99CE-B980E1E8C70E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2F80BDCE-7606-4F23-99CE-B980E1E8C70E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C5A5B136-224B-43B4-B220-C677BF4D8294}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C5A5B136-224B-43B4-B220-C677BF4D8294}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C5A5B136-224B-43B4-B220-C677BF4D8294}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C5A5B136-224B-43B4-B220-C677BF4D8294}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DB1D40BF-6C1B-4565-B629-4647834B8F40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DB1D40BF-6C1B-4565-B629-4647834B8F40}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DB1D40BF-6C1B-4565-B629-4647834B8F40}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DB1D40BF-6C1B-4565-B629-4647834B8F40}.Release|Any CPU.Build.0 = Release|Any CPU
+ {316025D1-B4C1-4053-87E4-34DC46FF7B23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {316025D1-B4C1-4053-87E4-34DC46FF7B23}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {316025D1-B4C1-4053-87E4-34DC46FF7B23}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {316025D1-B4C1-4053-87E4-34DC46FF7B23}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7808E16E-87A9-4D8C-82A5-BFBABBDD2C3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7808E16E-87A9-4D8C-82A5-BFBABBDD2C3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7808E16E-87A9-4D8C-82A5-BFBABBDD2C3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7808E16E-87A9-4D8C-82A5-BFBABBDD2C3C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DD1FEF33-10CA-4DF2-872A-D8879A8302DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DD1FEF33-10CA-4DF2-872A-D8879A8302DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DD1FEF33-10CA-4DF2-872A-D8879A8302DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DD1FEF33-10CA-4DF2-872A-D8879A8302DA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1098672C-C215-4912-AB71-906E6176A4AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1098672C-C215-4912-AB71-906E6176A4AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1098672C-C215-4912-AB71-906E6176A4AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1098672C-C215-4912-AB71-906E6176A4AA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F932902B-7C87-4E8A-B43D-FEAABBB1AB2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F932902B-7C87-4E8A-B43D-FEAABBB1AB2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F932902B-7C87-4E8A-B43D-FEAABBB1AB2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F932902B-7C87-4E8A-B43D-FEAABBB1AB2A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {21DD38E0-3B0C-4F3E-B7B2-77869FB5471D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {21DD38E0-3B0C-4F3E-B7B2-77869FB5471D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {21DD38E0-3B0C-4F3E-B7B2-77869FB5471D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {21DD38E0-3B0C-4F3E-B7B2-77869FB5471D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {096D90EF-4ABC-40B4-85D1-E813969C40D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {096D90EF-4ABC-40B4-85D1-E813969C40D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {096D90EF-4ABC-40B4-85D1-E813969C40D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {096D90EF-4ABC-40B4-85D1-E813969C40D1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {10DE679A-E842-4227-8120-AB0D91F02C3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {10DE679A-E842-4227-8120-AB0D91F02C3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {10DE679A-E842-4227-8120-AB0D91F02C3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {10DE679A-E842-4227-8120-AB0D91F02C3B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {161D23AA-B910-4826-984E-5F71E6115F3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {161D23AA-B910-4826-984E-5F71E6115F3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {161D23AA-B910-4826-984E-5F71E6115F3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {161D23AA-B910-4826-984E-5F71E6115F3C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8F19C132-61E2-4351-AC47-4653E86D7456}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8F19C132-61E2-4351-AC47-4653E86D7456}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8F19C132-61E2-4351-AC47-4653E86D7456}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8F19C132-61E2-4351-AC47-4653E86D7456}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CE704EE3-FC1E-48D5-A9FF-13ACB9C2E529}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CE704EE3-FC1E-48D5-A9FF-13ACB9C2E529}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CE704EE3-FC1E-48D5-A9FF-13ACB9C2E529}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CE704EE3-FC1E-48D5-A9FF-13ACB9C2E529}.Release|Any CPU.Build.0 = Release|Any CPU
+ {15344920-AE73-4C0A-AEB2-7D75748B791E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {15344920-AE73-4C0A-AEB2-7D75748B791E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {15344920-AE73-4C0A-AEB2-7D75748B791E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {15344920-AE73-4C0A-AEB2-7D75748B791E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {39664900-A87E-4A6D-8BFA-EAC97F5892ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {39664900-A87E-4A6D-8BFA-EAC97F5892ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {39664900-A87E-4A6D-8BFA-EAC97F5892ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {39664900-A87E-4A6D-8BFA-EAC97F5892ED}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EBDF3AD9-BE1C-43B3-ADE4-2336DE09355E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EBDF3AD9-BE1C-43B3-ADE4-2336DE09355E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EBDF3AD9-BE1C-43B3-ADE4-2336DE09355E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EBDF3AD9-BE1C-43B3-ADE4-2336DE09355E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {54B5632D-C113-4383-913E-2701501D951D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {54B5632D-C113-4383-913E-2701501D951D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {54B5632D-C113-4383-913E-2701501D951D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {54B5632D-C113-4383-913E-2701501D951D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {54742C48-894C-4B28-B0D6-BF4F6CE7E76B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {54742C48-894C-4B28-B0D6-BF4F6CE7E76B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {54742C48-894C-4B28-B0D6-BF4F6CE7E76B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {54742C48-894C-4B28-B0D6-BF4F6CE7E76B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {60637559-5F48-44A1-B1F6-16AEA6B1BA01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {60637559-5F48-44A1-B1F6-16AEA6B1BA01}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {60637559-5F48-44A1-B1F6-16AEA6B1BA01}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {60637559-5F48-44A1-B1F6-16AEA6B1BA01}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A4619E76-5B45-4B85-B305-FD99A80EAAFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A4619E76-5B45-4B85-B305-FD99A80EAAFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A4619E76-5B45-4B85-B305-FD99A80EAAFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A4619E76-5B45-4B85-B305-FD99A80EAAFF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A0D587EC-3860-41A7-A648-ABDE1DBB2B01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A0D587EC-3860-41A7-A648-ABDE1DBB2B01}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A0D587EC-3860-41A7-A648-ABDE1DBB2B01}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A0D587EC-3860-41A7-A648-ABDE1DBB2B01}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AEDA5B3F-0DD4-4F00-AD27-9C74E7B58E4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AEDA5B3F-0DD4-4F00-AD27-9C74E7B58E4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AEDA5B3F-0DD4-4F00-AD27-9C74E7B58E4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AEDA5B3F-0DD4-4F00-AD27-9C74E7B58E4A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1346E39C-2A3C-45F3-B3F1-7BC486BC6C3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1346E39C-2A3C-45F3-B3F1-7BC486BC6C3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1346E39C-2A3C-45F3-B3F1-7BC486BC6C3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1346E39C-2A3C-45F3-B3F1-7BC486BC6C3F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {136DFCD0-EEC3-4856-88FC-875549E69567}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {136DFCD0-EEC3-4856-88FC-875549E69567}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {136DFCD0-EEC3-4856-88FC-875549E69567}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {136DFCD0-EEC3-4856-88FC-875549E69567}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BB6E867B-D3C5-4EB8-8A08-919A8E530753}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BB6E867B-D3C5-4EB8-8A08-919A8E530753}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BB6E867B-D3C5-4EB8-8A08-919A8E530753}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BB6E867B-D3C5-4EB8-8A08-919A8E530753}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1BE80F2C-F652-4E36-8DA3-EFFD46BEC8AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1BE80F2C-F652-4E36-8DA3-EFFD46BEC8AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1BE80F2C-F652-4E36-8DA3-EFFD46BEC8AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1BE80F2C-F652-4E36-8DA3-EFFD46BEC8AA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {650813DD-F043-4C38-B235-4F2986B96DF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {650813DD-F043-4C38-B235-4F2986B96DF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {650813DD-F043-4C38-B235-4F2986B96DF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {650813DD-F043-4C38-B235-4F2986B96DF4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E064C30A-5B7D-4253-B3F2-A2172F4DBF7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E064C30A-5B7D-4253-B3F2-A2172F4DBF7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E064C30A-5B7D-4253-B3F2-A2172F4DBF7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E064C30A-5B7D-4253-B3F2-A2172F4DBF7D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F4511D97-994D-4393-BE3D-178C0DC1301A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F4511D97-994D-4393-BE3D-178C0DC1301A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F4511D97-994D-4393-BE3D-178C0DC1301A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F4511D97-994D-4393-BE3D-178C0DC1301A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E340800D-3FCB-4389-8E95-39454110F40A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E340800D-3FCB-4389-8E95-39454110F40A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E340800D-3FCB-4389-8E95-39454110F40A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E340800D-3FCB-4389-8E95-39454110F40A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8262B019-389D-4E9A-9EE4-606D3F2023FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8262B019-389D-4E9A-9EE4-606D3F2023FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8262B019-389D-4E9A-9EE4-606D3F2023FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8262B019-389D-4E9A-9EE4-606D3F2023FC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CB5B8A98-2204-4F53-A8A8-B6BB32E85F64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CB5B8A98-2204-4F53-A8A8-B6BB32E85F64}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CB5B8A98-2204-4F53-A8A8-B6BB32E85F64}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CB5B8A98-2204-4F53-A8A8-B6BB32E85F64}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C99CFF53-B1BD-4FAA-A285-3C149CACE44F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C99CFF53-B1BD-4FAA-A285-3C149CACE44F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C99CFF53-B1BD-4FAA-A285-3C149CACE44F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C99CFF53-B1BD-4FAA-A285-3C149CACE44F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AE455D02-0572-43BA-B213-4D6BF8EDD37B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AE455D02-0572-43BA-B213-4D6BF8EDD37B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AE455D02-0572-43BA-B213-4D6BF8EDD37B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AE455D02-0572-43BA-B213-4D6BF8EDD37B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CE011088-8685-47FC-8274-2141025946D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CE011088-8685-47FC-8274-2141025946D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CE011088-8685-47FC-8274-2141025946D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CE011088-8685-47FC-8274-2141025946D2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {40244095-2B04-407C-AF92-CED881D0429D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {40244095-2B04-407C-AF92-CED881D0429D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {40244095-2B04-407C-AF92-CED881D0429D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {40244095-2B04-407C-AF92-CED881D0429D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BAB2ACB4-1914-48FB-B141-A52C85FBDDC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BAB2ACB4-1914-48FB-B141-A52C85FBDDC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BAB2ACB4-1914-48FB-B141-A52C85FBDDC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BAB2ACB4-1914-48FB-B141-A52C85FBDDC1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E6720C0D-274D-4AEF-A45E-897EBDCE0911}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E6720C0D-274D-4AEF-A45E-897EBDCE0911}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E6720C0D-274D-4AEF-A45E-897EBDCE0911}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E6720C0D-274D-4AEF-A45E-897EBDCE0911}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CEBDD8CA-8AC5-41B2-95CE-21EDA9D38AFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CEBDD8CA-8AC5-41B2-95CE-21EDA9D38AFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CEBDD8CA-8AC5-41B2-95CE-21EDA9D38AFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CEBDD8CA-8AC5-41B2-95CE-21EDA9D38AFF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3BCB9CBC-A3EE-4493-B605-6EBE559F295A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3BCB9CBC-A3EE-4493-B605-6EBE559F295A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3BCB9CBC-A3EE-4493-B605-6EBE559F295A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3BCB9CBC-A3EE-4493-B605-6EBE559F295A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5D786C6B-2A75-440B-A1FB-C077E8B8B898}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5D786C6B-2A75-440B-A1FB-C077E8B8B898}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5D786C6B-2A75-440B-A1FB-C077E8B8B898}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5D786C6B-2A75-440B-A1FB-C077E8B8B898}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9F5AFB87-3F4F-40A9-A76F-BFC6C78BD59B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9F5AFB87-3F4F-40A9-A76F-BFC6C78BD59B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9F5AFB87-3F4F-40A9-A76F-BFC6C78BD59B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9F5AFB87-3F4F-40A9-A76F-BFC6C78BD59B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {394C3304-3228-4F16-AD8A-06D7B32A3D46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {394C3304-3228-4F16-AD8A-06D7B32A3D46}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {394C3304-3228-4F16-AD8A-06D7B32A3D46}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {394C3304-3228-4F16-AD8A-06D7B32A3D46}.Release|Any CPU.Build.0 = Release|Any CPU
+ {121DD302-DF4B-4F49-B6F9-B3AD358BD842}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {121DD302-DF4B-4F49-B6F9-B3AD358BD842}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {121DD302-DF4B-4F49-B6F9-B3AD358BD842}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {121DD302-DF4B-4F49-B6F9-B3AD358BD842}.Release|Any CPU.Build.0 = Release|Any CPU
+ {033DCC6B-9081-4119-8F9E-F51B834992CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {033DCC6B-9081-4119-8F9E-F51B834992CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {033DCC6B-9081-4119-8F9E-F51B834992CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {033DCC6B-9081-4119-8F9E-F51B834992CC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4AC66D72-FD8B-40B3-9236-C76F97FFD487}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4AC66D72-FD8B-40B3-9236-C76F97FFD487}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4AC66D72-FD8B-40B3-9236-C76F97FFD487}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4AC66D72-FD8B-40B3-9236-C76F97FFD487}.Release|Any CPU.Build.0 = Release|Any CPU
+ {130FBF70-7031-4F7C-92AC-2C616442F18D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {130FBF70-7031-4F7C-92AC-2C616442F18D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {130FBF70-7031-4F7C-92AC-2C616442F18D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {130FBF70-7031-4F7C-92AC-2C616442F18D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {56BC6E17-FC0B-4AB5-BFB2-B92344E707FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {56BC6E17-FC0B-4AB5-BFB2-B92344E707FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {56BC6E17-FC0B-4AB5-BFB2-B92344E707FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {56BC6E17-FC0B-4AB5-BFB2-B92344E707FA}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {0A0FBC87-CC98-42F9-9A0A-8E9BA7BFFCD5} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {ACC68C00-F79A-4901-AD56-56608A4ED459} = {0A0FBC87-CC98-42F9-9A0A-8E9BA7BFFCD5}
+ {8EBFE2CE-07A1-45F6-85AC-8023014A0A8A} = {ACC68C00-F79A-4901-AD56-56608A4ED459}
+ {AAAB9A5A-635B-436F-8C37-EC7AEC4E2CD6} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {021CDAC2-FA64-47D4-B135-BE88307070F3} = {AAAB9A5A-635B-436F-8C37-EC7AEC4E2CD6}
+ {880203DF-F9E6-4888-9978-A2FBE22BD25A} = {021CDAC2-FA64-47D4-B135-BE88307070F3}
+ {8CA3AB2F-92C6-4C50-8D9E-CA2B47C2C3D8} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {E538F135-D7F1-4D06-B4FA-42CC9B2045C0} = {8CA3AB2F-92C6-4C50-8D9E-CA2B47C2C3D8}
+ {E5C344F3-4239-4F98-BF5B-642646B0A68A} = {E538F135-D7F1-4D06-B4FA-42CC9B2045C0}
+ {F2457324-04D1-4703-91D4-30CB9046C94F} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {D54F9F07-8ED9-4511-A572-57AA57D7ABEE} = {F2457324-04D1-4703-91D4-30CB9046C94F}
+ {CD8CA3A7-2D4D-416A-BB82-76279B1843C2} = {D54F9F07-8ED9-4511-A572-57AA57D7ABEE}
+ {D6AA01DF-D60F-497E-A29D-28268B164B8D} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {E20DDD90-B221-4873-A9F9-7F831F17FF95} = {D6AA01DF-D60F-497E-A29D-28268B164B8D}
+ {6846E9D4-264E-4FFD-876D-88BFBDAFE69F} = {E20DDD90-B221-4873-A9F9-7F831F17FF95}
+ {42DE3F58-875F-49A2-8BB3-AE9ABB6ABD98} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {EB2D434B-1053-42C1-95B0-3A1C8112DA49} = {42DE3F58-875F-49A2-8BB3-AE9ABB6ABD98}
+ {E10BD658-9B0E-4A95-97B7-C288C429C094} = {EB2D434B-1053-42C1-95B0-3A1C8112DA49}
+ {5A7E4CE3-E5F2-46FB-80F8-AAF2EA16D5E4} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {FAA052F2-328B-41A2-9A2B-CCD32A7517A3} = {5A7E4CE3-E5F2-46FB-80F8-AAF2EA16D5E4}
+ {CFA4A2CE-A230-4303-83B1-677B23B66266} = {FAA052F2-328B-41A2-9A2B-CCD32A7517A3}
+ {2FCA2E8E-D20D-421A-8F6B-4641DF47CF84} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {7BBC9237-2D49-4C6F-BDC6-0B495FD43FB6} = {2FCA2E8E-D20D-421A-8F6B-4641DF47CF84}
+ {7F6A3EC0-1B12-4F2A-B0F8-1EBA1C113460} = {7BBC9237-2D49-4C6F-BDC6-0B495FD43FB6}
+ {96FD05B9-272B-4AC4-81AB-A8D411823A37} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {D5E91541-FE1E-48BB-BCA2-EF80BF0F4381} = {96FD05B9-272B-4AC4-81AB-A8D411823A37}
+ {E69808C1-8776-4055-8385-05CCE596C4E5} = {D5E91541-FE1E-48BB-BCA2-EF80BF0F4381}
+ {5C85A61A-EED6-4A1D-9BA0-245900C0B493} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {91324E15-E4A3-4C49-9385-7F311012AB3D} = {5C85A61A-EED6-4A1D-9BA0-245900C0B493}
+ {98F1FA3D-7B10-4178-A6A4-41F6958CCBE5} = {91324E15-E4A3-4C49-9385-7F311012AB3D}
+ {985ED6EE-AC9D-4BD4-88D7-06CC4740ACD1} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {D9C0DE7D-885D-4CB3-80FA-2A653026A28E} = {985ED6EE-AC9D-4BD4-88D7-06CC4740ACD1}
+ {A90B225A-0F85-416B-9CE8-EEBDF2929BC4} = {D9C0DE7D-885D-4CB3-80FA-2A653026A28E}
+ {2A8BDC9C-C864-46B7-98A0-ECC9BA0ECDFF} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {5B9A381F-95C5-4879-BB11-67E7FE333C45} = {2A8BDC9C-C864-46B7-98A0-ECC9BA0ECDFF}
+ {48F1B70D-8C96-49BA-B4A2-957377393EEF} = {5B9A381F-95C5-4879-BB11-67E7FE333C45}
+ {F2100C68-99AA-437E-8B6F-569CFF60319A} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {D277FFE9-E342-4D8F-9EEA-ACB984B3F20E} = {F2100C68-99AA-437E-8B6F-569CFF60319A}
+ {C11D6283-7A34-4CDD-8C27-65F8499E5CFE} = {D277FFE9-E342-4D8F-9EEA-ACB984B3F20E}
+ {E3A38228-9D83-4287-BB40-3B37105327C3} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {0A6E4D7B-7E46-4428-B8A2-04670F4AE4E8} = {E3A38228-9D83-4287-BB40-3B37105327C3}
+ {C37BA915-33E8-48C6-9098-6681EE54884D} = {0A6E4D7B-7E46-4428-B8A2-04670F4AE4E8}
+ {263ABDC6-0FF9-4CEF-BADE-AF910A4CD06E} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {55BA7DED-599D-4518-BE9A-EF537FF15FD5} = {263ABDC6-0FF9-4CEF-BADE-AF910A4CD06E}
+ {2C70A6EE-70B7-42C0-8C0B-66C690AB8C87} = {55BA7DED-599D-4518-BE9A-EF537FF15FD5}
+ {4FBDE444-8013-449D-829B-1A10E5C84ED2} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {81C41B64-01DB-4B74-ACC0-E3FC9EBCC8F1} = {4FBDE444-8013-449D-829B-1A10E5C84ED2}
+ {F44EB030-BD0E-42AB-82BD-5E7E0F530A24} = {81C41B64-01DB-4B74-ACC0-E3FC9EBCC8F1}
+ {3C7B03EF-F829-4183-8447-5FFAAB41736D} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {504632B3-C3E0-4AEE-BB19-4B83AB67EE98} = {3C7B03EF-F829-4183-8447-5FFAAB41736D}
+ {96C98AA8-D5D5-4F3D-AC36-DFB044A10283} = {504632B3-C3E0-4AEE-BB19-4B83AB67EE98}
+ {CF5E9E32-F322-427D-9282-75D9241B01A9} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {36D4B481-06AB-4B67-8794-E9CFB5502973} = {CF5E9E32-F322-427D-9282-75D9241B01A9}
+ {D3966891-3616-427F-BC24-CEBAD4B3B6BE} = {36D4B481-06AB-4B67-8794-E9CFB5502973}
+ {F15D5FFF-2C08-4EB8-B2D7-A1DD8162F5AF} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {BBB2D930-94EA-4246-8455-237671065539} = {F15D5FFF-2C08-4EB8-B2D7-A1DD8162F5AF}
+ {FAFEE1DA-438D-4D7F-91B1-9BB2444DB30E} = {BBB2D930-94EA-4246-8455-237671065539}
+ {6E2CC07F-56CA-40F3-B3F3-3DA8AE603896} = {000361F4-B47A-430A-A0C2-0A7086A31436}
+ {C6A58830-B745-41A4-90D2-DA163CF2BB67} = {6E2CC07F-56CA-40F3-B3F3-3DA8AE603896}
+ {DA97B418-6D04-4FA2-8214-6FE3113E02C7} = {C6A58830-B745-41A4-90D2-DA163CF2BB67}
+ {A3BE5D15-F8AA-4EDB-8E75-E1F37924CEF6} = {000361F4-B47A-430A-A0C2-0A7086A31436}
+ {8E528AAF-4A6F-4829-B806-EDBD5C30F355} = {A3BE5D15-F8AA-4EDB-8E75-E1F37924CEF6}
+ {DD92F97D-EA78-4377-8DB7-63D1C6048670} = {8E528AAF-4A6F-4829-B806-EDBD5C30F355}
+ {4D2D22C2-B933-495B-9846-811D5907A57D} = {000361F4-B47A-430A-A0C2-0A7086A31436}
+ {929BA453-227D-46A5-BDD7-0A19825BE5E5} = {4D2D22C2-B933-495B-9846-811D5907A57D}
+ {891D09C7-E16C-4467-BDEE-BDAAB5552B7A} = {929BA453-227D-46A5-BDD7-0A19825BE5E5}
+ {269FF747-D5E0-40D8-B049-6E4C4964ADA6} = {000361F4-B47A-430A-A0C2-0A7086A31436}
+ {2E90B124-81A7-4537-927F-8DB160C1FE80} = {269FF747-D5E0-40D8-B049-6E4C4964ADA6}
+ {A3B23699-5387-4266-B784-C7AE207E6923} = {2E90B124-81A7-4537-927F-8DB160C1FE80}
+ {9101C64B-D96D-473D-B675-3774012104DA} = {000361F4-B47A-430A-A0C2-0A7086A31436}
+ {35EB5074-E17E-414B-9057-2E26E4C43D5B} = {9101C64B-D96D-473D-B675-3774012104DA}
+ {BA41DE74-F49C-4C07-A83D-2317566E7808} = {35EB5074-E17E-414B-9057-2E26E4C43D5B}
+ {3F4A40BF-90D0-4F0B-A8E7-4353FAC34D4C} = {000361F4-B47A-430A-A0C2-0A7086A31436}
+ {E78D409D-0A8E-4A95-9E03-165B01A953BF} = {3F4A40BF-90D0-4F0B-A8E7-4353FAC34D4C}
+ {80B82340-D9C3-431F-9B22-947F6DDAE0F6} = {E78D409D-0A8E-4A95-9E03-165B01A953BF}
+ {044CF8A5-7174-45AD-A429-BFAE3DC59B3B} = {000361F4-B47A-430A-A0C2-0A7086A31436}
+ {2924AEED-876E-4AFA-A233-B34229F73BE4} = {044CF8A5-7174-45AD-A429-BFAE3DC59B3B}
+ {74B56470-25B2-4846-810D-53560F6EB5F1} = {2924AEED-876E-4AFA-A233-B34229F73BE4}
+ {DB05923D-5D5E-4630-AF81-386E8FD267A6} = {000361F4-B47A-430A-A0C2-0A7086A31436}
+ {AABB6D87-3D71-4E9B-964C-C2327BE60CFA} = {DB05923D-5D5E-4630-AF81-386E8FD267A6}
+ {5C73EE37-B28D-476A-825E-4EF73D0F6D80} = {AABB6D87-3D71-4E9B-964C-C2327BE60CFA}
+ {25A7010F-FAAF-47FB-85F4-CBA5803D29FB} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {C430C499-9B05-46D5-A3F8-5BA3FB0FEC97} = {25A7010F-FAAF-47FB-85F4-CBA5803D29FB}
+ {61FCF96E-F3D6-4609-9D75-78D9582E692D} = {C430C499-9B05-46D5-A3F8-5BA3FB0FEC97}
+ {7856E480-B1CB-4658-A2FB-ABA0C201A41F} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {0819B57C-7DC1-4766-88DE-2E6EE93100B8} = {7856E480-B1CB-4658-A2FB-ABA0C201A41F}
+ {BF317DEB-2946-49C4-A6D2-3A0B4175AF64} = {0819B57C-7DC1-4766-88DE-2E6EE93100B8}
+ {8A254CA8-A07F-4729-9D33-0494853B734B} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {48443654-8823-499D-9FDA-B95460C5307C} = {8A254CA8-A07F-4729-9D33-0494853B734B}
+ {951F433D-47BB-46CD-9577-38DC2EEF38F1} = {48443654-8823-499D-9FDA-B95460C5307C}
+ {0EE07F7A-DE9B-4C55-A697-3A17B5D3E0B4} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {92896FB4-C0F8-4387-858D-A290CD242622} = {0EE07F7A-DE9B-4C55-A697-3A17B5D3E0B4}
+ {92B8FAFF-3EBC-4C12-91AB-71A8B6E0EC1C} = {92896FB4-C0F8-4387-858D-A290CD242622}
+ {2EBD7821-313E-4099-B11E-A64208AF5828} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {D7AF3953-4C0F-4D48-9B9B-41CC9030C3CC} = {2EBD7821-313E-4099-B11E-A64208AF5828}
+ {6C8B2D4E-6B4E-4F71-AA72-BF0BB37D6DAD} = {D7AF3953-4C0F-4D48-9B9B-41CC9030C3CC}
+ {916C4EA8-832B-4A46-87E0-B7E791370E40} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {59C0DA6D-19D4-4558-99E4-214E303A4577} = {916C4EA8-832B-4A46-87E0-B7E791370E40}
+ {66B48A43-2EA8-4463-81B5-D842A49DBD73} = {59C0DA6D-19D4-4558-99E4-214E303A4577}
+ {B980A4D6-935E-4EBC-B2EA-6CCA456F7A58} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {5D0E2857-73F0-4629-8E2E-AE0697AD80D1} = {B980A4D6-935E-4EBC-B2EA-6CCA456F7A58}
+ {30536342-FF9E-4B4E-8679-55DDF1583BCE} = {5D0E2857-73F0-4629-8E2E-AE0697AD80D1}
+ {BE0926CC-9242-4907-B7D9-DD44FA3DB846} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {483EBECF-595C-41E1-9133-F6823CAEAD21} = {BE0926CC-9242-4907-B7D9-DD44FA3DB846}
+ {1A694B8E-C1E4-4BC2-A5F3-F658EB733EDB} = {483EBECF-595C-41E1-9133-F6823CAEAD21}
+ {2C0EA586-4767-4FD7-B994-7FD140C88410} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {921533E6-BAEC-4661-81D4-93379BC098C5} = {2C0EA586-4767-4FD7-B994-7FD140C88410}
+ {86177A39-B69B-40BC-AAA4-E5DDDCE80B54} = {921533E6-BAEC-4661-81D4-93379BC098C5}
+ {6FE112DA-68F4-4478-B3D4-0998C796B069} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {9A6E6002-400C-4E20-B720-98E4C6C08C91} = {6FE112DA-68F4-4478-B3D4-0998C796B069}
+ {3FF581CD-E646-48CE-8611-159999784EDB} = {9A6E6002-400C-4E20-B720-98E4C6C08C91}
+ {E08F12C4-FC31-46E7-8929-D588E0516D1E} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {A6FAE91B-BC05-4231-9B18-B77861456554} = {E08F12C4-FC31-46E7-8929-D588E0516D1E}
+ {6BDE17DC-A368-4EB8-9BA5-222E2E8469D1} = {A6FAE91B-BC05-4231-9B18-B77861456554}
+ {FB1CC579-E541-4CB9-B1B8-4F5DF7E9AC14} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {78A1EE8A-2B3C-48C5-B604-A769436714D6} = {FB1CC579-E541-4CB9-B1B8-4F5DF7E9AC14}
+ {24C6898B-ACF8-4406-8767-4EB388950D3B} = {78A1EE8A-2B3C-48C5-B604-A769436714D6}
+ {B3B19CA3-CA80-4010-98E6-C175AA88B8CC} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {99767C82-2DC7-41C7-92F8-C92C28985A87} = {B3B19CA3-CA80-4010-98E6-C175AA88B8CC}
+ {2F80BDCE-7606-4F23-99CE-B980E1E8C70E} = {99767C82-2DC7-41C7-92F8-C92C28985A87}
+ {3085F22A-78A0-4BF2-AF0D-5E2A0EC3B1FD} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {805B67FD-07D3-4B16-85E6-EA8039FE0C51} = {3085F22A-78A0-4BF2-AF0D-5E2A0EC3B1FD}
+ {C5A5B136-224B-43B4-B220-C677BF4D8294} = {805B67FD-07D3-4B16-85E6-EA8039FE0C51}
+ {1DC7633F-5218-4A44-963F-730CA81B66E2} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {E4806DB9-88E3-4192-8077-90047B8DD2A1} = {1DC7633F-5218-4A44-963F-730CA81B66E2}
+ {DB1D40BF-6C1B-4565-B629-4647834B8F40} = {E4806DB9-88E3-4192-8077-90047B8DD2A1}
+ {CF2C3F58-8A1E-48C4-ACA7-7D540DBEDD80} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {B34807AE-1728-48FE-8B3A-4FCC4DD8D40C} = {CF2C3F58-8A1E-48C4-ACA7-7D540DBEDD80}
+ {316025D1-B4C1-4053-87E4-34DC46FF7B23} = {B34807AE-1728-48FE-8B3A-4FCC4DD8D40C}
+ {CACFA014-FC77-4B94-827C-2B59DE04BE16} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {96787B73-62AA-4C09-B688-823A4E4FB6E2} = {CACFA014-FC77-4B94-827C-2B59DE04BE16}
+ {7808E16E-87A9-4D8C-82A5-BFBABBDD2C3C} = {96787B73-62AA-4C09-B688-823A4E4FB6E2}
+ {C6AEDC14-DF11-4B52-BB08-6FF557237010} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {F425D415-34EF-4A22-B010-F250131034F6} = {C6AEDC14-DF11-4B52-BB08-6FF557237010}
+ {DD1FEF33-10CA-4DF2-872A-D8879A8302DA} = {F425D415-34EF-4A22-B010-F250131034F6}
+ {C5965E3E-F9B7-457D-976B-FF198E971AEE} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {BC476C0E-2947-47EE-B395-69D71D46C179} = {C5965E3E-F9B7-457D-976B-FF198E971AEE}
+ {1098672C-C215-4912-AB71-906E6176A4AA} = {BC476C0E-2947-47EE-B395-69D71D46C179}
+ {4254A869-193E-4AD5-B403-AA628B30E75D} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {5C8BC972-E212-4ACD-BF34-AC11F29372F2} = {4254A869-193E-4AD5-B403-AA628B30E75D}
+ {F932902B-7C87-4E8A-B43D-FEAABBB1AB2A} = {5C8BC972-E212-4ACD-BF34-AC11F29372F2}
+ {AEA3EB59-34FB-455C-AD80-C93186A5BE8D} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {7E3CABB1-B098-486F-BBF9-93138E58E1B6} = {AEA3EB59-34FB-455C-AD80-C93186A5BE8D}
+ {21DD38E0-3B0C-4F3E-B7B2-77869FB5471D} = {7E3CABB1-B098-486F-BBF9-93138E58E1B6}
+ {EEA6E326-AAF9-4772-B4C1-AECF9FADAA19} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {BAA404DB-39D2-41E4-AC87-4DE55BE7B346} = {EEA6E326-AAF9-4772-B4C1-AECF9FADAA19}
+ {096D90EF-4ABC-40B4-85D1-E813969C40D1} = {BAA404DB-39D2-41E4-AC87-4DE55BE7B346}
+ {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E} = {B8F1F599-6153-4506-BA3A-C68123D23987}
+ {000361F4-B47A-430A-A0C2-0A7086A31436} = {B8F1F599-6153-4506-BA3A-C68123D23987}
+ {1387AD44-A709-427B-8B95-2262C0284BE5} = {B8F1F599-6153-4506-BA3A-C68123D23987}
+ {67FCA1BE-D816-4972-9138-F74F39F3A158} = {B8F1F599-6153-4506-BA3A-C68123D23987}
+ {50BD1A91-4AE4-4595-A3E5-C3CCB29C222A} = {000361F4-B47A-430A-A0C2-0A7086A31436}
+ {6BFD42BE-5AB6-484B-9751-18184B4602A1} = {50BD1A91-4AE4-4595-A3E5-C3CCB29C222A}
+ {10DE679A-E842-4227-8120-AB0D91F02C3B} = {6BFD42BE-5AB6-484B-9751-18184B4602A1}
+ {08A830E5-212D-4BB4-8ABA-0C22368496AC} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {0485686F-900D-4D21-9ED6-60CB21E3F0D4} = {08A830E5-212D-4BB4-8ABA-0C22368496AC}
+ {161D23AA-B910-4826-984E-5F71E6115F3C} = {0485686F-900D-4D21-9ED6-60CB21E3F0D4}
+ {704C4816-BDEA-47B7-94A7-00F3E19BD47E} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {7467768D-4858-4847-9A5B-97ECB096EFE8} = {704C4816-BDEA-47B7-94A7-00F3E19BD47E}
+ {8F19C132-61E2-4351-AC47-4653E86D7456} = {7467768D-4858-4847-9A5B-97ECB096EFE8}
+ {8E9348FF-4214-4BFE-953F-E564A2C01DFD} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {7D0320C0-C6C2-45F5-8F14-EA15BB063A90} = {8E9348FF-4214-4BFE-953F-E564A2C01DFD}
+ {CE704EE3-FC1E-48D5-A9FF-13ACB9C2E529} = {7D0320C0-C6C2-45F5-8F14-EA15BB063A90}
+ {01B3171D-AF96-4796-8388-8649053CF04E} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {313BAE04-DBEC-4EE2-ACF3-D85D8C8798C5} = {01B3171D-AF96-4796-8388-8649053CF04E}
+ {15344920-AE73-4C0A-AEB2-7D75748B791E} = {313BAE04-DBEC-4EE2-ACF3-D85D8C8798C5}
+ {DE565C75-358D-43AF-82FA-0A70925FFFB4} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {1CDBE1A6-3E5B-4FBE-B98F-5705633BFE9C} = {DE565C75-358D-43AF-82FA-0A70925FFFB4}
+ {39664900-A87E-4A6D-8BFA-EAC97F5892ED} = {1CDBE1A6-3E5B-4FBE-B98F-5705633BFE9C}
+ {F9D1F2B5-1B82-4B5F-A65A-18EA75F38457} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {93D303A0-945B-403E-82D4-AC8E2CA4463F} = {F9D1F2B5-1B82-4B5F-A65A-18EA75F38457}
+ {EBDF3AD9-BE1C-43B3-ADE4-2336DE09355E} = {93D303A0-945B-403E-82D4-AC8E2CA4463F}
+ {471F09E3-9BA6-43AB-A8F1-359D797FD136} = {4EB973CF-9705-442F-AA83-7DBE73B010D0}
+ {DCB5C4A9-9AA5-413D-A4AA-CBBB66A0262E} = {471F09E3-9BA6-43AB-A8F1-359D797FD136}
+ {54B5632D-C113-4383-913E-2701501D951D} = {DCB5C4A9-9AA5-413D-A4AA-CBBB66A0262E}
+ {1DC34F9A-8397-4B6D-8B13-175A850DECFB} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {E98FBEDE-0103-4D38-8A72-92FAE634C67E} = {1DC34F9A-8397-4B6D-8B13-175A850DECFB}
+ {54742C48-894C-4B28-B0D6-BF4F6CE7E76B} = {E98FBEDE-0103-4D38-8A72-92FAE634C67E}
+ {6D68EB04-A8B4-4843-A20E-5BFC4F07923B} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {477D4BB3-CA8F-4CB3-AD08-CD84CBF4215E} = {6D68EB04-A8B4-4843-A20E-5BFC4F07923B}
+ {60637559-5F48-44A1-B1F6-16AEA6B1BA01} = {477D4BB3-CA8F-4CB3-AD08-CD84CBF4215E}
+ {4EB973CF-9705-442F-AA83-7DBE73B010D0} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {86C29745-85F2-4F63-9CBB-EF0F364E3633} = {4EB973CF-9705-442F-AA83-7DBE73B010D0}
+ {A4619E76-5B45-4B85-B305-FD99A80EAAFF} = {86C29745-85F2-4F63-9CBB-EF0F364E3633}
+ {E12EF30F-3FD3-4A97-8BBD-FC008108298D} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {77EB4E23-F3B6-4259-8A37-68ADDEC79FA3} = {E12EF30F-3FD3-4A97-8BBD-FC008108298D}
+ {A0D587EC-3860-41A7-A648-ABDE1DBB2B01} = {77EB4E23-F3B6-4259-8A37-68ADDEC79FA3}
+ {FA0D3054-CC09-4B44-BE75-A4BBA43CF568} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {FE9B754D-0964-43E7-B284-E5BFCE219339} = {FA0D3054-CC09-4B44-BE75-A4BBA43CF568}
+ {AEDA5B3F-0DD4-4F00-AD27-9C74E7B58E4A} = {FE9B754D-0964-43E7-B284-E5BFCE219339}
+ {761F0B1D-C5E2-4B7F-9757-2569DE22242C} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {1346E39C-2A3C-45F3-B3F1-7BC486BC6C3F} = {7CE65D69-9B3F-4CA8-9837-75BCB4E3F083}
+ {7CE65D69-9B3F-4CA8-9837-75BCB4E3F083} = {761F0B1D-C5E2-4B7F-9757-2569DE22242C}
+ {44497CF8-959A-44C6-A40B-E517BC2376A6} = {000361F4-B47A-430A-A0C2-0A7086A31436}
+ {9357F636-7980-46DF-8AE1-967D9B52D4C7} = {44497CF8-959A-44C6-A40B-E517BC2376A6}
+ {136DFCD0-EEC3-4856-88FC-875549E69567} = {9357F636-7980-46DF-8AE1-967D9B52D4C7}
+ {AA4DF06F-0801-4132-8993-A5BED221A9F2} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {D73D3AA8-4D8A-4820-B62C-9BB9F0C0CB3A} = {AA4DF06F-0801-4132-8993-A5BED221A9F2}
+ {BB6E867B-D3C5-4EB8-8A08-919A8E530753} = {D73D3AA8-4D8A-4820-B62C-9BB9F0C0CB3A}
+ {8564D43C-9FD5-4B61-86F6-5F1DE20B072E} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {CC2F9BCC-C904-4EC8-A7D6-B45B3FC6946E} = {8564D43C-9FD5-4B61-86F6-5F1DE20B072E}
+ {1BE80F2C-F652-4E36-8DA3-EFFD46BEC8AA} = {CC2F9BCC-C904-4EC8-A7D6-B45B3FC6946E}
+ {21586975-5E83-42BD-BDB0-B34FCD5B734A} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {0B90312C-7E10-4C6F-B3EC-C580BAD0FFE9} = {21586975-5E83-42BD-BDB0-B34FCD5B734A}
+ {650813DD-F043-4C38-B235-4F2986B96DF4} = {0B90312C-7E10-4C6F-B3EC-C580BAD0FFE9}
+ {653A4FE9-34F5-4248-AD24-2113A58731B4} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {6E66E383-08AD-49AD-AE98-062EF74A2D0A} = {653A4FE9-34F5-4248-AD24-2113A58731B4}
+ {E064C30A-5B7D-4253-B3F2-A2172F4DBF7D} = {6E66E383-08AD-49AD-AE98-062EF74A2D0A}
+ {83AD0011-B9F9-41CE-993A-C82BEC443354} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {B16C0689-BE91-4470-867C-29CD41BECBE3} = {83AD0011-B9F9-41CE-993A-C82BEC443354}
+ {E340800D-3FCB-4389-8E95-39454110F40A} = {B16C0689-BE91-4470-867C-29CD41BECBE3}
+ {5658AB3B-3A50-4586-B407-D028CA678ADE} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {FB7BBE6E-9121-415B-ACAC-FE412DF3CE41} = {5658AB3B-3A50-4586-B407-D028CA678ADE}
+ {450B0EA2-2AFF-4CBF-9ED0-B3F230C33621} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {AD67A5A6-BA20-4F9E-83C7-1D0AFB9091C2} = {450B0EA2-2AFF-4CBF-9ED0-B3F230C33621}
+ {8262B019-389D-4E9A-9EE4-606D3F2023FC} = {AD67A5A6-BA20-4F9E-83C7-1D0AFB9091C2}
+ {FA87E4AC-AFBE-4811-848E-EF6AED874F59} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {CB5B8A98-2204-4F53-A8A8-B6BB32E85F64} = {AA75ECB6-3554-4CD6-A240-53637B392904}
+ {AA75ECB6-3554-4CD6-A240-53637B392904} = {FA87E4AC-AFBE-4811-848E-EF6AED874F59}
+ {B572C23F-1A8A-4514-A785-CF1C717691EB} = {ED714ADB-432F-456C-B767-06576666A43B}
+ {31293883-B73F-4DA8-9BA2-4A9930B44AA2} = {1387AD44-A709-427B-8B95-2262C0284BE5}
+ {35CDF4F0-89D5-463D-B3BA-628F032DDCDC} = {31293883-B73F-4DA8-9BA2-4A9930B44AA2}
+ {C99CFF53-B1BD-4FAA-A285-3C149CACE44F} = {35CDF4F0-89D5-463D-B3BA-628F032DDCDC}
+ {06C10087-A052-40BD-8101-18DB37909B14} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {AE455D02-0572-43BA-B213-4D6BF8EDD37B} = {FB7BBE6E-9121-415B-ACAC-FE412DF3CE41}
+ {83888528-487F-4071-8605-151E4F586C78} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {5A8BECBC-089B-4425-BE29-AB6F2750DAC6} = {83888528-487F-4071-8605-151E4F586C78}
+ {CE011088-8685-47FC-8274-2141025946D2} = {5A8BECBC-089B-4425-BE29-AB6F2750DAC6}
+ {2D9E833E-0229-4DA6-BC6C-2A039E925176} = {B8F1F599-6153-4506-BA3A-C68123D23987}
+ {7E38EF2C-F2CD-40A4-9052-F5472E30CBDC} = {2D9E833E-0229-4DA6-BC6C-2A039E925176}
+ {F85E1F14-3D62-4F7A-BEB2-B73AA16BB2F8} = {7E38EF2C-F2CD-40A4-9052-F5472E30CBDC}
+ {40244095-2B04-407C-AF92-CED881D0429D} = {F85E1F14-3D62-4F7A-BEB2-B73AA16BB2F8}
+ {197C8362-EB09-4F2C-A70B-2D29E5F04D21} = {2D9E833E-0229-4DA6-BC6C-2A039E925176}
+ {4B4DE002-28B5-4E4A-AD2F-837DF34D5F2F} = {197C8362-EB09-4F2C-A70B-2D29E5F04D21}
+ {BAB2ACB4-1914-48FB-B141-A52C85FBDDC1} = {4B4DE002-28B5-4E4A-AD2F-837DF34D5F2F}
+ {CA1F8B6F-2EA4-4A7C-B468-190B7C76E97B} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {F623050B-10E1-407E-91F4-0AE24EE144FB} = {CA1F8B6F-2EA4-4A7C-B468-190B7C76E97B}
+ {E6720C0D-274D-4AEF-A45E-897EBDCE0911} = {F623050B-10E1-407E-91F4-0AE24EE144FB}
+ {CEBDD8CA-8AC5-41B2-95CE-21EDA9D38AFF} = {57375AE4-BFE0-4D8A-8D76-27AF0FA5479E}
+ {57375AE4-BFE0-4D8A-8D76-27AF0FA5479E} = {06C10087-A052-40BD-8101-18DB37909B14}
+ {644EE9B7-3883-4C1A-900C-0A3217CD5122} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {5EF9AA74-6CD0-4FC4-8D8F-19BECE6D5041} = {644EE9B7-3883-4C1A-900C-0A3217CD5122}
+ {3BCB9CBC-A3EE-4493-B605-6EBE559F295A} = {5EF9AA74-6CD0-4FC4-8D8F-19BECE6D5041}
+ {C66C3B0F-2B02-414E-A02C-20E40E4323CA} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {38F41597-6448-4CB2-A73B-457C53354FD6} = {C66C3B0F-2B02-414E-A02C-20E40E4323CA}
+ {5D786C6B-2A75-440B-A1FB-C077E8B8B898} = {38F41597-6448-4CB2-A73B-457C53354FD6}
+ {BBF714D6-0319-4D28-B531-BD06728F5E4F} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {09CDBAFA-14B3-4C0D-A604-56AB25627D75} = {BBF714D6-0319-4D28-B531-BD06728F5E4F}
+ {9F5AFB87-3F4F-40A9-A76F-BFC6C78BD59B} = {09CDBAFA-14B3-4C0D-A604-56AB25627D75}
+ {ECD7B20D-BB60-447D-9379-CB231CED783D} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {99DE7371-2C7F-49CB-BE2D-03C2C6DB4ABB} = {ECD7B20D-BB60-447D-9379-CB231CED783D}
+ {394C3304-3228-4F16-AD8A-06D7B32A3D46} = {99DE7371-2C7F-49CB-BE2D-03C2C6DB4ABB}
+ {6337C220-C88D-40F6-8430-5D587AAAA6E1} = {B8F1F599-6153-4506-BA3A-C68123D23987}
+ {1A8EC1C6-6712-4C84-9495-1E6B9C7C0695} = {6337C220-C88D-40F6-8430-5D587AAAA6E1}
+ {121DD302-DF4B-4F49-B6F9-B3AD358BD842} = {1A8EC1C6-6712-4C84-9495-1E6B9C7C0695}
+ {9184AD19-8580-4A8F-8220-8A679639C57F} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {D1E71180-9B7B-40BB-831D-48BB98F0A834} = {9184AD19-8580-4A8F-8220-8A679639C57F}
+ {033DCC6B-9081-4119-8F9E-F51B834992CC} = {D1E71180-9B7B-40BB-831D-48BB98F0A834}
+ {A1466055-9F55-4B87-8D6F-323E4F0EA85C} = {E1863B9A-556C-4B02-A74D-E47F6EFCCC5E}
+ {06F7B8FB-7357-4F31-93CF-E76050F07224} = {A1466055-9F55-4B87-8D6F-323E4F0EA85C}
+ {4AC66D72-FD8B-40B3-9236-C76F97FFD487} = {06F7B8FB-7357-4F31-93CF-E76050F07224}
+ {72128F4D-352C-4DEF-BA5A-DAB4A2A7CC93} = {2D9E833E-0229-4DA6-BC6C-2A039E925176}
+ {B257C040-9707-4DF4-93BB-F7151D0C0702} = {72128F4D-352C-4DEF-BA5A-DAB4A2A7CC93}
+ {130FBF70-7031-4F7C-92AC-2C616442F18D} = {B257C040-9707-4DF4-93BB-F7151D0C0702}
+ {50494B33-0532-42E6-AF1F-05BA2F7B8D81} = {67FCA1BE-D816-4972-9138-F74F39F3A158}
+ {B7B98608-DFC0-47A9-AA5A-760D948D7DE1} = {50494B33-0532-42E6-AF1F-05BA2F7B8D81}
+ {56BC6E17-FC0B-4AB5-BFB2-B92344E707FA} = {B7B98608-DFC0-47A9-AA5A-760D948D7DE1}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {8A34D641-4198-452E-88BE-371C26F30977}
+ EndGlobalSection
+EndGlobal
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders.xml b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders.xml
new file mode 100644
index 0000000..5fdd3f2
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders.xml
@@ -0,0 +1,31 @@
+
+
+ BookMultipleOrders
+ Script 1.0.1.77
+ Automation
+ SKYLINE2\VictorSC
+ FALSE
+ YLE/Customer UI
+
+
+
+
+
+
+
+
+
+ OrderIds
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/.editorconfig b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/BookMultipleOrdersDialog.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/BookMultipleOrdersDialog.cs
new file mode 100644
index 0000000..46f70ab
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/BookMultipleOrdersDialog.cs
@@ -0,0 +1,165 @@
+namespace BookMultipleOrders_2
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Controllers;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Notifications;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Order;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Tasks.LoadingScreenTasks;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Tasks.OrderTasks;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.LoadingScreens;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+ using OrderStatus = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Order.Status;
+ using Status = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Tasks.Status;
+
+ public class BookMultipleOrdersDialog : LoadingDialog
+ {
+ private readonly List orderGuids = new List();
+ private readonly List ordersToBook = new List();
+ private readonly List ordersThatShouldNotBeBooked = new List();
+ private readonly List ordersThatWereSuccessfullyBooked = new List();
+ private readonly List ordersThatFailedToGetBooked = new List();
+
+ public BookMultipleOrdersDialog(Helpers helpers) : base(helpers)
+ {
+ }
+
+ protected override void GetScriptInput()
+ {
+ string scriptParameter = Engine.GetScriptParam("OrderIds").Value;
+
+ foreach (var orderId in scriptParameter.Split(','))
+ {
+ if (Guid.TryParse(orderId, out var orderGuid))
+ {
+ orderGuids.Add(orderGuid);
+ }
+ else
+ {
+ Log(nameof(GetScriptInput), $"Unable to parse {orderId} to a Guid");
+ }
+ }
+ }
+
+ protected override void CollectActions()
+ {
+ methodsToExecute.Add(GetOrdersAndLocks);
+ methodsToExecute.Add(StartChangeTracking);
+ methodsToExecute.Add(GetUserInfo);
+ methodsToExecute.Add(BookOrders);
+ methodsToExecute.Add(ShowResultsInUi);
+ }
+
+ private void StartChangeTracking()
+ {
+ ordersToBook.ForEach(o => o.AcceptChanges());
+ }
+
+ protected override void SendReportButton_Pressed(object sender, EventArgs e)
+ {
+ string title = "Exception while booking multiple orders [" + DateTime.Now + "]";
+
+ string message = $"Orders: {string.Join(",", ordersToBook.Select(o => o.Name))}
User: {Engine.UserLoginName}
Timestamp: {DateTime.Now}
Exception: {informationMessageLabel.Text.Replace(" at ", "
at ")}";
+
+ NotificationManager.SendMailToSkylineDevelopers(Helpers, title, message);
+
+ reportSuccessfullySentLabel.IsVisible = true;
+ }
+
+ private void GetOrdersAndLocks()
+ {
+ foreach (var orderGuid in orderGuids)
+ {
+ var getOrderTask = new GetOrderTask(Helpers, orderGuid);
+ Tasks.Add(getOrderTask);
+ getOrderTask.Execute();
+ if (getOrderTask.Status == Status.Fail) continue;
+
+ var getLockTask = new GetOrderLockTask(Helpers, getOrderTask.Order.Id);
+ Tasks.Add(getLockTask);
+ getLockTask.Execute();
+
+ if (getLockTask.Status == Status.Fail) continue;
+
+ if (getOrderTask.Order.Status == OrderStatus.Preliminary && getLockTask.LockInfo != null && getLockTask.LockInfo.IsLockGranted)
+ {
+ ordersToBook.Add(getOrderTask.Order);
+ }
+ else
+ {
+ ordersThatShouldNotBeBooked.Add(getOrderTask.Order);
+ }
+ }
+ }
+
+ private void GetUserInfo()
+ {
+ var getUserInfoTask = new GetBaseUserInfoTask(Helpers);
+ Tasks.Add(getUserInfoTask);
+
+ IsSuccessful &= getUserInfoTask.Execute();
+ if (!IsSuccessful) return;
+
+ UserInfo = getUserInfoTask.UserInfo;
+ }
+
+ private void BookOrders()
+ {
+ foreach (var order in ordersToBook)
+ {
+ Helpers.AddOrderReferencesForLogging(order.Id);
+
+ if (UserInfo.IsMcrUser) order.Status = OrderStatus.Confirmed;
+ else if (order.Status == OrderStatus.Preliminary || order.Status == OrderStatus.Cancelled || order.Status == OrderStatus.Rejected) order.Status = OrderStatus.Planned;
+ else if (order.Status == OrderStatus.Confirmed) order.Status = OrderStatus.ChangeRequested;
+ else
+ {
+ // No order status update required
+ }
+
+ if (!new OrderValidator(Helpers, order, UserInfo, Options.None).Validate())
+ {
+ ordersThatShouldNotBeBooked.Add(order);
+ continue;
+ }
+
+ var updateResult = order.AddOrUpdate(Helpers, UserInfo.IsMcrUser);
+ Helpers.LockManager.ReleaseOrderLock(order.Id);
+ Tasks.AddRange(updateResult.Tasks);
+
+ if (!updateResult.UpdateWasSuccessful)
+ {
+ ordersThatFailedToGetBooked.Add(order);
+ }
+ else
+ {
+ ordersThatWereSuccessfullyBooked.Add(order);
+ }
+ }
+ }
+
+ private void ShowResultsInUi()
+ {
+ var sb = new StringBuilder();
+
+ if (ordersThatWereSuccessfullyBooked.Any())
+ {
+ sb.Append($"Orders {string.Join(", ", ordersThatWereSuccessfullyBooked.Select(o => o.Name))} were successfully booked. \n");
+ }
+
+ if (ordersThatFailedToGetBooked.Any())
+ {
+ sb.Append($"Orders {string.Join(", ", ordersThatFailedToGetBooked.Select(o => o.Name))} failed to get booked. \n");
+ }
+
+ if (ordersThatShouldNotBeBooked.Any())
+ {
+ sb.Append($"Orders {string.Join(", ", ordersThatShouldNotBeBooked.Select(o => o.Name))} are not Preliminary, not valid or couldn't get a valid lock \n");
+ }
+
+ PrepareUiForManualMessage(sb.ToString(), showSendReportButton: false, showExceptionWidgets: false);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/BookMultipleOrders_2.csproj b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/BookMultipleOrders_2.csproj
new file mode 100644
index 0000000..650b014
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/BookMultipleOrders_2.csproj
@@ -0,0 +1,101 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {E10BD658-9B0E-4A95-97B7-C288C429C094}
+ Library
+ Properties
+ BookMultipleOrders_2
+ BookMultipleOrders_2
+ v4.7.2
+ 512
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\BookMultipleOrders_2.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\BookMultipleOrders_2.xml
+
+
+ None
+
+
+
+ ..\Dlls\SLMediationSnippets.dll
+
+
+ ..\Dlls\SLSRMLibrary.dll
+ C:\Skyline DataMiner\Files\SLSRMLibrary.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.3.5
+
+
+ 7.0.1
+
+
+
+
+ {121dd302-df4b-4f49-b6f9-b3ad358bd842}
+ Library_1
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/Properties/AssemblyInfo.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..80893a7
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("BookMultipleOrders_2")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("BookMultipleOrders_2")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("C0DD7709-41FC-4519-88F6-7D7EDDE8A6AB")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/Script.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/Script.cs
new file mode 100644
index 0000000..8509546
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/Script.cs
@@ -0,0 +1,147 @@
+/*
+****************************************************************************
+* Copyright (c) 2021, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+dd/mm/2021 1.0.0.1 XXX, Skyline Initial version
+****************************************************************************
+*/
+
+
+
+//---------------------------------
+// BookMultipleOrders_2.cs
+//---------------------------------
+
+namespace BookMultipleOrders_2
+{
+ using System;
+ using Skyline.DataMiner.Automation;
+ using Skyline.DataMiner.Utils.InteractiveAutomationScript;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+ using ExceptionDialog = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Reports.ExceptionDialog;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Configuration;
+
+ ///
+ /// DataMiner Script Class.
+ ///
+ class Script : IDisposable
+ {
+ private InteractiveController app;
+ private Helpers helpers;
+ private bool disposedValue;
+
+ ///
+ /// The Script entry point.
+ ///
+ /// Link with SLScripting process.
+ public void Run(Engine engine)
+ {
+ try
+ {
+ //engine.ShowUI();
+ engine.SetFlag(RunTimeFlags.NoKeyCaching);
+ engine.SetFlag(RunTimeFlags.NoCheckingSets);
+ engine.SetFlag(RunTimeFlags.NoInformationEvents);
+ engine.Timeout = TimeSpan.FromHours(10);
+
+ app = new InteractiveController(engine);
+ helpers = new Helpers(engine, Scripts.BookMultipleOrders);
+
+ var bookMultipleOrdersDialog = new BookMultipleOrdersDialog(helpers);
+ bookMultipleOrdersDialog.Execute();
+ helpers.LockManager.ReleaseLocks();
+ app.Run(bookMultipleOrdersDialog);
+ }
+ catch (ScriptAbortException)
+ {
+ // nothing
+ }
+ catch (InteractiveUserDetachedException)
+ {
+ // nothing
+ }
+ catch (Exception e)
+ {
+ helpers?.Log(nameof(Script), nameof(Run), $"Exception: {e}");
+ ShowExceptionDialog(engine, e);
+ }
+ finally
+ {
+ helpers?.LockManager.ReleaseLocks();
+ Dispose();
+ }
+ }
+
+ private void ShowExceptionDialog(Engine engine, Exception exception)
+ {
+ var dialog = new ExceptionDialog(engine, exception);
+ dialog.OkButton.Pressed += (sender, args) => engine.ExitSuccess("Something went wrong during the booking of multiple orders.");
+
+ if (app.IsRunning) app.ShowDialog(dialog);
+ else app.Run(dialog);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ helpers.Dispose();
+ }
+
+ disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/app.config b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/app.config
new file mode 100644
index 0000000..fda1974
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/app.config
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/stylecop.json b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/BookMultipleOrders_2/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders.xml b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders.xml
new file mode 100644
index 0000000..10626eb
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders.xml
@@ -0,0 +1,31 @@
+
+
+ CancelMultipleOrders
+ Script 1.0.1.77
+ Automation
+ SKYLINE2\VictorSC
+ FALSE
+ YLE/Customer UI
+
+
+
+
+
+
+
+
+
+ OrderIds
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/.editorconfig b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/.editorconfig
new file mode 100644
index 0000000..a612a7a
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/CancelMultipleOrdersProgressDialog.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/CancelMultipleOrdersProgressDialog.cs
new file mode 100644
index 0000000..b15b5a0
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/CancelMultipleOrdersProgressDialog.cs
@@ -0,0 +1,192 @@
+namespace CancelMultipleOrders_2
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Notifications;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Order;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Tasks.LoadingScreenTasks;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Tasks.OrderTasks;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.LoadingScreens;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+ using OrderStatus = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Order.Status;
+ using Status = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Tasks.Status;
+
+ public class CancelMultipleOrdersProgressDialog : LoadingDialog
+ {
+ private readonly string reasonForCancellation;
+ private readonly List orderGuids = new List();
+ private readonly List retrievedOrders = new List();
+ private readonly List orderIdsThatFailedToBeRetrieved = new List();
+ private readonly List ordersToCancel = new List();
+ private readonly List ordersThatFailedToBeCancelled = new List();
+ private readonly List lockedOrders = new List();
+ private readonly List ordersThatCantBeCancelled = new List();
+ private readonly List ordersThatSucceededToBeCancelled = new List();
+
+ public CancelMultipleOrdersProgressDialog(Helpers helpers, string reasonForCancellation) : base(helpers)
+ {
+ this.reasonForCancellation = reasonForCancellation;
+ }
+
+ protected override void GetScriptInput()
+ {
+ string scriptParameter = Engine.GetScriptParam("OrderIds").Value;
+
+ foreach (var orderId in scriptParameter.Split(','))
+ {
+ if (Guid.TryParse(orderId, out var orderGuid))
+ {
+ orderGuids.Add(orderGuid);
+ Helpers.AddOrderReferencesForLogging(orderGuid);
+ }
+ else
+ {
+ Engine.Log($"Run|Unable to parse {orderId} to a Guid");
+ }
+ }
+ }
+
+ protected override void CollectActions()
+ {
+ methodsToExecute.Add(InitializeOrderLogger);
+ methodsToExecute.Add(GetOrders);
+ methodsToExecute.Add(GetLocks);
+ methodsToExecute.Add(CancelOrders);
+ methodsToExecute.Add(ShowResultsInUi);
+ }
+
+ protected override void SendReportButton_Pressed(object sender, EventArgs e)
+ {
+ string title = "Exception while canceling multiple orders [" + DateTime.Now + "]";
+
+ string message = $"Orders: {string.Join(",", ordersToCancel.Select(o => o.Name))}
User: {Engine.UserLoginName}
Timestamp: {DateTime.Now}
Exception: {informationMessageLabel.Text.Replace(" at ", "
at ")}";
+
+ NotificationManager.SendMailToSkylineDevelopers(Helpers, title, message);
+
+ reportSuccessfullySentLabel.IsVisible = true;
+ }
+
+ private void InitializeOrderLogger()
+ {
+ Helpers.Log(nameof(CancelMultipleOrdersProgressDialog), "START SCRIPT", "Cancel Multiple Orders");
+ }
+
+ private void GetOrders()
+ {
+ LogActionStart(nameof(GetOrders), out var stopWatch);
+
+ foreach (var orderGuid in orderGuids)
+ {
+ var getOrderTask = new GetOrderTask(Helpers, orderGuid);
+ Tasks.Add(getOrderTask);
+
+ IsSuccessful &= getOrderTask.Execute();
+ if (IsSuccessful)
+ {
+ retrievedOrders.Add(getOrderTask.Order);
+ }
+ else
+ {
+ orderIdsThatFailedToBeRetrieved.Add(orderGuid);
+ }
+ }
+
+ Log(nameof(GetOrders), $"Unable to retrieve orders {string.Join(", ", orderIdsThatFailedToBeRetrieved)}");
+
+ LogActionCompleted(nameof(GetOrders), stopWatch);
+ }
+
+ private void GetLocks()
+ {
+ LogActionStart(nameof(GetLocks), out var stopWatch);
+
+ foreach (var order in retrievedOrders)
+ {
+ var getLockTask = new GetOrderLockTask(Helpers, order.Id);
+ Tasks.Add(getLockTask);
+
+ IsSuccessful &= getLockTask.Execute();
+ if (!IsSuccessful) return;
+
+ if (getLockTask.Status == Status.Fail) continue;
+
+ LockInfos.Add(getLockTask.LockInfo);
+
+ if (!order.CanCancel)
+ {
+ ordersThatCantBeCancelled.Add(order);
+ }
+ else if (!getLockTask.LockInfo.IsLockGranted)
+ {
+ lockedOrders.Add(order);
+ }
+ else
+ {
+ ordersToCancel.Add(order);
+ }
+ }
+
+ LogActionCompleted(nameof(GetLocks), stopWatch);
+ }
+
+ private void CancelOrders()
+ {
+ LogActionStart(nameof(CancelOrders), out var stopWatch);
+
+ foreach (var order in ordersToCancel)
+ {
+ order.ReasonForCancellationOrRejection = reasonForCancellation;
+ var updateOrderStatusTask = new UpdateOrderStatusTask(Helpers, order, OrderStatus.Cancelled);
+ Tasks.Add(updateOrderStatusTask);
+ updateOrderStatusTask.Execute();
+
+ Helpers.LockManager.ReleaseOrderLock(order.Id);
+
+ if (updateOrderStatusTask.Status == Status.Fail)
+ {
+ ordersThatFailedToBeCancelled.Add(order);
+ }
+ else
+ {
+ ordersThatSucceededToBeCancelled.Add(order);
+ }
+ }
+
+ LogActionCompleted(nameof(CancelOrders), stopWatch);
+ }
+
+ private void ShowResultsInUi()
+ {
+ var sb = new StringBuilder();
+
+ if (ordersThatSucceededToBeCancelled.Any())
+ {
+ sb.AppendLine($"Order{(lockedOrders.Count > 1 ? "s" : String.Empty)} {string.Join(", ", ordersThatSucceededToBeCancelled.Select(o => o.Name))} {(lockedOrders.Count > 1 ? "were" : "was")} successfully canceled.");
+ }
+
+ if (orderIdsThatFailedToBeRetrieved.Any())
+ {
+ sb.AppendLine($"Some orders could not be retrieved.");
+ }
+
+ if (ordersThatFailedToBeCancelled.Any())
+ {
+ sb.AppendLine($"Orders {string.Join(", ", ordersThatFailedToBeCancelled.Select(o => o.Name))} failed to get canceled.");
+ }
+
+ foreach (var order in ordersThatCantBeCancelled)
+ {
+ sb.AppendLine($"Order {order.Name} can't be canceled because is has state {order.Status.GetDescription()}");
+ }
+
+ if (lockedOrders.Any())
+ {
+ sb.AppendLine($"Order{(lockedOrders.Count > 1 ? "s" : String.Empty)} {string.Join(", ", lockedOrders.Select(o => o.Name))} couldn't be canceled because {(lockedOrders.Count > 1 ? "they are" : "it is")} locked.");
+ }
+
+ PrepareUiForManualMessage(sb.ToString(), showSendReportButton: false, showExceptionWidgets: false);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/CancelMultipleOrders_2.csproj b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/CancelMultipleOrders_2.csproj
new file mode 100644
index 0000000..97898fa
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/CancelMultipleOrders_2.csproj
@@ -0,0 +1,101 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {CFA4A2CE-A230-4303-83B1-677B23B66266}
+ Library
+ Properties
+ CancelMultipleOrders_2
+ CancelMultipleOrders_2
+ v4.7.2
+ 512
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\CancelMultipleOrders_2.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\CancelMultipleOrders_2.xml
+
+
+ None
+
+
+
+ ..\Dlls\SLMediationSnippets.dll
+
+
+ ..\Dlls\SLSRMLibrary.dll
+ C:\Skyline DataMiner\Files\SLSRMLibrary.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10.3.5
+
+
+ 7.0.1
+
+
+
+
+ {121dd302-df4b-4f49-b6f9-b3ad358bd842}
+ Library_1
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/Properties/AssemblyInfo.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d14bf05
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("CancelMultipleOrders_2")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("CancelMultipleOrders_2")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("A2D7791A-1055-4790-B9DA-722276902179")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/Script.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/Script.cs
new file mode 100644
index 0000000..6a7502a
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/Script.cs
@@ -0,0 +1,158 @@
+/*
+****************************************************************************
+* Copyright (c) 2021, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+dd/mm/2021 1.0.0.1 XXX, Skyline Initial version
+****************************************************************************
+*/
+
+namespace CancelMultipleOrders_2
+{
+ using System;
+ using Skyline.DataMiner.Automation;
+ using Skyline.DataMiner.Utils.InteractiveAutomationScript;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Order;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+ using ExceptionDialog = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.UI.Reports.ExceptionDialog;
+ using OrderStatus = Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Order.Status;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Configuration;
+
+ ///
+ /// DataMiner Script Class.
+ ///
+ class Script : IDisposable
+ {
+ private Helpers helpers;
+ private InteractiveController app;
+ private ProvideReasonForStatusChangeDialog provideReasonForStatusChangeDialog;
+ private CancelMultipleOrdersProgressDialog cancelMultipleOrdersProgresssDialog;
+
+ ///
+ /// The Script entry point.
+ ///
+ /// Link with SLScripting process.
+ public void Run(Engine engine)
+ {
+ try
+ {
+ //engine.ShowUI();
+ engine.Timeout = TimeSpan.FromHours(10);
+
+ app = new InteractiveController(engine);
+ helpers = new Helpers(engine, Scripts.CancelMultipleOrders);
+
+ provideReasonForStatusChangeDialog = new ProvideReasonForStatusChangeDialog(engine, OrderStatus.Cancelled);
+ provideReasonForStatusChangeDialog.OkButton.Pressed += CancelOrders;
+ app.Run(provideReasonForStatusChangeDialog);
+ }
+ catch (ScriptAbortException)
+ {
+ // nothing
+ }
+ catch (InteractiveUserDetachedException)
+ {
+ // nothing
+ }
+ catch (Exception e)
+ {
+ helpers.Log(nameof(Script), nameof(Run), $"Something went wrong: {e}");
+ ShowExceptionDialog(e);
+ }
+ finally
+ {
+ helpers.LockManager.ReleaseLocks();
+ Dispose();
+ }
+ }
+
+ private void CancelOrders(object sender, EventArgs e)
+ {
+ cancelMultipleOrdersProgresssDialog = new CancelMultipleOrdersProgressDialog(helpers, provideReasonForStatusChangeDialog.ReasonForStatusChange);
+ cancelMultipleOrdersProgresssDialog.Execute();
+ helpers.LockManager.ReleaseLocks();
+
+ if (app.IsRunning) app.ShowDialog(cancelMultipleOrdersProgresssDialog);
+ else app.Run(cancelMultipleOrdersProgresssDialog);
+ }
+
+ private void ShowExceptionDialog(Exception exception)
+ {
+ var dialog = new ExceptionDialog((Engine)helpers.Engine, exception);
+ dialog.OkButton.Pressed += (sender, args) => helpers.Engine.ExitSuccess("Something went wrong during the creation of the new Order.");
+
+ if (app.IsRunning) app.ShowDialog(dialog);
+ else app.Run(dialog);
+ }
+
+ #region IDisposable Support
+ private bool disposedValue; // To detect redundant calls
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue && disposing)
+ {
+ helpers.Dispose();
+ }
+
+ disposedValue = true;
+ }
+
+ ~Script()
+ {
+ // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
+ Dispose(false);
+ }
+
+ // This code added to correctly implement the disposable pattern.
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/app.config b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/app.config
new file mode 100644
index 0000000..fda1974
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/app.config
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/stylecop.json b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/stylecop.json
new file mode 100644
index 0000000..3703ae9
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/CancelMultipleOrders_2/stylecop.json
@@ -0,0 +1,76 @@
+{
+ // ACTION REQUIRED: This file was automatically added to your project, but it
+ // will not take effect until additional steps are taken to enable it. See the
+ // following page for additional information:
+ //
+ // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
+
+ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
+ "settings": {
+ "namingRules": {
+ "allowCommonHungarianPrefixes": false,
+ "allowedHungarianPrefixes": [
+ "ab",
+ "ac",
+ "ad",
+ "af",
+ "ai",
+ "al",
+ "ao",
+ "as",
+ "ax",
+ "b",
+ "by",
+ "c",
+ "d",
+ "dt",
+ "e",
+ "f",
+ "hs",
+ "i",
+ "ip",
+ "is",
+ "l",
+ "lb",
+ "lc",
+ "ld",
+ "lf",
+ "li",
+ "ll",
+ "lo",
+ "ls",
+ "lx",
+ "my",
+ "no",
+ "o",
+ "qb",
+ "qc",
+ "qd",
+ "qf",
+ "qi",
+ "ql",
+ "qo",
+ "qs",
+ "qx",
+ "rx",
+ "s",
+ "sb",
+ "sc",
+ "sd",
+ "sf",
+ "sh",
+ "si",
+ "sl",
+ "so",
+ "ss",
+ "sx",
+ "to",
+ "ts",
+ "tx",
+ "ui",
+ "ul",
+ "x"
+ ]
+ }
+ }
+}
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices.xml b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices.xml
new file mode 100644
index 0000000..b0bafda
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices.xml
@@ -0,0 +1,28 @@
+
+
+ ClearExpiredServices
+ Script 1.0.1.77
+ Automation
+ SKYLINE2\Joey
+ FALSE
+ YLE/SRM
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices_1/.editorconfig b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices_1/.editorconfig
new file mode 100644
index 0000000..c54055f
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices_1/.editorconfig
@@ -0,0 +1,17 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+trim_trailing_whitespace = true
+
+[*.cs]
+dotnet_sort_system_directives_first = true
+
+# SA1501: Statement should not be on a single line
+dotnet_diagnostic.SA1501.severity = none
+
+# S1172: Unused method parameters should be removed
+dotnet_diagnostic.S1172.severity = none
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices_1/ClearExpiredServices_1.csproj b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices_1/ClearExpiredServices_1.csproj
new file mode 100644
index 0000000..8c660bf
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices_1/ClearExpiredServices_1.csproj
@@ -0,0 +1,101 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {951F433D-47BB-46CD-9577-38DC2EEF38F1}
+ Library
+ Properties
+ ClearExpiredServices_1
+ ClearExpiredServices_1
+ v4.7.2
+ 512
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-debug.ruleset
+ bin\Debug\ClearExpiredServices_1.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ ..\Internal\Code Analysis\qaction-release.ruleset
+ bin\Release\ClearExpiredServices_1.xml
+
+
+ None
+
+
+
+ ..\Dlls\SLMediationSnippets.dll
+
+
+ ..\Dlls\SLSRMLibrary.dll
+ C:\Skyline DataMiner\Files\SLSRMLibrary.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.1.0.5
+
+
+ 10.3.5
+
+
+ 7.0.1
+
+
+
+
+ {121dd302-df4b-4f49-b6f9-b3ad358bd842}
+ Library_1
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices_1/Properties/AssemblyInfo.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices_1/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f98fa16
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices_1/Properties/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("ClearExpiredServices_1")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Skyline Communications")]
+[assembly: AssemblyProduct("ClearExpiredServices_1")]
+[assembly: AssemblyCopyright("Copyright © Skyline Communications")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: Guid("F8794006-B94C-4989-8415-3470A9741382")]
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices_1/Script.cs b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices_1/Script.cs
new file mode 100644
index 0000000..63617ce
--- /dev/null
+++ b/DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/ClearExpiredServices_1/Script.cs
@@ -0,0 +1,384 @@
+/*
+****************************************************************************
+* Copyright (c) 2021, Skyline Communications NV All Rights Reserved. *
+****************************************************************************
+
+By using this script, you expressly agree with the usage terms and
+conditions set out below.
+This script and all related materials are protected by copyrights and
+other intellectual property rights that exclusively belong
+to Skyline Communications.
+
+A user license granted for this script is strictly for personal use only.
+This script may not be used in any way by anyone without the prior
+written consent of Skyline Communications. Any sublicensing of this
+script is forbidden.
+
+Any modifications to this script by the user are only allowed for
+personal use and within the intended purpose of the script,
+and will remain the sole responsibility of the user.
+Skyline Communications will not be responsible for any damages or
+malfunctions whatsoever of the script resulting from a modification
+or adaptation by the user.
+
+The content of this script is confidential information.
+The user hereby agrees to keep this confidential information strictly
+secret and confidential and not to disclose or reveal it, in whole
+or in part, directly or indirectly to any person, entity, organization
+or administration without the prior written consent of
+Skyline Communications.
+
+Any inquiries can be addressed to:
+
+ Skyline Communications NV
+ Ambachtenstraat 33
+ B-8870 Izegem
+ Belgium
+ Tel. : +32 51 31 35 69
+ Fax. : +32 51 31 01 29
+ E-mail : info@skyline.be
+ Web : www.skyline.be
+ Contact : Ben Vandenberghe
+
+****************************************************************************
+Revision History:
+
+DATE VERSION AUTHOR COMMENTS
+
+dd/mm/2021 1.0.0.1 XXX, Skyline Initial version
+****************************************************************************
+*/
+
+namespace ClearExpiredServices_1
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using Skyline.DataMiner.Automation;
+ using Skyline.DataMiner.Core.DataMinerSystem.Common;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Configuration;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.DataMinerInterface;
+ using Skyline.DataMiner.DeveloperCommunityLibrary.YLE.Utilities;
+ using Skyline.DataMiner.Net.Messages;
+ using Skyline.DataMiner.Net.Messages.Advanced;
+ using Skyline.DataMiner.Net.Messages.SLDataGateway;
+ using Skyline.DataMiner.Net.ReportsAndDashboards;
+ using Skyline.DataMiner.Net.ResourceManager.Objects;
+ using Skyline.DataMiner.Net.ServiceManager.Objects;
+ using Skyline.DataMiner.Net.Ticketing;
+
+ ///
+ /// DataMiner Script Class.
+ ///
+ class Script : IDisposable
+ {
+ private Helpers helpers;
+ private TicketingGatewayHelper ticketingHelper;
+
+ ///
+ /// The Script entry point.
+ ///
+ /// Link with SLAutomation process.
+ public void Run(Engine engine)
+ {
+ helpers = new Helpers(engine, Scripts.ClearExpiredServices);
+ engine.Timeout = TimeSpan.FromHours(2);
+
+ ticketingHelper = new TicketingGatewayHelper { HandleEventsAsync = false };
+ ticketingHelper.RequestResponseEvent += (sender, args) => args.responseMessage = Engine.SLNet.SendSingleResponseMessage(args.requestMessage);
+
+ ReportInfo reportInfo = new ReportInfo();
+ reportInfo = RetrieveServicesToRemove(engine, reportInfo);
+ reportInfo = RetrieveServiceDefinitionsToRemove(reportInfo);
+
+ if (reportInfo.ServicesToRemove.Any()) RemoveServices(reportInfo.ServicesToRemove);
+ if (reportInfo.ReservationsToRemove.Any()) RemoveReservationInstances(reportInfo.ReservationsToRemove);
+ if (reportInfo.TicketsToRemove.Any()) RemoveTickets(ticketingHelper, reportInfo.TicketsToRemove);
+ //if (reportInfo.ServiceDefinitionsToRemove.Any()) RemoveServiceDefinitions(reportInfo.ServiceDefinitionsToRemove);
+
+ GenerateReport(engine, reportInfo);
+
+ Dispose();
+ }
+
+ private void Log(string nameOfMethod, string message)
+ {
+ helpers?.Log(nameof(Script), nameOfMethod, message);
+ }
+
+ private ReportInfo RetrieveServicesToRemove(Engine engine, ReportInfo reportInfo)
+ {
+ var dms = Engine.SLNetRaw.GetDms();
+
+ // get the srm service view
+ var srmServiceViews = dms.GetViews().Where(v => v.Name.Contains("Services")).ToList();
+ if (!srmServiceViews.Any())
+ {
+ Log(nameof(RetrieveServicesToRemove), "No SRM service views found");
+ return reportInfo;
+ }
+
+ reportInfo.ServicesToRemove = new List();
+ reportInfo.ReservationsToRemove = new List();
+ reportInfo.TicketsToRemove = new List();
+
+ foreach (var service in dms.GetServices())
+ {
+ if (!service.Views.Overlaps(srmServiceViews))
+ {
+ // not an SRM service
+ continue;
+ }
+
+ // find reservation instance with name of this service
+ var reservationInstance = FindReservationInstance(service.Name);
+ if (reservationInstance == null)
+ {
+ reportInfo.ServicesToRemove.Add(service.DmsServiceId);
+ continue;
+ }
+
+ // check if it's an order or service
+ if (IsOrderReservationInstance(reservationInstance))
+ {
+ // Remove the DM Service if the order is finished (this should have happened by the SRM solution)
+ if (reservationInstance.End.AddHours(1) < DateTime.Now)
+ {
+ reportInfo.ServicesToRemove.Add(service.DmsServiceId);
+ }
+
+ // no need to remove the reservation instances of orders.
+ continue;
+ }
+
+ // find service order reservation instances
+ var orderReservationInstances = FindOrderReservationInstancesForService(reservationInstance);
+ bool isUsedByOneOrMoreOrders = orderReservationInstances.Any();
+
+ if (!isUsedByOneOrMoreOrders)
+ {
+ // remove service and service reservationInstance if there is no order reservation for it
+ reportInfo.ReservationsToRemove.Add(reservationInstance);
+ reportInfo.TicketsToRemove.AddRange(FindTicketsForService(ticketingHelper, reservationInstance));
+ reportInfo.ServicesToRemove.Add(service.DmsServiceId);
+ }
+ }
+
+ return reportInfo;
+ }
+
+ private ReportInfo RetrieveServiceDefinitionsToRemove(ReportInfo reportInfo)
+ {
+ reportInfo.ServiceDefinitionsToRemove = new List();
+
+ var serviceDefinitions = DataMinerInterface.ServiceManager.GetServiceDefinitions(helpers, ServiceDefinitionExposers.Name.NotMatches("_.*").AND(ServiceDefinitionExposers.Name.NotMatches(".*[.]Default"))).ToArray();
+
+ foreach (var serviceDefinition in serviceDefinitions)
+ {
+ try
+ {
+ var filter = ServiceReservationInstanceExposers.ServiceDefinitionID.Equal(serviceDefinition.ID);
+ var reservationInstances = DataMinerInterface.ResourceManager.GetReservationInstances(helpers, filter);
+
+ if (reservationInstances == null)
+ {
+ reportInfo.ExtraMessages.Add($"Received null when requesting reservation instances using service definition {serviceDefinition.Name}");
+ continue;
+ }
+
+ if (reservationInstances.Any()) continue; // the SD is being used
+
+ reportInfo.ServiceDefinitionsToRemove.Add(serviceDefinition);
+ }
+ catch (Exception e)
+ {
+ reportInfo.ExtraMessages.Add($"Exception occurred while getting reservations for definition {serviceDefinition.ID}: {e}");
+ }
+ }
+
+ return reportInfo;
+ }
+
+ private ReservationInstance FindReservationInstance(string name)
+ {
+ try
+ {
+ return DataMinerInterface.ResourceManager.GetReservationInstances(helpers, new ANDFilterElement(ReservationInstanceExposers.Name.Contains(name))).FirstOrDefault();
+ }
+ catch (Exception)
+ {
+ // no need to log
+ }
+
+ return null;
+ }
+
+ private static bool IsOrderReservationInstance(ReservationInstance reservationInstance)
+ {
+ try
+ {
+ var virtualPlatformProperty = reservationInstance.Properties.FirstOrDefault(p => p.Key == "Virtual Platform");
+ if (virtualPlatformProperty.Value == null || String.IsNullOrEmpty(Convert.ToString(virtualPlatformProperty.Value))) return true;
+
+ return virtualPlatformProperty.Value.ToString() == "Order";
+ }
+ catch (Exception)
+ {
+ // no need to log
+ }
+
+ return true;
+ }
+
+ private List FindOrderReservationInstancesForService(ReservationInstance serviceReservationInstance)
+ {
+ var orderReservationInstances = new List();
+
+ try
+ {
+ var contributingResourceFilter = ReservationInstanceExposers.ResourceIDsInReservationInstance.Contains(serviceReservationInstance.ID);
+
+ orderReservationInstances = DataMinerInterface.ResourceManager.GetReservationInstances(helpers, new ANDFilterElement(contributingResourceFilter)).ToList();
+ }
+ catch (Exception ex)
+ {
+ Log(nameof(FindOrderReservationInstancesForService), $"Exception occurred while finding order reservations using contributing resource {serviceReservationInstance.ID}: {ex}");
+ }
+
+ return orderReservationInstances;
+ }
+
+ private static List FindTicketsForService(TicketingGatewayHelper helper, ReservationInstance serviceReservationInstance)
+ {
+ try
+ {
+ return helper.GetTickets(filter: TicketingExposers.CustomTicketFields.DictStringField("Service ID").Equal(serviceReservationInstance.ID.ToString())).ToList();
+ }
+ catch (Exception)
+ {
+ // no need to log
+ }
+
+ return new List();
+ }
+
+ private static void GenerateReport(Engine engine, ReportInfo reportInfo)
+ {
+ var message = new StringBuilder();
+
+ message.AppendLine("Services to remove: ");
+ if (!reportInfo.ServicesToRemove.Any()) message.Append("None
");
+ foreach (var service in reportInfo.ServicesToRemove) message.AppendLine($"
{service.Value}");
+
+ message.AppendLine("
");
+ message.AppendLine("
Reservations to remove: ");
+ if (!reportInfo.ReservationsToRemove.Any()) message.Append("None
");
+ foreach (var reservationInstance in reportInfo.ReservationsToRemove) message.AppendLine($"
{reservationInstance.Name} [{reservationInstance.ID}]");
+
+ message.AppendLine("
");
+ message.AppendLine("
Tickets to remove: ");
+ if (!reportInfo.TicketsToRemove.Any()) message.Append("None
");
+ foreach (var ticket in reportInfo.TicketsToRemove) message.AppendLine($"
{ticket.ID}");
+
+ message.AppendLine("
");
+ message.AppendLine("
Service Definitions that are marked to be removed: ");
+ if (!reportInfo.ServiceDefinitionsToRemove.Any()) message.Append("None
");
+ foreach (var serviceDefinition in reportInfo.ServiceDefinitionsToRemove) message.AppendLine($"
{serviceDefinition.Name}");
+
+ message.AppendLine("
");
+ message.AppendLine("
Extra messages: ");
+ foreach(var extraMessage in reportInfo.ExtraMessages) message.AppendLine($"
{extraMessage}");
+
+ engine.SendEmail(new EmailOptions(message.ToString(), "YLE DEBUG - Clear Expired Services Report", "squad.deploy-the.pioneers@skyline.be"));
+ }
+
+ private void RemoveServices(List services)
+ {
+ foreach (var serviceId in services)
+ {
+ try
+ {
+ helpers.Engine.SendSLNetMessage(new SetDataMinerInfoMessage
+ {
+ Uia1 = new UIA(new[] { (uint)serviceId.AgentId, (uint)serviceId.ServiceId }),
+ What = 74
+ });
+ }
+ catch (Exception e)
+ {
+ Log(nameof(RemoveServices), $"Exception removing service '{serviceId}': {e}");
+ }
+ }
+ }
+
+ private void RemoveReservationInstances(List reservationInstances)
+ {
+ try
+ {
+ helpers.ResourceManager.RemoveReservationInstances(reservationInstances.ToArray());
+ }
+ catch (Exception e)
+ {
+ Log(nameof(RemoveReservationInstances), $"Exception removing reservations: {e}");
+ }
+ }
+
+ private void RemoveTickets(TicketingGatewayHelper helper, List tickets)
+ {
+ if (tickets.Any())
+ {
+ try
+ {
+ if (!helper.RemoveTickets(out var error, tickets.ToArray()))
+ {
+ Log(nameof(RemoveTickets), $"Error removing tickets: {error}");
+ }
+ }
+ catch (Exception e)
+ {
+ Log(nameof(RemoveTickets), $"Exception removing tickets: {e}");
+ }
+ }
+ }
+
+ private bool disposedValue;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue && disposing)
+ {
+ helpers.Dispose();
+
+ helpers.LockManager.ReleaseLocks();
+ }
+
+ disposedValue = true;
+ }
+
+ ~Script()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+
+ GC.SuppressFinalize(this);
+ }
+
+ class ReportInfo
+ {
+ public List ServicesToRemove { get; set; } = new List();
+
+ public List ReservationsToRemove { get; set; } = new List();
+
+ public List TicketsToRemove { get; set; } = new List();
+
+ public List ServiceDefinitionsToRemove { get; set; } = new List