private function executeQuery(string $url, string $locale = null): AddressCollection
    {
        if (null !== $locale) {
            // Locale code transformation: for example from it_IT to it
            $url = sprintf('%s&lang=%s', $url, substr($locale, 0, 2));
        }

        $content = $this->getUrlContents($url);
        if (null === $json = json_decode($content)) {
            throw InvalidServerResponse::create($url);
        }

        if (isset($json->totalResultsCount) && empty($json->totalResultsCount)) {
            return new AddressCollection([]);
        }

        $data = $json->geonames;

        if (empty($data)) {
            return new AddressCollection([]);
        }

        $results = [];
        foreach ($data as $item) {
            $builder = new AddressBuilder($this->getName());

            if (isset($item->bbox)) {
                $builder->setBounds($item->bbox->south, $item->bbox->west, $item->bbox->north, $item->bbox->east);
            }

            for ($level = 1; $level <= AdminLevelCollection::MAX_LEVEL_DEPTH; ++$level) {
                $adminNameProp = 'adminName'.$level;
                $adminCodeProp = 'adminCode'.$level;
                if (!empty($item->$adminNameProp)) {
                    $builder->addAdminLevel($level, $item->$adminNameProp, $item->$adminCodeProp ?? null);
                }
            }

            $builder->setCoordinates($item->lat ?? null, $item->lng ?? null);
            $builder->setLocality($item->name ?? null);
            $builder->setCountry($item->countryName ?? null);
            $builder->setCountryCode($item->countryCode ?? null);
            $builder->setTimezone($item->timezone->timeZoneId ?? null);

            /** @var GeonamesAddress $address */
            $address = $builder->build(GeonamesAddress::class);
            $address = $address->withName($item->name ?? null);
            $address = $address->withAsciiName($item->asciiName ?? null);
            $address = $address->withFclName($item->fclName ?? null);
            $address = $address->withAlternateNames($item->alternateNames ?? []);
            $address = $address->withPopulation($item->population ?? null);
            $address = $address->withGeonameId($item->geonameId ?? null);
            $address = $address->withFcode($item->fcode ?? null);

            $results[] = $address;
        }

        return new AddressCollection($results);
    }
private function executeQuery(string $url, string $locale = null): AddressCollection
    {
        if (null !== $locale) {
            // Locale code transformation: for example from it_IT to it
            $url = sprintf('%s&lang=%s', $url, substr($locale, 0, 2));
        }

        $content = $this->getUrlContents($url);
        if (null === $json = json_decode($content)) {
            throw InvalidServerResponse::create($url);
        }

        if (isset($json->totalResultsCount) && empty($json->totalResultsCount)) {
            return new AddressCollection([]);
        }

        $data = $json->geonames;

        if (empty($data)) {
            return new AddressCollection([]);
        }

        $results = [];
        foreach ($data as $item) {
            $builder = new AddressBuilder($this->getName());

            if (isset($item->bbox)) {
                $builder->setBounds($item->bbox->south, $item->bbox->west, $item->bbox->north, $item->bbox->east);
            }

            for ($level = 1; $level <= AdminLevelCollection::MAX_LEVEL_DEPTH; ++$level) {
                $adminNameProp = 'adminName'.$level;
                $adminCodeProp = 'adminCode'.$level;
                if (!empty($item->$adminNameProp)) {
                    $builder->addAdminLevel($level, $item->$adminNameProp, $item->$adminCodeProp ?? null);
                }
            }

            $builder->setCoordinates($item->lat ?? null, $item->lng ?? null);
            $builder->setLocality($item->name ?? null);
            $builder->setCountry($item->countryName ?? null);
            $builder->setCountryCode($item->countryCode ?? null);
            $builder->setTimezone($item->timezone->timeZoneId ?? null);

            /** @var GeonamesAddress $address */
            $address = $builder->build(GeonamesAddress::class);
            $address = $address->withName($item->name ?? null);
            $address = $address->withAsciiName($item->asciiName ?? null);
            $address = $address->withFclName($item->fclName ?? null);
            $address = $address->withAlternateNames($item->alternateNames ?? []);
            $address = $address->withPopulation($item->population ?? null);
            $address = $address->withGeonameId($item->geonameId ?? null);
            $address = $address->withFcode($item->fcode ?? null);

            $results[] = $address;
        }

        return new AddressCollection($results);
    }
@param string      $url
@param string|null $locale

@return AddressCollection