text:
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/ash/components/geolocation/simple_geolocation_request.h"

#include <stddef.h>

#include <algorithm>
#include <memory>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/escape.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chromeos/ash/components/geolocation/simple_geolocation_provider.h"
#include "chromeos/ash/components/geolocation/simple_geolocation_request_test_monitor.h"
#include "google_apis/google_api_keys.h"
#include "net/base/load_flags.h"
#include "net/http/http_status_code.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/url_response_head.mojom.h"

// Location resolve timeout is usually 1 minute, so 2 minutes with 50 buckets
// should be enough.
#define UMA_HISTOGRAM_LOCATION_RESPONSE_TIMES(name, sample)        \
  UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, base::Milliseconds(10), \
                             base::Minutes(2), 50)

namespace ash {

namespace {

// Used if sending location signals (WiFi APs, cell towers, etc) is disabled.
constexpr char kSimpleGeolocationRequestBody[] = "{\"considerIp\": \"true\"}";

// Geolocation request field keys:
// Top-level request data fields.
constexpr char kConsiderIp[] = "considerIp";
constexpr char kWifiAccessPoints[] = "wifiAccessPoints";
constexpr char kCellTowers[] = "cellTowers";
// Shared Wifi and Cell Tower objects.
constexpr char kAge[] = "age";
constexpr char kSignalStrength[] = "signalStrength";
// WiFi access point objects.
constexpr char kMacAddress[] = "macAddress";
constexpr char kChannel[] = "channel";
constexpr char kSignalToNoiseRatio[] = "signalToNoiseRatio";
// Cell tower objects.
constexpr char kCellId[] = "cellId";
constexpr char kLocationAreaCode[] = "locationAreaCode";
constexpr char kMobileCountryCode[] = "mobileCountryCode";
constexpr char kMobileNetworkCode[] = "mobileNetworkCode";

// Geolocation response field keys:
constexpr char kLocationString[] = "location";
constexpr char kLatString[] = "lat";
constexpr char kLngString[] = "lng";
constexpr char kAccuracyString[] = "accuracy";

// Error object and its contents.
constexpr char kErrorString[] = "error";
// "errors" array in "error" object is ignored.
constexpr char kCodeString[] = "code";
constexpr char kMessageString[] = "message";

// We are using "sparse" histograms for the number of retry attempts,
// so we need to explicitly limit maximum value (in case something goes wrong).
const size_t kMaxRetriesValueInHistograms = 20;

// Sleep between geolocation request retry on HTTP error.
const unsigned int kResolveGeolocationRetrySleepOnServerErrorSeconds = 5;

// Sleep between geolocation request retry on bad server response.
const unsigned int kResolveGeolocationRetrySleepBadResponseSeconds = 10;

enum SimpleGeolocationRequestEvent {
  // NOTE: Do not renumber these as that would confuse interpretation of
  // previously logged data. When making changes, also update the enum list
  // in tools/metrics/histograms/histograms.xml to keep it in sync.
  SIMPLE_GEOLOCATION_REQUEST_EVENT_REQUEST_START = 0,
  SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_SUCCESS = 1,
  SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_NOT_OK = 2,
  SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_EMPTY = 3,
  SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_MALFORMED = 4,

  // NOTE: Add entries only immediately above this line.
  SIMPLE_GEOLOCATION_REQUEST_EVENT_COUNT = 5
};

enum SimpleGeolocationRequestResult {
  // NOTE: Do not renumber these as that would confuse interpretation of
  // previously logged data. When making changes, also update the enum list
  // in tools/metrics/histograms/histograms.xml to keep it in sync.
  SIMPLE_GEOLOCATION_REQUEST_RESULT_SUCCESS = 0,
  SIMPLE_GEOLOCATION_REQUEST_RESULT_FAILURE = 1,
  SIMPLE_GEOLOCATION_REQUEST_RESULT_SERVER_ERROR = 2,
  SIMPLE_GEOLOCATION_REQUEST_RESULT_CANCELLED = 3,

  // NOTE: Add entries only immediately above this line.
  SIMPLE_GEOLOCATION_REQUEST_RESULT_COUNT = 4
};

SimpleGeolocationRequestTestMonitor* g_test_request_hook = nullptr;

// Too many requests (more than 1) mean there is a problem in implementation.
void RecordUmaEvent(SimpleGeolocationRequestEvent event) {
  UMA_HISTOGRAM_ENUMERATION("SimpleGeolocation.Request.Event", event,
                            SIMPLE_GEOLOCATION_REQUEST_EVENT_COUNT);
}

void RecordUmaResponseCode(int code) {
  base::UmaHistogramSparse("SimpleGeolocation.Request.ResponseCode", code);
}

// Slow geolocation resolve leads to bad user experience.
void RecordUmaResponseTime(base::TimeDelta elapsed, bool success) {
  if (success) {
    UMA_HISTOGRAM_LOCATION_RESPONSE_TIMES(
        "SimpleGeolocation.Request.ResponseSuccessTime", elapsed);
  } else {
    UMA_HISTOGRAM_LOCATION_RESPONSE_TIMES(
        "SimpleGeolocation.Request.ResponseFailureTime", elapsed);
  }
}

void RecordUmaResult(SimpleGeolocationRequestResult result, size_t retries) {
  UMA_HISTOGRAM_ENUMERATION("SimpleGeolocation.Request.Result", result,
                            SIMPLE_GEOLOCATION_REQUEST_RESULT_COUNT);
  base::UmaHistogramSparse("SimpleGeolocation.Request.Retries",
                           std::min(retries, kMaxRetriesValueInHistograms));
}

// Creates the request url to send to the server.
GURL GeolocationRequestURL(const GURL& url) {
  if (url != SimpleGeolocationProvider::DefaultGeolocationProviderURL())
    return url;

  std::string api_key = google_apis::GetAPIKey();
  if (api_key.empty())
    return url;

  std::string query(url.query());
  if (!query.empty())
    query += "&";
  query += "key=" + base::EscapeQueryParamValue(api_key, true);
  GURL::Replacements replacements;
  replacements.SetQueryStr(query);
  return url.ReplaceComponents(replacements);
}

void PrintGeolocationError(const GURL& server_url,
                           const std::string& message,
                           Geoposition* position) {
  position->status = Geoposition::STATUS_SERVER_ERROR;
  position->error_message = base::StringPrintf(
      "SimpleGeolocation provider at '%s' : %s.",
      server_url.DeprecatedGetOriginAsURL().spec().c_str(), message.c_str());
  VLOG(1) << "SimpleGeolocationRequest::GetGeolocationFromResponse() : "
          << position->error_message;
}

// Parses the server response body. Returns true if parsing was successful.
// Sets |*position| to the parsed Geolocation if a valid position was received,
// otherwise leaves it unchanged.
bool ParseServerResponse(const GURL& server_url,
                         const std::string& response_body,
                         Geoposition* position) {
  DCHECK(position);

  if (response_body.empty()) {
    PrintGeolocationError(server_url, "Server returned empty response",
                          position);
    RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_EMPTY);
    return false;
  }
  VLOG(1) << "SimpleGeolocationRequest::ParseServerResponse() : "
             "Parsing response '"
          << response_body << "'";

  // Parse the response, ignoring comments.
  auto response_result =
      base::JSONReader::ReadAndReturnValueWithError(response_body);
  if (!response_result.has_value()) {
    PrintGeolocationError(
        server_url, "JSONReader failed: " + response_result.error().message,
        position);
    RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_MALFORMED);
    return false;
  }
  base::Value response_value = std::move(*response_result);

  if (!response_value.is_dict()) {
    PrintGeolocationError(
        server_url,
        "Unexpected response type : " +
            base::StringPrintf(
                "%u", static_cast<unsigned int>(response_value.type())),
        position);
    RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_MALFORMED);
    return false;
  }

  base::Value* error_object = response_value.FindDictKey(kErrorString);
  base::Value* location_object = response_value.FindDictKey(kLocationString);

  position->timestamp = base::Time::Now();

  if (error_object) {
    std::string* error_message = error_object->FindStringKey(kMessageString);
    if (!error_message) {
      position->error_message = "Server returned error without message.";
    } else {
      position->error_message = *error_message;
    }

    // Ignore result (code defaults to zero).
    position->error_code =
        error_object->FindIntKey(kCodeString).value_or(position->error_code);
  } else {
    position->error_message.erase();
  }

  if (location_object) {
    absl::optional<double> latitude =
        location_object->FindDoubleKey(kLatString);
    if (!latitude) {
      PrintGeolocationError(server_url, "Missing 'lat' attribute.", position);
      RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_MALFORMED);
      return false;
    }
    position->latitude = latitude.value();

    absl::optional<double> longitude =
        location_object->FindDoubleKey(kLngString);
    if (!longitude) {
      PrintGeolocationError(server_url, "Missing 'lon' attribute.", position);
      RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_MALFORMED);
      return false;
    }
    position->longitude = longitude.value();

    absl::optional<double> accuracy =
        response_value.FindDoubleKey(kAccuracyString);
    if (!accuracy) {
      PrintGeolocationError(server_url, "Missing 'accuracy' attribute.",
                            position);
      RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_MALFORMED);
      return false;
    }
    position->accuracy = accuracy.value();
  }

  if (error_object) {
    position->status = Geoposition::STATUS_SERVER_ERROR;
    return false;
  }
  // Empty response is STATUS_OK but not Valid().
  position->status = Geoposition::STATUS_OK;
  return true;
}

