/// <summary>
        /// Imports test cases and associated steps
        /// </summary>
        /// <param name="streamWriter"></param>
        /// <param name="spiraClient"></param>
        /// <param name="testRailApi"></param>
        private void ImportTestCases(StreamWriter streamWriter, SpiraSoapService.SoapServiceClient spiraClient, APIClient testRailApi)
        {
            //If we have any test suites, then we need to query by suite, otherwise we can get all for the project
            foreach (KeyValuePair <int, int> kvp in this.testSuiteMapping)
            {
                //Get the test cases from the TestRail API
                JArray testCases = (JArray)testRailApi.SendGet("get_cases/" + this.testRailProjectId + "&suite_id=" + kvp.Key);
                if (testCases != null)
                {
                    foreach (JObject testCase in testCases)
                    {
                        //Extract the user data
                        int testRailId = testCase["id"].Value <int>();

                        //Create the new SpiraTest test case
                        RemoteTestCase remoteTestCase = new RemoteTestCase();
                        remoteTestCase.Name = testCase["title"].Value <string>();
                        if (testCase["custom_description"] != null && testCase["custom_preconds"] != null)
                        {
                            string description = testCase["custom_description"].Value <string>();
                            string preconds    = testCase["custom_preconds"].Value <string>();
                            remoteTestCase.Description = description + " " + preconds;
                        }
                        remoteTestCase.TestCaseTypeId   = /* Functional */ 3;
                        remoteTestCase.TestCaseStatusId = /* Ready For Test */ 5;
                        if (testCase["priority_id"] != null)
                        {
                            int?testCasePriorityId = testCase["priority_id"].Value <int?>();
                            if (testCasePriorityId.HasValue && testCasePriorityId >= 1 && testCasePriorityId <= 4)
                            {
                                remoteTestCase.TestCasePriorityId = testCasePriorityId.Value;
                            }
                        }
                        if (testCase["created_by"] != null)
                        {
                            int?createdById = testCase["created_by"].Value <int?>();
                            if (createdById.HasValue && this.usersMapping.ContainsKey(createdById.Value))
                            {
                                remoteTestCase.AuthorId = this.usersMapping[createdById.Value];
                            }
                        }

                        //See if we have a suite or section to put it under (section takes precedence)
                        int?testSuiteId = null;
                        if (testCase["suite_id"] != null)
                        {
                            testSuiteId = testCase["suite_id"].Value <int?>();
                        }
                        int?testSectionId = null;
                        if (testCase["section_id"] != null)
                        {
                            testSectionId = testCase["section_id"].Value <int?>();
                        }

                        if (testSectionId.HasValue && this.testSuiteSectionMapping.ContainsKey(testSectionId.Value))
                        {
                            remoteTestCase.TestCaseFolderId = this.testSuiteSectionMapping[testSectionId.Value];
                        }
                        else if (testSuiteId.HasValue && this.testSuiteMapping.ContainsKey(testSuiteId.Value))
                        {
                            remoteTestCase.TestCaseFolderId = this.testSuiteMapping[testSuiteId.Value];
                        }
                        int newTestCaseId = spiraClient.TestCase_Create(remoteTestCase).TestCaseId.Value;
                        streamWriter.WriteLine("Added test case: " + testRailId);

                        //Add the test case to the release (if specified)
                        int?milestoneId = testCase["milestone_id"].Value <int?>();
                        if (milestoneId.HasValue && this.releaseMapping.ContainsKey(milestoneId.Value))
                        {
                            int releaseId = this.releaseMapping[milestoneId.Value];
                            spiraClient.Release_AddTestMapping(new RemoteReleaseTestCaseMapping()
                            {
                                ReleaseId = releaseId, TestCaseId = newTestCaseId
                            });
                        }

                        //Now see if we have steps (custom steps in TestRail)
                        JArray testSteps = testCase["custom_steps_separated"].Value <JArray>();
                        if (testSteps != null && testSteps.Count > 0)
                        {
                            streamWriter.WriteLine("Adding " + testSteps.Count + " custom steps to test case: " + testRailId);
                            foreach (JObject testStep in testSteps)
                            {
                                RemoteTestStep remoteTestStep = new RemoteTestStep();
                                remoteTestStep.Description    = testStep["content"].Value <string>();
                                remoteTestStep.ExpectedResult = testStep["expected"].Value <string>();
                                spiraClient.TestCase_AddStep(remoteTestStep, newTestCaseId);
                            }
                        }
                        streamWriter.WriteLine("Added custom steps to test case: " + testRailId);

                        //Add to the mapping hashtables
                        if (!this.testCaseMapping.ContainsKey(testRailId))
                        {
                            this.testCaseMapping.Add(testRailId, newTestCaseId);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Imports test cases and associated steps
        /// </summary>
        private void ImportTestCasesAndSteps(StreamWriter streamWriter, SpiraSoapService.SoapServiceClient spiraClient, TestLink testLinkApi)
        {
            //Loop through all the mapped, imported test suites
            foreach (KeyValuePair <int, int> kvp in this.testSuiteMapping)
            {
                //Get the test cases from the TestLink API
                int testSuiteId  = kvp.Key;
                int testFolderId = kvp.Value;
                streamWriter.WriteLine(String.Format("Getting test cases in test suite: {0}", testSuiteId));
                List <TestCaseFromTestSuite> testCasesInSuite = testLinkApi.GetTestCasesForTestSuite(testSuiteId, true);
                if (testCasesInSuite != null)
                {
                    foreach (TestCaseFromTestSuite testCaseInSuite in testCasesInSuite)
                    {
                        //Extract the user data
                        int    tlTestCaseId         = testCaseInSuite.id;
                        string tlTestCaseExternalId = testCaseInSuite.external_id;
                        streamWriter.WriteLine(String.Format("Finding test case: {0} - {1}", tlTestCaseId, tlTestCaseExternalId));

                        //Get the actual test case object (with steps)
                        try
                        {
                            TestCase testCase = testLinkApi.GetTestCase(tlTestCaseId);
                            if (testCase != null)
                            {
                                streamWriter.WriteLine(String.Format("Importing test case: {0}", tlTestCaseId));
                                string description = "";
                                if (!String.IsNullOrEmpty(testCase.summary))
                                {
                                    description += "<p>" + testCase.summary + "</p>";
                                }
                                if (!String.IsNullOrEmpty(testCase.preconditions))
                                {
                                    description += "<p>" + testCase.preconditions + "</p>";
                                }

                                //Reauthenticate at this point, in case disconnected
                                spiraClient.Connection_Authenticate2(Properties.Settings.Default.SpiraUserName, Properties.Settings.Default.SpiraPassword, "TestLinkImporter");
                                spiraClient.Connection_ConnectToProject(this.newProjectId);

                                //Create the new SpiraTest test case
                                RemoteTestCase remoteTestCase = new RemoteTestCase();
                                remoteTestCase.Name             = testCase.name;
                                remoteTestCase.Description      = description;
                                remoteTestCase.TestCaseTypeId   = /* Functional */ 3;
                                remoteTestCase.TestCaseStatusId = (testCase.active) ? /* Ready For Test */ 5 : /* Draft*/ 1;
                                remoteTestCase.CreationDate     = testCase.creation_ts;
                                if (testCase.importance >= 1 && testCase.importance <= 4)
                                {
                                    remoteTestCase.TestCasePriorityId = testCase.importance;
                                }

                                //We don't import the author currently
                                //remoteTestCase.AuthorId = this.usersMapping[createdById.Value];

                                //Map to the folder
                                remoteTestCase.TestCaseFolderId = testFolderId;

                                int newTestCaseId = spiraClient.TestCase_Create(remoteTestCase).TestCaseId.Value;
                                streamWriter.WriteLine("Added test case: " + tlTestCaseId);

                                //See if we have any test steps for this test case
                                if (testCase.steps != null && testCase.steps.Count > 0)
                                {
                                    streamWriter.WriteLine("Adding " + testCase.steps.Count + " test steps to test case: " + tlTestCaseId);
                                    foreach (TestStep testStep in testCase.steps)
                                    {
                                        RemoteTestStep remoteTestStep = new RemoteTestStep();
                                        remoteTestStep.Description    = testStep.actions;
                                        remoteTestStep.ExpectedResult = testStep.expected_results;
                                        spiraClient.TestCase_AddStep(remoteTestStep, newTestCaseId);
                                    }
                                    streamWriter.WriteLine("Added test steps to test case: " + tlTestCaseId);
                                }

                                //Add to the mapping hashtables
                                if (!this.testCaseMapping.ContainsKey(tlTestCaseId))
                                {
                                    this.testCaseMapping.Add(tlTestCaseId, newTestCaseId);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            streamWriter.WriteLine(String.Format("Error importing test case {0}: {1} ({2})", tlTestCaseId, ex.Message, ex.StackTrace));
                        }
                    }
                }
            }
        }