コード例 #1
0
        internal cStoreFeedback(IEnumerable <iMessageHandle> pMessageHandles, eStoreOperation pOperation, cStorableFlags pFlags)
        {
            if (pMessageHandles == null)
            {
                throw new ArgumentNullException(nameof(pMessageHandles));
            }
            if (pFlags == null)
            {
                throw new ArgumentNullException(nameof(pFlags));
            }

            object lMessageCache = null;

            foreach (var lMessageHandle in pMessageHandles)
            {
                if (lMessageHandle == null)
                {
                    throw new ArgumentOutOfRangeException(nameof(pMessageHandles), "contains nulls");
                }
                if (lMessageCache == null)
                {
                    lMessageCache = lMessageHandle.MessageCache;
                }
                else if (!ReferenceEquals(lMessageHandle.MessageCache, lMessageCache))
                {
                    throw new ArgumentOutOfRangeException(nameof(pMessageHandles), "contains mixed message caches");
                }
            }

            mItems     = new List <cStoreFeedbackItem>(from lMessageHandle in pMessageHandles.Distinct() select new cStoreFeedbackItem(lMessageHandle));
            mOperation = pOperation;
            mFlags     = pFlags;
        }
コード例 #2
0
        internal cUIDStoreFeedback(IEnumerable <cUID> pUIDs, eStoreOperation pOperation, cStorableFlags pFlags)
        {
            if (pUIDs == null)
            {
                throw new ArgumentNullException(nameof(pUIDs));
            }
            if (pFlags == null)
            {
                throw new ArgumentNullException(nameof(pFlags));
            }

            uint lUIDValidity = 0;

            foreach (var lUID in pUIDs)
            {
                if (lUID == null)
                {
                    throw new ArgumentOutOfRangeException(nameof(pUIDs), "contains nulls");
                }
                if (lUIDValidity == 0)
                {
                    lUIDValidity = lUID.UIDValidity;
                }
                else if (lUID.UIDValidity != lUIDValidity)
                {
                    throw new ArgumentOutOfRangeException(nameof(pUIDs), "contains mixed uidvalidities");
                }
            }

            mItems     = new List <cUIDStoreFeedbackItem>(from lUID in pUIDs.Distinct() select new cUIDStoreFeedbackItem(lUID));
            mOperation = pOperation;
            mFlags     = pFlags;
        }
コード例 #3
0
ファイル: frmStoreDialog.cs プロジェクト: bacome/imapclient
        private bool ZTryParseFlagNames(string pText, out cStorableFlags rFlags)
        {
            if (pText == null)
            {
                rFlags = cStorableFlags.Empty; return(true);
            }

            List <string> lFlags = new List <string>();

            foreach (var lFlag in pText.Trim().Split(' '))
            {
                if (!string.IsNullOrWhiteSpace(lFlag))
                {
                    lFlags.Add(lFlag);
                }
            }

            if (lFlags.Count == 0)
            {
                rFlags = cStorableFlags.Empty; return(true);
            }

            try { rFlags = new cStorableFlags(lFlags); }
            catch { rFlags = null; return(false); }

            return(true);
        }
コード例 #4
0
ファイル: frmStoreDialog.cs プロジェクト: bacome/imapclient
        private string ZFlagNames(cStorableFlags pFlags)
        {
            if (pFlags == null || pFlags.Count == 0)
            {
                return(string.Empty);
            }

            StringBuilder lBuilder = new StringBuilder();
            bool          lFirst   = true;

            foreach (var lFlag in pFlags)
            {
                if (lFirst)
                {
                    lFirst = false;
                }
                else
                {
                    lBuilder.Append(" ");
                }
                lBuilder.Append(lFlag);
            }

            return(lBuilder.ToString());
        }
