private void AddCacheEntry(ProxyAddress proxyAddress, Result <TEntry> result, bool isLockRequired, bool populateCalculatedProperties)
        {
            TEntry data = result.Data;

            if (populateCalculatedProperties && data != null)
            {
                this.PopulateCalculatedProperties(data);
            }
            this.SetEntry(proxyAddress, result, isLockRequired);
            if (data == null)
            {
                return;
            }
            ProxyAddress primarySmtpAddress = ADRecipientCache <TEntry> .GetPrimarySmtpAddress(data);

            if (ADRecipientCache <TEntry> .IsSmtpAddress(proxyAddress))
            {
                ProxyAddress proxyAddress2 = ProxyAddress.Parse(ProxyAddressPrefix.LegacyDN.PrimaryPrefix, ADRecipientCache <TEntry> .GetLegacyExchangeDN(data));
                this.SetEntry(proxyAddress2, result, isLockRequired);
                if (null != primarySmtpAddress && primarySmtpAddress != proxyAddress)
                {
                    this.SetEntry(primarySmtpAddress, result, isLockRequired);
                    return;
                }
            }
            else if (primarySmtpAddress != null)
            {
                this.SetEntry(primarySmtpAddress, result, isLockRequired);
            }
        }
        public virtual IList <Result <TEntry> > FindAndCacheRecipients(IList <ProxyAddress> proxyAddressList)
        {
            if (proxyAddressList == null)
            {
                throw new ArgumentNullException("proxyAddressList");
            }
            List <Result <TEntry> > list    = new List <Result <TEntry> >(proxyAddressList.Count);
            List <ProxyAddress>     proxies = new List <ProxyAddress>(proxyAddressList.Count);
            List <int> list2 = new List <int>(proxyAddressList.Count);

            lock (this.dictionaryLock)
            {
                int num = 0;
                foreach (ProxyAddress proxyAddress in proxyAddressList)
                {
                    Result <TEntry> item = new Result <TEntry>(default(TEntry), null);
                    if (null == proxyAddress || this.dictionary.TryGetValue(proxyAddress, out item))
                    {
                        list.Add(item);
                    }
                    else
                    {
                        list.Add(item);
                        proxies.Add(proxyAddress);
                        list2.Add(num);
                    }
                    num++;
                }
            }
            if (ADRecipientCache <TEntry> .PerfCounters != null)
            {
                ADRecipientCache <TEntry> .PerfCounters.AggregateHits_Base.Increment();

                if (list2.Count == 0)
                {
                    ADRecipientCache <TEntry> .PerfCounters.AggregateHits.Increment();
                }
                else
                {
                    int num2 = list2.Count / ADRecipientCache <TEntry> .BatchSize;
                    if (list2.Count % ADRecipientCache <TEntry> .BatchSize != 0)
                    {
                        num2++;
                    }
                    ADRecipientCache <TEntry> .PerfCounters.AggregateMisses.IncrementBy((long)num2);
                }
            }
            if (proxies.Count == 0)
            {
                return(list);
            }
            if (ADRecipientCache <TEntry> .PerfCounters != null)
            {
                ADRecipientCache <TEntry> .PerfCounters.BatchedAddressLookupsTotal.Increment();

                ADRecipientCache <TEntry> .PerfCounters.RequestsPendingTotal.Increment();

                ADRecipientCache <TEntry> .PerfCounters.AggregateLookupsTotal.Increment();

                this.IncrementQueriesPerCacheCounter();
            }
            Result <TEntry>[] rawResults = null;
            Stopwatch         stopwatch  = Stopwatch.StartNew();

            try
            {
                int i;
                ADNotificationAdapter.RunADOperation(delegate()
                {
                    if (typeof(TEntry) == typeof(ADRawEntry))
                    {
                        Result <ADRawEntry>[] source = this.ADSession.FindByProxyAddresses(proxies.ToArray(), this.properties);
                        rawResults = (from i in source
                                      select new Result <TEntry>((TEntry)((object)i.Data), i.Error)).ToArray <Result <TEntry> >();
                        return;
                    }
                    if (typeof(TEntry) == typeof(TransportMiniRecipient))
                    {
                        Result <TransportMiniRecipient>[] source2 = this.ADSession.FindByProxyAddresses <TransportMiniRecipient>(proxies.ToArray());
                        rawResults = (from i in source2
                                      select new Result <TEntry>(i.Data as TEntry, i.Error)).ToArray <Result <TEntry> >();
                        return;
                    }
                    throw new NotSupportedException();
                });
            }
            finally
            {
                stopwatch.Stop();
                if (ADRecipientCache <TEntry> .PerfCounters != null)
                {
                    ADRecipientCache <TEntry> .PerfCounters.AverageLookupQueryLatency.IncrementBy(stopwatch.ElapsedMilliseconds);
                }
                ADRecipientCache <TEntry> .DecrementPendingRequestsCounter();
            }
            for (int i = 0; i < rawResults.Length; i++)
            {
                if (rawResults[i].Data != null)
                {
                    this.PopulateCalculatedProperties(rawResults[i].Data);
                }
                list[list2[i]] = rawResults[i];
            }
            bool flag2 = false;

            lock (this.dictionaryLock)
            {
                for (int j = 0; j < proxies.Count; j++)
                {
                    Result <TEntry> value;
                    if (proxies[j] != null && this.dictionary.TryGetValue(proxies[j], out value))
                    {
                        list[list2[j]] = value;
                        flag2          = true;
                    }
                    else
                    {
                        this.AddCacheEntry(proxies[j], list[list2[j]], false, false);
                    }
                }
            }
            if (flag2 && ADRecipientCache <TEntry> .PerfCounters != null)
            {
                ADRecipientCache <TEntry> .PerfCounters.RepeatedQueryForTheSameRecipient.Increment();
            }
            return(list);
        }
        public virtual bool Remove(ProxyAddress proxyAddress)
        {
            bool result2;

            lock (this.dictionaryLock)
            {
                Result <TEntry> result;
                if (this.dictionary.TryGetValue(proxyAddress, out result))
                {
                    this.dictionary.Remove(proxyAddress);
                    if (result.Data == null)
                    {
                        result2 = true;
                    }
                    else
                    {
                        if (ADRecipientCache <TEntry> .IsExAddress(proxyAddress))
                        {
                            this.dictionary.Remove(ADRecipientCache <TEntry> .GetPrimarySmtpAddress(result.Data));
                        }
                        else if (ADRecipientCache <TEntry> .IsSmtpAddress(proxyAddress))
                        {
                            this.dictionary.Remove(ProxyAddress.Parse(ProxyAddressPrefix.LegacyDN.PrimaryPrefix, ADRecipientCache <TEntry> .GetLegacyExchangeDN(result.Data)));
                        }
                        result2 = true;
                    }
                }
                else
                {
                    result2 = false;
                }
            }
            return(result2);
        }
        public virtual Result <TEntry> FindAndCacheRecipient(ADObjectId objectId)
        {
            if (objectId == null)
            {
                throw new ArgumentNullException("objectId");
            }
            if (ADRecipientCache <TEntry> .PerfCounters != null)
            {
                ADRecipientCache <TEntry> .PerfCounters.IndividualAddressLookupsTotal.Increment();

                ADRecipientCache <TEntry> .PerfCounters.RequestsPendingTotal.Increment();

                ADRecipientCache <TEntry> .PerfCounters.AggregateHits_Base.Increment();

                ADRecipientCache <TEntry> .PerfCounters.AggregateMisses.Increment();

                ADRecipientCache <TEntry> .PerfCounters.AggregateLookupsTotal.Increment();

                this.IncrementQueriesPerCacheCounter();
            }
            Stopwatch       stopwatch = Stopwatch.StartNew();
            Result <TEntry> result;

            try
            {
                TEntry entry = default(TEntry);
                ADNotificationAdapter.RunADOperation(delegate()
                {
                    if (typeof(TEntry) == typeof(TransportMiniRecipient))
                    {
                        entry = (this.ADSession.ReadMiniRecipient <TransportMiniRecipient>(objectId, this.properties) as TEntry);
                        return;
                    }
                    if (this.isFullADRecipientObject)
                    {
                        entry = (TEntry)((object)this.ADSession.Read(objectId));
                        return;
                    }
                    entry = (TEntry)((object)this.ADSession.ReadADRawEntry(objectId, this.properties));
                });
                if (entry == null)
                {
                    result = new Result <TEntry>(default(TEntry), ProviderError.NotFound);
                }
                else
                {
                    result = new Result <TEntry>(entry, null);
                }
            }
            catch (DataValidationException ex)
            {
                ComponentTrace <ADRecipientCacheTags> .TraceError <DataValidationException>(0, -1L, "DataValidationException: {0}", ex);

                result = new Result <TEntry>(default(TEntry), ex.Error);
            }
            finally
            {
                stopwatch.Stop();
                if (ADRecipientCache <TEntry> .PerfCounters != null)
                {
                    ADRecipientCache <TEntry> .PerfCounters.AverageLookupQueryLatency.IncrementBy(stopwatch.ElapsedMilliseconds);
                }
                ADRecipientCache <TEntry> .DecrementPendingRequestsCounter();
            }
            if (result.Data != null)
            {
                ProxyAddress primarySmtpAddress = ADRecipientCache <TEntry> .GetPrimarySmtpAddress(result.Data);

                if (primarySmtpAddress != null)
                {
                    this.AddCacheEntry(primarySmtpAddress, result);
                }
            }
            return(result);
        }