// Attempts to extract a position from the response. Detects and indicates
// various failure cases.
bool GetGeolocationFromResponse(bool http_success,
                                int status_code,
                                const std::string& response_body,
                                const GURL& server_url,
                                Geoposition* position) {
  VLOG(1) << "GetGeolocationFromResponse(http_success=" << http_success
          << ", status_code=" << status_code << "): response_body:\n"
          << response_body;

  // HttpPost can fail for a number of reasons. Most likely this is because
  // we're offline, or there was no response.
  if (!http_success) {
    PrintGeolocationError(server_url, "No response received", position);
    RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_EMPTY);
    return false;
  }
  if (status_code != net::HTTP_OK) {
    std::string message = "Returned error code ";
    message += base::NumberToString(status_code);
    PrintGeolocationError(server_url, message, position);
    RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_NOT_OK);
    return false;
  }

  return ParseServerResponse(server_url, response_body, position);
}

void ReportUmaHasWiFiAccessPoints(bool value) {
  UMA_HISTOGRAM_BOOLEAN("SimpleGeolocation.Request.HasWiFiAccessPoints", value);
}
void ReportUmaHasCellTowers(bool value) {
  UMA_HISTOGRAM_BOOLEAN("SimpleGeolocation.Request.HasCellTowers", value);
}

// Helpers to reformat data into dictionaries for conversion to request JSON
base::Value::Dict CreateAccessPointDictionary(
    const WifiAccessPoint& access_point) {
  base::Value::Dict access_point_dictionary;

  access_point_dictionary.Set(kMacAddress, access_point.mac_address);
  access_point_dictionary.Set(kSignalStrength, access_point.signal_strength);
  if (!access_point.timestamp.is_null()) {
    access_point_dictionary.Set(
        kAge,
        base::NumberToString(
            (base::Time::Now() - access_point.timestamp).InMilliseconds()));
  }

  access_point_dictionary.Set(kChannel, access_point.channel);
  access_point_dictionary.Set(kSignalToNoiseRatio,
                              access_point.signal_to_noise);

  return access_point_dictionary;
}

base::Value::Dict CreateCellTowerDictionary(const CellTower& cell_tower) {
  base::Value::Dict cell_tower_dictionary;
  cell_tower_dictionary.Set(kCellId, cell_tower.ci);
  cell_tower_dictionary.Set(kLocationAreaCode, cell_tower.lac);
  cell_tower_dictionary.Set(kMobileCountryCode, cell_tower.mcc);
  cell_tower_dictionary.Set(kMobileNetworkCode, cell_tower.mnc);

  if (!cell_tower.timestamp.is_null()) {
    cell_tower_dictionary.Set(
        kAge, base::NumberToString(
                  (base::Time::Now() - cell_tower.timestamp).InMilliseconds()));
  }
  return cell_tower_dictionary;
}

}  // namespace

SimpleGeolocationRequest::SimpleGeolocationRequest(
    scoped_refptr<network::SharedURLLoaderFactory> factory,
    const GURL& service_url,
    base::TimeDelta timeout,
    std::unique_ptr<WifiAccessPointVector> wifi_data,
    std::unique_ptr<CellTowerVector> cell_tower_data)
    : shared_url_loader_factory_(std::move(factory)),
      service_url_(service_url),
      retry_sleep_on_server_error_(
          base::Seconds(kResolveGeolocationRetrySleepOnServerErrorSeconds)),
      retry_sleep_on_bad_response_(
          base::Seconds(kResolveGeolocationRetrySleepBadResponseSeconds)),
      timeout_(timeout),
      retries_(0),
      wifi_data_(wifi_data.release()),
      cell_tower_data_(cell_tower_data.release()) {}

SimpleGeolocationRequest::~SimpleGeolocationRequest() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  // If callback is not empty, request is cancelled.
  if (callback_) {
    RecordUmaResponseTime(base::Time::Now() - request_started_at_, false);
    RecordUmaResult(SIMPLE_GEOLOCATION_REQUEST_RESULT_CANCELLED, retries_);
  }

  if (g_test_request_hook)
    g_test_request_hook->OnRequestCreated(this);
}

std::string SimpleGeolocationRequest::FormatRequestBody() const {
  if (!wifi_data_)
    ReportUmaHasWiFiAccessPoints(false);

  if (!cell_tower_data_)
    ReportUmaHasCellTowers(false);

  if (!cell_tower_data_ && !wifi_data_)
    return std::string(kSimpleGeolocationRequestBody);

  base::Value::Dict request;
  request.Set(kConsiderIp, true);

  if (wifi_data_) {
    base::Value::List wifi_access_points;
    for (const WifiAccessPoint& access_point : *wifi_data_) {
      wifi_access_points.Append(CreateAccessPointDictionary(access_point));
    }
    request.Set(kWifiAccessPoints, std::move(wifi_access_points));
  }

  if (cell_tower_data_) {
    base::Value::List cell_towers;
    for (const CellTower& cell_tower : *cell_tower_data_) {
      cell_towers.Append(CreateCellTowerDictionary(cell_tower));
    }
    request.Set(kCellTowers, std::move(cell_towers));
  }

  std::string result;
  if (!base::JSONWriter::Write(request, &result)) {
    // If there's no data for a network type, we will have already reported
    // false above
    if (wifi_data_)
      ReportUmaHasWiFiAccessPoints(false);
    if (cell_tower_data_)
      ReportUmaHasCellTowers(false);

    return std::string(kSimpleGeolocationRequestBody);
  }

  if (wifi_data_)
    ReportUmaHasWiFiAccessPoints(wifi_data_->size());
  if (cell_tower_data_)
    ReportUmaHasCellTowers(cell_tower_data_->size());

  return result;
}

void SimpleGeolocationRequest::StartRequest() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_REQUEST_START);
  ++retries_;

  const std::string request_body = FormatRequestBody();
  VLOG(1) << "SimpleGeolocationRequest::StartRequest(): request body:\n"
          << request_body;

  auto request = std::make_unique<network::ResourceRequest>();
  request->url = request_url_;
  request->method = "POST";
  request->load_flags = net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE;
  request->credentials_mode = network::mojom::CredentialsMode::kOmit;

  simple_url_loader_ = network::SimpleURLLoader::Create(
      std::move(request), NO_TRAFFIC_ANNOTATION_YET);
  simple_url_loader_->AttachStringForUpload(request_body, "application/json");

  // Call test hook before asynchronous request actually starts.
  if (g_test_request_hook)
    g_test_request_hook->OnStart(this);

  simple_url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
      shared_url_loader_factory_.get(),
      base::BindOnce(&SimpleGeolocationRequest::OnSimpleURLLoaderComplete,
                     base::Unretained(this)));
}

void SimpleGeolocationRequest::MakeRequest(ResponseCallback callback) {
  callback_ = std::move(callback);
  request_url_ = GeolocationRequestURL(service_url_);
  timeout_timer_.Start(FROM_HERE, timeout_, this,
                       &SimpleGeolocationRequest::OnTimeout);
  request_started_at_ = base::Time::Now();
  StartRequest();
}

// static
void SimpleGeolocationRequest::SetTestMonitor(
    SimpleGeolocationRequestTestMonitor* monitor) {
  g_test_request_hook = monitor;
}

std::string SimpleGeolocationRequest::FormatRequestBodyForTesting() const {
  return FormatRequestBody();
}

void SimpleGeolocationRequest::Retry(bool server_error) {
  base::TimeDelta delay(server_error ? retry_sleep_on_server_error_
                                     : retry_sleep_on_bad_response_);
  request_scheduled_.Start(FROM_HERE, delay, this,
                           &SimpleGeolocationRequest::StartRequest);
}

void SimpleGeolocationRequest::OnSimpleURLLoaderComplete(
    std::unique_ptr<std::string> response_body) {
  bool is_success = !!response_body;
  int response_code = -1;
  if (simple_url_loader_->ResponseInfo() &&
      simple_url_loader_->ResponseInfo()->headers) {
    response_code =
        simple_url_loader_->ResponseInfo()->headers->response_code();
  }
  RecordUmaResponseCode(response_code);

  const bool parse_success = GetGeolocationFromResponse(
      is_success, response_code, response_body ? *response_body : std::string(),
      simple_url_loader_->GetFinalURL(), &position_);
  // Note that SimpleURLLoader doesn't return a body for non-2xx
  // responses by default.
  const bool server_error =
      (!is_success && (response_code == -1 || response_code / 100 == 2)) ||
      (response_code >= 500 && response_code < 600);
  const bool success = parse_success && position_.Valid();
  simple_url_loader_.reset();

  DVLOG(1)
      << "SimpleGeolocationRequest::OnSimpleURLLoaderComplete(): position={"
      << position_.ToString() << "}";

  if (!success) {
    Retry(server_error);
    return;
  }
  const base::TimeDelta elapsed = base::Time::Now() - request_started_at_;
  RecordUmaResponseTime(elapsed, success);

  RecordUmaResult(SIMPLE_GEOLOCATION_REQUEST_RESULT_SUCCESS, retries_);

  ReplyAndDestroySelf(elapsed, server_error);
  // "this" is already destroyed here.
}

