private static void addAll(Map<String, Node> nodes, CubeDockerConfiguration config, String id) {
    CubeContainer content = config.getDockerContainersContent().get(id);
    if (content == null) {
      return;
    }
    Node parent = nodes.get(id);
    if (content.getLinks() != null) {
      Collection<Link> links = content.getLinks();
      for (Link link : links) {
        String name = link.getName();

        if (config.getDockerContainersContent().get(name) != null) {
          Node child = nodes.get(name);
          if (child == null) {
            child = Node.from(name);
            nodes.put(name, child);
          }
          // Only continue recursively if this was a new found child
          if (child.addAsChildOf(parent)) {
            addAll(nodes, config, name);
          }
        }
      }
    }
  }
 private void configure(ArquillianDescriptor arquillianDescriptor) {
   operatingSystemFamilyInstanceProducer.set(
       new OperatingSystemResolver().currentOperatingSystem().getFamily());
   Map<String, String> config =
       arquillianDescriptor.extension(EXTENSION_NAME).getExtensionProperties();
   config = resolveSystemEnvironmentVariables(config);
   config = resolveAutoStartDockerMachine(config);
   config = resolveDefaultDockerMachine(config);
   config = resolveServerUriByOperativeSystem(config);
   config = resolveServerUriTcpProtocol(config);
   config = resolveServerIp(config);
   CubeDockerConfiguration cubeConfiguration = CubeDockerConfiguration.fromMap(config);
   System.out.println(cubeConfiguration);
   hostUriContextInstanceProducer.set(new HostUriContext(cubeConfiguration.getDockerServerUri()));
   configurationProducer.set(cubeConfiguration);
 }
  private Map<String, String> resolveDownloadDockerMachine(Map<String, String> config) {
    if (config.containsKey(CubeDockerConfiguration.DOCKER_MACHINE_NAME)) {
      final String cliPathExec = config.get(CubeDockerConfiguration.DOCKER_MACHINE_PATH);
      if (!dockerMachineInstance.get().isDockerMachineInstalled(cliPathExec)) {
        String machineVersion = GitHubUtil.getDockerMachineLatestVersion();
        String machineCustomPath = config.get(CubeDockerConfiguration.DOCKER_MACHINE_CUSTOM_PATH);
        String machineArquillianPath =
            CubeDockerConfiguration.resolveMachinePath(machineCustomPath, machineVersion);
        File dockerMachineFile = new File(machineArquillianPath);

        boolean dockerMachineFileExist = dockerMachineFile != null && dockerMachineFile.exists();

        String machineName = config.get(CubeDockerConfiguration.DOCKER_MACHINE_NAME);
        String machineUrl = CubeDockerConfiguration.resolveUrl(machineVersion);

        if (!dockerMachineFileExist) {
          Spacelift.task(DownloadTool.class)
              .from(machineUrl)
              .to(dockerMachineFile)
              .execute()
              .await();
          config.put(
              CubeDockerConfiguration.DOCKER_MACHINE_PATH, dockerMachineFile.getAbsolutePath());

          dockerMachineInstance.get().grantPermissionToDockerMachine(machineArquillianPath);

          String machineDriver = config.get(CubeDockerConfiguration.DOCKER_MACHINE_DRIVER);
          dockerMachineInstance
              .get()
              .createMachine(machineArquillianPath, machineDriver, machineName);
        } else {
          config.put(
              CubeDockerConfiguration.DOCKER_MACHINE_PATH, dockerMachineFile.getAbsolutePath());
        }
      }
    }
    return config;
  }
  static Set<Node> from(CubeDockerConfiguration config) {
    Map<String, Node> nodes = new HashMap<>();

    AutoStartParser autoStartParser = config.getAutoStartContainers();
    if (autoStartParser != null) {
      nodes.putAll(autoStartParser.parse());
    }

    // add all children links
    Map<String, Node> autoStartNodes = new HashMap<>(nodes);
    for (Map.Entry<String, Node> node : autoStartNodes.entrySet()) {
      addAll(nodes, config, node.getKey());
    }

    return new HashSet<>(nodes.values());
  }
  @SuppressWarnings("unchecked")
  public static CubeDockerConfiguration fromMap(Map<String, String> map) {
    CubeDockerConfiguration cubeConfiguration = new CubeDockerConfiguration();

    if (map.containsKey(DOCKER_SERVER_IP)) {
      cubeConfiguration.dockerServerIp = map.get(DOCKER_SERVER_IP);
    }

    if (map.containsKey(DOCKER_VERSION)) {
      cubeConfiguration.dockerServerVersion = map.get(DOCKER_VERSION);
    }

    if (map.containsKey(DOCKER_URI)) {
      cubeConfiguration.dockerServerUri = map.get(DOCKER_URI);
    }

    if (map.containsKey(DIND_RESOLUTION)) {
      cubeConfiguration.dockerInsideDockerResolution =
          Boolean.parseBoolean(map.get(DIND_RESOLUTION));
    }

    if (map.containsKey(BOOT2DOCKER_PATH)) {
      cubeConfiguration.boot2DockerPath = map.get(BOOT2DOCKER_PATH);
    }

    if (map.containsKey(DOCKER_MACHINE_PATH)) {
      cubeConfiguration.dockerMachinePath = map.get(DOCKER_MACHINE_PATH);
    }

    if (map.containsKey(DOCKER_MACHINE_NAME)) {
      cubeConfiguration.machineName = map.get(DOCKER_MACHINE_NAME);
    }

    if (map.containsKey(USERNAME)) {
      cubeConfiguration.username = map.get(USERNAME);
    }

    if (map.containsKey(PASSWORD)) {
      cubeConfiguration.password = map.get(PASSWORD);
    }

    if (map.containsKey(EMAIL)) {
      cubeConfiguration.email = map.get(EMAIL);
    }

    if (map.containsKey(CERT_PATH)) {
      cubeConfiguration.certPath = map.get(CERT_PATH);
    }

    if (map.containsKey(DOCKER_REGISTRY)) {
      cubeConfiguration.dockerRegistry = map.get(DOCKER_REGISTRY);
    }

    if (map.containsKey(DEFINITION_FORMAT)) {
      String definitionContent = map.get(DEFINITION_FORMAT);
      cubeConfiguration.definitionFormat =
          DefinitionFormat.valueOf(DefinitionFormat.class, definitionContent);
    }

    if (map.containsKey(DOCKER_CONTAINERS)) {
      String content = map.get(DOCKER_CONTAINERS);
      cubeConfiguration.dockerContainersContent =
          DockerContainerDefinitionParser.convert(content, cubeConfiguration.definitionFormat);
    }

    if (map.containsKey(DOCKER_CONTAINERS_FILE)) {
      final String location = map.get(DOCKER_CONTAINERS_FILE);
      final List<URI> resolveUri = new ArrayList<>();
      try {
        final URI uri = URI.create(location);
        resolveUri.add(uri);

        if (System.getProperty(CUBE_ENVIRONMENT) != null) {
          final String resolveFilename = resolveFilename(uri);
          final String environmentUri =
              uri.toString()
                  .replace(
                      resolveFilename,
                      resolveFilename + "." + System.getProperty(CUBE_ENVIRONMENT));
          resolveUri.add(URI.create(environmentUri));
        }

        cubeConfiguration.dockerContainersContent =
            DockerContainerDefinitionParser.convert(
                cubeConfiguration.definitionFormat, resolveUri.toArray(new URI[resolveUri.size()]));
      } catch (IOException e) {
        throw new IllegalArgumentException(e);
      }
    }

    if (map.containsKey(DOCKER_CONTAINERS_FILES)) {

      String locations = map.get(DOCKER_CONTAINERS_FILES);
      List<URI> realLocations = getUris(locations);
      try {
        cubeConfiguration.dockerContainersContent =
            DockerContainerDefinitionParser.convert(
                cubeConfiguration.definitionFormat,
                realLocations.toArray(new URI[realLocations.size()]));
      } catch (IOException e) {
        throw new IllegalArgumentException(e);
      }
    }

    if (!map.containsKey(DOCKER_CONTAINERS)
        && !map.containsKey(DOCKER_CONTAINERS_FILE)
        && !map.containsKey(DOCKER_CONTAINERS_FILES)) {
      try {
        cubeConfiguration.dockerContainersContent =
            DockerContainerDefinitionParser.convertDefault(cubeConfiguration.definitionFormat);
      } catch (IOException e) {
        throw new IllegalArgumentException(e);
      }
    }

    if (map.containsKey(AUTO_START_CONTAINERS)) {
      String expression = map.get(AUTO_START_CONTAINERS);
      Map<String, Object> containerDefinitions = cubeConfiguration.getDockerContainersContent();
      AutoStartParser autoStartParser =
          AutoStartParserFactory.create(expression, containerDefinitions);

      cubeConfiguration.autoStartContainers = autoStartParser;
    }

    return cubeConfiguration;
  }