text:
namespace Microsoft.Protocols.TestSuites.MS_LISTSWS
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Services.Protocols;
    using Microsoft.Protocols.TestSuites.Common;
    using Microsoft.Protocols.TestTools;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// This scenario is designed to test the following operations with valid or invalid parameters.
    /// <list type="bullet">
    ///     <item>GetAttachmentCollection</item>
    ///     <item>AddAttachment</item>
    ///     <item>DeleteAttachment</item>
    /// </list>
    /// </summary>
    [TestClass]
    public class S04_OperationOnAttachment : TestClassBase
    {
        #region Private member variables

        /// <summary>
        /// Protocol adapter
        /// </summary>
        private IMS_LISTSWSAdapter listswsAdapterInstance;

        #endregion

        #region Additional test attributes

        /// <summary>
        /// Class initialization
        /// </summary>
        /// <param name="testContext">A parameter represents a testContext.</param>
        [ClassInitialize]
        public static void ClassInitialize(TestContext testContext)
        {
            TestClassBase.Initialize(testContext);
        }

        /// <summary>
        /// Class clean up
        /// </summary>
        [ClassCleanup]
        public static void ClassCleanup()
        {
            TestClassBase.Cleanup();
        }

        #endregion

        #region Test cases

        #region AddAttachment

        /// <summary>
        /// This test case is used to verify that the server returns error code "0x8007000d"
        /// when adding an attachment to a list item that content length equals to zero in AddAttachment operation.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC01_AddAttachment_ContentLengthZero()
        {
            #region Create a new list

            bool createListSucceeded = false;
            string listName = TestSuiteHelper.GetUniqueListName();
            string listGuid = TestSuiteHelper.CreateList(listName);
            createListSucceeded = !string.IsNullOrEmpty(listGuid);
            Site.Assert.IsTrue(createListSucceeded, "MSLISTSWS_S04_TC01_AddAttachment_ContentLenghZero, created a new list successfully.");
            #endregion

            #region Add a list item

            List<string> listItemIds = TestSuiteHelper.AddListItems(listGuid, 1);
            Site.Assert.IsNotNull(listItemIds, "Called AddListItems successfully.");

            #endregion

            #region Call the AddAttachment with the content length 0

            bool addAttachmentFail = false;
            string errorCode = null;
            try
            {
                // Call the AddAttachment with the content length 0
                string fileName = Common.GetConfigurationPropertyValue("AttachmentName", this.Site);
                byte[] attachment = new byte[0];
                this.listswsAdapterInstance.AddAttachment(listName, listItemIds[0], fileName, attachment);
            }
            catch (SoapException exp)
            {
                errorCode = TestSuiteHelper.GetErrorCode(exp);
                addAttachmentFail = true;
            }

            Site.Assert.IsTrue(addAttachmentFail, "MSLISTSWS_S04_TC01_AddAttachment_ContentLenghZero, calling AddAttachmet with content length 0 fails.");

            // Capture R299 if the error code 0x8007000d is returned.
            Site.CaptureRequirementIfAreEqual<string>(
                "0x8007000d",
                errorCode,
                299,
                @"[In AddAttachment] If the protocol client requests to add an attachment of content length zero, the protocol server MUST return a SOAP fault with error code 0x8007000d.");
            #endregion
        }

        /// <summary>
        /// This test case is used to test AddAttachment operation when at least one of its
        /// input parameters is invalid.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC02_AddAttachment_InvalidParameters()
        {
            #region Add a list and add a list item
            string uniqueListName = TestSuiteHelper.GetUniqueListName();
            string listId = TestSuiteHelper.CreateList(uniqueListName);

            // add one item, if not successful or added number not equal to the specified, will fail the test case.
            List<string> listitemIds = TestSuiteHelper.AddListItems(listId, 1);
            #endregion

            // Add an attachment using valid GUID as listName parameter.
            string attachmentFileName = Common.GetConfigurationPropertyValue("AttachmentName", this.Site);
            byte[] attachmentData = TestSuiteHelper.GetAttachmentContent(attachmentFileName);
            string addedListitemId = listitemIds[0];

            bool isSoapFaultReturned = false;
            string errorCode = string.Empty;
            try
            {
                string invalidGuidAndAndNocorrespondListName = TestSuiteHelper.GetInvalidGuidAndNocorrespondString();
                this.listswsAdapterInstance.AddAttachment(
                                                    invalidGuidAndAndNocorrespondListName,
                                                    addedListitemId,
                                                    attachmentFileName,
                                                    attachmentData);
            }
            catch (SoapException soapEx)
            {
                isSoapFaultReturned = true;
                errorCode = TestSuiteHelper.GetErrorCode(soapEx);
            }

            // if the error code 0x82000006 is returned, Capture R2750
            if (Common.IsRequirementEnabled(2750, this.Site))
            {
                Site.Log.Add(
                    LogEntryKind.Debug,
                    "The actual values: isSoapFaultReturned[{0}],errorCode[{1}] for requirement #R2750",
                    isSoapFaultReturned,
                    !string.IsNullOrEmpty(errorCode) ? "NullOrEmpty" : errorCode);

                Site.CaptureRequirementIfIsTrue(
                    isSoapFaultReturned && !string.IsNullOrEmpty(errorCode)
                    && errorCode.Equals("0x82000006", StringComparison.OrdinalIgnoreCase),
                    2750,
                    @"[In AddAttachment]Implementation does return a SOAP fault with error code 0x82000006, if listName does not correspond to a list from either of these checks.(SharePoint Foundation 2010 and above follow this behavior.)");
            }

            // Try to add an attachment with listItemID that does not correspond to a ListItem.
            isSoapFaultReturned = false;
            errorCode = string.Empty;
            try
            {
                // Current List only added one list item in this step.
                int notcorrespondListItemId = int.MaxValue;
                this.listswsAdapterInstance.AddAttachment(
                                                    listId,
                                                    notcorrespondListItemId.ToString(),
                                                    attachmentFileName,
                                                    attachmentData);
            }
            catch (SoapException soapEx)
            {
                isSoapFaultReturned = true;
                errorCode = TestSuiteHelper.GetErrorCode(soapEx);
            }

            // If a SOAP fault without error code is returned. capture R296 and R1551
            Site.Log.Add(
                    LogEntryKind.Debug,
                    "The actual value: isSoapFaultReturned[{0}],errorCode[{1}] for requirement #R296 and #R1551",
                    isSoapFaultReturned,
                    string.IsNullOrEmpty(errorCode) ? "NullOrEmpty" : errorCode);

            Site.CaptureRequirementIfIsTrue(
                isSoapFaultReturned && string.IsNullOrEmpty(errorCode),
                296,
                @"[In AddAttachment] If the listItemID does not correspond to a list item in a specified list on the site, the protocol server MUST return a SOAP fault.");

            Site.CaptureRequirementIfIsTrue(
                isSoapFaultReturned && string.IsNullOrEmpty(errorCode),
                1551,
                @"[In AddAttachment] [If the listItemID does not correspond to a list item in a specified list on the site, the protocol server MUST return a SOAP fault.]There is no error code returned for this fault.");

            // Add an attachment.
            string attachmentUrl = this.listswsAdapterInstance.AddAttachment(
                                                listId,
                                                addedListitemId,
                                                attachmentFileName,
                                                attachmentData);
            this.Site.Assert.IsTrue(
                                   attachmentUrl.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) > 0,
                                   "Add an attachment into the list item should be successful.");

            // Try to add an attachment with the same fileName into same list item.
            isSoapFaultReturned = false;
            errorCode = string.Empty;
            try
            {
                string duplicateFileName = attachmentFileName;
                this.listswsAdapterInstance.AddAttachment(
                                                listId,
                                                addedListitemId,
                                                duplicateFileName,
                                                attachmentData);
            }
            catch (SoapException soapEx)
            {
                isSoapFaultReturned = true;
                errorCode = TestSuiteHelper.GetErrorCode(soapEx);
            }

            // If an error code 0x81020067 is returned.Capture R297 and R1552
            Site.Log.Add(
                    LogEntryKind.Debug,
                    "The actual value: isSoapFaultReturned[{0}],errorCode[{1}] for requirement #R297 and #R1552",
                    isSoapFaultReturned,
                    errorCode.Equals("0x81020067") ? "0x81020067" : errorCode);

            Site.CaptureRequirementIfIsTrue(
               isSoapFaultReturned && !string.IsNullOrEmpty(errorCode)
               && errorCode.Equals("0x81020067", StringComparison.OrdinalIgnoreCase),
               297,
                @"[In AddAttachment] If the specified fileName is not unique for the specified list item's attachment collection then the protocol server MUST return a SOAP fault with error code 0x81020067.");

            Site.CaptureRequirementIfIsTrue(
                isSoapFaultReturned && !string.IsNullOrEmpty(errorCode)
                && errorCode.Equals("0x81020067", StringComparison.OrdinalIgnoreCase),
                1552,
                @"[In AddAttachment] [If the specified fileName is not unique for the specified list item's attachment collection then the protocol server MUST return a SOAP fault with error code 0x81020067.] This indicates that the specified fileName is already in use.");

            // Try to add an attachment without listItemID parameter.
            isSoapFaultReturned = false;
            errorCode = string.Empty;
            try
            {
                string emptyListItemId = string.Empty;
                this.listswsAdapterInstance.AddAttachment(
                                                listId,
                                                emptyListItemId,
                                                attachmentFileName,
                                                attachmentData);
            }
            catch (SoapException soapEx)
            {
                isSoapFaultReturned = true;
                errorCode = TestSuiteHelper.GetErrorCode(soapEx);
            }

            // Capture R300 if an error code 0x82000001 is returned.
            Site.Log.Add(
                    LogEntryKind.Debug,
                    "The actual value: isSoapFaultReturned[{0}],errorCode[{1}] for requirement #R300",
                    isSoapFaultReturned,
                    errorCode.Equals("0x82000001") ? "0x82000001" : errorCode);

            Site.CaptureRequirementIfIsTrue(
                  isSoapFaultReturned && !string.IsNullOrEmpty(errorCode)
                  && errorCode.Equals("0x82000001", StringComparison.OrdinalIgnoreCase),
                  300,
                  @"[In AddAttachment] If the protocol client request excludes the listItemID parameter, the protocol server MUST return a SOAP fault with error code 0x82000001.");

            // Add second list item on the current list, and now add attachment operation target to the second ListItem.
            List<string> secondAddedListitemIds = TestSuiteHelper.AddListItems(listId, 1);
            string secondListitemId = secondAddedListitemIds[0];
            isSoapFaultReturned = false;
            errorCode = string.Empty;
            try
            {
                this.listswsAdapterInstance.AddAttachment(
                                                listId,
                                                secondListitemId,
                                                attachmentFileName,
                                                null);
            }
            catch (SoapException soapEx)
            {
                isSoapFaultReturned = true;
                errorCode = TestSuiteHelper.GetErrorCode(soapEx);
            }

            // Capture R1554 if a SOAP fault without error code is returned.
            Site.Log.Add(
                    LogEntryKind.Debug,
                    "The actual value: isSoapFaultReturned[{0}],errorCode[{1}] for requirement #R1554",
                    isSoapFaultReturned,
                    string.IsNullOrEmpty(errorCode) ? "IsNullOrEmpty" : errorCode);

            Site.CaptureRequirementIfIsTrue(
                    isSoapFaultReturned && string.IsNullOrEmpty(errorCode),
                    1554,
                    @"[In AddAttachment] Otherwise [if the protocol client request includes the listItemID parameter and], if the listName or attachment parameters are missing, the protocol server MUST return a SOAP fault with no error code.");
        }

        /// <summary>
        /// This test case is used to verify that the server returns error code "0x81020073" with FileName parameter is Null in AddAttachment operation.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC03_AddAttachment_NullFileName()
        {
            #region Create a new list

            bool createListSucceeded = false;
            string listName = TestSuiteHelper.GetUniqueListName();
            string listGuid = TestSuiteHelper.CreateList(listName);
            createListSucceeded = !string.IsNullOrEmpty(listGuid);
            Site.Assert.IsTrue(createListSucceeded, "MSLISTSWS_S04_TC03_AddAttachment_NullFileName, created a new list successfully.");
            #endregion

            #region Add a list item
            List<string> listItemIds = TestSuiteHelper.AddListItems(listGuid, 1);
            Site.Assert.IsNotNull(listItemIds, "Called AddListItems successfully.");

            #endregion

            #region AddAttachment with the file name is null

            bool addAttachmentFail = false;
            string errorCode = null;
            try
            {
                // Call the AddAttachment with the file name is null.
                string fileName = Common.GetConfigurationPropertyValue("AttachmentName", this.Site);
                byte[] attachment = TestSuiteHelper.GetAttachmentContent(fileName);
                this.listswsAdapterInstance.AddAttachment(listName, listItemIds[0], null, attachment);
            }
            catch (SoapException exp)
            {
                errorCode = TestSuiteHelper.GetErrorCode(exp);
                addAttachmentFail = true;
            }

            Site.Assert.IsTrue(addAttachmentFail, "MSLISTSWS_S04_TC03_AddAttachment_NullFileName, call AddAttachmet with file name is null.");

            // Capture R3011 if the error code 0x81020073 is returned.
            Site.CaptureRequirementIfAreEqual<string>(
                "0x81020073",
                errorCode,
                3011,
                @"[In AddAttachment] Otherwise [if the protocol client request includes the listItemID, listName and attachment parameters], if the fileName parameter is missing, the protocol server MUST return a SOAP fault with error code 0x81020073.");

            #endregion
        }

        /// <summary>
        /// This test case is used to validate AddAttachment operation in Windows SharePoint Services 3.0 when ListName parameter cannot be found in the current existing lists.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC04_AddAttachment_SP3()
        {
            Site.Assume.IsTrue(Common.IsRequirementEnabled(2426, this.Site), @"Test is executed only when R2426Enabled is set to true.");

            // Add a list
            #region Add a list
            string guid = TestSuiteHelper.CreateList();
            string expectederrorString = "Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).";
            #endregion

            #region Initialize property value

            // Add one List item
            List<string> ids = TestSuiteHelper.AddListItems(guid, 1);

            #endregion

            #region Invoke AddAttachment and capture requirements
            string errorCode = string.Empty;
            string errorString = string.Empty;
            bool isSoapFaultGenerate = false;
            try
            {
                // Add an attachment using invalid GUID as listName parameter.
                string invalidGuidListName = TestSuiteHelper.GetInvalidGuidAndNocorrespondString();
                this.listswsAdapterInstance.AddAttachment(invalidGuidListName, ids[0], null, null);
            }
            catch (SoapException exp)
            {
                isSoapFaultGenerate = true;
                errorCode = TestSuiteHelper.GetErrorCode(exp);
                errorString = TestSuiteHelper.GetErrorString(exp);
            }

            this.Site.Assert.IsTrue(isSoapFaultGenerate, "There should be a soap fault generated for AddAttachment operation, when use invalid GUID.");
            this.Site.Assert.IsTrue(string.IsNullOrEmpty(errorCode), "The Soap exception contains error Code.");

            this.Site.Log.Add(LogEntryKind.Debug, "The actual error string:[{0}] \r\n for requirement #R2426", errorString);

            Site.Log.Add(
                LogEntryKind.Debug,
                "The actual value: errorString[{0}] for requirement #R2426",
                errorString);

            Site.CaptureRequirementIfIsTrue(
                expectederrorString.Equals(errorString, StringComparison.OrdinalIgnoreCase),
                2426,
                @"[In Appendix B: Product Behavior]Implementation does not return a SOAP fault with error code 0x82000006. (<33> Section 3.1.4.1: Windows SharePoint Services 3.0 return the following SOAP fault with no error code: ""GUID should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx)"".)");

            #endregion
        }

        /// <summary>
        /// This test case is used to test AddAttachment operation when all its input parameters are valid.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC05_AddAttachment_Succeed()
        {
            #region Add a list and add a list item
            string uniqueListName = TestSuiteHelper.GetUniqueListName();
            string listId = TestSuiteHelper.CreateList(uniqueListName);

            // add one item, if not successful or added number not equal to the specified, will fail the test case.
            List<string> listitemIds = TestSuiteHelper.AddListItems(listId, 1);
            #endregion

            // Add an attachment using valid GUID as listName parameter.
            string attachmentFileName = Common.GetConfigurationPropertyValue("AttachmentName", this.Site);
            byte[] attachmentData = TestSuiteHelper.GetAttachmentContent(attachmentFileName);
            string addedListitemId = listitemIds[0];

            // call AddAttachment operation to add an attachment to the added list item.
            string attachmentUrl = this.listswsAdapterInstance.AddAttachment(
                                                    listId,
                                                    addedListitemId,
                                                    attachmentFileName,
                                                    attachmentData);

            // Get attachment to verify whether AddAttachment operation successfully or not.
            GetAttachmentCollectionResponseGetAttachmentCollectionResult attachmentResult = null;
            attachmentResult = this.listswsAdapterInstance.GetAttachmentCollection(listId, addedListitemId);
            if (null == attachmentResult || null == attachmentResult.Attachments || attachmentResult.Attachments.Length == 0)
            {
                this.Site.Assert.Fail("Could Not get the expected added attachment in List, List Id:[{0}]", listId);
            }

            // Get the attachment URL from GetAttachmentCollection response.
            // The URL value is contained in a string array,  which is defined in [MS-LISTSWS].
            // There is at least one text item which contains the "attacgneFileName" in the Text array.
            var attachmentUrlItem = from string urlItem in attachmentResult.Attachments
                                    where urlItem.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) >= 0
                                    select urlItem;

            bool isAttachFileNameContained = attachmentUrlItem.Count() > 0;

            // If the AddAttachment succeeds. Capture R292, R301 and R302
            Site.Log.Add(
                    LogEntryKind.Debug,
                    "The actual value: isAttachFileNameContained[{0}],attachmentUrl[{1}] for requirement #R292 #R301 and #R302",
                    isAttachFileNameContained,
                    attachmentUrl);

            Site.CaptureRequirementIfIsTrue(
                isAttachFileNameContained && attachmentUrl.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) >= 0,
                292,
                @"[AddAttachment]If the specified listName is a valid GUID and corresponds to the identification of a list on the site, use that list.");

            Site.CaptureRequirementIfIsTrue(
                 isAttachFileNameContained && attachmentUrl.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) >= 0,
                 301,
                 @"[In AddAttachment] If the protocol client passes valid input parameters, the protocol server MUST add the attachment to the specified list item in the specified list.");

            Site.CaptureRequirementIfIsTrue(
                isAttachFileNameContained && attachmentUrl.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) >= 0,
                302,
                @"[In AddAttachment operation] If the operation succeeds, an attachment MUST be added to the specified list item in the specified list.");

            // Add a new list item to the list, and use this new added item to call AddAttachment operation.
            listitemIds = TestSuiteHelper.AddListItems(listId, 1);
            string secondaddedListitemId = listitemIds[0];

            // call AddAttachment operation to add an attachment to the added list item.
            attachmentUrl = string.Empty;

            attachmentUrl = this.listswsAdapterInstance.AddAttachment(
                                                uniqueListName,
                                                secondaddedListitemId,
                                                attachmentFileName,
                                                attachmentData);

            // Get attachment to verify whether AddAttachment operation successfully or not
            attachmentResult = null;
            attachmentResult = this.listswsAdapterInstance.GetAttachmentCollection(listId, secondaddedListitemId);
            if (null == attachmentResult || null == attachmentResult.Attachments || attachmentResult.Attachments.Length == 0)
            {
                this.Site.Assert.Fail("Could Not get the expected added attachment in List, List Id:[{0}]", listId);
            }

            // Get the attachment URL from GetAttachmentCollection response.
            // The URL value is contained in a string array,  which is defined in [MS-LISTSWS].
            // There is at least one text item which contain the "attacgneFileName" in the Text array.
            attachmentUrlItem = from string urlItem in attachmentResult.Attachments
                                where urlItem.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) >= 0
                                select urlItem;

            isAttachFileNameContained = attachmentUrlItem.Count() > 0;

            // if the AddAttachment succeeds, Capture R293 and R294
            Site.Log.Add(
                    LogEntryKind.Debug,
                    "The actual value: isAttachFileNameContained[{0}],attachmentUrl[{1}] for requirement #R293 and #R294",
                    isAttachFileNameContained,
                    attachmentUrl);

            Site.CaptureRequirementIfIsTrue(
               isAttachFileNameContained && attachmentUrl.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) >= 0,
                293,
                @"[AddAttachment]If the specified listName is not a valid GUID, check if the listName corresponds to the list title of a list on the site and if so, use that list.");

            Site.CaptureRequirementIfIsTrue(
               isAttachFileNameContained && attachmentUrl.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) >= 0,
                294,
                @"[AddAttachment]If the specified listName [is not a valid GUID or] does not correspond to the identification of a list on the site, check if the listName corresponds to the list title of a list on the site and if so, use that list.");
        }

        #endregion

        #region DeleteAttachment

        /// <summary>
        /// This test case is used to test DeleteAttachment operation when at least one of its input parameters is invalid.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC06_DeleteAttachment_InvalidParameters()
        {
            #region Add a list

            string listId = TestSuiteHelper.CreateList();

            #endregion

            #region Add a list item and add attachment into the list item.

            // Add one item, if not successful or added number not equal to the specified, will fail the test case.
            List<string> listitemIds = TestSuiteHelper.AddListItems(listId, 1);
            string attachmentFileName = Common.GetConfigurationPropertyValue("AttachmentName", this.Site);

            // Get the attachment bytes data
            byte[] attachmentData = TestSuiteHelper.GetAttachmentContent(attachmentFileName);
            string addedListitemId = listitemIds[0];

            // call AddAttachment operation to add an attachment to the added list item.
            string attachmentUrl = this.listswsAdapterInstance.AddAttachment(
                                                    listId,
                                                    addedListitemId,
                                                    attachmentFileName,
                                                    attachmentData);
            this.Site.Assert.IsTrue(
                                  attachmentUrl.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) > 0,
                                  "Add an attachment into the list item should be successful.");

            #endregion

            #region Invoke DeleteAttachment and capture requirements

            bool isSoapFaultReturned = false;
            string errorCode = string.Empty;
            try
            {
                string fullUrlOfAttachment = TestSuiteHelper.GetAttachmentFullUrl(listId, addedListitemId, attachmentFileName);
                string invalidGuidAndNocorrespondName = TestSuiteHelper.GetInvalidGuidAndNocorrespondString();
                this.listswsAdapterInstance.DeleteAttachment(
                                            invalidGuidAndNocorrespondName,
                                            addedListitemId,
                                            fullUrlOfAttachment);
            }
            catch (SoapException soapEx)
            {
                isSoapFaultReturned = true;
                errorCode = TestSuiteHelper.GetErrorCode(soapEx);
            }

            this.Site.Assert.IsTrue(isSoapFaultReturned, "There is a Soap fault returned for Requirement #1968");

            // Capture R2754 if the error code 0x82000006 is returned.
            if (Common.IsRequirementEnabled(2754, this.Site))
            {
                Site.Log.Add(
                    LogEntryKind.Debug,
                    "Returned Error Code [{0}] for requirement R2754",
                    string.IsNullOrEmpty(errorCode) ? "NullOrEmpty" : errorCode);

                Site.CaptureRequirementIfIsTrue(
                     errorCode.Equals("0x82000006", StringComparison.OrdinalIgnoreCase),
                     2754,
                     @"[DeleteAttachment]Implementation does return a SOAP fault with error code 0x82000006, if listName does not correspond to a list from either of these checks.(SharePoint Foundation 2010 and above follow this behavior.)");
            }

            isSoapFaultReturned = false;
            errorCode = string.Empty;
            try
            {
                string emptyListItemId = string.Empty;
                string fullUrlOfAttachment = TestSuiteHelper.GetAttachmentFullUrl(listId, addedListitemId, attachmentFileName);
                this.listswsAdapterInstance.DeleteAttachment(
                                            listId,
                                            emptyListItemId,
                                            fullUrlOfAttachment);
            }
            catch (SoapException soapEx)
            {
                isSoapFaultReturned = true;
                errorCode = TestSuiteHelper.GetErrorCode(soapEx);
            }

            this.Site.Assert.IsTrue(isSoapFaultReturned && !string.IsNullOrEmpty(errorCode), "No Soap fault or error code was returned for requirement #R1700.");

            // Capture R1700 and R479 if the error code 0x82000001 is returned.
            Site.Log.Add(
                    LogEntryKind.Debug,
                    "The actual value: errorCode[{0}] for requirement #R1700 and #R479",
                    errorCode.Equals("0x82000001") ? "0x82000001" : errorCode);

            Site.CaptureRequirementIfIsTrue(
                 errorCode.Equals("0x82000001", StringComparison.OrdinalIgnoreCase),
                 1700,
                 @"[In DeleteAttachment operation] If the protocol client excludes the listItemID parameter, the protocol server MUST return a SOAP fault with error code 0x82000001.");

            Site.CaptureRequirementIfIsTrue(
               errorCode.Equals("0x82000001", StringComparison.OrdinalIgnoreCase),
                479,
                @"[In DeleteAttachment operation] otherwise [if the operation failed], the protocol server MUST return a SOAP fault with error codes as described in section 3.1.4.10.");

            // Try to delete the attachment with invalid-URL parameter.
            // Current list contains two list items, try to call DeleteAttachment operation with second added ListItem id
            // but the use the first list item's attachment URL.
            List<string> listitemIdsOfSecondAdded = TestSuiteHelper.AddListItems(listId, 1);
            string secondAddedListitemId = listitemIdsOfSecondAdded[0];

            isSoapFaultReturned = false;
            errorCode = string.Empty;
            try
            {
                // Try to use the attachment URL of first added item, and send the target item id is second added.
                string invalidAttachmentPath = TestSuiteHelper.GetAttachmentFullUrl(listId, addedListitemId, attachmentFileName);
                this.listswsAdapterInstance.DeleteAttachment(
                                            listId,
                                            secondAddedListitemId,
                                            invalidAttachmentPath);
            }
            catch (SoapException soapEx)
            {
                isSoapFaultReturned = true;
                errorCode = TestSuiteHelper.GetErrorCode(soapEx);
            }

            this.Site.Assert.IsTrue(isSoapFaultReturned && !string.IsNullOrEmpty(errorCode), "There is no Soap fault existed or the no ErrorCode return for Requirement #1700");

            // Capture R471 and R1701 if the error code 0x82000001 is returned.
            Site.Log.Add(
                   LogEntryKind.Debug,
                   "The actual value: errorCode[{0}] for requirement #R471 and #R1701",
                   errorCode.Equals("0x82000001") ? "0x82000001" : errorCode);

            Site.CaptureRequirementIfIsTrue(
                 errorCode.Equals("0x82000001", StringComparison.OrdinalIgnoreCase),
                 471,
                 @"[In DeleteAttachment operation] If the specified URL does not correspond to the absolute URL path of an attachment in a specified list item in a specified list on the site, the protocol server MUST return a SOAP fault with error code 0x82000001.");

            Site.CaptureRequirementIfIsTrue(
                 errorCode.Equals("0x82000001", StringComparison.OrdinalIgnoreCase),
                 1701,
                 @"[In DeleteAttachment operation] [If the specified URL does not correspond to the absolute URL path of an attachment in a specified list item in a specified list on the site, the protocol server MUST return a SOAP fault with error code 0x82000001.] This indicates that the URL is missing or is invalid.");

            #endregion
        }

        /// <summary>
        /// This test case is used to verify DeleteAttachment operation when the list ItemId is specified but the list name or URL is excluded.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC07_DeleteAttachment_ListNameOrUrlExclude()
        {
            #region Create a new list

            bool createListSucceeded = false;
            string listName = TestSuiteHelper.GetUniqueListName();
            string listGuid = TestSuiteHelper.CreateList(listName);
            createListSucceeded = !string.IsNullOrEmpty(listGuid);
            Site.Assert.IsTrue(createListSucceeded, "MSLISTSWS_S04_TC07_DeleteAttachment_ListNameOrUrlExclude, created a new list successfully.");
            #endregion

            #region Add a list item
            List<string> listItemIds = TestSuiteHelper.AddListItems(listGuid, 1);
            Site.Assert.IsNotNull(listItemIds, "Called AddListItems successfully.");

            #endregion

            #region Add an attachment

            string fileName = Common.GetConfigurationPropertyValue("AttachmentName", this.Site);
            byte[] attachment = TestSuiteHelper.GetAttachmentContent(fileName);
            string addAttachment = this.listswsAdapterInstance.AddAttachment(listName, listItemIds[0], fileName, attachment);
            Site.Assert.IsNotNull(addAttachment, "Called AddAttachment successfully.");

            #endregion

            #region DeleteAttachment when the list name or the URL is null

            // Delete the attachment when the list name is null
            bool listNameError = false;
            try
            {
                this.listswsAdapterInstance.DeleteAttachment(null, listItemIds[0], addAttachment);
            }
            catch (SoapException exp)
            {
                listNameError = TestSuiteHelper.GetErrorCode(exp) == null;
            }

            Site.Assert.IsTrue(listNameError, "Deleting attachment when the list name is null should fail.");

            // Delete the attachment when the URL is null
            bool attachmentUrlError = false;
            try
            {
                this.listswsAdapterInstance.DeleteAttachment(listName, listItemIds[0], null);
            }
            catch (SoapException exp)
            {
                attachmentUrlError = TestSuiteHelper.GetErrorCode(exp) == null;
            }

            Site.Assert.IsTrue(attachmentUrlError, "Deleting attachment when the URL is null should fail.");

            // Delete the attachment when the URL and list name are null
            bool listNameAndAttachmentUrlError = false;
            try
            {
                this.listswsAdapterInstance.DeleteAttachment(null, listItemIds[0], null);
            }
            catch (SoapException exp)
            {
                listNameAndAttachmentUrlError = TestSuiteHelper.GetErrorCode(exp) == null;
            }

            Site.Assert.IsTrue(listNameAndAttachmentUrlError, "Deleting attachment when both of the list name and URL are null should fail.");

            // If listNameError, attachmentUrlError and listNameAndAttachmentUrlError are all true, R3013 will be able to be captured.
            Site.CaptureRequirement(
                3013,
                @"[In DeleteAttachment operation] Otherwise [if the protocol client includes the listItemID parameter], if the protocol client excludes any of the other parameters, the protocol server MUST return a SOAP fault with no error code.");

            #endregion
        }

        /// <summary>
        /// This test case is used to test the DeleteAttachment operation when ListItemID parameter
        /// does not correspond to a list item.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC08_DeleteAttachment_ListItemIDNotCorrespond()
        {
            #region Add a list and add a list item
            string uniqueListName = TestSuiteHelper.GetUniqueListName();
            string listId = TestSuiteHelper.CreateList(uniqueListName);

            // add one item, if not successful or added number not equal to the specified, fail the test case.
            List<string> listitemIds = TestSuiteHelper.AddListItems(listId, 1);
            #endregion

            // Add an attachment using valid GUID as listName parameter.
            string attachmentFileName = Common.GetConfigurationPropertyValue("AttachmentName", this.Site);
            byte[] attachmentData = TestSuiteHelper.GetAttachmentContent(attachmentFileName);
            string addedListitemId = listitemIds[0];

            #region Add an attachment
            // call AddAttachment operation to add an attachment to the added list item.
            string attachmentUrl = this.listswsAdapterInstance.AddAttachment(
                                                    listId,
                                                    addedListitemId,
                                                    attachmentFileName,
                                                    attachmentData);
            this.Site.Assert.IsTrue(
                                  attachmentUrl.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) > 0,
                                  "Adding an attachment into the list item should be successful.");
            #endregion

            #region Invoke DeleteAttachment and capture requirements

            // Delete the attachment with the ListItemID which does not correspond to a list item.
            string fullUrlOfAttachment = TestSuiteHelper.GetAttachmentFullUrl(listId, addedListitemId, attachmentFileName);
            string listItemIDNotCorrespond = (int.Parse(addedListitemId) + 1).ToString();

            try
            {
                this.listswsAdapterInstance.DeleteAttachment(listId, listItemIDNotCorrespond, fullUrlOfAttachment);
                this.Site.Assert.Fail("DeleteAttachment operation must return a SOAP fault if the listItemID parameter does not correspond to a list item.");
            }
            catch (SoapException ex)
            {
                string errorCode = TestSuiteHelper.GetErrorCode(ex);

                // If a SOAP exception is returned and the error code is null, capture R470.
                Site.CaptureRequirementIfIsNull(
                    errorCode,
                    470,
                    @"[In DeleteAttachment operation] If the listItemID does not correspond to a list item in a specified list on the site, the protocol server MUST return a SOAP fault. There is no error code for this fault.");

                //Verify MS-LISTSWS requirement: MS-LISTSWS_R465001
                Site.CaptureRequirementIfIsNull(
                    errorCode,
                    465001,
                    @"[In DeleteAttachment operation] If the listItemID does not correspond to a list item in a specified list on the site, the protocol server MUST return a SOAP fault.");

                //Verify MS-LISTSWS requirement: MS-LISTSWS_R465002
                Site.CaptureRequirementIfIsNull(
                    errorCode,
                    465002,
                    @"There is no error code for this fault.");

            }

            #endregion
        }

        /// <summary>
        /// This test case is used to verify DeleteAttachment operation in Windows SharePoint Services 3.0 when ListName parameter cannot be found in the current existing lists.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC09_DeleteAttachment_NonExistentListName_WSS3()
        {
            Site.Assume.IsTrue(Common.IsRequirementEnabled(2440, this.Site), @"Test is executed only when R2440Enabled is set to true.");

            // Add a list
            #region Add a list
            string invalidListName = TestSuiteHelper.GetInvalidGuidAndNocorrespondString();
            string guid = TestSuiteHelper.CreateList();
            string expectederrorString = "Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).";
            #endregion

            #region Initialize property value

            // Add one List item
            List<string> ids = TestSuiteHelper.AddListItems(guid, 1);

            #endregion

            #region Invoke AddAttachment and capture requirements
            string errorCode = string.Empty;
            string errorString = string.Empty;
            bool isSoapFaultGenerate = false;
            try
            {
                // Add an attachment using invalid GUID as listName parameter.
                string attchmentFileName = Common.GetConfigurationPropertyValue("AttachmentName", this.Site);
                byte[] attachmentFile = TestSuiteHelper.GetAttachmentContent(attchmentFileName);
                string attachmentUrl = this.listswsAdapterInstance.AddAttachment(guid, ids[0], attchmentFileName, attachmentFile);

                // Delete the attachment with an invalid list name.
                this.listswsAdapterInstance.DeleteAttachment(invalidListName, ids[0], attachmentUrl);
            }
            catch (SoapException exp)
            {
                isSoapFaultGenerate = true;
                errorCode = TestSuiteHelper.GetErrorCode(exp);
                errorString = TestSuiteHelper.GetErrorString(exp);
            }

            this.Site.Assert.IsTrue(isSoapFaultGenerate, "There should be a soap fault generated for AddAttachment operation, when use invalid GUID.");
            this.Site.Assert.IsTrue(string.IsNullOrEmpty(errorCode), "The Soap exception contains error Code.");
            this.Site.Log.Add(LogEntryKind.Debug, "The actual error string:[{0}] \r\n for requirement #R2440", errorString);

            // If the error string equal to the "Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)."
            Site.Log.Add(
                LogEntryKind.Debug,
                "The actual value: errorString[{0}] for requirement #R2440",
                errorString);

            Site.CaptureRequirementIfIsTrue(
                        expectederrorString.IndexOf(errorString, StringComparison.OrdinalIgnoreCase) >= 0,
                        2440,
                        @"[In Appendix B: Product Behavior]Implementation does not return a SOAP fault with error code 0x82000006. (<47> Section 3.1.4.10: Windows SharePoint Services 3.0 return the following SOAP fault with no error code: ""GUID should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx)"".)");
            #endregion
        }

        /// <summary>
        /// This test case is used to test DeleteAttachment operation when all its input parameters are valid.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC10_DeleteAttachment_Succeed()
        {
            #region Add a list and add a list item
            string uniqueListName = TestSuiteHelper.GetUniqueListName();
            string listId = TestSuiteHelper.CreateList(uniqueListName);

            // add one item, if not successful or added number not equal to the specified, fail the test case.
            List<string> listitemIds = TestSuiteHelper.AddListItems(listId, 1);
            #endregion

            // Add an attachment using valid GUID as listName parameter.
            string attachmentFileName = Common.GetConfigurationPropertyValue("AttachmentName", this.Site);
            byte[] attachmentData = TestSuiteHelper.GetAttachmentContent(attachmentFileName);
            string addedListitemId = listitemIds[0];

            #region Add an attachment
            // call AddAttachment operation to add an attachment to the added list item.
            string attachmentUrl = this.listswsAdapterInstance.AddAttachment(
                                                    listId,
                                                    addedListitemId,
                                                    attachmentFileName,
                                                    attachmentData);
            this.Site.Assert.IsTrue(
                                  attachmentUrl.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) > 0,
                                  "Add an attachment into the list item should be successful.");
            #endregion

            #region Invoke DeleteAttachment and capture requirements

            // Delete the attachment with valid GUID as listName parameter.
            string fullUrlOfAttachment = TestSuiteHelper.GetAttachmentFullUrl(listId, addedListitemId, attachmentFileName);
            this.listswsAdapterInstance.DeleteAttachment(listId, addedListitemId, fullUrlOfAttachment);

            // Call GetAttachmentCollection to verify delete successfully or not.
            GetAttachmentCollectionResponseGetAttachmentCollectionResult getAttachmenResult = null;
            getAttachmenResult = this.listswsAdapterInstance.GetAttachmentCollection(listId, addedListitemId);
            if (null == getAttachmenResult || null == getAttachmenResult.Attachments)
            {
                this.Site.Assert.Fail("Could not Get the valid response of GetAttachmentCollection operation");
            }

            // Capture R466, R473 and R478 if the DeleteAttachment succeeds.
            Site.CaptureRequirementIfAreEqual<int>(
                0,
                getAttachmenResult.Attachments.Length,
                466,
                @"[In DeleteAttachment operation] If the specified listName is a valid GUID and corresponds to the identification of a list on the site, use that list.");

            Site.CaptureRequirementIfAreEqual<int>(
                0,
               getAttachmenResult.Attachments.Length,
                473,
                @"[In DeleteAttachment operation] If the protocol client calls the operation by passing valid input parameters, the protocol server MUST delete the attachment associated with the specified list item in the specified list.");

            Site.CaptureRequirementIfAreEqual<int>(
                0,
                getAttachmenResult.Attachments.Length,
                478,
                @"[In DeleteAttachment operation] If the operation succeeds, the attachment MUST be deleted.");

            // Add an attachment.
            List<string> listitemIdsOfsecond = TestSuiteHelper.AddListItems(listId, 1);
            string secondListitemId = listitemIdsOfsecond[0];
            attachmentUrl = string.Empty;
            attachmentUrl = this.listswsAdapterInstance.AddAttachment(
                                                   listId,
                                                   secondListitemId,
                                                   attachmentFileName,
                                                   attachmentData);
            this.Site.Assert.IsTrue(
                                  !string.IsNullOrEmpty(attachmentUrl)
                                  && attachmentUrl.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) > 0,
                                  "Add an attachment into the list item should be successful.");

            // Delete the attachment with valid list title as listName parameter.
            fullUrlOfAttachment = string.Empty;
            fullUrlOfAttachment = TestSuiteHelper.GetAttachmentFullUrl(listId, secondListitemId, attachmentFileName);
            this.listswsAdapterInstance.DeleteAttachment(uniqueListName, secondListitemId, fullUrlOfAttachment);

            // Call GetAttachmentCollection to verify delete successfully or not.
            getAttachmenResult = null;
            getAttachmenResult = this.listswsAdapterInstance.GetAttachmentCollection(listId, secondListitemId);
            if (null == getAttachmenResult || null == getAttachmenResult.Attachments)
            {
                this.Site.Assert.Fail("Could Not Get the valid response of GetAttachmentCollection operation");
            }

            // Capture R467 and R468 if the DeleteAttachment succeeds.
            Site.CaptureRequirementIfAreEqual<int>(
                0,
               getAttachmenResult.Attachments.Length,
                467,
                @"[In DeleteAttachment operation] If the specified listName is not a valid GUID, check if the listName corresponds to the list title of a list on the site and if so, use that list.");

            Site.CaptureRequirementIfAreEqual<int>(
              0,
             getAttachmenResult.Attachments.Length,
                468,
                @"[In DeleteAttachment operation] If the specified listName does not correspond to the identification of a list on the site, check if the listName corresponds to the list title of a list on the site and if so, use that list.");

            #endregion
        }

        #endregion

        #region GetAttachmentCollection

        /// <summary>
        /// This test case is used to test the server behavior when the input parameters are valid but no attachment exists in GetAttachmentCollection operation.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC11_GetAttachmentCollection_ZeroAttachmentTest()
        {
            #region Add a list and add a list item

            string listId = TestSuiteHelper.CreateList();

            // add one item, if not successful or added number not equal to the specified, will fail the test case.
            List<string> listitemIds = TestSuiteHelper.AddListItems(listId, 1);
            #endregion

            #region Invoke GetAttachmentCollection and capture requirements

            GetAttachmentCollectionResponseGetAttachmentCollectionResult getAttachmentCollectionResult = null;
            bool isSoapFault = false;
            try
            {
                // pick up the added item id, the number is one.
                getAttachmentCollectionResult = this.listswsAdapterInstance.GetAttachmentCollection(listId, listitemIds[0]);
            }
            catch (SoapException)
            {
                isSoapFault = true;
            }

            #endregion

            #region Requirement Verification

            // If no soap fault, and getAttachmentCollectionResult is not null and the returned
            // Attachments' length is zero, requirement 543 is captured.
            this.Site.Assert.IsFalse(isSoapFault, "There is unexpected Soap Fault when calling [GetAttachmentCollection] operation.");

            Site.CaptureRequirementIfAreEqual<int>(
                0,
                getAttachmentCollectionResult.Attachments.Length,
                543,
                @"[In GetAttachmentCollection operation] If the protocol client calls the operation on a listItemID containing zero attachments, the protocol server MUST return an empty attachment collection.");

            #endregion
        }

        /// <summary>
        /// This test case is used to test GetAttachmentCollection operation when at least one of parameters are valid.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC12_GetAttachmentCollection_InvalidParameters()
        {
            #region Add a list and add a list item
            string uniqueListName = TestSuiteHelper.GetUniqueListName();
            string listId = TestSuiteHelper.CreateList(uniqueListName);

            // add one item, if not successful or added number not equal to the specified, will fail the test case.
            List<string> listitemIds = TestSuiteHelper.AddListItems(listId, 1);
            #endregion

            // Add an attachment using valid GUID as listName parameter.
            string attachmentFileName = Common.GetConfigurationPropertyValue("AttachmentName", this.Site);
            byte[] attachmentData = TestSuiteHelper.GetAttachmentContent(attachmentFileName);
            string addedListitemId = listitemIds[0];

            #region Add an attachment
            // call AddAttachment operation to add an attachment to the added list item.
            string attachmentUrl = this.listswsAdapterInstance.AddAttachment(
                                                    listId,
                                                    addedListitemId,
                                                    attachmentFileName,
                                                    attachmentData);
            this.Site.Assert.IsTrue(
                                  attachmentUrl.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) > 0,
                                  "Add an attachment into the list item should be successful.");
            #endregion

            #region Invoke GetAttachmentCollection and capture requirements

            // Try to get the attachment collection with an invalid listName parameter.
            bool isSoapFaultReturned = false;
            string errorCode = string.Empty;
            try
            {
                // Get a list name that is not a valid GUID and it does not correspond to any existing list
                string invalidGuidAndNocorrespondName = TestSuiteHelper.GetInvalidGuidAndNocorrespondString();
                this.listswsAdapterInstance.GetAttachmentCollection(invalidGuidAndNocorrespondName, addedListitemId);
            }
            catch (SoapException soapEx)
            {
                isSoapFaultReturned = true;
                errorCode = TestSuiteHelper.GetErrorCode(soapEx);
            }

            // Capture R2758, if the error code 0x82000006 is returned.
            if (Common.IsRequirementEnabled(2758, this.Site))
            {
                Site.Log.Add(
                   LogEntryKind.Debug,
                   "Returned Error Code [{0}] for requirement #R2758",
                   string.IsNullOrEmpty(errorCode) ? "NullOrEmpty" : errorCode);

                Site.CaptureRequirementIfIsTrue(
                    isSoapFaultReturned && "0x82000006".Equals(errorCode, StringComparison.OrdinalIgnoreCase),
                    2758,
                    @"[In GetAttachmentCollection operation]Implementation does return a SOAP fault with error code 0x82000006, if listName does not correspond to a list from either of these checks.(SharePoint Foundation 2010 and above follow this behavior.) ");
            }

            // Try to get the attachment collection with invalid listItemID parameter.
            isSoapFaultReturned = false;
            errorCode = string.Empty;
            try
            {
                // Get a list item ID that does not correspond to any existed ListItem on current list.
                // Current List only added one item.
                string invalidlistItemID = int.MaxValue.ToString();
                this.listswsAdapterInstance.GetAttachmentCollection(uniqueListName, invalidlistItemID);
            }
            catch (SoapException soapEx)
            {
                isSoapFaultReturned = true;
                errorCode = TestSuiteHelper.GetErrorCode(soapEx);
            }

            // Capture R538, R549 and R1748 if a SOAP fault without error code is returned.
            Site.Log.Add(
                   LogEntryKind.Debug,
                   "The actual value: isSoapFaultReturned[{0}],errorCode[{1}] for requirement #R538, #R549 and #R1748",
                   isSoapFaultReturned,
                   string.IsNullOrEmpty(errorCode) ? "NullOrEmpty" : errorCode);

            Site.CaptureRequirementIfIsTrue(
                isSoapFaultReturned && string.IsNullOrEmpty(errorCode),
                538,
                @"[In GetAttachmentCollection operation] If the listItemID does not correspond to a list item in a specified list on the site, the protocol server MUST return a SOAP fault.");

            Site.CaptureRequirementIfIsTrue(
                isSoapFaultReturned && string.IsNullOrEmpty(errorCode),
                1748,
                @"[In GetAttachmentCollection operation] [If the listItemID does not correspond to a list item in a specified list on the site, the protocol server MUST return a SOAP fault.]There is no error code for this fault.");

            Site.CaptureRequirementIfIsTrue(
                isSoapFaultReturned && string.IsNullOrEmpty(errorCode),
                549,
                @"[In GetAttachmentCollection operation] otherwise [if the operation failed], the protocol server MUST return a SOAP fault with error codes as described in section 3.1.4.14.");

            #endregion
        }

        /// <summary>
        /// This test case is used to verify GetAttachmentCollection operation in Windows SharePoint Services 3.0 when ListName parameter cannot be found in the current existing lists.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC13_GetAttachmentCollection_NonExistentListName_WSS3()
        {
            Site.Assume.IsTrue(Common.IsRequirementEnabled(2450, this.Site), @"Test is executed only when R2450Enabled is set to true.");

            // Add a list
            #region Add a list
            string invalidListName = "123";
            string guid = TestSuiteHelper.CreateList();
            string expectederrorString = "GUID should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).";
            #endregion

            #region Initialize property value

            // Add one List item
            List<string> ids = TestSuiteHelper.AddListItems(guid, 1);

            #endregion

            #region Invoke AddAttachment and capture requirements
            string errorCode = string.Empty;
            string errorString = string.Empty;
            bool isSoapFaultGenerate = false;
            try
            {
                // Delete the attachment with an invalid listName.
                this.listswsAdapterInstance.GetAttachmentCollection(invalidListName, ids[0]);
            }
            catch (SoapException exp)
            {
                isSoapFaultGenerate = true;
                errorCode = TestSuiteHelper.GetErrorCode(exp);
                errorString = TestSuiteHelper.GetErrorString(exp);
            }

            this.Site.Assert.IsTrue(isSoapFaultGenerate, "There should be a soap fault generated for AddAttachment operation, when use invalid GUID.");
            this.Site.Assert.IsTrue(string.IsNullOrEmpty(errorCode), "The Soap exception contains error Code.");
            this.Site.Log.Add(LogEntryKind.Debug, "The actual error string:[{0}] \r\n for requirement #R2450", errorString);

            // If the error string equal to the "Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)." capture R2450
            Site.Log.Add(
                LogEntryKind.Debug,
                "The actual value: errorString[{0}] for requirement #R2450",
                errorString);

            Site.CaptureRequirementIfIsTrue(
                        expectederrorString.IndexOf(errorString, StringComparison.OrdinalIgnoreCase) >= 0,
                        2450,
                        @"[In Appendix B: Product Behavior]Implementation does not return a SOAP fault with error code 0x82000006. (<53> Section 3.1.4.14: Windows SharePoint Services 3.0 return the following SOAP fault with no error code: ""GUID should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx)"".)");

            #endregion
        }

        /// <summary>
        /// The test case is used to verify GetAttachmentCollection operation when list item id is null.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC14_GetAttachmentCollection_NullItemId()
        {
            #region Create a new list

            bool createListSucceeded = false;
            string listName = TestSuiteHelper.GetUniqueListName();
            string listGuid = TestSuiteHelper.CreateList(listName);
            createListSucceeded = !string.IsNullOrEmpty(listGuid);
            Site.Assert.IsTrue(createListSucceeded, "MSLISTSWS_S04_TC13_GetAttachmentCollection_NullItemId, created a new list successfully.");
            #endregion

            #region GetAttachmentCollection when the list item ID is null.
            string errorCode = null;
            bool isCaptureR540 = false;
            try
            {
                // Call GetAttachmentCollection when list item id is null.
                this.listswsAdapterInstance.GetAttachmentCollection(listName, null);
            }
            catch (SoapException exp)
            {
                errorCode = TestSuiteHelper.GetErrorCode(exp);
                isCaptureR540 = true;
            }

            Site.Assert.IsTrue(isCaptureR540, "Calling GetAttachmentCollection with list item id is null fail.");

            // Capture R540 if the error code 0x82000001 is returned.
            Site.CaptureRequirementIfAreEqual<string>(
                "0x82000001",
                errorCode,
                540,
                @"[In GetAttachmentCollection operation] If the protocol client excludes the listItemID parameter, the protocol server MUST return a SOAP fault with error code 0x82000001.");

            #endregion
        }

        /// <summary>
        /// This test case is used to verify GetAttachmentCollection operation when the list name is null.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC15_GetAttachmentCollection_NullListName()
        {
            #region Create a new list

            bool createListSucceeded = false;
            string listName = TestSuiteHelper.GetUniqueListName();
            string listGuid = TestSuiteHelper.CreateList(listName);
            createListSucceeded = !string.IsNullOrEmpty(listGuid);
            Site.Assert.IsTrue(createListSucceeded, "MSLISTSWS_S04_TC14_GetAttachmentCollection_NullListName, created a new list successfully.");
            #endregion

            #region Add a list item
            List<string> listItemIds = TestSuiteHelper.AddListItems(listGuid, 1);
            Site.Assert.IsNotNull(listItemIds, "Called AddListItems successfully.");

            #endregion

            #region Invoke GetAttachmentCollection and capture requirements
            string errorCode = null;
            bool isCaptureR541 = false;
            try
            {
                // Call GetAttachmentCollection without list name.
                this.listswsAdapterInstance.GetAttachmentCollection(null, listItemIds[0]);
            }
            catch (SoapException exp)
            {
                errorCode = TestSuiteHelper.GetErrorCode(exp);
                isCaptureR541 = errorCode == null;
            }

            // Capture R541 if the protocol server return a SOAP fault with no error code.
            Site.Log.Add(
                    LogEntryKind.Debug,
                    "The actual value: isCaptureR541[{0}] for requirement #R541",
                    isCaptureR541);

            Site.CaptureRequirementIfIsTrue(
                isCaptureR541,
                541,
                @"[In GetAttachmentCollection operation] If the protocol client excludes the listName parameter, the protocol server MUST return a SOAP fault with no error code.");

            #endregion
        }

        /// <summary>
        /// This test case is used to test GetAttachmentCollection operation when all its input parameters are valid.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC16_GetAttachmentCollection_Succeed()
        {
            #region Add a list

            string uniqueListName = TestSuiteHelper.GetUniqueListName();
            string listId = TestSuiteHelper.CreateList(uniqueListName);

            #endregion

            #region Add a list item and add attachment into the list item.

            // Add one item, if not successful or added number not equal to the specified, will fail the test case.
            List<string> listitemIds = TestSuiteHelper.AddListItems(listId, 1);
            string attachmentFileName = Common.GetConfigurationPropertyValue("AttachmentName", this.Site);

            // Get the attachment bytes data
            byte[] attachmentData = TestSuiteHelper.GetAttachmentContent(attachmentFileName);
            string addedListitemId = listitemIds[0];

            // call AddAttachment operation to add an attachment to the added list item.
            string attachmentUrl = this.listswsAdapterInstance.AddAttachment(
                                                    listId,
                                                    addedListitemId,
                                                    attachmentFileName,
                                                    attachmentData);
            this.Site.Assert.IsTrue(
                                  attachmentUrl.IndexOf(attachmentFileName, StringComparison.OrdinalIgnoreCase) > 0,
                                  "Add an attachment into the list item should be successful.");

            #endregion

            #region Invoke GetAttachmentCollection and capture requirements
            // Get the attachment collection with valid GUID as listName parameter.
            bool isSoapFaultReturned = false;
            GetAttachmentCollectionResponseGetAttachmentCollectionResult getAttachmentCollectionResult = null;
            try
            {
                getAttachmentCollectionResult = this.listswsAdapterInstance.GetAttachmentCollection(listId, addedListitemId);
            }
            catch (SoapException)
            {
                isSoapFaultReturned = true;
                string errorMsg = string.Format(
                     "There is unexpected SoapFault thrown when calling GetAttachmentCollection operation with valid list GUID [{0}]",
                     listId);
                this.Site.Log.Add(LogEntryKind.Debug, errorMsg);
            }

            // Capture R534 and R542 if the GetAttachmentCollection succeeds and there is no exception.
            Site.CaptureRequirementIfIsFalse(
                isSoapFaultReturned,
                534,
                @"[In GetAttachmentCollection operation] If the specified listName is a valid GUID and corresponds to the identification of a list on the site, use that list.");

            Site.CaptureRequirementIfIsFalse(
                isSoapFaultReturned,
                542,
                @"[In GetAttachmentCollection operation] If the protocol client passes valid input parameters, the protocol server MUST return the collection of attachments associated with the list item.");

            // Get the attachment collection with valid list title as listName parameter.
            // Current List use a specified name and record by "uniqueListName"
            isSoapFaultReturned = false;
            try
            {
                this.listswsAdapterInstance.GetAttachmentCollection(uniqueListName, addedListitemId);
            }
            catch (SoapException)
            {
                isSoapFaultReturned = true;
                string errorMsg = string.Format(
                     "There is unexpected SoapFault was thrown when calling GetAttachmentCollection operation with existed list Name [{0}]",
                     uniqueListName);
                this.Site.Log.Add(LogEntryKind.Debug, errorMsg);
            }

            // Capture R535 and R536 if the GetAttachmentCollection succeeds.
            Site.CaptureRequirementIfIsFalse(
                isSoapFaultReturned,
                535,
                @"[In GetAttachmentCollection operation] If the specified listName is not a valid GUID, check if the listName corresponds to the list title of a list on the site and if so, use that list.");

            Site.CaptureRequirementIfIsFalse(
                isSoapFaultReturned,
                536,
                @"[In GetAttachmentCollection operation] If the specified listName does not correspond to the identification of a list on the site, check if the listName corresponds to the list title of a list on the site and if so, use that list.");

            // Delete the attachment.
            // Add second list item and without adding any attachments.
            List<string> listIdsOfSecondListItem = TestSuiteHelper.AddListItems(listId, 1);
            string secondListItemId = listIdsOfSecondListItem[0];

            // Get the attachment collection with valid GUID as listName parameter.
            getAttachmentCollectionResult = null;
            isSoapFaultReturned = false;
            try
            {
                getAttachmentCollectionResult = this.listswsAdapterInstance.GetAttachmentCollection(listId, secondListItemId);
            }
            catch (SoapException)
            {
                isSoapFaultReturned = true;
                string errorMsg = string.Format(
                     "There is unexpected SoapFault thrown when calling GetAttachmentCollection operation with valid list GUID [{0}] and valid listitemId[{1}]"
                     + @"to the target ListItem does not contain any attachment",
                     listId,
                     secondListItemId);
                this.Site.Assert.Fail(errorMsg);
            }

            this.Site.Assert.IsTrue(
                    getAttachmentCollectionResult != null && getAttachmentCollectionResult.Attachments != null,
                    "The response of GetAttachmentCollection operation must not be null for Requirement #543.");

            // Capture R543 if the GetAttachmentCollection succeeds and no attachment is returned.
            Site.CaptureRequirementIfAreEqual<int>(
                0,
                getAttachmentCollectionResult.Attachments.Length,
                543,
                @"[In GetAttachmentCollection operation] If the protocol client calls the operation on a listItemID containing zero attachments, the protocol server MUST return an empty attachment collection.");
            #endregion
        }

        /// <summary>
        /// The test case will verify GetAttachmentCollection operation when list item ID is negative.
        /// </summary>
        [TestCategory("MSLISTSWS"), TestMethod()]
        public void MSLISTSWS_S04_TC17_GetAttachmentCollection_NegativeListItemID()
        {
            Site.Assume.IsTrue(
                Common.IsRequirementEnabled(30371, this.Site) || Common.IsRequirementEnabled(30372, this.Site),
                @"Test is executed only when R30371Enabled is set to true or R30372Enabled is set to true.");

            #region Create a new list

            bool createListSucceeded = false;
            string listName = TestSuiteHelper.GetUniqueListName();
            string listGuid = TestSuiteHelper.CreateList(listName);
            createListSucceeded = !string.IsNullOrEmpty(listGuid);
            Site.Assert.IsTrue(createListSucceeded, "MSLISTSWS_S04_TC16_GetAttachmentCollection_NegativeListItemID, created a new list successfully.");
            #endregion

            #region Invoke GetAttachmentCollection and capture requirements
            string negativeItemID = "-1";
            bool caughtSoapException = false;

            try
            {
                // Call GetAttachmentCollection with negative listItemID.
                this.listswsAdapterInstance.GetAttachmentCollection(listName, negativeItemID);

                Site.Assert.Fail("GetAttachmentCollection operation must return a SOAP fault if the listItemID parameter is negative.");
            }
            catch (SoapException ex)
            {
                caughtSoapException = true;
                string errorCode = TestSuiteHelper.GetErrorCode(ex);
                string errorString = TestSuiteHelper.GetErrorString(ex);

                // Capture R30371 if the protocol server return a SOAP fault with no error code.
                // Capture R30372 if the protocol server return a SOAP fault with error code 0x81020014.
                Site.Log.Add(
                            LogEntryKind.Debug,
                            "The actual value: errorCode[{0}]",
                            string.IsNullOrEmpty(errorCode) ? "NullOrEmpty" : errorCode);

                Site.Log.Add(
                            LogEntryKind.Debug,
                            "The actual value: errorString[{0}]",
                            string.IsNullOrEmpty(errorString) ? "NullOrEmpty" : errorString);

                if (Common.IsRequirementEnabled(30371, this.Site))
                {
                    string expectedErrorString = "Value does not fall within the expected range.";

                    bool isR30371Verified = errorCode == null && expectedErrorString.Equals(errorString, StringComparison.OrdinalIgnoreCase);

                    Site.CaptureRequirementIfIsTrue(
                            isR30371Verified,
                            30371,
                            @"[In GetAttachmentCollection operation]  Implementation does return the following SOAP fault with no error code: ""Value does not fall within the expected range."", "
                            + @" if the listItemID is a negative value. (<54> Section 3.1.4.14: wss3 return the following SOAP fault with no error code: ""Value does not fall within the expected range."")");
                }

                if (Common.IsRequirementEnabled(30372, this.Site))
                {
                    Site.CaptureRequirementIfAreEqual<string>(
                            "0x81020014",
                            errorCode,
                            30372,
                            @"[In GetAttachmentCollection operation] Implementation does return a SOAP fault with error code 0x81020014, if the listItemID is a negative value. (SharePoint Foundation 2010 and above follow this behavior.)");
                }
            }

            Site.Assert.IsTrue(caughtSoapException, "A SOAP exception should be thrown by the server when invoke the operation 'GetAttachmentCollection' with negative listItemID.");

            #endregion
        }

        #endregion

        #endregion

        #region Override methods
        /// <summary>
        /// This method will run before test case executes
        /// </summary>
        [TestInitialize]
        public void TestCaseInitialize()
        {
            this.listswsAdapterInstance = this.Site.GetAdapter<IMS_LISTSWSAdapter>();

            Common.CheckCommonProperties(this.Site, true);

            #region new initialization
            if (!TestSuiteHelper.GuardEnviromentClean())
            {
                Site.Debug.Fail("The test environment is not clean, refer the log files for details.");
            }

            // Initialize the TestSuiteHelper
            TestSuiteHelper.Initialize(this.Site, this.listswsAdapterInstance);
            #endregion
        }

        /// <summary>
        /// This method will run after test case executes
        /// </summary>
        [TestCleanup]
        public void TestCaseCleanup()
        {
            #region new clean up
            TestSuiteHelper.CleanUp();
            #endregion
        }

        #endregion
    }
}