void SimpleGeolocationRequest::ReplyAndDestroySelf(
    const base::TimeDelta elapsed,
    bool server_error) {
  simple_url_loader_.reset();
  timeout_timer_.Stop();
  request_scheduled_.Stop();

  ResponseCallback callback = std::move(callback_);

  // Empty callback is used to identify "completed or not yet started request".
  callback_.Reset();

  // callback.Run() usually destroys SimpleGeolocationRequest, because this is
  // the way callback is implemented in GeolocationProvider.
  std::move(callback).Run(position_, server_error, elapsed);
  // "this" is already destroyed here.
}

void SimpleGeolocationRequest::OnTimeout() {
  const SimpleGeolocationRequestResult result =
      (position_.status == Geoposition::STATUS_SERVER_ERROR
           ? SIMPLE_GEOLOCATION_REQUEST_RESULT_SERVER_ERROR
           : SIMPLE_GEOLOCATION_REQUEST_RESULT_FAILURE);
  RecordUmaResult(result, retries_);
  position_.status = Geoposition::STATUS_TIMEOUT;
  const base::TimeDelta elapsed = base::Time::Now() - request_started_at_;
  ReplyAndDestroySelf(elapsed, true /* server_error */);
  // "this" is already destroyed here.
}

}  // namespace ash


text:
package com.linkedin.thirdeye.rootcause.impl;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import java.util.Arrays;
import org.testng.Assert;
import org.testng.annotations.Test;

public class MetricEntityTest {
  @Test
  public void testType() {
    MetricEntity.fromURN("thirdeye:metric:12345", 1.0);
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testTypeFail() {
    MetricEntity.fromURN("thirdeye:other:12345", 1.0);
  }

  @Test
  public void testFilter() {
    MetricEntity e = MetricEntity.fromURN("thirdeye:metric:12345:key=value", 1.0);
    Assert.assertEquals(e.getFilters().size(), 1);
    Assert.assertEquals(e.getFilters().get("key").iterator().next(), "value");
  }

  @Test
  public void testFilterEncoded() {
    MetricEntity e = MetricEntity.fromURN("thirdeye:metric:12345:key%3Dvalue", 1.0);
    Assert.assertEquals(e.getFilters().size(), 1);
    Assert.assertEquals(e.getFilters().get("key").iterator().next(), "value");
  }

  @Test
  public void testFilterEncodedMultipleEquals() {
    MetricEntity e = MetricEntity.fromURN("thirdeye:metric:12345:key%3Dvalue%3D1", 1.0);
    Assert.assertEquals(e.getFilters().size(), 1);
    Assert.assertEquals(e.getFilters().get("key").iterator().next(), "value=1");
  }

  @Test
  public void testFiltersMultikey() {
    MetricEntity e = MetricEntity.fromURN("thirdeye:metric:12345:key=value:key=other:otherKey=yetAnotherValue", 1.0);
    Assert.assertEquals(e.getFilters().size(), 3);
    Assert.assertEquals(e.getFilters().get("key"), Arrays.asList("other", "value")); // stratification
    Assert.assertEquals(e.getFilters().get("otherKey").iterator().next(), "yetAnotherValue");
  }

  @Test(expectedExceptions = IllegalArgumentException.class)
  public void testFiltersShortFail() {
    MetricEntity.fromURN("thirdeye:metric:12345:key:key2=value2", 1.0);
  }

  @Test
  public void testCreateWithFilter() {
    Multimap<String, String> filters = ArrayListMultimap.create();
    filters.put("key", "value");
    filters.put("key", "otherValue");
    filters.put("anotherKey", "otherValue");

    MetricEntity e = MetricEntity.fromMetric(1.0, 123, filters);

    Assert.assertEquals(e.getUrn().split(":").length, 6);
    Assert.assertTrue(e.getUrn().startsWith("thirdeye:metric:123"));
    Assert.assertTrue(e.getUrn().contains(":anotherKey%3DotherValue"));
    Assert.assertTrue(e.getUrn().contains(":key%3Dvalue"));
    Assert.assertTrue(e.getUrn().contains(":key%3DotherValue"));
  }

  @Test
  public void testSetFilters() {
    Multimap<String, String> filters1 = ArrayListMultimap.create();
    filters1.put("key", "otherValue");
    filters1.put("anotherKey", "otherValue");

    Multimap<String, String> filters2 = ArrayListMultimap.create();
    filters2.put("key", "value");

    MetricEntity e = MetricEntity.fromMetric(1.0, 123, filters1);
    Assert.assertEquals(e.getUrn().split(":").length, 5);
    Assert.assertTrue(e.getUrn().startsWith("thirdeye:metric:123"));
    Assert.assertTrue(e.getUrn().contains(":anotherKey%3DotherValue"));
    Assert.assertTrue(e.getUrn().contains(":key%3DotherValue"));

    MetricEntity aug = e.withFilters(filters2);
    Assert.assertEquals(aug.getUrn().split(":").length, 4);
    Assert.assertTrue(aug.getUrn().startsWith("thirdeye:metric:123"));
    Assert.assertTrue(aug.getUrn().contains(":key%3Dvalue"));
  }

  @Test
  public void testRemoveFilters() {
    Multimap<String, String> filters = ArrayListMultimap.create();
    filters.put("key", "value");
    filters.put("key", "otherValue");
    filters.put("anotherKey", "otherValue");

    MetricEntity e = MetricEntity.fromMetric(1.0, 123, filters);
    Assert.assertEquals(e.getUrn().split(":").length, 6);
    Assert.assertTrue(e.getUrn().startsWith("thirdeye:metric:123"));
    Assert.assertTrue(e.getUrn().contains(":anotherKey%3DotherValue"));
    Assert.assertTrue(e.getUrn().contains(":key%3Dvalue"));
    Assert.assertTrue(e.getUrn().contains(":key%3DotherValue"));

    MetricEntity drop = e.withoutFilters();
    Assert.assertEquals(drop.getUrn(), "thirdeye:metric:123");
  }

}

redpajama_set_name: RedPajamaGithub


text:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.compomics.pride_asa_pipeline.core.logic.spectrum;

import com.compomics.pride_asa_pipeline.core.repository.factory.FileParserType;
import java.io.File;
import org.apache.commons.io.FilenameUtils;
import org.apache.log4j.Logger;
import uk.ac.ebi.pride.tools.dta_parser.DtaFile;
import uk.ac.ebi.pride.tools.jmzreader.JMzReader;
import uk.ac.ebi.pride.tools.jmzreader.JMzReaderException;
import uk.ac.ebi.pride.tools.mgf_parser.MgfFile;
import uk.ac.ebi.pride.tools.ms2_parser.Ms2File;
import uk.ac.ebi.pride.tools.mzdata_parser.MzDataFile;
import uk.ac.ebi.pride.tools.mzml_wrapper.MzMlWrapper;
import uk.ac.ebi.pride.tools.mzxml_parser.MzXMLFile;
import uk.ac.ebi.pride.tools.mzxml_parser.MzXMLParsingException;
import uk.ac.ebi.pride.tools.pkl_parser.PklFile;
import uk.ac.ebi.pride.tools.pride_wrapper.PRIDEXmlWrapper;

/**
 *
 * @author Kenneth Verheggen
 */
public class SpectrumParserFactory {

    private static final Logger LOGGER = Logger.getLogger(SpectrumParserFactory.class);
    private static File currentInputFile;
    private static FileParserType currentType;

    public static JMzReader getJMzReader(File inputFile) throws ClassNotFoundException, MzXMLParsingException, JMzReaderException {
        currentInputFile = inputFile;
        JMzReader parser = null;
            String extension = FilenameUtils.getExtension(inputFile.getAbsolutePath());
            switch (extension.toLowerCase()) {
                case "mzxml":
                    LOGGER.info("Detected mzXml file extension.");
                    currentType = FileParserType.MZXML;
                    parser = new MzXMLFile(inputFile);
                    break;
                case "mzml":
                    LOGGER.info("Detected mzml file extension.");
                    currentType = FileParserType.MZML;
                    parser = new MzMlWrapper(inputFile);
                    break;
                case "dta":
                    LOGGER.info("Detected dta file extension.");
                    currentType = FileParserType.DTA;
                    parser = new DtaFile(inputFile);
                    break;
                case "mgf":
                    LOGGER.info("Detected mgf file extension.");
                    currentType = FileParserType.MGF;
                    parser = new MgfFile(inputFile);
                    break;
                case "ms2":
                    LOGGER.info("Detected ms2 file extension.");
                    currentType = FileParserType.MS2;
                    parser = new Ms2File(inputFile);
                    break;
                case "mzData":
                    LOGGER.info("Detected mzData file extension.");
                    currentType = FileParserType.MZDATA;
                    parser = new MzDataFile(inputFile);
                    break;
                case "xml":
                    LOGGER.info("Detected xml file extension.");
                    currentType = FileParserType.PRIDEXML;
                    parser = new PRIDEXmlWrapper(inputFile);
                    break;
                case "pkl":
                    LOGGER.info("Detected pkl file extension.");
                    currentType = FileParserType.PKL;
                    parser = new PklFile(inputFile);
                    break;
                default:
                    throw new ClassNotFoundException("No suitable parser was found for the inputfile.");
            }
        return parser;
    }

