public HashMap<Integer, int[]> getStatisticNumbers() {
    final int[][] allCounters = new int[4][4];
    HashMap<Integer, int[]> fs = new HashMap<Integer, int[]>();

    for (int i = 0; i < signatureArray.length; ++i) {
      AbstractSignature signature = signatureArray[i];
      if (signature instanceof AbstractFieldSignature) {
        count(signature, allCounters[2], fs, 2);
      } else if (signature instanceof AbstractMethodSignature) {
        count(signature, allCounters[3], fs, 3);
      } else if (signature instanceof AbstractClassSignature) {
        if (signature.getParent() != null) {
          count(signature, allCounters[1], fs, 1);
        } else {
          count(signature, allCounters[0], fs, 0);
        }
      }
    }
    int[] spl = new int[3];
    int[] iface = new int[3];
    spl[0] = allCounters[0][1];
    spl[1] = allCounters[2][1];
    spl[2] = allCounters[3][1];
    iface[0] = allCounters[0][0];
    iface[1] = allCounters[2][0];
    iface[2] = allCounters[3][0];
    fs.put(-2, spl);
    fs.put(-3, iface);

    return fs;
  }
  private void count(
      AbstractSignature signature, int[] curCounter, HashMap<Integer, int[]> fs, int i) {
    for (FeatureData feature : signature.getFeatureData()) {
      int[] x = fs.get(feature);
      if (x == null) {
        x = new int[] {0, 0, 0, 0};
        fs.put(feature.getId(), x);
      }
      x[i]++;
    }

    curCounter[0]++;
    curCounter[1] += signature.getFeatureData().length;
    if (signature.isPrivate()) {
      curCounter[2]++;
      curCounter[3] += signature.getFeatureData().length;
    }
  }
  public String getStatisticsString() {
    final int[][] allCounters = new int[4][4];
    HashMap<Integer, int[]> fs = new HashMap<Integer, int[]>();

    for (int i = 0; i < signatureArray.length; ++i) {
      AbstractSignature signature = signatureArray[i];
      if (signature instanceof AbstractFieldSignature) {
        count(signature, allCounters[2], fs, 2);
      } else if (signature instanceof AbstractMethodSignature) {
        count(signature, allCounters[3], fs, 3);
      } else if (signature instanceof AbstractClassSignature) {
        if (signature.getParent() != null) {
          count(signature, allCounters[1], fs, 1);
        } else {
          count(signature, allCounters[0], fs, 0);
          System.out.println(signature.getFullName());
        }
      }
    }

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < allCounters.length; i++) {
      int[] curCounter = allCounters[i];
      switch (i) {
        case 0:
          sb.append("#Classes: ");
          break;
        case 1:
          sb.append("#InnerClasses: ");
          break;
        case 2:
          sb.append("#Fields: ");
          break;
        case 3:
          sb.append("#Methods: ");
          break;
      }
      sb.append(curCounter[0]);
      sb.append("\n\t#Private: ");
      sb.append(curCounter[2]);
      sb.append("\n\t#Definitions: ");
      sb.append(curCounter[1]);
      sb.append("\n\t\t#Private Definitions: ");
      sb.append(curCounter[3]);
      sb.append("\n");
    }
    sb.append("\n\nPer Feature:");
    for (Entry<Integer, int[]> entry : fs.entrySet()) {
      sb.append("\n\t");
      sb.append(entry.getKey());
      sb.append("\n");
      int[] x = entry.getValue();
      for (int i = 0; i < x.length; i++) {
        switch (i) {
          case 0:
            sb.append("\t\t#Classes: ");
            break;
          case 1:
            sb.append("\t\t#InnerClasses: ");
            break;
          case 2:
            sb.append("\t\t#Fields: ");
            break;
          case 3:
            sb.append("\t\t#Methods: ");
            break;
        }
        sb.append(x[i]);
        sb.append("\n");
      }
    }
    return sb.toString();
  }