text:
#ifndef PYEXPATNS_H
#define PYEXPATNS_H

#define XML_DefaultCurrent              PyExpat_XML_DefaultCurrent
#define XML_ErrorString                 PyExpat_XML_ErrorString
#define XML_ExpatVersion                PyExpat_XML_ExpatVersion
#define XML_ExpatVersionInfo            PyExpat_XML_ExpatVersionInfo
#define XML_ExternalEntityParserCreate  PyExpat_XML_ExternalEntityParserCreate
#define XML_FreeContentModel            PyExpat_XML_FreeContentModel
#define XML_GetBase                     PyExpat_XML_GetBase
#define XML_GetBuffer                   PyExpat_XML_GetBuffer
#define XML_GetCurrentByteCount         PyExpat_XML_GetCurrentByteCount
#define XML_GetCurrentByteIndex         PyExpat_XML_GetCurrentByteIndex
#define XML_GetCurrentColumnNumber      PyExpat_XML_GetCurrentColumnNumber
#define XML_GetCurrentLineNumber        PyExpat_XML_GetCurrentLineNumber
#define XML_GetErrorCode                PyExpat_XML_GetErrorCode
#define XML_GetFeatureList              PyExpat_XML_GetFeatureList
#define XML_GetIdAttributeIndex         PyExpat_XML_GetIdAttributeIndex
#define XML_GetInputContext             PyExpat_XML_GetInputContext
#define XML_GetParsingStatus            PyExpat_XML_GetParsingStatus
#define XML_GetSpecifiedAttributeCount  PyExpat_XML_GetSpecifiedAttributeCount
#define XmlGetUtf16InternalEncoding     PyExpat_XmlGetUtf16InternalEncoding
#define XmlGetUtf16InternalEncodingNS   PyExpat_XmlGetUtf16InternalEncodingNS
#define XmlGetUtf8InternalEncoding      PyExpat_XmlGetUtf8InternalEncoding
#define XmlGetUtf8InternalEncodingNS    PyExpat_XmlGetUtf8InternalEncodingNS
#define XmlInitEncoding                 PyExpat_XmlInitEncoding
#define XmlInitEncodingNS               PyExpat_XmlInitEncodingNS
#define XmlInitUnknownEncoding          PyExpat_XmlInitUnknownEncoding
#define XmlInitUnknownEncodingNS        PyExpat_XmlInitUnknownEncodingNS
#define XML_MemFree                     PyExpat_XML_MemFree
#define XML_MemMalloc                   PyExpat_XML_MemMalloc
#define XML_MemRealloc                  PyExpat_XML_MemRealloc
#define XML_Parse                       PyExpat_XML_Parse
#define XML_ParseBuffer                 PyExpat_XML_ParseBuffer
#define XML_ParserCreate                PyExpat_XML_ParserCreate
#define XML_ParserCreate_MM             PyExpat_XML_ParserCreate_MM
#define XML_ParserCreateNS              PyExpat_XML_ParserCreateNS
#define XML_ParserFree                  PyExpat_XML_ParserFree
#define XML_ParserReset                 PyExpat_XML_ParserReset
#define XmlParseXmlDecl                 PyExpat_XmlParseXmlDecl
#define XmlParseXmlDeclNS               PyExpat_XmlParseXmlDeclNS
#define XmlPrologStateInit              PyExpat_XmlPrologStateInit
#define XmlPrologStateInitExternalEntity    PyExpat_XmlPrologStateInitExternalEntity
#define XML_ResumeParser                PyExpat_XML_ResumeParser
#define XML_SetAttlistDeclHandler       PyExpat_XML_SetAttlistDeclHandler
#define XML_SetBase                     PyExpat_XML_SetBase
#define XML_SetCdataSectionHandler      PyExpat_XML_SetCdataSectionHandler
#define XML_SetCharacterDataHandler     PyExpat_XML_SetCharacterDataHandler
#define XML_SetCommentHandler           PyExpat_XML_SetCommentHandler
#define XML_SetDefaultHandler           PyExpat_XML_SetDefaultHandler
#define XML_SetDefaultHandlerExpand     PyExpat_XML_SetDefaultHandlerExpand
#define XML_SetDoctypeDeclHandler       PyExpat_XML_SetDoctypeDeclHandler
#define XML_SetElementDeclHandler       PyExpat_XML_SetElementDeclHandler
#define XML_SetElementHandler           PyExpat_XML_SetElementHandler
#define XML_SetEncoding                 PyExpat_XML_SetEncoding
#define XML_SetEndCdataSectionHandler   PyExpat_XML_SetEndCdataSectionHandler
#define XML_SetEndDoctypeDeclHandler    PyExpat_XML_SetEndDoctypeDeclHandler
#define XML_SetEndElementHandler        PyExpat_XML_SetEndElementHandler
#define XML_SetEndNamespaceDeclHandler  PyExpat_XML_SetEndNamespaceDeclHandler
#define XML_SetEntityDeclHandler        PyExpat_XML_SetEntityDeclHandler
#define XML_SetExternalEntityRefHandler PyExpat_XML_SetExternalEntityRefHandler
#define XML_SetExternalEntityRefHandlerArg  PyExpat_XML_SetExternalEntityRefHandlerArg
#define XML_SetHashSalt                 PyExpat_XML_SetHashSalt
#define XML_SetNamespaceDeclHandler     PyExpat_XML_SetNamespaceDeclHandler
#define XML_SetNotationDeclHandler      PyExpat_XML_SetNotationDeclHandler
#define XML_SetNotStandaloneHandler     PyExpat_XML_SetNotStandaloneHandler
#define XML_SetParamEntityParsing       PyExpat_XML_SetParamEntityParsing
#define XML_SetProcessingInstructionHandler PyExpat_XML_SetProcessingInstructionHandler
#define XML_SetReturnNSTriplet          PyExpat_XML_SetReturnNSTriplet
#define XML_SetSkippedEntityHandler     PyExpat_XML_SetSkippedEntityHandler
#define XML_SetStartCdataSectionHandler PyExpat_XML_SetStartCdataSectionHandler
#define XML_SetStartDoctypeDeclHandler  PyExpat_XML_SetStartDoctypeDeclHandler
#define XML_SetStartElementHandler      PyExpat_XML_SetStartElementHandler
#define XML_SetStartNamespaceDeclHandler    PyExpat_XML_SetStartNamespaceDeclHandler
#define XML_SetUnknownEncodingHandler   PyExpat_XML_SetUnknownEncodingHandler
#define XML_SetUnparsedEntityDeclHandler    PyExpat_XML_SetUnparsedEntityDeclHandler
#define XML_SetUserData                 PyExpat_XML_SetUserData
#define XML_SetXmlDeclHandler           PyExpat_XML_SetXmlDeclHandler
#define XmlSizeOfUnknownEncoding        PyExpat_XmlSizeOfUnknownEncoding
#define XML_StopParser                  PyExpat_XML_StopParser
#define XML_UseForeignDTD               PyExpat_XML_UseForeignDTD
#define XML_UseParserAsHandlerArg       PyExpat_XML_UseParserAsHandlerArg
#define XmlUtf16Encode                  PyExpat_XmlUtf16Encode
#define XmlUtf8Encode                   PyExpat_XmlUtf8Encode