    public static File getCurrentInputFile() {
        return currentInputFile;
    }

    public static void setCurrentInputFile(File currentInputFile) {
        SpectrumParserFactory.currentInputFile = currentInputFile;
    }

    public static FileParserType getCurrentType() {
        return currentType;
    }

    public static void setCurrentType(FileParserType currentType) {
        SpectrumParserFactory.currentType = currentType;
    }

}


text:
package nyla.solutions.core.patterns.decorator;

import nyla.solutions.core.data.Textable;

public class StringText implements Textable
{

	/**
	 *
	 */
	public StringText()
	{
	}// --------------------------------------------------------
	/**
	 * @param text
	 */
	public StringText(String text)
	{
		super();
		this.text = text;
	}
	/**
	 * @return the text
	 */
	public String getText()
	{
		return text;
	}
	/**
	 * @param text the text to set
	 */
	public void setText(String text)
	{
		this.text = text;
	}

	private String text = null;

}


text:
namespace Semantics
{

}


text:
//
//  RXAFSecurityPolicy.h
//  RXVerifyExample
//
//  Created by Rush.D.Xzj on 2018/11/6.
//  Copyright © 2018 Rush.D.Xzj. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <Security/Security.h>

// TODOAFN_M_1
typedef NS_ENUM(NSUInteger, RXAFSSLPinningMode) {
    RXAFSSLPinningModeNone,
    RXAFSSLPinningModePublicKey,
    RXAFSSLPinningModeCertificate,
};

// TODOAFN_M_1_K_1: nonnull相关
// 如果去掉这个,会出现Pointer is missing a nullability type specifier  警告
// https://baijiahao.baidu.com/s?id=1591982073136556768&wfr=spider&for=pc
NS_ASSUME_NONNULL_BEGIN

@interface RXAFSecurityPolicy : NSObject <NSSecureCoding, NSCopying>

/**
 The criteria by which server trust should be evaluated against the pinned SSL certificates. Defaults to `AFSSLPinningModeNone`.
 */
// TODOAFN_M_1_K_2: 属性的readonly与readwrite
@property (readonly, nonatomic, assign) RXAFSSLPinningMode SSLPinningMode;

/**
 The certificates used to evaluate server trust according to the SSL pinning mode.

 By default, this property is set to any (`.cer`) certificates included in the target compiling AFNetworking. Note that if you are using AFNetworking as embedded framework, no certificates will be pinned by default. Use `certificatesInBundle` to load certificates from your target, and then create a new policy by calling `policyWithPinningMode:withPinnedCertificates`.

 Note that if pinning is enabled, `evaluateServerTrust:forDomain:` will return true if any pinned certificate matches.
 */
@property (nonatomic, strong, nullable) NSSet <NSData *> *pinnedCertificates;
/**
 Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`.
 */
@property (nonatomic, assign) BOOL allowInvalidCertificates;

/**
 Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`.
 */
@property (nonatomic, assign) BOOL validatesDomainName;

///-----------------------------------------
/// @name Getting Certificates from the Bundle
///-----------------------------------------

/**
 Returns any certificates included in the bundle. If you are using AFNetworking as an embedded framework, you must use this method to find the certificates you have included in your app bundle, and use them when creating your security policy by calling `policyWithPinningMode:withPinnedCertificates`.

 @return The certificates included in the given bundle.
 */
+ (NSSet <NSData *> *)certificatesInBundle:(NSBundle *)bundle;

///-----------------------------------------
/// @name Getting Specific Security Policies
///-----------------------------------------

/**
 Returns the shared default security policy, which does not allow invalid certificates, validates domain name, and does not validate against pinned certificates or public keys.

 @return The default security policy.
 */
+ (instancetype)defaultPolicy;

///---------------------
/// @name Initialization
///---------------------

/**
 Creates and returns a security policy with the specified pinning mode.

 @param pinningMode The SSL pinning mode.

 @return A new security policy.
 */
+ (instancetype)policyWithPinningMode:(RXAFSSLPinningMode)pinningMode;

/**
 Creates and returns a security policy with the specified pinning mode.

 @param pinningMode The SSL pinning mode.
 @param pinnedCertificates The certificates to pin against.

 @return A new security policy.
 */
+ (instancetype)policyWithPinningMode:(RXAFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet <NSData *> *)pinnedCertificates;

///------------------------------
/// @name Evaluating Server Trust
///------------------------------

/**
 Whether or not the specified server trust should be accepted, based on the security policy.

 This method should be used when responding to an authentication challenge from a server.

 @param serverTrust The X.509 certificate trust of the server.
 @param domain The domain of serverTrust. If `nil`, the domain will not be validated.

 @return Whether or not to trust the server.
 */
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
                  forDomain:(nullable NSString *)domain;

@end

// TODOAFN_M_1_K_1
NS_ASSUME_NONNULL_END

///----------------
/// @name Constants
///----------------

/**
 ## SSL Pinning Modes

 The following constants are provided by `AFSSLPinningMode` as possible SSL pinning modes.

 enum {
 AFSSLPinningModeNone,
 AFSSLPinningModePublicKey,
 AFSSLPinningModeCertificate,
 }

 `AFSSLPinningModeNone`
 Do not used pinned certificates to validate servers.

 `AFSSLPinningModePublicKey`
 Validate host certificates against public keys of pinned certificates.

 `AFSSLPinningModeCertificate`
 Validate host certificates against pinned certificates.
 */


text:
package msgraph

// MiracastChannel undocumented
type MiracastChannel string

const (
	// MiracastChannelVUserDefined undocumented
	MiracastChannelVUserDefined MiracastChannel = "userDefined"
	// MiracastChannelVOne undocumented
	MiracastChannelVOne MiracastChannel = "one"
	// MiracastChannelVTwo undocumented
	MiracastChannelVTwo MiracastChannel = "two"
	// MiracastChannelVThree undocumented
	MiracastChannelVThree MiracastChannel = "three"
	// MiracastChannelVFour undocumented
	MiracastChannelVFour MiracastChannel = "four"
	// MiracastChannelVFive undocumented
	MiracastChannelVFive MiracastChannel = "five"
	// MiracastChannelVSix undocumented
	MiracastChannelVSix MiracastChannel = "six"
	// MiracastChannelVSeven undocumented
	MiracastChannelVSeven MiracastChannel = "seven"
	// MiracastChannelVEight undocumented
	MiracastChannelVEight MiracastChannel = "eight"
	// MiracastChannelVNine undocumented
	MiracastChannelVNine MiracastChannel = "nine"
	// MiracastChannelVTen undocumented
	MiracastChannelVTen MiracastChannel = "ten"
	// MiracastChannelVEleven undocumented
	MiracastChannelVEleven MiracastChannel = "eleven"
	// MiracastChannelVThirtySix undocumented
	MiracastChannelVThirtySix MiracastChannel = "thirtySix"
	// MiracastChannelVForty undocumented
	MiracastChannelVForty MiracastChannel = "forty"
	// MiracastChannelVFortyFour undocumented
	MiracastChannelVFortyFour MiracastChannel = "fortyFour"
	// MiracastChannelVFortyEight undocumented
	MiracastChannelVFortyEight MiracastChannel = "fortyEight"
	// MiracastChannelVOneHundredFortyNine undocumented
	MiracastChannelVOneHundredFortyNine MiracastChannel = "oneHundredFortyNine"
	// MiracastChannelVOneHundredFiftyThree undocumented
	MiracastChannelVOneHundredFiftyThree MiracastChannel = "oneHundredFiftyThree"
	// MiracastChannelVOneHundredFiftySeven undocumented
	MiracastChannelVOneHundredFiftySeven MiracastChannel = "oneHundredFiftySeven"
	// MiracastChannelVOneHundredSixtyOne undocumented
	MiracastChannelVOneHundredSixtyOne MiracastChannel = "oneHundredSixtyOne"
	// MiracastChannelVOneHundredSixtyFive undocumented
	MiracastChannelVOneHundredSixtyFive MiracastChannel = "oneHundredSixtyFive"
)

var (
	// MiracastChannelPUserDefined is a pointer to MiracastChannelVUserDefined
	MiracastChannelPUserDefined = &_MiracastChannelPUserDefined
	// MiracastChannelPOne is a pointer to MiracastChannelVOne
	MiracastChannelPOne = &_MiracastChannelPOne
	// MiracastChannelPTwo is a pointer to MiracastChannelVTwo
	MiracastChannelPTwo = &_MiracastChannelPTwo
	// MiracastChannelPThree is a pointer to MiracastChannelVThree
	MiracastChannelPThree = &_MiracastChannelPThree
	// MiracastChannelPFour is a pointer to MiracastChannelVFour
	MiracastChannelPFour = &_MiracastChannelPFour
	// MiracastChannelPFive is a pointer to MiracastChannelVFive
	MiracastChannelPFive = &_MiracastChannelPFive
	// MiracastChannelPSix is a pointer to MiracastChannelVSix
	MiracastChannelPSix = &_MiracastChannelPSix
	// MiracastChannelPSeven is a pointer to MiracastChannelVSeven
	MiracastChannelPSeven = &_MiracastChannelPSeven
	// MiracastChannelPEight is a pointer to MiracastChannelVEight
	MiracastChannelPEight = &_MiracastChannelPEight
	// MiracastChannelPNine is a pointer to MiracastChannelVNine
	MiracastChannelPNine = &_MiracastChannelPNine
	// MiracastChannelPTen is a pointer to MiracastChannelVTen
	MiracastChannelPTen = &_MiracastChannelPTen
	// MiracastChannelPEleven is a pointer to MiracastChannelVEleven
	MiracastChannelPEleven = &_MiracastChannelPEleven
	// MiracastChannelPThirtySix is a pointer to MiracastChannelVThirtySix
	MiracastChannelPThirtySix = &_MiracastChannelPThirtySix
	// MiracastChannelPForty is a pointer to MiracastChannelVForty
	MiracastChannelPForty = &_MiracastChannelPForty
	// MiracastChannelPFortyFour is a pointer to MiracastChannelVFortyFour
	MiracastChannelPFortyFour = &_MiracastChannelPFortyFour
	// MiracastChannelPFortyEight is a pointer to MiracastChannelVFortyEight
	MiracastChannelPFortyEight = &_MiracastChannelPFortyEight
	// MiracastChannelPOneHundredFortyNine is a pointer to MiracastChannelVOneHundredFortyNine
	MiracastChannelPOneHundredFortyNine = &_MiracastChannelPOneHundredFortyNine
	// MiracastChannelPOneHundredFiftyThree is a pointer to MiracastChannelVOneHundredFiftyThree
	MiracastChannelPOneHundredFiftyThree = &_MiracastChannelPOneHundredFiftyThree
	// MiracastChannelPOneHundredFiftySeven is a pointer to MiracastChannelVOneHundredFiftySeven
	MiracastChannelPOneHundredFiftySeven = &_MiracastChannelPOneHundredFiftySeven
	// MiracastChannelPOneHundredSixtyOne is a pointer to MiracastChannelVOneHundredSixtyOne
	MiracastChannelPOneHundredSixtyOne = &_MiracastChannelPOneHundredSixtyOne
	// MiracastChannelPOneHundredSixtyFive is a pointer to MiracastChannelVOneHundredSixtyFive
	MiracastChannelPOneHundredSixtyFive = &_MiracastChannelPOneHundredSixtyFive
)

var (
	_MiracastChannelPUserDefined          = MiracastChannelVUserDefined
	_MiracastChannelPOne                  = MiracastChannelVOne
	_MiracastChannelPTwo                  = MiracastChannelVTwo
	_MiracastChannelPThree                = MiracastChannelVThree
	_MiracastChannelPFour                 = MiracastChannelVFour
	_MiracastChannelPFive                 = MiracastChannelVFive
	_MiracastChannelPSix                  = MiracastChannelVSix
	_MiracastChannelPSeven                = MiracastChannelVSeven
	_MiracastChannelPEight                = MiracastChannelVEight
	_MiracastChannelPNine                 = MiracastChannelVNine
	_MiracastChannelPTen                  = MiracastChannelVTen
	_MiracastChannelPEleven               = MiracastChannelVEleven
	_MiracastChannelPThirtySix            = MiracastChannelVThirtySix
	_MiracastChannelPForty                = MiracastChannelVForty
	_MiracastChannelPFortyFour            = MiracastChannelVFortyFour
	_MiracastChannelPFortyEight           = MiracastChannelVFortyEight
	_MiracastChannelPOneHundredFortyNine  = MiracastChannelVOneHundredFortyNine
	_MiracastChannelPOneHundredFiftyThree = MiracastChannelVOneHundredFiftyThree
	_MiracastChannelPOneHundredFiftySeven = MiracastChannelVOneHundredFiftySeven
	_MiracastChannelPOneHundredSixtyOne   = MiracastChannelVOneHundredSixtyOne
	_MiracastChannelPOneHundredSixtyFive  = MiracastChannelVOneHundredSixtyFive
)


text:
using System;
using System.IO;
using System.Collections;
using System.Data;

using HtmlHelp.ChmDecoding;

namespace HtmlHelp
{
	/// <summary>
	/// The class <c>HtmlHelpSystem</c> implements the main object for reading chm files
	/// </summary>
	public sealed class HtmlHelpSystem
	{
		/// <summary>
		/// Private shared instance of current HtmlHelpSystem class
		/// </summary>
		private static HtmlHelpSystem _current=null;
		/// <summary>
		/// Internal member storing the attached files
		/// </summary>
		private ArrayList _chmFiles = new ArrayList();
		/// <summary>
		/// Internal member storing a merged table of contents
		/// </summary>
		private TableOfContents _toc = new TableOfContents();
		/// <summary>
		/// Internal member storing a merged index
		/// </summary>
		private Index _index = new Index();
		/// <summary>
		/// URL prefix for specifying a chm destination
		/// </summary>
		private static string _urlPrefix = "ms-its:";
		/// <summary>
		/// Internal flag specifying if the system should use the tree-images list
		/// from HtmlHelp2. If false the standard CHM-Viewer pics will be used.
		/// </summary>
		private static bool _useHH2TreePics = false;
		/// <summary>
		/// Internal member storing the read information types
		/// </summary>
		private ArrayList _informationTypes = new ArrayList();
		/// <summary>
		/// Internal member storing the read categories
		/// </summary>
		private ArrayList _categories = new ArrayList();

