private static void fillForBasicFilter(final BaseGeocacheFilter basicFilter, final Parameters params, final Map<String, String> valueMap, @NonNull final OCApiConnector connector) {
        switch (basicFilter.getType()) {
            case TYPE:
                valueMap.put("type", CollectionStream.of(((TypeGeocacheFilter) basicFilter).getRawValues())
                        .map(OkapiClient::getFilterFromType).filter(StringUtils::isNotBlank).toJoinedString("|"));
                break;
            case NAME:
                valueMap.put("name", "*" + ((NameGeocacheFilter) basicFilter).getStringFilter().getTextValue().replace('?', '_') + "*");
                break;
            case SIZE:
                valueMap.put("size2", CollectionStream.of(((SizeGeocacheFilter) basicFilter).getRawValues())
                        .map(CacheSize::getOcSize2).filter(StringUtils::isNotBlank).toJoinedString("|"));
                break;
            case DISTANCE:
                final DistanceGeocacheFilter distanceFilter = (DistanceGeocacheFilter) basicFilter;
                final Geopoint coord = distanceFilter.getEffectiveCoordinate();
                if (distanceFilter.getMaxRangeValue() != null) {
                    fillSearchParameterBox(valueMap, params, new Viewport(coord, distanceFilter.getMaxRangeValue()));
                } else {
                    fillSearchParameterCenter(valueMap, params, coord, DEFAULT_RADIUS);
                }
                break;
            case DIFFICULTY:
            case TERRAIN:
                final NumberRangeGeocacheFilter<Float> nrFilter = (NumberRangeGeocacheFilter<Float>) basicFilter;
                if (nrFilter.isFiltering()) {
                    valueMap.put(nrFilter.getType() == GeocacheFilterType.DIFFICULTY ? "difficulty" : "terrain",
                            (nrFilter.getMinRangeValue() == null ? "1" : ((int) Math.floor(nrFilter.getMinRangeValue()))) + "-" + (nrFilter.getMaxRangeValue() == null ? "5" : Math.round(nrFilter.getMaxRangeValue())));
                }
                break;
            case DIFFICULTY_TERRAIN:
                fillForBasicFilter(((DifficultyAndTerrainGeocacheFilter) basicFilter).difficultyGeocacheFilter, params, valueMap, connector);
                fillForBasicFilter(((DifficultyAndTerrainGeocacheFilter) basicFilter).terrainGeocacheFilter, params, valueMap, connector);
                break;
            case RATING:
                final RatingGeocacheFilter ratingFilter = (RatingGeocacheFilter) basicFilter;
                if (ratingFilter.getMinRangeValue() != null) {
                    valueMap.put("rating", (ratingFilter.getMinRangeValue() == null ? "1" : ((int) Math.floor(ratingFilter.getMinRangeValue()))) + "-" + (ratingFilter.getMaxRangeValue() == null ? "5" : Math.round(ratingFilter.getMaxRangeValue())));
                }
                break;
            case OWNER:
                final String uuid = getUserUUID(connector, ((OwnerGeocacheFilter) basicFilter).getStringFilter().getTextValue());
                // If uuid ==null then user is not known on oc platform.
                // In that case, set a nonexisting uuid so the search will return no result
                valueMap.put("owner_uuid", uuid == null ? "unknown-user" : uuid);
                break;
            case FAVORITES:
                final FavoritesGeocacheFilter favFilter = (FavoritesGeocacheFilter) basicFilter;
                if (favFilter.getMinRangeValue() != null) {
                    valueMap.put("min_rcmds", ((int) Math.round(favFilter.getMinRangeValue())) + (favFilter.isPercentage() ? "%" : ""));
                }
                break;
            case STATUS:
                final StatusGeocacheFilter statusFilter = (StatusGeocacheFilter) basicFilter;
                String value = "";
                if (!statusFilter.isExcludeActive()) {
                    value += "|Available";
                }
                if (!statusFilter.isExcludeDisabled()) {
                    value += "|Temporarily unavailable";
                }
                //DON'T return archived caches even if the filter says so. See #11208 for explanation
                //Note: if at a later point in time Archived shall be included, just add following codeline:
                //   if (!statusFilter.isExcludeArchived()) {
                //       value += "|Archived";
                //   }
                if (!value.isEmpty()) {
                    valueMap.put("status", value.substring(1));
                }

                if (statusFilter.getStatusFound() != null) {
                    valueMap.put("found_status", statusFilter.getStatusFound() ? "found_only" : "notfound_only");
                }
                if (FALSE.equals(statusFilter.getStatusOwned())) {
                    valueMap.put("exclude_my_own", "true");
                }
                break;
            case LOGS_COUNT:
                final LogsCountGeocacheFilter logsCountFilter = (LogsCountGeocacheFilter) basicFilter;
                if (logsCountFilter.getLogType().equals(LogType.FOUND_IT)) {
                    if (logsCountFilter.getMinRangeValue() != null) {
                        valueMap.put("min_founds", "" + logsCountFilter.getMinRangeValue());
                    }
                    if (logsCountFilter.getMaxRangeValue() != null) {
                        valueMap.put("max_founds", "" + logsCountFilter.getMaxRangeValue());
                    }
                }
                break;
            case LOG_ENTRY:
                final LogEntryGeocacheFilter logEntryFilter = (LogEntryGeocacheFilter) basicFilter;
                if (StringUtils.isNotBlank(logEntryFilter.getFoundByUser())) {
                    String uuid2 = getUserUUID(connector, logEntryFilter.getFoundByUser());
                    if (uuid2 == null) {
                        uuid2 = "unknown-user"; //set a nonexisting uuid so the search will return nothing
                    }
                    if (logEntryFilter.isInverse()) {
                        valueMap.put("not_found_by", uuid2);
                    } else {
                        valueMap.put("found_by", uuid2);
                    }
                }
                break;
            default:
                break;
        }

    }
Client for the OpenCaching API (Okapi).

@see <a href="http://www.opencaching.de/okapi/introduction.html">Okapi overview</a>
main/src/main/java/cgeo/geocaching/connector/oc/OkapiClient.java