#endif /* !PYEXPATNS_H */

redpajama_set_name: RedPajamaGithub


text:
package sgload

import "expvar"

var (
	writersProgressStats  *expvar.Map
	readersProgressStats  *expvar.Map
	updatersProgressStats *expvar.Map
	globalProgressStats   *expvar.Map
)

func init() {
	writersProgressStats = expvar.NewMap("writers")
	readersProgressStats = expvar.NewMap("readers")
	updatersProgressStats = expvar.NewMap("updaters")
	globalProgressStats = expvar.NewMap("sgload")
}

// Since sometimes we want to just ignore any calls to update expvarstats
// depending on CLI args, wrap up expvar.Map behind an interface and offer
// a "no-op" version
type ExpVarStatsCollector interface {
	Set(key string, av expvar.Var)
	Add(key string, delta int64)
}

// An impl of ExpVarStatsCollector which ignores every operation
type NoOpExpvarStatsCollector struct{}

func (e NoOpExpvarStatsCollector) Set(key string, av expvar.Var) {}

func (e NoOpExpvarStatsCollector) Add(key string, delta int64) {}


text:
DATE: 27 December 2017

* \#153: Upgraded to JTS 1.15.  This JTS release has an API breakage in that the package root was changed
  from com.vividsolutions to org.locationtech but should otherwise be compatible.
  JTS is now dual-licensed as EPL 1.0 and EDL 1.0 (a BSD style license).
  This JTS release also included various improvements, including faster LineString intersection.
  (David Smiley)