		/// <summary>
		/// Gets/Sets the url prefix for specifying a chm destination
		/// </summary>
		public static string UrlPrefix
		{
			get { return _urlPrefix; }
			set { _urlPrefix = value; }
		}

		/// <summary>
		/// Gets/Sets the flag specifying if the system should use the tree-images list
		/// from HtmlHelp2. If false the standard CHM-Viewer pics will be used.
		/// </summary>
		public static bool UseHH2TreePics
		{
			get { return _useHH2TreePics; }
			set { _useHH2TreePics = value; }
		}

		/// <summary>
		/// Gets the current HtmlHelpSystem instance
		/// </summary>
		public static HtmlHelpSystem Current
		{
			get
			{
				return _current;
			}
		}

		/// <summary>
		/// Standard constructor
		/// </summary>
		public HtmlHelpSystem() : this("")
		{
		}

		/// <summary>
		/// Constructor of the reader class
		/// </summary>
		/// <param name="chmFile">chm file to attach with the reader</param>
		public HtmlHelpSystem(string chmFile)
		{
			_current = this;
			OpenFile(chmFile);
		}

		/// <summary>
		/// Opens a chm file and creates
		/// </summary>
		/// <param name="chmFile">full file path of the chm file to open</param>
		/// <remarks>If you call this method, all existing merged files will be cleared.</remarks>
		public void OpenFile(string chmFile)
		{
			OpenFile(chmFile, null);
		}

		/// <summary>
		/// Opens a chm file and creates
		/// </summary>
		/// <param name="chmFile">full file path of the chm file to open</param>
		/// <param name="dmpInfo">dumping info</param>
		/// <remarks>If you call this method, all existing merged files will be cleared.</remarks>
		public void OpenFile(string chmFile, DumpingInfo dmpInfo)
		{
			if( File.Exists(chmFile ) )
			{
				_chmFiles.Clear();
				_toc.Clear();
				_index.Clear();
				_informationTypes.Clear();
				_categories.Clear();

				CHMFile newFile = new CHMFile(this, chmFile, dmpInfo);

				_toc = new TableOfContents( newFile.TOC );
				_index = new Index( newFile.IndexKLinks, newFile.IndexALinks );

				_chmFiles.Add(newFile);
				// add all infotypes and categories of the read file to this system instance
				MergeFileInfoTypesCategories(newFile);

				// check if the file has a merged files list
				if( newFile.MergedFiles.Length > 0 )
				{
					// extract the path of the chm file (usually merged files are in the same path)
					FileInfo fi = new FileInfo(chmFile);
					string sPath = fi.DirectoryName;

					for(int i=0; i<newFile.MergedFiles.Length; i++)
					{
						string sFile = newFile.MergedFiles[i];

						if(sFile.Length > 0)
						{
							if(sFile[1] != ':') // no full path setting
							{
								sFile = Path.Combine(sPath, sFile);
							}

							MergeFile(sFile, dmpInfo, true);
						}
					}

					if(newFile.MergLinks.Count > 0)
						RecalculateMergeLinks(newFile);

					RemoveMergeLinks(); // clear all merge-links which have no target !
				}
			}
		}

