public void TestPathTemplateLocation()
        {
            string templateDir = Path.Combine(GetSamplePortalTemplateDir(), "TestTemplates");

            Assert.IsTrue(Directory.Exists(templateDir));
            PathTemplateLocation location = new PathTemplateLocation(templateDir);
            Template             template;

            // Make sure that null fileName causes exception.
            try
            {
                template = new Template(null, location, null, null);
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex.Message.Contains("fileName"));
            }

            // Make sure that null location causes exception.
            try
            {
                template = new Template("filename.docx", null, null, null);
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex.Message.Contains("location"));
            }

            // Make sure that a null location causes exception.
            try
            {
                template = new Template(null, null, null);
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex.Message.Contains("location"));
            }

            // Try to locate a template with a null locator.
            try
            {
                template = Template.Locate(null);
                Assert.Fail();
            }
            catch (ArgumentNullException ex)
            {
                Assert.IsTrue(ex.Message.Contains("locator"));
            }

            // Try to locate a template with an empty string locator.
            try
            {
                template = Template.Locate("");
                Assert.Fail();
            }
            catch (ArgumentNullException ex)
            {
                Assert.IsTrue(ex.Message.Contains("locator"));
            }

            // Try to locate a template with an invalid template locator.
            try
            {
                template = Template.Locate(Util.EncryptString("abcdefg"));
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex.Message.Contains("Invalid template locator."));
            }

            try
            {
                HotDocs.Sdk.TemplateLocation.RegisterLocation(typeof(string));
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex.Message.Contains("The registered location must be of type TemplateLocation."));
            }

            // Try to get the TemplateType for an unknown template type.
            template = new Template("filename.tfx", location, null, null);
            Assert.AreEqual(TemplateType.Unknown, template.TemplateType);
            Assert.AreEqual("", template.Title);

            // Verify that null switches and key resolve to empty string.
            template = new Template("Demo Employment Agreement.docx", location, null, null);
            Assert.AreEqual("", template.Switches);
            Assert.AreEqual("", template.Key);



            string switches = "/ni";
            string key      = "Test file key";

            Dictionary <string, TemplateInfo> testTemplates = new Dictionary <string, TemplateInfo>();

            testTemplates.Add("Demo Employment Agreement.docx", new TemplateInfo()
            {
                Title        = "Employment Agreement",
                DocExtension = ".docx",
                TmpType      = TemplateType.WordDOCX,
                DocType      = DocumentType.WordDOCX
            });
            testTemplates.Add("Sample rtf template.rtf", new TemplateInfo()
            {
                Title        = "Sample rtf template",
                DocExtension = ".rtf",
                TmpType      = TemplateType.WordRTF,
                DocType      = DocumentType.WordRTF
            });
            testTemplates.Add("Sample wpt template.wpt", new TemplateInfo()
            {
                Title        = "Sample wpt template",
                DocExtension = ".wpd",
                TmpType      = TemplateType.WordPerfect,
                DocType      = DocumentType.WordPerfect
            });
            testTemplates.Add("sample interview template.cmp", new TemplateInfo()
            {
                Title        = "sample interview template",
                DocExtension = ".wpd",
                TmpType      = TemplateType.InterviewOnly,
                DocType      = DocumentType.Unknown
            });
            testTemplates.Add("sample hft template.hft", new TemplateInfo()
            {
                Title        = "sample hft template",
                DocExtension = ".hfd",
                TmpType      = TemplateType.HotDocsHFT,
                DocType      = DocumentType.HFD
            });
            testTemplates.Add("sample pdf template.hpt", new TemplateInfo()
            {
                Title        = "sample pdf template",
                DocExtension = ".pdf",
                TmpType      = TemplateType.HotDocsPDF,
                DocType      = DocumentType.PDF
            });
            testTemplates.Add("sample ttx template.ttx", new TemplateInfo()
            {
                Title        = "sample ttx template",
                DocExtension = ".txt",
                TmpType      = TemplateType.PlainText,
                DocType      = DocumentType.PlainText
            });


            foreach (var t in testTemplates)
            {
                template = new Template(t.Key, location, switches, key);
                Assert.AreEqual(template.Title, t.Value.Title);
                string filePath = template.GetFullPath();
                Assert.IsTrue(File.Exists(filePath));
                TestTemplate(template, t.Value);
            }
        }
        public void TestTemplateLocationEquatability()
        {
            string templateDir = Path.Combine(GetSamplePortalTemplateDir(), "TestTemplates");
            string dir1        = Path.Combine(templateDir, "temp");
            string dir2        = Path.Combine(templateDir, "tĕmp");
            string dir3        = Path.Combine(templateDir, "tëmp");

            // ensure PathTemplateLocation is case insensitive and not diacritic insensitive
            var loc1a = new PathTemplateLocation(dir1);
            var loc1b = new PathTemplateLocation(dir1.ToUpper());
            var loc2a = new PathTemplateLocation(dir2);
            var loc2b = new PathTemplateLocation(dir2.ToUpper());
            var loc3  = new PathTemplateLocation(dir3);
            PathTemplateLocation loc4 = null;
            PathTemplateLocation loc5 = null;

            // Try to get a TemplateLocation from an invalid locator.
            TemplateLocation loc = TemplateLocation.Locate(Util.EncryptString("abcdefg"));

            Assert.IsNull(loc);

            try
            {
                loc = TemplateLocation.Locate(Util.EncryptString("abc|defg"));
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsTrue(ex.Message.Contains("The type abc is not registered"));
            }

            // ensure PathTemplateLocation is case insensitive
            Assert.AreNotEqual(loc1a, "");
            Assert.AreEqual(loc1a, loc1b);
            Assert.AreEqual(loc1a.GetHashCode(), loc1b.GetHashCode());
            Assert.AreEqual(loc2a, loc2b);
            Assert.AreEqual(loc2a.GetHashCode(), loc2b.GetHashCode());
            // ensure PathTemplateLocation is not unicode/diacritic insensitive
            Assert.AreNotEqual(loc1a, loc2a);
            Assert.AreNotEqual(loc1a.GetHashCode(), loc2a.GetHashCode());
            Assert.AreNotEqual(loc1a, loc3);
            Assert.AreNotEqual(loc1a.GetHashCode(), loc3.GetHashCode());
            Assert.AreNotEqual(loc2b, loc3);
            Assert.AreNotEqual(loc2b.GetHashCode(), loc3.GetHashCode());
            // ensure we can tell the difference between nulls & non
            Assert.AreNotEqual(loc1a, loc4);
            Assert.AreEqual(loc4, loc5);             // null template locations are equal to each other, I suppose

            // ensure hashing is working pretty much like we expect it to
            var set = new HashSet <TemplateLocation>();

            set.Add(loc1a);
            Assert.IsTrue(set.Contains(loc1a));
            Assert.IsTrue(set.Contains(loc1b));
            Assert.IsFalse(set.Contains(loc2a));
            Assert.IsFalse(set.Contains(loc2b));
            Assert.IsFalse(set.Contains(loc3));
            Assert.IsFalse(set.Contains(loc4));
            Assert.IsFalse(set.Contains(loc5));
            set.Add(loc3);
            Assert.IsTrue(set.Contains(loc1a));
            Assert.IsTrue(set.Contains(loc1b));
            Assert.IsFalse(set.Contains(loc2a));
            Assert.IsFalse(set.Contains(loc2b));
            Assert.IsTrue(set.Contains(loc3));
            Assert.IsFalse(set.Contains(loc4));
            Assert.IsFalse(set.Contains(loc5));
            set.Add(loc2b);
            Assert.IsTrue(set.Contains(loc1a));
            Assert.IsTrue(set.Contains(loc1b));
            Assert.IsTrue(set.Contains(loc2a));
            Assert.IsTrue(set.Contains(loc2b));
            Assert.IsFalse(set.Contains(loc4));
            Assert.IsFalse(set.Contains(loc5));
            set.Add(loc4);
            Assert.IsTrue(set.Contains(loc4));
            Assert.IsTrue(set.Contains(loc5));

            // now test PackagePathTemplateLocation too (& in combination)
            var pkgloc1a = new PackagePathTemplateLocation(@"2f98a9f3-d106-44a8-ba16-e01d8cd65cbd", Path.Combine(dir1, "temp.pkg"));
            var pkgloc1b = new PackagePathTemplateLocation(@"2f98a9f3-d106-44a8-ba16-e01d8cd65cbd", Path.Combine(dir1, "TEMP.pkg"));
            var pkgloc2a = new PackagePathTemplateLocation(@"2f98a9f3-d106-44a8-ba16-e01d8cd65cbD", Path.Combine(dir1, "TEMP.pkg"));
            var pkgloc3a = new PackagePathTemplateLocation(@"l'identité unique", Path.Combine(dir3, "tëmp.pkg"));
            var pkgloc3b = new PackagePathTemplateLocation(@"l'identité unique", Path.Combine(dir3, "TËMP.pkg"));
            var pkgloc4a = new PackagePathTemplateLocation(@"l'identité unique", Path.Combine(dir2, "tĕmp.pkg"));
            var pkgloc5a = new PackagePathTemplateLocation(@"l'identite unique", Path.Combine(dir2, "TĔMP.pkg"));

            // ensure package ID is case sensitive & package path is case insensitive
            Assert.AreEqual(pkgloc1a, pkgloc1b);
            Assert.AreEqual(pkgloc1a.GetHashCode(), pkgloc1b.GetHashCode());
            Assert.AreNotEqual(pkgloc1a, pkgloc2a);
            Assert.AreNotEqual(pkgloc1a.GetHashCode(), pkgloc2a.GetHashCode());
            Assert.AreNotEqual(pkgloc1b, pkgloc2a);
            Assert.AreNotEqual(pkgloc1b.GetHashCode(), pkgloc2a.GetHashCode());
            // ensure package ID & path are diacritic sensitive
            Assert.AreEqual(pkgloc3a, pkgloc3b);
            Assert.AreEqual(pkgloc3a.GetHashCode(), pkgloc3b.GetHashCode());
            Assert.AreNotEqual(pkgloc3a, pkgloc4a);
            Assert.AreNotEqual(pkgloc3a.GetHashCode(), pkgloc4a.GetHashCode());
            Assert.AreNotEqual(pkgloc3b, pkgloc5a);
            Assert.AreNotEqual(pkgloc3b.GetHashCode(), pkgloc5a.GetHashCode());

            // TODO: check comparisons/equality of different types of TemplateLocations with each other.
            // (should always be not equal, hopefully even if null?)
        }