* \#138: Feature: Added integration for the Jackson-databind ("ObjectMapper") serialization library.
  It's a popular library to serialize/deserialize JSON, XML, and other formats to/from Java objects.
  Jackson is an optional dependency for Spatial4j that is only required for this feature.
  (Ryan McKinley)

* \#151: Moved application of JtsContext.autoIndex from JtsShapeFactory.makeShapeFromGeometry() to
  JtsSpatialContext.makeShape is which is more central.
  (Justin Deoliveira)

* \#155: Ensure that JTS Geometry objects passed to Spatial4j are never modified.  If Spatial4j wants to
  do so in order to dateline wrap it, then it'll now be cloned first (at some new cost, which we try to avoid).
  (David Smiley)

* 408c14a7: Bug: JtsShapeFactory.lineString: if useJtsLineString (true by default) and we have a non-0 buffer
  then a buffer of 0 was applied instead of the intended buffer.
  (Ryan McKinley)

* \#152: Removed test dependency on jeo library; some classes were copied in.
  (Justin Deoliveira)

## VERSION 0.6

DATE: 26 February 2016

### Notes:

* Package change from com.spatial4j.core to org.locationtech.spatial4j. Also, maven coordinates change from groupId
  com.spatial4j to org.locationtech.spatial4j.  (David Smiley)