		/// <summary>
		/// Merges a chm file to the current help contents
		/// </summary>
		/// <param name="chmFile">full file path of the chm file to merge</param>
		public void MergeFile(string chmFile)
		{
			MergeFile(chmFile, null);
		}

		/// <summary>
		/// Merges a chm file to the current help contents
		/// </summary>
		/// <param name="chmFile">full file path of the chm file to merge</param>
		/// <param name="dmpInfo">dumping info</param>
		public void MergeFile(string chmFile, DumpingInfo dmpInfo)
		{
			MergeFile(chmFile, dmpInfo, false);
		}

		/// <summary>
		/// Merges a chm file to the current help contents
		/// </summary>
		/// <param name="chmFile">full file path of the chm file to merge</param>
		/// <param name="dmpInfo">dumping info</param>
		/// <param name="mergedFileList">true if the merge is done because a merged file list
		/// was found in the previously loaded CHM.</param>
		internal void MergeFile(string chmFile, DumpingInfo dmpInfo, bool mergedFileList)
		{
			if( File.Exists(chmFile ) )
			{
				if( _chmFiles.Count == 1)
				{
					// if we open the first file, we directly point into the toc and index of this file.
					// So that we don't merge the new toc's indexe's into the first file, we have to
					// clone the internal arraylists first to a new instance of the toc/index holder classes.
					ArrayList atoc = _toc.TOC;
					ArrayList alinks = _index.ALinks;
					ArrayList klinks = _index.KLinks;

					_toc = new TableOfContents();
					_index = new Index();

					_toc.MergeToC( atoc );
					_index.MergeIndex( alinks, IndexType.AssiciativeLinks );
					_index.MergeIndex( klinks, IndexType.KeywordLinks );
				}

				CHMFile newFile = new CHMFile(this, chmFile, dmpInfo);

				if(mergedFileList) // if we've called this method due to a merged file list merge
				{
					RecalculateMergeLinks(newFile);

					_toc.MergeToC( newFile.TOC, _chmFiles );
					_index.MergeIndex( newFile.IndexALinks, IndexType.AssiciativeLinks );
					_index.MergeIndex( newFile.IndexKLinks, IndexType.KeywordLinks );

					_chmFiles.Add(newFile);

					// add all infotypes and categories of the read file to this system instance
					MergeFileInfoTypesCategories(newFile);
				}
				else
				{
					_toc.MergeToC( newFile.TOC, _chmFiles );
					_index.MergeIndex( newFile.IndexALinks, IndexType.AssiciativeLinks );
					_index.MergeIndex( newFile.IndexKLinks, IndexType.KeywordLinks );

					_chmFiles.Add(newFile);

					// add all infotypes and categories of the read file to this system instance
					MergeFileInfoTypesCategories(newFile);

					// check if the file has a merged files list
					if( newFile.MergedFiles.Length > 0 )
					{
						// extract the path of the chm file (usually merged files are in the same path)
						FileInfo fi = new FileInfo(chmFile);
						string sPath = fi.DirectoryName;

						for(int i=0; i<newFile.MergedFiles.Length; i++)
						{
							string sFile = newFile.MergedFiles[i];

							if(sFile.Length > 0)
							{
								if(sFile[1] != ':') // no full path setting
								{
									sFile = Path.Combine(sPath, sFile);
								}

								MergeFile(sFile, dmpInfo, true);
							}
						}

						//if(newFile.MergLinks.Count > 0)
						//	RecalculateMergeLinks(newFile);

						RemoveMergeLinks(); // clear all merge-links which have no target !
					}
				}
			}
		}

		/// <summary>
		/// Checks all Merg-links read till now. Checks if the merg-link points to the
		/// file <c>currentFile</c>. If yes the link will be replaced by the contents of the
		/// merged file.
		/// </summary>
		/// <param name="currentFile">Current CHMFile instance</param>
		internal void RecalculateMergeLinks(CHMFile currentFile)
		{
			foreach(CHMFile curFile in _chmFiles)
			{
				if( curFile.MergLinks.Count > 0)
				{
					for(int i=0; i<curFile.MergLinks.Count; i++)
					{
						TOCItem curItem = curFile.MergLinks[i] as TOCItem;

						string sMerge = curItem.MergeLink;
						string [] sSplit = sMerge.Split( new char[]{':'} );

						string sFName = "";
						string sTarget = "";

						if( sSplit.Length > 3) // merge info contains path name
						{
							sFName = sSplit[0] + ":" + sSplit[1];
							sTarget = sSplit[3];
						}
						else if( sSplit.Length == 3)// merge info contains only file name
						{
							FileInfo fi = new FileInfo(currentFile.ChmFilePath);
							string sPath = fi.DirectoryName;

							string sFile = sSplit[0];

							if(sFile.Length > 0)
							{
								if(sFile[1] != ':') // no full path setting
								{
									sFile = Path.Combine(sPath, sFile);
								}
							}

							sFName = sFile;
							sTarget = sSplit[2];
						}

						ArrayList arrToc = null;

						if( (sFName.Length>0) && (sTarget.Length>0) )
						{
						// if this link points into the current file
							if( sFName.ToLower() == currentFile.ChmFilePath.ToLower() )
							{
								if(sTarget.ToLower().IndexOf(".hhc") >= 0)
								{
									string sfCheck = sTarget;

									// remove prefixing ./
									while( (sfCheck[0]=='.') || (sfCheck[0]=='/') )
									{
										sfCheck = sfCheck.Substring(1);
									}

									if( currentFile.ContentsFile.ToLower() != sfCheck )
									{
										arrToc = currentFile.ParseHHC( sTarget );

										if( arrToc.Count > 0)
										{
										}
									}
									else
									{
										arrToc = currentFile.TOC;
									}

									// target points to a complete TOC
									int nCnt = 0;

									foreach(TOCItem chkItem in arrToc)
									{
										if(nCnt == 0)
										{
											curItem.AssociatedFile = currentFile;
											curItem.Children = chkItem.Children;
											curItem.ChmFile = currentFile.ChmFilePath;
											curItem.ImageIndex = chkItem.ImageIndex;
											curItem.Local = chkItem.Local;
											curItem.MergeLink = chkItem.MergeLink;
											curItem.Name = chkItem.Name;
											curItem.TocMode = chkItem.TocMode;
											curItem.TopicOffset = chkItem.TopicOffset;

											MarkChildrenAdded(chkItem.Children, curFile.MergLinks);
										}
										else
										{
											ArrayList checkList = null;

											if(curItem.Parent != null)
												checkList = curItem.Parent.Children;
											else
												checkList = curFile.TOC;

											int nIdx = checkList.IndexOf(curItem);
											if((nIdx+nCnt)>checkList.Count)
												checkList.Add(chkItem);
											else
												checkList.Insert(nIdx+nCnt, chkItem);

											curFile.MergLinks.Add(chkItem);
											MarkChildrenAdded(chkItem.Children, curFile.MergLinks);
										}

										nCnt++;
									}

								}
								else
								{

									// target points to a single topic
									TOCItem chkItem = currentFile.GetTOCItemByLocal(sTarget);
									if(chkItem != null)
									{
										curItem.AssociatedFile = currentFile;
										curItem.Children = chkItem.Children;
										curItem.ChmFile = currentFile.ChmFilePath;
										curItem.ImageIndex = chkItem.ImageIndex;
										curItem.Local = chkItem.Local;
										curItem.MergeLink = chkItem.MergeLink;
										curItem.Name = chkItem.Name;
										curItem.TocMode = chkItem.TocMode;
										curItem.TopicOffset = chkItem.TopicOffset;

										curFile.MergLinks.Add(chkItem);
										MarkChildrenAdded(chkItem.Children, curFile.MergLinks);
									}
								}
							}
						}
					}
				}
			}
		}

		/// <summary>
		/// Adds sub-items of an TOC-entry to the merg-linked list.
		/// This will mark this item as "added" during the extra merge run
		/// of the HtmlHelpSystem class.
		/// </summary>
		/// <param name="tocs">TOCItem list</param>
		/// <param name="merged">Arraylist which holds the merged-items</param>
		internal void MarkChildrenAdded(ArrayList tocs, ArrayList merged)
		{
			foreach(TOCItem curItem in tocs)
			{
				if(!merged.Contains(curItem))
				{
					merged.Add(curItem);

					MarkChildrenAdded(curItem.Children, merged);
				}
			}
		}

		/// <summary>
		/// Removes merge-links from the toc of files which were not loaded
		/// </summary>
		internal void RemoveMergeLinks()
		{
			foreach(CHMFile curFile in _chmFiles)
			{
				if( curFile.MergLinks.Count > 0)
				{
					while(curFile.MergLinks.Count > 0)
					{
						TOCItem curItem = curFile.MergLinks[0] as TOCItem;
						if(curItem.MergeLink.Length > 0)
							curFile.RemoveTOCItem(curItem);

						curFile.MergLinks.RemoveAt(0);
					}
				}
			}
		}