コード例 #5
0
ファイル: messageflags.cs プロジェクト: bacome/imapclient
        internal static void _Tests(cTrace.cContext pParentContext)
        {
            bool lFailed;

            var lFlags = new cStorableFlagList();

            lFlags.Add("a");
            lFlags.Add("b");
            lFlags.Add(kMessageFlag.Answered, kMessageFlag.Deleted);
            lFlags.Add(kMessageFlag.Answered, kMessageFlag.Deleted, kMessageFlag.Forwarded);
            lFlags.Add(@"\answereD");
            lFlags.Add(@"\ansWereD", "A", @"\deleteD");

            lFailed = false;
            try { lFlags.Add("fr ed"); }
            catch { lFailed = true; }
            if (!lFailed)
            {
                throw new cTestsException($"{nameof(cStorableFlagList)}.1");
            }

            lFailed = false;
            try { lFlags.Add(kMessageFlag.Answered, kMessageFlag.Deleted, kMessageFlag.Draft, kMessageFlag.Recent); }
            catch { lFailed = true; }
            if (!lFailed)
            {
                throw new cTestsException($"{nameof(cStorableFlagList)}.1");
            }

            if (lFlags.Count != 5)
            {
                throw new cTestsException($"{nameof(cStorableFlagList)}.2");
            }
            if (!lFlags.Contains("A") || !lFlags.Contains("B") || !lFlags.Contains(@"\aNswereD") || lFlags.Contains(kMessageFlag.Draft) || !lFlags.Contains("$forwarded"))
            {
                throw new cTestsException($"{nameof(cStorableFlagList)}.3");
            }

            cStorableFlags  lF1 = new cStorableFlags("a", "A", "b", @"\answered", "\\deleted", kMessageFlag.Forwarded);
            cFetchableFlags lF2 = new cFetchableFlags("a", "A", "b", @"\answered", "\\deleted", kMessageFlag.Recent);
            cStorableFlags  lF3 = new cStorableFlags("a", "b", "\\deleted", kMessageFlag.Forwarded);

            if (!lFlags.Contains(lF1) || lFlags.Contains(lF2) || !lFlags.Contains(lF3))
            {
                throw new cTestsException($"{nameof(cStorableFlagList)}.4");
            }

            lFlags.Remove("A");
            if (lFlags.Count != 4 || lFlags.Contains(lF1) || lFlags.Contains(lF3))
            {
                throw new cTestsException($"{nameof(cStorableFlagList)}.5");
            }

            lFlags.Remove("B", "$forwarded", @"\answered");
            if (lFlags.Count != 1 || lFlags.Contains(lF3))
            {
                throw new cTestsException($"{nameof(cStorableFlagList)}.6");
            }
        }
コード例 #6
0
        internal cUIDStoreFeedback(cUID pUID, eStoreOperation pOperation, cStorableFlags pFlags)
        {
            if (pUID == null)
            {
                throw new ArgumentNullException(nameof(pUID));
            }
            if (pFlags == null)
            {
                throw new ArgumentNullException(nameof(pFlags));
            }

            mItems = new List <cUIDStoreFeedbackItem>();
            mItems.Add(new cUIDStoreFeedbackItem(pUID));

            mOperation = pOperation;
            mFlags     = pFlags;
        }
コード例 #7
0
        internal cStoreFeedback(iMessageHandle pMessageHandle, eStoreOperation pOperation, cStorableFlags pFlags)
        {
            if (pMessageHandle == null)
            {
                throw new ArgumentNullException(nameof(pMessageHandle));
            }
            if (pFlags == null)
            {
                throw new ArgumentNullException(nameof(pFlags));
            }

            mItems = new List <cStoreFeedbackItem>();
            mItems.Add(new cStoreFeedbackItem(pMessageHandle));

            mOperation = pOperation;
            mFlags     = pFlags;
        }
