@NotNull
  private FSRecords.NameId[] persistAllChildren(
      @NotNull final VirtualFile file, final int id, @NotNull FSRecords.NameId[] current) {
    assert file != mySuperRoot;
    final NewVirtualFileSystem fs = replaceWithNativeFS(getDelegate(file));

    String[] delegateNames = VfsUtil.filterNames(fs.list(file));
    if (delegateNames.length == 0 && current.length > 0) {
      return current;
    }

    Set<String> toAdd = ContainerUtil.newHashSet(delegateNames);
    for (FSRecords.NameId nameId : current) {
      toAdd.remove(nameId.name);
    }

    final TIntArrayList childrenIds = new TIntArrayList(current.length + toAdd.size());
    final List<FSRecords.NameId> nameIds =
        ContainerUtil.newArrayListWithExpectedSize(current.length + toAdd.size());
    for (FSRecords.NameId nameId : current) {
      childrenIds.add(nameId.id);
      nameIds.add(nameId);
    }
    for (String newName : toAdd) {
      FakeVirtualFile child = new FakeVirtualFile(file, newName);
      FileAttributes attributes = fs.getAttributes(child);
      if (attributes != null) {
        int childId = createAndFillRecord(fs, child, id, attributes);
        childrenIds.add(childId);
        nameIds.add(new FSRecords.NameId(childId, FileNameCache.storeName(newName), newName));
      }
    }

    FSRecords.updateList(id, childrenIds.toNativeArray());
    setChildrenCached(id);

    return nameIds.toArray(new FSRecords.NameId[nameIds.size()]);
  }
  // please keep an implementation in sync with [junit-rt] ProcessBuilder.createProcess()
  @NotNull
  public static List<String> toCommandLine(
      @NotNull String command, @NotNull List<String> parameters, @NotNull Platform platform) {
    List<String> commandLine = ContainerUtil.newArrayListWithExpectedSize(parameters.size() + 1);

    commandLine.add(FileUtilRt.toSystemDependentName(command, platform.fileSeparator));

    boolean isWindows = platform == Platform.WINDOWS;
    boolean winShell =
        isWindows
            && ("cmd".equalsIgnoreCase(command) || "cmd.exe".equalsIgnoreCase(command))
            && parameters.size() > 1
            && "/c".equalsIgnoreCase(parameters.get(0));

    for (String parameter : parameters) {
      if (isWindows) {
        if (parameter.contains("\"")) {
          parameter = StringUtil.replace(parameter, "\"", "\\\"");
        } else if (parameter.isEmpty()) {
          parameter = "\"\"";
        }
      }

      if (winShell && StringUtil.containsAnyChar(parameter, WIN_SHELL_SPECIALS)) {
        parameter = quote(parameter, SPECIAL_QUOTE);
      }

      if (isQuoted(parameter, SPECIAL_QUOTE)) {
        parameter = quote(parameter.substring(1, parameter.length() - 1), '"');
      }

      commandLine.add(parameter);
    }

    return commandLine;
  }
  protected JComponent createSouthPanel() {
    JPanel panel = new JPanel(new BorderLayout());
    panel.setBorder(BorderFactory.createEmptyBorder(8, 0, 0, 0));

    JPanel buttonPanel = new JPanel();

    if (SystemInfo.isMac) {
      panel.add(buttonPanel, BorderLayout.EAST);
      buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));

      if (!UIUtil.isUnderDarcula()) {
        myHelpButton.putClientProperty("JButton.buttonType", "help");
      }
      if (UIUtil.isUnderAquaLookAndFeel()) {
        myHelpButton.setText("");
      }

      JPanel leftPanel = new JPanel();
      if (ApplicationInfo.contextHelpAvailable()) {
        leftPanel.add(myHelpButton);
      }
      leftPanel.add(myCancelButton);
      panel.add(leftPanel, BorderLayout.WEST);

      if (mySteps.size() > 1) {
        buttonPanel.add(Box.createHorizontalStrut(5));
        buttonPanel.add(myPreviousButton);
      }
      buttonPanel.add(Box.createHorizontalStrut(5));
      buttonPanel.add(myNextButton);
    } else {
      panel.add(buttonPanel, BorderLayout.CENTER);
      GroupLayout layout = new GroupLayout(buttonPanel);
      buttonPanel.setLayout(layout);
      layout.setAutoCreateGaps(true);

      final GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
      final GroupLayout.ParallelGroup vGroup = layout.createParallelGroup();
      final Collection<Component> buttons = ContainerUtil.newArrayListWithExpectedSize(5);
      final boolean helpAvailable = ApplicationInfo.contextHelpAvailable();

      if (helpAvailable && UIUtil.isUnderGTKLookAndFeel()) {
        add(hGroup, vGroup, buttons, myHelpButton);
      }
      add(hGroup, vGroup, null, Box.createHorizontalGlue());
      if (mySteps.size() > 1) {
        add(hGroup, vGroup, buttons, myPreviousButton);
      }
      add(hGroup, vGroup, buttons, myNextButton, myCancelButton);
      if (helpAvailable && !UIUtil.isUnderGTKLookAndFeel()) {
        add(hGroup, vGroup, buttons, myHelpButton);
      }

      layout.setHorizontalGroup(hGroup);
      layout.setVerticalGroup(vGroup);
      layout.linkSize(buttons.toArray(new Component[buttons.size()]));
    }

    myPreviousButton.setEnabled(false);
    myPreviousButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(final ActionEvent e) {
            doPreviousAction();
          }
        });
    myNextButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(final ActionEvent e) {
            if (isLastStep()) {
              // Commit data of current step and perform OK action
              final Step currentStep = mySteps.get(myCurrentStep);
              LOG.assertTrue(currentStep != null);
              try {
                currentStep._commit(true);
                doOKAction();
              } catch (final CommitStepException exc) {
                String message = exc.getMessage();
                if (message != null) {
                  Messages.showErrorDialog(myContentPanel, message);
                }
              }
            } else {
              doNextAction();
            }
          }
        });

    myCancelButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(final ActionEvent e) {
            doCancelAction();
          }
        });
    myHelpButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(final ActionEvent e) {
            helpAction();
          }
        });

    return panel;
  }