		/// <summary>
		/// Merges the information types and categories read by the CHMFile instance
		/// into the system instance
		/// </summary>
		/// <param name="chmFile">file instance</param>
		private void MergeFileInfoTypesCategories(CHMFile chmFile)
		{
			if(chmFile.HasInformationTypes)
			{
				for(int i=0; i<chmFile.InformationTypes.Count;i++)
				{
					InformationType curType = chmFile.InformationTypes[i] as InformationType;
					InformationType sysType = GetInformationType( curType.Name );

					if( sysType == null)
						_informationTypes.Add(curType);
					else
						curType.ReferenceCount++;
				}
			}

			if(chmFile.HasCategories)
			{
				for(int i=0; i<chmFile.Categories.Count;i++)
				{
					Category curCat = chmFile.Categories[i] as Category;
					Category sysCat = GetCategory( curCat.Name );

					if(sysCat == null)
						_categories.Add(curCat);
					else
						curCat.ReferenceCount++;
				}
			}
		}

		/// <summary>
		/// Removes the information types and categories read by the CHMFile instance
		/// </summary>
		/// <param name="chmFile">file instance</param>
		private void RemoveFileInfoTypesCategories(CHMFile chmFile)
		{
			if(chmFile.HasInformationTypes)
			{
				for(int i=0; i<chmFile.InformationTypes.Count;i++)
				{
					InformationType curType = chmFile.InformationTypes[i] as InformationType;
					InformationType sysType = GetInformationType( curType.Name );

					if(sysType != null)
					{
						sysType.ReferenceCount--;

						if(sysType.ReferenceCount<=0)
							_informationTypes.Remove(sysType);
					}
				}
			}

			if(chmFile.HasCategories)
			{
				for(int i=0; i<chmFile.Categories.Count;i++)
				{
					Category curCat = chmFile.Categories[i] as Category;
					Category sysCat = GetCategory( curCat.Name );

					if(sysCat != null)
					{
						sysCat.ReferenceCount--;

						if(sysCat.ReferenceCount<=0)
							_categories.Remove(sysCat);
					}
				}
			}
		}

		/// <summary>
		/// Removes a chm file from the internal file collection
		/// </summary>
		/// <param name="chmFile">full file path of the chm file to remove</param>
		public void RemoveFile(string chmFile)
		{
			int nIdx = -1;
			CHMFile removeInstance=null;

			foreach(CHMFile curFile in _chmFiles)
			{
				nIdx++;

				if( curFile.ChmFilePath.ToLower() == chmFile.ToLower() )
				{
					removeInstance = curFile;
					break;
				}
			}

			if(nIdx >= 0)
			{
				_toc.Clear(); // forces a rebuild of the merged toc
				_index.Clear(); // force a rebuild of the merged index

				RemoveFileInfoTypesCategories(removeInstance);
				_chmFiles.RemoveAt(nIdx);
			}
		}

		/// <summary>
		/// Closes all files and destroys TOC/index
		/// </summary>
		public void CloseAllFiles()
		{
			for(int i=0; i < _chmFiles.Count; i++)
			{
				CHMFile curFile = _chmFiles[i] as CHMFile;

				_chmFiles.RemoveAt(i);
				curFile.Dispose();
				i--;
			}

			_chmFiles.Clear();
			_toc.Clear();
			_index.Clear();
			_informationTypes.Clear();
			_categories.Clear();
		}

		/// <summary>
		/// Gets an array of loaded chm files.
		/// </summary>
		public CHMFile[] FileList
		{
			get
			{
				CHMFile[] ret = new CHMFile[ _chmFiles.Count ];
				for(int i=0;i<_chmFiles.Count;i++)
					ret[i] = (CHMFile)_chmFiles[i];

				return ret;
			}
		}

		/// <summary>
		/// Returns true if the HtmlHelpSystem instance contains 1 or more information types
		/// </summary>
		public bool HasInformationTypes
		{
			get { return (_informationTypes.Count>0); }
		}

		/// <summary>
		/// Returns true if the HtmlHelpSystem instance contains 1 or more categories
		/// </summary>
		public bool HasCategories
		{
			get { return (_categories.Count>0); }
		}

		/// <summary>
		/// Gets an ArrayList of <see cref="InformationType">InformationType</see> items
		/// </summary>
		public ArrayList InformationTypes
		{
			get { return _informationTypes; }
		}

		/// <summary>
		/// Gets an ArrayList of <see cref="Category">Category</see> items
		/// </summary>
		public ArrayList Categories
		{
			get { return _categories; }
		}

		/// <summary>
		/// Gets the information type specified by its name
		/// </summary>
		/// <param name="name">name of the information type to receive</param>
		/// <returns>Returns the Instance for the name or null if not found</returns>
		public InformationType GetInformationType(string name)
		{
			if(HasInformationTypes)
			{
				for(int i=0; i<_informationTypes.Count;i++)
				{
					InformationType iT = _informationTypes[i] as InformationType;

					if(iT.Name == name)
						return iT;
				}
			}

			return null;
		}

		/// <summary>
		/// Gets the category specifiyd by its name
		/// </summary>
		/// <param name="name">name of the category</param>
		/// <returns>Returns the Instance for the name or null if not found</returns>
		public Category GetCategory(string name)
		{
			if(HasCategories)
			{
				for(int i=0; i<_categories.Count;i++)
				{
					Category cat = _categories[i] as Category;

					if(cat.Name == name)
						return cat;
				}
			}

			return null;
		}

		/// <summary>
		/// Gets the default topic
		/// </summary>
		public string DefaultTopic
		{
			get
			{
				if( _chmFiles.Count > 0 )
				{
					foreach(CHMFile curFile in _chmFiles)
					{
						if( curFile.DefaultTopic.Length > 0)
						{
							return curFile.FormURL( curFile.DefaultTopic );
						}
					}
				}

				return "about:blank";
			}
		}

		/// <summary>
		/// Gets a merged table of contents of all opened chm files
		/// </summary>
		public TableOfContents TableOfContents
		{
			get
			{
				if( _chmFiles.Count > 0 )
				{
					if( _toc.Count() <= 0)
					{
						// merge toc of files
						foreach(CHMFile curFile in _chmFiles)
						{
							_toc.MergeToC( curFile.TOC );
						}
					}
				}

				return _toc;
			}
		}

		/// <summary>
		/// Gets a merged index  of all opened chm files
		/// </summary>
		public Index Index
		{
			get
			{
				if( _chmFiles.Count > 0 )
				{
					if( (_index.Count(IndexType.KeywordLinks)+_index.Count(IndexType.AssiciativeLinks)) <= 0)
					{
						// merge index files
						foreach(CHMFile curFile in _chmFiles)
						{
							_index.MergeIndex( curFile.IndexKLinks, IndexType.KeywordLinks);
							_index.MergeIndex( curFile.IndexALinks, IndexType.AssiciativeLinks);
						}
					}
				}

				return _index;
			}
		}

		/// <summary>
		/// Gets a flag if the current instance offers a table of contents
		/// </summary>
		public bool HasTableOfContents
		{
			get
			{
				return (TableOfContents.Count() > 0);
			}
		}

		/// <summary>
		/// Gets a flag if the current instance offers an index
		/// </summary>
		public bool HasIndex
		{
			get
			{
				return (HasALinks || HasKLinks);
			}
		}

		/// <summary>
		/// Gets a flag if the index holds klinks
		/// </summary>
		public bool HasKLinks
		{
			get
			{
				return (_index.Count(IndexType.KeywordLinks) > 0);
			}
		}

		/// <summary>
		/// Gets a flag if the index holds alinks
		/// </summary>
		public bool HasALinks
		{
			get
			{
				return (_index.Count(IndexType.AssiciativeLinks) > 0);
			}
		}

		/// <summary>
		/// Gets a flag if the current instance supports fulltext searching
		/// </summary>
		public bool FullTextSearch
		{
			get
			{
				bool bRet = false;

				foreach(CHMFile curFile in _chmFiles)
				{
					bRet |= curFile.FullTextSearch;
				}

				return bRet;
			}
		}

		/// <summary>
		/// Performs a full-text search over the chm files
		/// </summary>
		/// <param name="words">words to search</param>
		/// <param name="partialMatches">true if partial word should be matched also
		/// ( if this is true a search of 'support' will match 'supports', otherwise not )</param>
		/// <param name="titleOnly">true if titles only</param>
		/// <returns>A DataTable containing the search hits</returns>
		public DataTable PerformSearch(string words, bool partialMatches, bool titleOnly)
		{
			return PerformSearch(words, -1, partialMatches, titleOnly);
		}