コード例 #8
0
        internal void IncrementSummary(iMessageHandle pMessageHandle, eStoreOperation pOperation, cStorableFlags pFlags, ref sStoreFeedbackSummary pSummary)
        {
            if (WasNotUnchangedSince)
            {
                pSummary.WasNotUnchangedSinceCount++;
                return;
            }

            if (ReceivedFlagsUpdate)
            {
                pSummary.UpdatedCount++;
                return;
            }

            if (pMessageHandle == null)
            {
                pSummary.UnknownCount++;
                return;
            }

            if (pMessageHandle.Expunged)
            {
                pSummary.ExpungedCount++;
                return;
            }

            if (pMessageHandle.Flags == null)
            {
                pSummary.UnknownCount++;
                return;
            }

            switch (pOperation)
            {
            case eStoreOperation.add:

                if (pMessageHandle.Flags.Contains(pFlags))
                {
                    pSummary.ReflectsOperationCount++;
                }
                else
                {
                    pSummary.NotReflectsOperationCount++;
                }
                return;

            case eStoreOperation.remove:

                if (pMessageHandle.Flags.Contains(pFlags))
                {
                    pSummary.NotReflectsOperationCount++;
                }
                else
                {
                    pSummary.ReflectsOperationCount++;
                }
                return;

            case eStoreOperation.replace:

                if (pMessageHandle.Flags.SymmetricDifference(pFlags, kMessageFlag.Recent).Count() == 0)
                {
                    pSummary.ReflectsOperationCount++;
                }
                else
                {
                    pSummary.NotReflectsOperationCount++;
                }
                return;
            }

            pSummary.UnknownCount++; // shouldn't happen
        }
コード例 #9
0
        /// <summary>
        /// Stores flags for a set of messages. The mailbox that the messages are in must be selected.
        /// </summary>
        /// <param name="pMessages"></param>
        /// <param name="pOperation">The type of store operation.</param>
        /// <param name="pFlags"></param>
        /// <param name="pIfUnchangedSinceModSeq"></param>
        /// <returns>Feedback on the success (or otherwise) of the store.</returns>
        /// <remarks>
        /// <paramref name="pIfUnchangedSinceModSeq"/> may only be specified if the containing mailbox's <see cref="cMailbox.HighestModSeq"/> is not zero.
        /// (i.e. <see cref="cCapabilities.CondStore"/> is in use and the mailbox supports the persistent storage of mod-sequences.)
        /// If a message has been modified since the specified value then the server will fail the store for that message.
        /// </remarks>
        public cStoreFeedback Store(IEnumerable <cMessage> pMessages, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq = null)
        {
            var lContext  = mRootContext.NewMethodV(nameof(cIMAPClient), nameof(Store), 3);
            var lFeedback = new cStoreFeedback(pMessages, pOperation, pFlags);
            var lTask     = ZStoreAsync(lFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq, lContext);

            mSynchroniser.Wait(lTask, lContext);
            return(lFeedback);
        }
コード例 #10
0
ファイル: uidstore.cs プロジェクト: bacome/imapclient
        internal async Task <cUIDStoreFeedback> UIDStoreAsync(iMailboxHandle pMailboxHandle, IEnumerable <cUID> pUIDs, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq)
        {
            var lContext  = mRootContext.NewMethod(nameof(cIMAPClient), nameof(UIDStore));
            var lFeedback = new cUIDStoreFeedback(pUIDs, pOperation, pFlags);

            await ZUIDStoreAsync(pMailboxHandle, lFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq, lContext).ConfigureAwait(false);

            return(lFeedback);
        }
