/// <summary>
 /// Performs validation and business logic checks on the CopyCourseSectionRequest values
 /// </summary>
 /// <param name="request"><see cref="CopyCourseSectionRequest">object</see></param>
 /// <exception cref="ArgumentNullException">Thrown when a required value is not set in the <see cref="CopyCourseSectionRequest">object</see></exception>
 /// <exception cref="ArgumentException">Thrown when there is a conflict between the values in the <see cref="CopyCourseSectionRequest">object</see></exception>
 /// <exception cref="ArgumentOutOfRangeException">Thrown when a value in the <see cref="CopyCourseSectionRequest">object</see> is invalid.</exception>
 private static void ValidateCopyCourseSectionRequest(CopyCourseSectionRequest request)
 {
     // Perform a Parameter Validation and Business Logic Check on the Request
     if (request.ClientString == null)
         throw new ArgumentNullException("The ClientString value is required.  Please correct and try the reqeust again.");
     else if (request.DestinationClientSortString == null)
         throw new ArgumentNullException("The DestinationClientSortString value is required.  Please correct and try the request again.");
     else if (request.DestinationCourseCallNumbers == null)
         throw new ArgumentNullException("The DestinationCourseCallNumbers value is required.  Please correct and try the request again.");
     else if (request.DestinationTermId == null && request.DestinationTermSourcedId == null)
         throw new ArgumentNullException("Either a DestinationTermId or DestinationTermSourcedId value is required.  Please correct and try the request again.");
     else if (request.SourceCourseCallNumber == null && request.SourceCourseId == null)
         throw new ArgumentNullException("Either a SourceCourseCallNumber or SourceCourseId value is required.  Please correct and try the request again.");
     else if (request.DestinationTermId != null && request.DestinationTermSourcedId != null)
         throw new ArgumentException("The DestinationTermId and DestinationTermSourcedId values are mutually exclusive.  Only set one of the values for a given Destination Term.  Please correct and try the request again.");
     else if (request.SourceCourseCallNumber != null && request.SourceCourseId != null)
         throw new ArgumentException("The SourceCourseCallNumber and SourceCourseId values are mutually exclusive.  Only set one of the values for a given Source Coruse.  Please correct and try the request again.");
     else if (request.DestinationSectionNumber > 255)
         throw new ArgumentOutOfRangeException("The DestinationSectionNumber has a Maximum allowed Value of 255.  Please correct and try the request again.");
     else if (request.DestinationTermSourcedId != null)
         if (!request.DestinationTermSourcedId.Contains(":"))
             throw new ArgumentOutOfRangeException("The DestinationTermSourcedId should have a format of \"{Source}:{Id}\".  Note the colon delimiter that seperates the two concatenated values.  " +
                 "In addition, please use your ClientString as the {Source} portion of this concatenated value.  Please correct and try the request again.");
 }
        /// <summary>
        /// Creates the XML payload for the CopyCourseSection Course API Request
        /// </summary>
        /// <param name="request"><see cref="CopyCourseSectionRequest">object</see></param>
        /// <returns><see cref="API.CourseSectionCopyRequestEx"/>object</returns>
        private API.CourseSectionCopyRequestEx SetCopyCourseSectionRequest(CopyCourseSectionRequest request)
        {
            // Initialize and Set the CopyCourseSectionRequest
            API.CourseSectionCopyRequestEx copyCourseSection = new API.CourseSectionCopyRequestEx();
            copyCourseSection.ClientString = request.ClientString;
            copyCourseSection.DestinationClientSortString = request.DestinationClientSortString;
            copyCourseSection.DestinationCourseIdentifiers = new API.CourseIdentifier[1];
            copyCourseSection.DestinationCourseIdentifiers[0] = new API.CourseIdentifier();

            // If more then 1 Call Number is used set them accordingly
            if (request.DestinationCourseCallNumbers.Length > 1)
            {
                // Initialize the CourseCallNumbers Object
                copyCourseSection.DestinationCourseIdentifiers[0].CourseCallNumbers = new API.CourseCallNumber[request.DestinationCourseCallNumbers.Length - 1];

                // Loop through the Call Numbers in the Request; the 1st is set in the DestinationCoruseIdentifier
                // the remainder, 2nd through n, are set in the CourseCallNumbers Object
                for (int i = 0; i < request.DestinationCourseCallNumbers.Length; i++)
                {
                    // Set the 1st Call Number accordingly, the rest are set in the CourseCallNumbers Object
                    if (i == 0)
                    {
                        copyCourseSection.DestinationCourseIdentifiers[0].ID = request.DestinationCourseCallNumbers[i];
                        copyCourseSection.DestinationCourseIdentifiers[0].MappingType = API.MappedIDType.CallNumber;
                    }
                    else
                    {
                        copyCourseSection.DestinationCourseIdentifiers[0].CourseCallNumbers[i - 1] = new API.CourseCallNumber();
                        copyCourseSection.DestinationCourseIdentifiers[0].CourseCallNumbers[i - 1].ClientCallNumber = request.DestinationCourseCallNumbers[i];
                    }
                }
            }
            else
            {
                copyCourseSection.DestinationCourseIdentifiers[0].ID = request.DestinationCourseCallNumbers[0];
                copyCourseSection.DestinationCourseIdentifiers[0].MappingType = API.MappedIDType.CallNumber;
            }

            copyCourseSection.DestinationDisplayCourseCode = request.DestinationDisplayCourseCode;
            copyCourseSection.DestinationSectionDescription = request.DestinationSectionDescription;
            copyCourseSection.DestinationSectionNumber = request.DestinationSectionNumber;
            copyCourseSection.DestinationSectionTitle = request.DestinationSectionTitle;
            copyCourseSection.DestinationTermID = 0;
            copyCourseSection.DestinationTermIdentifier = new API.TermIdentifier();

            // Set the Destination Term Identifier accordingly
            if (request.DestinationTermId != null)
            {
                copyCourseSection.DestinationTermIdentifier.ID = INTERNAL_IDENTIFIER + request.DestinationTermId;
                copyCourseSection.DestinationTermIdentifier.MappingType = API.MappedTermIDType.TermID;
            }
            else
            {
                copyCourseSection.DestinationTermIdentifier.ID = request.DestinationTermSourcedId;
                copyCourseSection.DestinationTermIdentifier.MappingType = API.MappedTermIDType.SourcedID;
            }

            copyCourseSection.IsACrossList = false;
            copyCourseSection.SourceCourseIdentifier = new API.CourseIdentifier();

            // Set the Source Coruse Identifier accordingly
            if (request.SourceCourseId != null)
            {
                copyCourseSection.SourceCourseIdentifier.ID = request.SourceCourseId;
                copyCourseSection.SourceCourseIdentifier.MappingType = API.MappedIDType.CourseID;
            }
            else
            {
                copyCourseSection.SourceCourseIdentifier.ID = request.SourceCourseCallNumber;
                copyCourseSection.SourceCourseIdentifier.MappingType = API.MappedIDType.CallNumber;
            }

            return copyCourseSection;
        }
        /// <summary>
        /// Generates a CopyCourseSection Course API Request
        /// </summary>
        /// <param name="request"><see cref="CopyCourseSectionRequest">object</see></param>
        /// <returns><see cref="Response"/>object</returns>
        public Response CopyCourseSection(CopyCourseSectionRequest request)
        {
            API.CourseSectionCopyRequestEx copyCourseSection = null;
            Response response = null;

            try
            {
                // Validate the Request Object
                ValidateCopyCourseSectionRequest(request);

                // Intialize and Set the CopyCourseSectionRequest
                copyCourseSection = SetCopyCourseSectionRequest(request);

                // Build the Response object from the SOAP response
                response = ReadCopyCourseSectionResponse(copyCourseSection);
            }
            catch (Exception ex)
            {
                Logger.Error("Exception from GenerateCopyCourseSectionRequest: ", ex);
                throw;
            }
            finally
            {
                if (this.courseAPI != null)
                    this.courseAPI.Close();
            }

            return response;
        }