/*
 * Copyright 2000-2017 JetBrains s.r.o.
 *
 * 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.
 */
package com.intellij.internal.statistic;

import com.intellij.internal.statistic.beans.GroupDescriptor;
import com.intellij.internal.statistic.beans.UsageDescriptor;
import com.intellij.openapi.extensions.ExtensionPointName;
import org.jetbrains.annotations.NotNull;

import java.util.Set;

public abstract class UsagesCollector {

  public static final ExtensionPointName<UsagesCollector> EP_NAME = ExtensionPointName.create("com.intellij.statistics.usagesCollector");

  @NotNull
  public abstract Set<UsageDescriptor> getUsages() throws CollectUsagesException;

  @NotNull
  public abstract GroupDescriptor getGroupId();
}

@@ -819,16 +819,55 @@
 ntName;%0A
+import com.intellij.openapi.util.Pair;%0A
 import o
@@ -922,16 +922,52 @@
 til.Set;
+%0Aimport java.util.function.Function;
 %0A%0Apublic
@@ -1292,11 +1292,1478 @@
 oupId();
+%0A%0A  private static Pair%3CDouble, Double%3E findBucket(double value, double... ranges) %7B%0A    if (ranges.length == 0) throw new IllegalArgumentException(%22Constrains are empty%22);%0A    if (value %3C ranges%5B0%5D) return Pair.create(null, ranges%5B0%5D);%0A    for (int i = 1; i %3C ranges.length; i++) %7B%0A      if (ranges%5Bi%5D %3C= ranges%5Bi - 1%5D)%0A        throw new IllegalArgumentException(%22Constrains are unsorted%22);%0A%0A      if (value %3C ranges%5Bi%5D) %7B%0A        return Pair.create(ranges%5Bi - 1%5D, ranges%5Bi%5D);%0A      %7D%0A    %7D%0A%0A    return Pair.create(ranges%5Branges.length - 1%5D, null);%0A  %7D%0A%0A  protected static String findBucket(long value, Function%3CLong, String%3E valueConverter, long...ranges) %7B%0A    double%5B%5D dRanges = new double%5Branges.length%5D;%0A    for (int i = 0; i %3C dRanges.length; i++) %7B%0A      dRanges%5Bi%5D = ranges%5Bi%5D;%0A    %7D%0A    return findBucket((double)value, (d) -%3E valueConverter.apply(d.longValue()), dRanges);%0A  %7D%0A%0A  protected static String findBucket(double value, Function%3CDouble, String%3E valueConverter, double...ranges) %7B%0A    for (double range : ranges) %7B%0A      if (range == value) %7B%0A        return valueConverter.apply(value);%0A      %7D%0A    %7D%0A%0A    Pair%3CDouble, Double%3E bucket = findBucket(value, ranges);%0A    if (bucket.first == null) return %22(*, %22 + valueConverter.apply(bucket.second) + %22)%22;%0A    if (bucket.second == null) return %22(%22 + valueConverter.apply(bucket.first) + %22, *)%22;%0A    return %22(%22 + valueConverter.apply(bucket.first) + %22, %22 + valueConverter.apply(bucket.second) + %22)%22;%0A  %7D
 %0A%7D%0A

add utility methods for grouping statistics