コード例 #11
0
ファイル: uidstore.cs プロジェクト: bacome/imapclient
        private async Task ZUIDStoreAsync(iMailboxHandle pMailboxHandle, cUIDStoreFeedback pFeedback, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq, cTrace.cContext pParentContext)
        {
            var lContext = pParentContext.NewMethod(nameof(cIMAPClient), nameof(ZUIDStoreAsync), pFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq);

            if (mDisposed)
            {
                throw new ObjectDisposedException(nameof(cIMAPClient));
            }

            var lSession = mSession;

            if (lSession == null || lSession.SelectedMailboxDetails?.SelectedForUpdate != true)
            {
                throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelectedForUpdate);
            }

            if (pMailboxHandle == null)
            {
                throw new ArgumentNullException(nameof(pMailboxHandle));
            }
            if (pFeedback == null)
            {
                throw new ArgumentNullException(nameof(pFeedback));
            }
            if (pFlags == null)
            {
                throw new ArgumentNullException(nameof(pFlags));
            }

            if (pIfUnchangedSinceModSeq == 0)
            {
                throw new ArgumentOutOfRangeException(nameof(pIfUnchangedSinceModSeq));
            }
            if (pIfUnchangedSinceModSeq != null && !lSession.Capabilities.CondStore)
            {
                throw new InvalidOperationException(kInvalidOperationExceptionMessage.CondStoreNotInUse);
            }

            if (pFeedback.Count == 0)
            {
                return;
            }
            // it is valid to add or remove zero flags according to the ABNF (!)

            using (var lToken = mCancellationManager.GetToken(lContext))
            {
                var lMC = new cMethodControl(mTimeout, lToken.CancellationToken);
                await lSession.UIDStoreAsync(lMC, pMailboxHandle, pFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq, lContext).ConfigureAwait(false);
            }
        }
コード例 #12
0
ファイル: store.cs プロジェクト: bacome/imapclient
            private async Task ZStoreAsync(cMethodControl pMC, cStoreFeedback pFeedback, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZStoreAsync), pMC, pFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq);

                // no validation ... all the parameters have been validated already by the cSession by the time we get here

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select

                    cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckInSelectedMailbox(pFeedback);
                    if (!lSelectedMailbox.SelectedForUpdate)
                    {
                        throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelectedForUpdate);
                    }

                    lBuilder.Add(await mPipeline.GetIdleBlockTokenAsync(pMC, lContext).ConfigureAwait(false)); // stop the pipeline from iding (idle is msnunsafe)
                    lBuilder.Add(await mMSNUnsafeBlock.GetTokenAsync(pMC, lContext).ConfigureAwait(false));    // wait until all commands that are msnunsafe complete, block all commands that are msnunsafe

                    // uidvalidity must be captured before the handles are resolved
                    lBuilder.AddUIDValidity(lSelectedMailbox.MessageCache.UIDValidity);

                    // collector
                    cStoreFeedbackCollector lFeedbackCollector = new cStoreFeedbackCollector();

                    // resolve the handles to MSNs
                    foreach (var lItem in pFeedback)
                    {
                        var lMSN = lSelectedMailbox.GetMSN(lItem.MessageHandle);
                        if (lMSN != 0)
                        {
                            lFeedbackCollector.Add(lMSN, lItem);
                        }
                    }

                    // if no handles were resolved, we are done
                    if (lFeedbackCollector.Count == 0)
                    {
                        return;
                    }

                    // build the command
                    lBuilder.Add(kStoreCommandPartStoreSpace, new cTextCommandPart(cSequenceSet.FromUInts(lFeedbackCollector.UInts)), cCommandPart.Space);
                    if (pIfUnchangedSinceModSeq != null)
                    {
                        lBuilder.Add(kStoreCommandPartLParenUnchangedSinceSpace, new cTextCommandPart(pIfUnchangedSinceModSeq.Value), kStoreCommandPartRParenSpace);
                    }
                    lBuilder.Add(pOperation, pFlags);

                    // add the hook
                    var lHook = new cCommandHookStore(lFeedbackCollector, null, lSelectedMailbox);
                    lBuilder.Add(lHook);

                    // submit the command
                    var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false);

                    // NOTE: updates may have been done on both OK and NO responses (see rfc 2180/ 7162) so we can't throw on a NO for this command ... NO indicates that some (or all) of the messages have pending deletes

                    // throw on a bad
                    if (lResult.ResultType == eCommandResultType.bad)
                    {
                        fCapabilities lTryIgnoring;
                        if (pIfUnchangedSinceModSeq == null)
                        {
                            lTryIgnoring = 0;
                        }
                        else
                        {
                            lTryIgnoring = fCapabilities.condstore;
                        }
                        throw new cProtocolErrorException(lResult, lTryIgnoring, lContext);
                    }

                    if (lResult.ResultType == eCommandResultType.ok)
                    {
                        lContext.TraceInformation("store success");
                    }
                    else
                    {
                        lContext.TraceInformation("store possible partial success");
                    }
                }
            }
