public async Task <IList <IGstLookupResult> > LookupGstDataAsync(GstLookupInputType inputType, string input, bool validateInput = false)
        {
            if (validateInput)
            {
                GstInputValidator.ValidateInput(inputType, input);
            }

            GstWebScraper scraper;
            var           pool = _pools[inputType];

            while (pool.TryDequeue(out scraper) && scraper.ShouldDispose)
            {
            }
            if (scraper == null)
            {
                scraper = new GstWebScraper();
            }

            try {
                return(await scraper.LookupGstDataAsync(inputType, input));
            } finally {
                if (!scraper.ShouldDispose)
                {
                    pool.Enqueue(scraper);
                }
            }
        }
        public async Task <IList <IGstLookupResult> > LookupGstDataAsync(GstLookupInputType inputType, string input, bool validateInput = false)
        {
            // Customs' server will return empty result if I send the same request two times in a row,
            // so I'm going to cache the most recent result and return that if the same requests were sent twice.
            var currentInput = Tuple.Create(inputType, input);

            if (currentInput.Equals(_previousInput))
            {
                if (_previousResults.Count > 0)
                {
                    var result = (GstLookupResult)_previousResults[0];
                    result.IsLiveData = false;
                }
                return(_previousResults);
            }

            if (validateInput)
            {
                GstInputValidator.ValidateInput(inputType, input);
            }

            if (_accessCount > 0)
            {
                throw new NotSupportedException(Resources.SingleLookupErrorMessage);
            }

            try {
                if (Interlocked.Increment(ref _accessCount) > 1)
                {
                    throw new NotSupportedException(Resources.SingleLookupErrorMessage);
                }

                if (!_isInitialized)
                {
                    await InitializeTokenAsync();
                    await LoadFrontPageAsync();
                    await BrowseToLookupPageAsync();

                    _isInitialized = true;
                }

                if (_inputType == null || _inputType != inputType)
                {
                    await SelectLookupInputTypeAsync(inputType);
                }

                var results = await ExecuteLookupAsync(input);

                _previousInput   = currentInput;
                _previousResults = results;
                return(results);
            } catch (WebException ex) {
                throw new CustomsGstException(ex.Message, innerException: ex);
            } finally {
                Interlocked.Decrement(ref _accessCount);
            }
        }