### Features:

* \#130: New ShapeFactory interface for shape creation. Related methods on SpatialContext are now deprecated; get the
  ShapeFactory from the SpatialContext.  ShapeFactory has builders for Polygon, LineString, MultiShape, MultiPoint,
  MultiLineString, and MultiPolygon.  The ShapeReader formats now use these and thus no longer have hard dependencies
  on JTS just to create a polygon, although should you need to create a polygon, you still need JTS on the classpath at
  this time.  A new JtsSpatialContextFactory.useJtsMulti option (defaults to true) toggles whether JTS's Multi*
  implementations are to be used in preference to Spatial4j's native ShapeCollection.
  (David Smiley, Justin Deoliveira)

### Bugs:

 * If tried to use an "empty" JTS geometry when geo=false, it would throw an exception. (David Smiley)

 * \#127: JtsGeometry.relate(Circle) was incorrect. (David Smiley)

---------------------------------------

## VERSION 0.5

DATE: 18 September 2015

### User/API changes & Notes:

 * \#96: Java 1.7 is now the minimum version supported by Spatial4j.

 * Spatial4j supports more formats now; see "FORMATS.md".  More info below.

 * \#107: The DatelineRule and ValidationRule enums were moved to the com.spatial4j.context.jts package, and the
   current setting is exposed on JtsSpatialContext. The autoIndex boolean was moved there too.
   These things used to be defined in JtsWktShapeParser. (Justin Deoliveira & David Smiley)

 * \#92: Shape now exposes the SpatialContext

 * Given a JTS Geometry instance and the desire to have a Spatial4j equivalent Shape, consider
   using JtsSpatialContext.createShapeFromGeometry(geometry) vs. makeShape(geometry).  See the
   javadocs.

 * WktShapeParser was renamed to WKTReader, although WktShapeParser still exists as a deprecated
   subclass of WKTReader.  SpatialContext.getWktShapeParser returns WKTReader.  JtsWktShapeParser
   was renamed to JtsWKTReader.

 * \#90: Publish the test-jar. (Nick Knize)

 * The internal class "Range" is deprecated, unused, and will be removed in a future release.