コード例 #13
0
ファイル: uidstore.cs プロジェクト: bacome/imapclient
        internal cUIDStoreFeedback UIDStore(iMailboxHandle pMailboxHandle, IEnumerable <cUID> pUIDs, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq)
        {
            var lContext  = mRootContext.NewMethod(nameof(cIMAPClient), nameof(UIDStore));
            var lFeedback = new cUIDStoreFeedback(pUIDs, pOperation, pFlags);
            var lTask     = ZUIDStoreAsync(pMailboxHandle, lFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq, lContext);

            mSynchroniser.Wait(lTask, lContext);
            return(lFeedback);
        }
コード例 #14
0
        /// <summary>
        /// Asynchronously stores flags for a set of messages. The mailbox that the messages are in must be selected.
        /// </summary>
        /// <param name="pMessages"></param>
        /// <param name="pOperation">The type of store operation.</param>
        /// <param name="pFlags"></param>
        /// <param name="pIfUnchangedSinceModSeq"></param>
        /// <inheritdoc cref="Store(IEnumerable{cMessage}, eStoreOperation, cStorableFlags, ulong?)" select="returns|remarks"/>
        public async Task <cStoreFeedback> StoreAsync(IEnumerable <cMessage> pMessages, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq = null)
        {
            var lContext  = mRootContext.NewMethodV(nameof(cIMAPClient), nameof(StoreAsync), 3);
            var lFeedback = new cStoreFeedback(pMessages, pOperation, pFlags);

            await ZStoreAsync(lFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq, lContext).ConfigureAwait(false);

            return(lFeedback);
        }
コード例 #15
0
        internal async Task <cStoreFeedback> StoreAsync(iMessageHandle pMessageHandle, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq)
        {
            var lContext  = mRootContext.NewMethodV(nameof(cIMAPClient), nameof(StoreAsync), 1);
            var lFeedback = new cStoreFeedback(pMessageHandle, pOperation, pFlags);

            await ZStoreAsync(lFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq, lContext).ConfigureAwait(false);

            return(lFeedback);
        }
コード例 #16
0
ファイル: store.cs プロジェクト: bacome/imapclient
            public async Task UIDStoreAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, cUIDStoreFeedback pFeedback, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(UIDStoreAsync), pMC, pMailboxHandle, pFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq);

                if (mDisposed)
                {
                    throw new ObjectDisposedException(nameof(cSession));
                }
                if (_ConnectionState != eConnectionState.selected)
                {
                    throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelected);
                }

                if (pMailboxHandle == null)
                {
                    throw new ArgumentNullException(nameof(pMailboxHandle));
                }
                if (pFeedback == null)
                {
                    throw new ArgumentNullException(nameof(pFeedback));
                }
                if (pFlags == null)
                {
                    throw new ArgumentNullException(nameof(pFlags));
                }

                if (pFeedback.Count == 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(pFeedback));
                }

                if (pIfUnchangedSinceModSeq == 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(pIfUnchangedSinceModSeq));
                }
                if (pIfUnchangedSinceModSeq != null && !_Capabilities.CondStore)
                {
                    throw new InvalidOperationException(kInvalidOperationExceptionMessage.CondStoreNotInUse);
                }

                uint lUIDValidity = pFeedback[0].UID.UIDValidity;

                cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, lUIDValidity); // to be repeated inside the select lock

                if (!lSelectedMailbox.SelectedForUpdate)
                {
                    throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelectedForUpdate);                                      // to be repeated inside the select lock
                }
                cStoreFeedbackCollector lFeedbackCollector = new cStoreFeedbackCollector(pFeedback);

                await ZUIDStoreAsync(pMC, pMailboxHandle, lUIDValidity, lFeedbackCollector, pOperation, pFlags, pIfUnchangedSinceModSeq, pFeedback, lContext).ConfigureAwait(false);
            }
