@NotNull
 private List<VcsCommitMetadata> log() {
   String output =
       git("log --all --date-order --full-history --sparse --pretty='%H|%P|%ct|%s|%B'");
   final VcsUser defaultUser = getDefaultUser();
   final Function<String, Hash> TO_HASH =
       new Function<String, Hash>() {
         @Override
         public Hash fun(String s) {
           return HashImpl.build(s);
         }
       };
   return ContainerUtil.map(
       StringUtil.splitByLines(output),
       new Function<String, VcsCommitMetadata>() {
         @Override
         public VcsCommitMetadata fun(String record) {
           String[] items = ArrayUtil.toStringArray(StringUtil.split(record, "|", true, false));
           long time = Long.valueOf(items[2]);
           return new VcsCommitMetadataImpl(
               TO_HASH.fun(items[0]),
               ContainerUtil.map(items[1].split(" "), TO_HASH),
               time,
               myProjectRoot,
               items[3],
               defaultUser,
               items[4],
               defaultUser,
               time);
         }
       });
 }
  /**
   * Parses "svn:externals" property in format starting from svn 1.5.
   *
   * @return map of externals definitions: key - relative directory, value - corresponding complete
   *     externals definition.
   */
  @NotNull
  public static Map<String, String> parseExternalsProperty(@NotNull String externals)
      throws SvnBindException {
    HashMap<String, String> map = ContainerUtil.newHashMap();

    for (String external : StringUtil.splitByLines(externals, true)) {
      map.put(parseRelativeDirectory(external), external);
    }

    return map;
  }
 @NotNull
 public static Set<VcsRef> readAllRefs(
     @NotNull VirtualFile root, @NotNull VcsLogObjectsFactory objectsFactory) {
   String[] refs =
       StringUtil.splitByLines(
           git("log --branches --tags --no-walk --format=%H%d --decorate=full"));
   Set<VcsRef> result = ContainerUtil.newHashSet();
   for (String ref : refs) {
     result.addAll(new RefParser(objectsFactory).parseCommitRefs(ref, root));
   }
   return result;
 }
  private void doSingleTest(String suffix, String path) throws Throwable {
    final String text = FileUtil.loadFile(new File(path, suffix), true);
    final StringBuilder result = new StringBuilder();
    for (String line : StringUtil.splitByLines(text)) {
      if (result.length() > 0) result.append("------\n");
      final AngularJSParserDefinition definition = new AngularJSParserDefinition();
      final PsiBuilder builder =
          PsiBuilderFactory.getInstance().createBuilder(definition, new AngularJSLexer(), line);
      final ASTNode root =
          definition.createParser(getProject()).parse(JSStubElementTypes.FILE, builder);
      result.append(DebugUtil.psiToString(root.getPsi(), false, false));
    }

    assertEquals(
        FileUtil.loadFile(new File(path, suffix.replace("js", "txt")), true), result.toString());
  }
  @NotNull
  private static List<String> excludeIgnoredFiles(
      @NotNull Project project, @NotNull VirtualFile root, @NotNull List<String> paths)
      throws VcsException {
    GitSimpleHandler handler = new GitSimpleHandler(project, root, GitCommand.LS_FILES);
    handler.setNoSSH(true);
    handler.setSilent(true);
    handler.addParameters("--ignored", "--others", "--exclude-standard");
    handler.endOptions();
    handler.addParameters(paths);
    String output = handler.run();

    List<String> nonIgnoredFiles = new ArrayList<String>(paths.size());
    Set<String> ignoredPaths = new HashSet<String>(Arrays.asList(StringUtil.splitByLines(output)));
    for (String pathToCheck : paths) {
      if (!ignoredPaths.contains(pathToCheck)) {
        nonIgnoredFiles.add(pathToCheck);
      }
    }
    return nonIgnoredFiles;
  }
  private static AllowedValues parseBeanInfo(@NotNull PsiModifierListOwner owner) {
    PsiMethod method = null;
    if (owner instanceof PsiParameter) {
      PsiParameter parameter = (PsiParameter) owner;
      PsiElement scope = parameter.getDeclarationScope();
      if (!(scope instanceof PsiMethod)) return null;
      PsiElement nav = scope.getNavigationElement();
      if (!(nav instanceof PsiMethod)) return null;
      method = (PsiMethod) nav;
      if (method.isConstructor()) {
        // not a property, try the @ConstructorProperties({"prop"})
        PsiAnnotation annotation =
            AnnotationUtil.findAnnotation(method, "java.beans.ConstructorProperties");
        if (annotation == null) return null;
        PsiAnnotationMemberValue value = annotation.findAttributeValue("value");
        if (!(value instanceof PsiArrayInitializerMemberValue)) return null;
        PsiAnnotationMemberValue[] initializers =
            ((PsiArrayInitializerMemberValue) value).getInitializers();
        PsiElement parent = parameter.getParent();
        if (!(parent instanceof PsiParameterList)) return null;
        int index = ((PsiParameterList) parent).getParameterIndex(parameter);
        if (index >= initializers.length) return null;
        PsiAnnotationMemberValue initializer = initializers[index];
        if (!(initializer instanceof PsiLiteralExpression)) return null;
        Object val = ((PsiLiteralExpression) initializer).getValue();
        if (!(val instanceof String)) return null;
        PsiMethod setter =
            PropertyUtil.findPropertySetter(
                method.getContainingClass(), (String) val, false, false);
        if (setter == null) return null;
        // try the @beaninfo of the corresponding setter
        method = (PsiMethod) setter.getNavigationElement();
      }
    } else if (owner instanceof PsiMethod) {
      PsiElement nav = owner.getNavigationElement();
      if (!(nav instanceof PsiMethod)) return null;
      method = (PsiMethod) nav;
    }
    if (method == null) return null;

    PsiClass aClass = method.getContainingClass();
    if (aClass == null) return null;
    if (PropertyUtil.isSimplePropertyGetter(method)) {
      List<PsiMethod> setters =
          PropertyUtil.getSetters(aClass, PropertyUtil.getPropertyNameByGetter(method));
      if (setters.size() != 1) return null;
      method = setters.get(0);
    }
    if (!PropertyUtil.isSimplePropertySetter(method)) return null;
    PsiDocComment doc = method.getDocComment();
    if (doc == null) return null;
    PsiDocTag beaninfo = doc.findTagByName("beaninfo");
    if (beaninfo == null) return null;
    String data =
        StringUtil.join(
            beaninfo.getDataElements(),
            new Function<PsiElement, String>() {
              @Override
              public String fun(PsiElement element) {
                return element.getText();
              }
            },
            "\n");
    int enumIndex = StringUtil.indexOfSubstringEnd(data, "enum:");
    if (enumIndex == -1) return null;
    data = data.substring(enumIndex);
    int colon = data.indexOf(":");
    int last = colon == -1 ? data.length() : data.substring(0, colon).lastIndexOf("\n");
    data = data.substring(0, last);

    List<PsiAnnotationMemberValue> values = new ArrayList<PsiAnnotationMemberValue>();
    for (String line : StringUtil.splitByLines(data)) {
      List<String> words = StringUtil.split(line, " ", true, true);
      if (words.size() != 2) continue;
      String ref = words.get(1);
      PsiExpression constRef =
          JavaPsiFacade.getElementFactory(aClass.getProject())
              .createExpressionFromText(ref, aClass);
      if (!(constRef instanceof PsiReferenceExpression)) continue;
      PsiReferenceExpression expr = (PsiReferenceExpression) constRef;
      values.add(expr);
    }
    if (values.isEmpty()) return null;
    PsiAnnotationMemberValue[] array = values.toArray(new PsiAnnotationMemberValue[values.size()]);
    return new AllowedValues(array, false);
  }
  @NotNull
  @Override
  public JsonResponse handle(@NotNull UnityTestStatePostRequest request) {
    UUID uuid = UUID.fromString(request.uuid);
    Unity3dTestSession session = Unity3dTestSessionManager.getInstance().findSession(uuid);
    if (session == null) {
      return JsonResponse.asError("no session");
    }

    GeneralTestEventsProcessor processor = session.getProcessor();
    ProcessHandler processHandler = session.getProcessHandler();

    String name = request.name;
    switch (request.type) {
      case TestStarted:
        processor.onTestStarted(new TestStartedEvent(name, null));
        break;
      case TestIgnored:
        processor.onTestIgnored(
            new TestIgnoredEvent(name, StringUtil.notNullize(request.message), request.stackTrace));
        break;
      case TestFailed:
        processor.onTestFailure(
            new TestFailedEvent(
                name,
                StringUtil.notNullize(request.message),
                request.stackTrace,
                false,
                null,
                null));
        break;
      case TestOutput:
        boolean stdOut = "Log".equals(request.messageType) || "Warning".equals(request.messageType);
        StringBuilder builder = new StringBuilder(request.message);
        if (!stdOut) {
          builder.append("\n");
          String[] strings = StringUtil.splitByLines(request.stackTrace);
          for (String line : strings) {
            builder.append("  at ").append(line).append("\n");
          }
        }
        processor.onTestOutput(new TestOutputEvent(name, builder.toString(), stdOut));
        break;
      case TestFinished:
        long time = (long) (request.time * 1000L);
        processor.onTestFinished(new TestFinishedEvent(name, time));
        break;
      case SuiteStarted:
        processor.onSuiteStarted(new TestSuiteStartedEvent(name, null));
        break;
      case SuiteFinished:
        processor.onSuiteFinished(new TestSuiteFinishedEvent(name));
        break;
      case RunFinished:
        processor.onFinishTesting();
        processHandler.destroyProcess();
        break;
    }

    return JsonResponse.asSuccess(null);
  }