### Features:

 * \#91: SpatialContext.getFormats() returns a new SupportedFormats which lists the supported
   Shape formats for readers & writers.  (Ryan McKinley)

 * \#94: WKT writing support. (Ryan McKinley)

 * \#94: GeoJSON format support; both reading & writing. (Ryan McKinley, Justin Deoliveira)

 * \#117: Polyshape format support; both reading & writing. (Ryan McKinley, Justin Deoliveira)

 * \#98: SpatialPredicate class -- moved from Lucene Spatial. (Ryan McKinley)

### Improvements:

 * \#103: JtsGeometry now accepts GeometryCollection if it's component geometry types are
   homogeneous. (Justin Deoliveira)
   note: for non-homogeneous ones, see JtsSpatialContext.createShapeFromGeometry

 * \#97: More consistent use of ParseException vs InvalidShapeException (Ryan McKinley)

### Bugs:

 * \#104: DistanceUtils.distHaversineRAD could return NaN given anti-podal points. (David Smiley)

 * \#77: When ShapeCollection & JtsGeometry computed the bounding box for multiple shapes
   longitudinally, it could sometimes produce a world-wrap longitude instead of the minimal
   enclosing span. (David Smiley)

 * \#86: Rectangle.getBuffered() in geo mode was sometimes slightly off in the southern hemisphere.
   (David Smiley)

 * \#85: Vertical line Rectangles at the dateline should relate with another such Rectangle
   consistently if one is declared at -180 longitude and the other at +180 longitude.  Before this
   fix, INTERSECTS would sometimes be returned instead of CONTAINS or WITHIN more accurately.
   (David Smiley)