コード例 #17
0
        internal cStoreFeedback Store(iMessageHandle pMessageHandle, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq)
        {
            var lContext  = mRootContext.NewMethodV(nameof(cIMAPClient), nameof(Store), 1);
            var lFeedback = new cStoreFeedback(pMessageHandle, pOperation, pFlags);
            var lTask     = ZStoreAsync(lFeedback, pOperation, pFlags, pIfUnchangedSinceModSeq, lContext);

            mSynchroniser.Wait(lTask, lContext);
            return(lFeedback);
        }
コード例 #18
0
            private async Task ZUIDStoreAsync(cMethodControl pMC, iMailboxHandle pMailboxHandle, uint pUIDValidity, cStoreFeedbackCollector pFeedbackCollector, eStoreOperation pOperation, cStorableFlags pFlags, ulong?pIfUnchangedSinceModSeq, cUIDStoreFeedback pFeedback, cTrace.cContext pParentContext)
            {
                var lContext = pParentContext.NewMethod(nameof(cSession), nameof(ZStoreAsync), pMC, pMailboxHandle, pUIDValidity, pFeedbackCollector, pOperation, pFlags, pIfUnchangedSinceModSeq, pFeedback);

                // no validation ... all the parameters have been validated already by the cSession by the time we get here

                using (var lBuilder = new cCommandDetailsBuilder())
                {
                    lBuilder.Add(await mSelectExclusiveAccess.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // block select

                    cSelectedMailbox lSelectedMailbox = mMailboxCache.CheckIsSelectedMailbox(pMailboxHandle, pUIDValidity);
                    if (!lSelectedMailbox.SelectedForUpdate)
                    {
                        throw new InvalidOperationException(kInvalidOperationExceptionMessage.NotSelectedForUpdate);
                    }

                    lBuilder.Add(await mMSNUnsafeBlock.GetBlockAsync(pMC, lContext).ConfigureAwait(false)); // this command is msnunsafe

                    lBuilder.AddUIDValidity(pUIDValidity);                                                  // the command is sensitive to UIDValidity changes

                    // build the command
                    lBuilder.Add(kUIDStoreCommandPartUIDStoreSpace, new cTextCommandPart(cSequenceSet.FromUInts(pFeedbackCollector.UInts)), cCommandPart.Space);
                    if (pIfUnchangedSinceModSeq != null)
                    {
                        lBuilder.Add(kStoreCommandPartLParenUnchangedSinceSpace, new cTextCommandPart(pIfUnchangedSinceModSeq.Value), kStoreCommandPartRParenSpace);
                    }
                    lBuilder.Add(pOperation, pFlags);

                    // add the hook
                    var lHook = new cCommandHookStore(pFeedbackCollector, pFeedback, lSelectedMailbox);
                    lBuilder.Add(lHook);

                    // submit the command
                    var lResult = await mPipeline.ExecuteAsync(pMC, lBuilder.EmitCommandDetails(), lContext).ConfigureAwait(false);

                    // note: the base spec states that non-existent UIDs are ignored without comment => a NO from a UID STORE is unexpected

                    if (lResult.ResultType == eCommandResultType.ok)
                    {
                        lContext.TraceInformation("uid store success");
                        return;
                    }

                    fCapabilities lTryIgnoring;
                    if (pIfUnchangedSinceModSeq == null)
                    {
                        lTryIgnoring = 0;
                    }
                    else
                    {
                        lTryIgnoring = fCapabilities.condstore;
                    }

                    if (lResult.ResultType == eCommandResultType.no)
                    {
                        throw new cUnsuccessfulCompletionException(lResult.ResponseText, lTryIgnoring, lContext);
                    }
                    throw new cProtocolErrorException(lResult, lTryIgnoring, lContext);
                }
            }