		/// <summary>
		/// Performs a full-text search over the chm files
		/// </summary>
		/// <param name="words">words to search</param>
		/// <param name="MaxResults">maximal number of hits to return</param>
		/// <param name="partialMatches">true if partial word should be matched also
		/// ( if this is true a search of 'support' will match 'supports', otherwise not )</param>
		/// <param name="titleOnly">true if titles only</param>
		/// <returns>A DataTable containing the search hits</returns>
		public DataTable PerformSearch(string words, int MaxResults, bool partialMatches, bool titleOnly)
		{
			if( ! FullTextSearch )
				return null;

			DataTable dtResult = null;

			int nCnt = 0;

			foreach(CHMFile curFile in _chmFiles)
			{
				if(nCnt == 0)
				{
					if(curFile.FullTextSearchEngine.CanSearch)
					{
						if(curFile.FullTextSearchEngine.Search(words, MaxResults, partialMatches, titleOnly))
						{
							dtResult = curFile.FullTextSearchEngine.Hits;
							dtResult.DefaultView.Sort = "Rating DESC";
						}
					}
				}
				else
				{
					if(curFile.FullTextSearchEngine.CanSearch)
					{
						if(curFile.FullTextSearchEngine.Search(words, MaxResults, partialMatches, titleOnly))
						{
							DataTable table = curFile.FullTextSearchEngine.Hits;

							// append rows from 2nd file
							foreach(DataRow curRow in table.Rows)
							{
								dtResult.ImportRow( curRow );
							}

							dtResult.DefaultView.Sort = "Rating DESC";

							// adjust max hits
							if(MaxResults >= 0)
							{
								if(dtResult.DefaultView.Count > MaxResults)
								{
									for(int i=MaxResults-1; i<dtResult.DefaultView.Count-1;i++)
									{
										if(dtResult.DefaultView[i].Row.RowState != DataRowState.Deleted)
										{
											dtResult.DefaultView[i].Row.Delete();
											dtResult.DefaultView[i].Row.AcceptChanges();
											i--;
										}
									}

									dtResult.AcceptChanges();
									dtResult.DefaultView.Sort = "Rating DESC";
								}
							}
						}
					}
				}

				nCnt++;
			}

			return dtResult;
		}
	}
}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
null

#### Original name
Melanconis leucostroma Niessl & Rehm

### Remarks
null


text:
Group        | Version     | Kind
------------ | ---------- | -----------
Core | v1beta1 | HorizontalPodAutoscalerSpec

> Example yaml coming soon...

Other api versions of this object exist: v1

specification of a horizontal pod autoscaler.

Appears In  HorizontalPodAutoscaler

Field        | Description
------------ | -----------
cpuUtilization
 *[CPUTargetUtilization](#cputargetutilization-v1beta1)* | target average CPU utilization (represented as a percentage of requested CPU) over all the pods; if not specified it defaults to the target CPU utilization at 80% of the requested resources.
maxReplicas
 *integer* | upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.
minReplicas
 *integer* | lower limit for the number of pods that can be set by the autoscaler, default 1.
scaleRef
 *[SubresourceReference](#subresourcereference-v1beta1)* | reference to Scale subresource; horizontal pod autoscaler will learn the current resource consumption from its status, and will set the desired number of pods by modifying its spec.


text: Brief description of the project


text:
#include <deque>
#include <sstream>
#include <string>
#include <mysql++/mysql++.h>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread.hpp>

class mysqlconn_pool : boost::noncopyable
{
public:
	mysqlconn_pool(int cnt);
	~mysqlconn_pool();
	unsigned size();
	bool execute(const std::string& sql);
	bool getuuid(std::string* id);
	bool pingdb();
	bool initconn(boost::shared_ptr<mysqlpp::Connection> conn);
	bool select_example();

private:
	friend class mysqlconn_helper;
	void addnewconn(boost::shared_ptr<mysqlpp::Connection> conn);
	bool popnewconn(boost::shared_ptr<mysqlpp::Connection>* conn);
	void newconn_threadfunc();
	bool get(boost::shared_ptr<mysqlpp::Connection>* conn);
	void back(boost::shared_ptr<mysqlpp::Connection> conn, bool broken = false);

private:
	unsigned conncount_;

	std::deque< boost::shared_ptr<mysqlpp::Connection> > conns_;
	boost::shared_mutex connslock_;

	std::deque< boost::shared_ptr<mysqlpp::Connection> > newconns_;
	boost::shared_mutex newconnslock_;

	boost::shared_ptr<boost::thread> newconnsthread_;
};

#endif


text:
namespace Microsoft.Azure.Management.ApiManagement.Models
{
    using Microsoft.Rest;
    using Newtonsoft.Json;
    using System.Linq;

    /// <summary>
    /// TagResource contract properties.
    /// </summary>
    public partial class TagResourceContract
    {
        /// <summary>
        /// Initializes a new instance of the TagResourceContract class.
        /// </summary>
        public TagResourceContract()
        {
            CustomInit();
        }

        /// <summary>
        /// Initializes a new instance of the TagResourceContract class.
        /// </summary>
        /// <param name="tag">Tag associated with the resource.</param>
        /// <param name="api">API associated with the tag.</param>
        /// <param name="operation">Operation associated with the tag.</param>
        /// <param name="product">Product associated with the tag.</param>
        public TagResourceContract(TagTagResourceContractProperties tag, ApiTagResourceContractProperties api = default(ApiTagResourceContractProperties), OperationTagResourceContractProperties operation = default(OperationTagResourceContractProperties), ProductTagResourceContractProperties product = default(ProductTagResourceContractProperties))
        {
            Tag = tag;
            Api = api;
            Operation = operation;
            Product = product;
            CustomInit();
        }

        /// <summary>
        /// An initialization method that performs custom operations like setting defaults
        /// </summary>
        partial void CustomInit();

        /// <summary>
        /// Gets or sets tag associated with the resource.
        /// </summary>
        [JsonProperty(PropertyName = "tag")]
        public TagTagResourceContractProperties Tag { get; set; }

        /// <summary>
        /// Gets or sets API associated with the tag.
        /// </summary>
        [JsonProperty(PropertyName = "api")]
        public ApiTagResourceContractProperties Api { get; set; }

        /// <summary>
        /// Gets or sets operation associated with the tag.
        /// </summary>
        [JsonProperty(PropertyName = "operation")]
        public OperationTagResourceContractProperties Operation { get; set; }

        /// <summary>
        /// Gets or sets product associated with the tag.
        /// </summary>
        [JsonProperty(PropertyName = "product")]
        public ProductTagResourceContractProperties Product { get; set; }

        /// <summary>
        /// Validate the object.
        /// </summary>
        /// <exception cref="ValidationException">
        /// Thrown if validation fails
        /// </exception>
        public virtual void Validate()
        {
            if (Tag == null)
            {
                throw new ValidationException(ValidationRules.CannotBeNull, "Tag");
            }
            if (Tag != null)
            {
                Tag.Validate();
            }
            if (Api != null)
            {
                Api.Validate();
            }
            if (Product != null)
            {
                Product.Validate();
            }
        }
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~  Copyright 2016 Google Inc. All Rights Reserved.
  ~  Licensed under the Apache License, Version 2.0 (the "License");
  ~  you may not use this file except in compliance with the License.
  ~  You may obtain a copy of the License at
  ~
  ~   http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~  Unless required by applicable law or agreed to in writing, software
  ~  distributed under the License is distributed on an "AS IS" BASIS,
  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~  See the License for the specific language governing permissions and
  ~  limitations under the License.
  -->
<com.google.blockly.android.ui.fieldview.BasicFieldDropdownView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/field_dropdown"
    app:itemLayout="@layout/default_spinner_closed_item"
    app:dropdownItemLayout="@layout/default_spinner_dropdown_item"
    android:background="@drawable/dropdown_background"
    android:singleLine="true"
    android:padding="4dip"
    android:paddingRight="@dimen/spinner_end_padding"
    android:paddingEnd="@dimen/spinner_end_padding"
    android:popupBackground="@drawable/rounded_rect_opaque_white"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>


text:
cask "mos" do
  version "3.3.1"
  sha256 "9bbe5c44a4dae57ea6495adce56eb55fb5a7dcf81d8f7b0b6489ddf78f02cc9d"

  url "https://github.com/Caldis/Mos/releases/download/#{version}/Mos.Versions.#{version}.dmg",
      verified: "github.com/Caldis/Mos/"
  appcast "https://github.com/Caldis/Mos/releases.atom"
  name "Mos"
  desc "Smooths scrolling and set mouse scroll directions independently"
  homepage "https://mos.caldis.me/"

  app "Mos.app"

  zap trash: "~/Library/Preferences/com.caldis.Mos.plist"
end


text:
        <select data-dojo-type="dijit/form/FilteringSelect"
            data-dojo-attach-point="countrySelect"
            data-dojo-props="maxHeight: 151"
            data-dojo-attach-event="onChange: _onCountryChanged">
        </select>

    <input type="text"
        data-dojo-type="esri/dijit/geoenrichment/DataBrowser/SearchTextBox"
        data-dojo-attach-point="txbSearch"
        data-dojo-props="prompt:'${nls.search}'"
        data-dojo-attach-event="onSearch: _search"
        class="DataCategoriesPage_Search" />