---------------------------------------

## VERSION 0.4

DATE: 20 January 2014

### User/API changes & Notes:

 * It used to be the case that rectangular polygons provided in WKT had to have its vertexes given
   in counter-clockwise order to indicate which way around the earth it went. The default is now
   the shorter width (less than 180 degrees). This setting can be changed via the "datelineRule"
   setting. To avoid ambiguity, just use the ENVELOPE syntax.

 * Unless you refer to the SpatialContext.GEO or JtsSpatialContext.GEO instances, the only true way
   to create a context is to use the SpatialContextFactory (and including the JTS based subclass),
   which have a host of settings that make Spatial4j very customizable.

 * SpatialContext.readShape(String) and toString(Shape) are still deprecated but will be
   removed in the next release. You should instead read WKT via the new method
   readShapeFromWkt(String). This also means the worldBounds initialization via SpatialContextFactory
   should be specified as an ENVELOPE WKT. Spatial4j will no longer provide a way to generate WKT
   from a shape although it's pretty easy to use JTS for that.

 * In Spatial4j's older JTS based implementation, it used to be the case that when reading WKT,
   latitudes would be normalized into the -90 to 90 range; it's now an error. Longitudes outside of
   -180 to 180 were also normalized and this is now an error too. Longitude normalization can be
   enabled with the "normWrapLongitude" option.

 * Newly deprecated: ParseUtils, some methods and constants in DistanceUtils (which seemed only used
   by Solr), and SpatialContext constructors other than that which takes a SpatialContextFactory.
   In the "io" package, these classes were **deleted**:  LineReader, SampleData..., Geoname...
   Copies of those were moved to the _Spatial Solr Sandbox_ project.

