anchor.diff:  Future<shelf.Response> _packagesHandlerHtmlCore(
       shelf.Request request, String platform) async {
     // TODO: use search memcache for all results here or remove search memcache
  +  final searchQuery = _parseSearchQuery(request, platform);
  +  final searchResult = await searchService.search(searchQuery);
  +  final int totalCount = searchResult.totalCount;
  +
  +  final links = new PackageLinks(searchQuery.offset, totalCount,
  +      searchQuery: searchQuery);
  +  return htmlResponse(templateService.renderPkgIndexPage(
  +    searchResult.packages,
  +    links,
  +    platform,
  +    searchQuery: searchQuery,
  +    totalCount: totalCount,
  +  ));
  +}
  +
  +SearchQuery _parseSearchQuery(shelf.Request request, String platform) {
     final int page = _pageFromUrl(request.url);
     final int offset = PackageLinks.resultsPerPage * (page - 1);
     final String queryText = request.requestedUri.queryParameters['q'] ?? '';
  
positive.code: 
  /// Handles requests for /api/search
  Future<shelf.Response> _apiSearchHandler(shelf.Request request) async {
    final q = request.requestedUri.queryParameters['q']?.trim();
    if (q == null || q.isEmpty) {
      return jsonResponse({}, status: HttpStatus.BAD_REQUEST);
    }
    final sr = await searchClient.search(new SearchQuery.parse(query: q));
    final packages = sr.packages.map((ps) => {'package': ps.package}).toList();
    final result = {
      'packages': packages,
    };
    return jsonResponse(result);
  }
  
  
negative.code:       ? null
        : parseSearchOrder(sortParam);
  
    return new SearchQuery.parse(
        query: queryText,
        platform: platform,
        order: sortOrder,
        offset: offset,
        limit: PackageLinks.resultsPerPage);
  }
  
  /// Handles requests for /packages/...  - multiplexes to HTML/JSON handlers
  