@Nullable
  @Override
  public Object buildAll(final String modelName, final Project project) {
    if (GradleVersionUtil.isCurrentGradleAtLeast("4.10")) {
      return null;
    }
    PluginContainer pluginContainer = project.getPlugins();
    if (!pluginContainer.hasPlugin(CppBasePlugin.class)) {
      if (pluginContainer.hasPlugin(CppPlugin.class)) {
        project.getLogger().error(
          "[sync warning] The IDE doesn't support 'cpp' gradle plugin. " +
          "Consider to use new gradle C++ plugins, see details at https://blog.gradle.org/introducing-the-new-cpp-plugins");
      }
      return null;
    }

    final CppProjectImpl cppProject = new CppProjectImpl();
    for (SoftwareComponent component : project.getComponents()) {
      if (component instanceof CppComponent) {
        CppComponent cppComponent = (CppComponent)component;
        String cppComponentName = cppComponent.getName();
        String cppComponentBaseName = cppComponent.getBaseName().get();

        Set<File> headerDirs = new LinkedHashSet<>(cppComponent.getPrivateHeaderDirs().getFiles());

        CppComponentImpl ideCppComponent;
        if (cppComponent instanceof ProductionCppComponent) {
          ideCppComponent = new CppComponentImpl(cppComponentName, cppComponentBaseName);
          cppProject.setMainComponent(ideCppComponent);
        }
        else if (cppComponent instanceof CppTestSuite) {
          CppTestSuiteImpl cppTestSuite = new CppTestSuiteImpl(cppComponentName, cppComponentBaseName);
          ideCppComponent = cppTestSuite;
          cppProject.setTestComponent(cppTestSuite);
        }
        else {
          continue;
        }

        for (CppBinary cppBinary : cppComponent.getBinaries().get()) {
          String binaryName = cppBinary.getName();
          String baseName = cppBinary.getBaseName().getOrElse("");
          String variantName = StringUtils.uncapitalize(StringUtils.removeStart(binaryName, "main"));

          boolean isExecutable = cppBinary instanceof ComponentWithExecutable;
          CppBinaryImpl binary;
          if (cppBinary instanceof CppSharedLibrary) {
            binary = new CppSharedLibraryImpl(binaryName, baseName, variantName);
          }
          else if (cppBinary instanceof CppStaticLibrary) {
            binary = new CppStaticLibraryImpl(binaryName, baseName, variantName);
          }
          else if (isExecutable) {
            binary = new CppExecutableImpl(binaryName, baseName, variantName);
          }
          else {
            continue;
          }
          ideCppComponent.addBinary(binary);

          Provider<CppCompile> cppCompileProvider = cppBinary.getCompileTask();
          if (cppCompileProvider.isPresent()) {
            CppCompile cppCompile = cppCompileProvider.get();
            CompilationDetailsImpl compilationDetails = new CompilationDetailsImpl();
            binary.setCompilationDetails(compilationDetails);

            String compileTaskName = cppCompile.getPath();
            DefaultExternalTask compileTask = new DefaultExternalTask();
            compileTask.setName(compileTaskName);
            compileTask.setQName(compileTaskName);
            compilationDetails.setCompileTask(compileTask);

            Set<File> compileIncludePath = new LinkedHashSet<>(cppBinary.getCompileIncludePath().getFiles());
            Set<File> systemIncludes = new LinkedHashSet<>();
            //Since Gradle 4.8, system header include directories should be accessed separately via the systemIncludes property
            //see https://github.com/gradle/gradle-native/blob/master/docs/RELEASE-NOTES.md#better-control-over-system-include-path-for-native-compilation---583
            if (GradleVersionUtil.isCurrentGradleAtLeast("4.8")) {
              compileIncludePath.addAll(cppCompile.getIncludes().getFiles());
              systemIncludes.addAll(cppCompile.getSystemIncludes().getFiles());
            }
            else {
              systemIncludes.addAll(cppCompile.getIncludes().getFiles());
            }
            compilationDetails.setSystemHeaderSearchPaths(new ArrayList<>(systemIncludes));
            compilationDetails.setUserHeaderSearchPaths(new ArrayList<>(compileIncludePath));
            compilationDetails.setHeaderDirs(headerDirs);

            Set<SourceFile> sources = getSources(project, cppBinary, cppCompile);
            compilationDetails.setSources(sources);

            File compilerWorkingDir = cppCompile.getObjectFileDir().get().getAsFile();
            compilationDetails.setCompileWorkingDir(compilerWorkingDir);
            File cppCompilerExecutable = findCppCompilerExecutable(project, cppBinary);
            compilationDetails.setCompilerExecutable(cppCompilerExecutable);

            List<String> compilerArgs = new ArrayList<>(cppCompile.getCompilerArgs().getOrElse(Collections.emptyList()));
            compilationDetails.setAdditionalArgs(compilerArgs);
          }

          LinkageDetailsImpl linkageDetails = new LinkageDetailsImpl();
          binary.setLinkageDetails(linkageDetails);
          DefaultExternalTask linkTask = new DefaultExternalTask();
          linkageDetails.setLinkTask(linkTask);
          linkTask.setName("");
          linkTask.setQName("");
          if (isExecutable) {
            Provider<? extends LinkExecutable> fileProvider = ((ComponentWithExecutable)cppBinary).getLinkTask();
            if (fileProvider.isPresent()) {
              LinkExecutable linkExecutable = fileProvider.get();
              String linkTaskName = linkExecutable.getPath();
              linkTask.setName(linkTaskName);
              linkTask.setQName(linkTaskName);
              File executableFile = getExecutableFile(linkExecutable);
              linkageDetails.setOutputLocation(executableFile);
            }
          }
        }
      }
    }
    return cppProject;
  }
@Nullable
  @Override
  public Object buildAll(final String modelName, final Project project)