### Features:

 * New built-in WKT parser separate from JTS's. JTS is no longer required for WKT but still is for
   certain shapes like polygons. It supports the ENVELOPE rectangle syntax seen in OGC's CQL spec,
   and it has a custom BUFFER(shape, distance) that can be used to buffer a shape. A buffered point
   is a circle. Parse via SpatialContext.readShapeFromWkt(String). JTS's WKT parser can be used as
   an alternative via the JtsWKTReaderShapeParser class.

 * New ShapeCollection shape. It's similar to a JTS/OGC GeometryCollection and is used to hold
   multiple shapes of the same or different types.

 * New BufferedLine & BufferedLineString shapes. A 0 buffer results in effectively Line &
   LineString shapes. A non-0 buffer is buffered in a rectangular corner fashion (i.e. a rectangle
   on an angle). This new shape does not yet support geodesics (e.g. the dateline), and so JTS's
   equivalents are used by default for now.

 * JtsGeometry can now be "indexed".  It builds an internal index to speed up subsequent
   calculations. It can be done automatically when read from WKT via the new "autoIndex" option.

 * JtsGeometry shapes when read via WKT have configurable validation and automatic repair via a
   couple algorithms. See the new "validationRule" setting.

 * Shapes can now be "empty"; see Shape.isEmpty().

 * Configurable dateline crossing algorithm: none, width180, ccwRect

 * JTS's PrecisionModel is configurable from the JtsSpatialContextFactory.

 * A new "BinaryCodec" is added which is a binary format for shapes; see
   SpatialContext.getBinaryCodec(). In this release it's a pretty straight-forward implementation,
   but might get optimized for more compactness in the future. When using JTS and the
   "floating_single" PrecisionModel, it will use 4-byte floats instead of 8-byte doubles for shapes
   other than JtsGeometry (i.e. non-polygons). JtsGeometry is written in WKB format which is always
   8-byte doubles. In the future, WKB will not likely be used.

 * New SpatialContext.calcDistance convenience methods to avoid referencing DistanceCalculator

 * New DistanceCalculator.withinDistance method used by Euclidean circle avoids a Math.sqrt call.

 * DistanceUtils.DEG_TO_KM & KM_TO_DEG convenience constants

### Bugs:

 * Geodetic circles sometimes computed the wrong relationship with a rectangle.

 * JtsGeometry now calculates the minimum geodetic bounding box (also used by ShapeCollection).
   This fixed an issue where Lucene-spatial would give Fiji a much courser grid granularity than it
   deserved.

 * JtsGeometry shapes that had > 180 width sometimes resulted in an exception. (#41 & SOLR-4879)

 * Converting a Euclidean circle to a polygonal geometry was wrong. (#44)

 * DistanceUtil.vectorDistance for Manhattan style was wrong. (LUCENE-3814)

 * More consistently wrap shape parsing errors with InvalidShapeException or ParseException as
   applicable.


text:
package sun.management;

import java.lang.management.MonitorInfo;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.OpenDataException;
import java.util.Set;

/**
 * A CompositeData for MonitorInfo for the local management support.
 * This class avoids the performance penalty paid to the
 * construction of a CompositeData use in the local case.
 */
public class MonitorInfoCompositeData extends LazyCompositeData {
    private final MonitorInfo lock;

    private MonitorInfoCompositeData(MonitorInfo mi) {
        this.lock = mi;
    }

    public MonitorInfo getMonitorInfo() {
        return lock;
    }

    public static CompositeData toCompositeData(MonitorInfo mi) {
        MonitorInfoCompositeData micd = new MonitorInfoCompositeData(mi);
        return micd.getCompositeData();
    }

    protected CompositeData getCompositeData() {
        // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
        // monitorInfoItemNames!

        int len = monitorInfoItemNames.length;
        Object[] values = new Object[len];
        CompositeData li = LockDataConverter.toLockInfoCompositeData(lock);

        for (int i = 0; i < len; i++) {
            String item = monitorInfoItemNames[i];
            if (item.equals(LOCKED_STACK_FRAME)) {
                StackTraceElement ste = lock.getLockedStackFrame();
                values[i] = (ste != null ? StackTraceElementCompositeData.
                                               toCompositeData(ste)
                                         : null);
            } else if (item.equals(LOCKED_STACK_DEPTH)) {
                values[i] = new Integer(lock.getLockedStackDepth());
            } else {
                values[i] = li.get(item);
            }
        }

        try {
            return new CompositeDataSupport(monitorInfoCompositeType,
                                            monitorInfoItemNames,
                                            values);
        } catch (OpenDataException e) {
            // Should never reach here
            throw new AssertionError(e);
        }
    }

    private static final CompositeType monitorInfoCompositeType;
    private static final String[] monitorInfoItemNames;
    static {
        try {
            monitorInfoCompositeType = (CompositeType)
                MappedMXBeanType.toOpenType(MonitorInfo.class);
            Set<String> s = monitorInfoCompositeType.keySet();
            monitorInfoItemNames = (String[]) s.toArray(new String[0]);
        } catch (OpenDataException e) {
            // Should never reach here
            throw new AssertionError(e);
        }
    }

    static CompositeType getMonitorInfoCompositeType() {
        return monitorInfoCompositeType;
    }

    private static final String CLASS_NAME         = "className";
    private static final String IDENTITY_HASH_CODE = "identityHashCode";
    private static final String LOCKED_STACK_FRAME = "lockedStackFrame";
    private static final String LOCKED_STACK_DEPTH = "lockedStackDepth";

    public static String getClassName(CompositeData cd) {
        return getString(cd, CLASS_NAME);
    }

    public static int getIdentityHashCode(CompositeData cd) {
        return getInt(cd, IDENTITY_HASH_CODE);
    }

    public static StackTraceElement getLockedStackFrame(CompositeData cd) {
        CompositeData ste = (CompositeData) cd.get(LOCKED_STACK_FRAME);
        if (ste != null) {
            return StackTraceElementCompositeData.from(ste);
        } else {
            return null;
        }
    }

    public static int getLockedStackDepth(CompositeData cd) {
        return getInt(cd, LOCKED_STACK_DEPTH);
    }

    /** Validate if the input CompositeData has the expected
     * CompositeType (i.e. contain all attributes with expected
     * names and types).
     */
    public static void validateCompositeData(CompositeData cd) {
        if (cd == null) {
            throw new NullPointerException("Null CompositeData");
        }

        if (!isTypeMatched(monitorInfoCompositeType, cd.getCompositeType())) {
            throw new IllegalArgumentException(
                "Unexpected composite type for MonitorInfo");
        }
    }

    private static final long serialVersionUID = -5825215591822908529L;
}