public SemEstimatorEditor(SemEstimatorWrapper _wrapper) {
    this.wrapper = _wrapper;
    panel = new JPanel();
    setLayout(new BorderLayout());

    JComboBox optimizerCombo = new JComboBox();
    optimizerCombo.addItem("Regression");
    optimizerCombo.addItem("EM");
    optimizerCombo.addItem("Powell");
    optimizerCombo.addItem("Random Search");
    optimizerCombo.addItem("RICF");

    optimizerCombo.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            JComboBox box = (JComboBox) e.getSource();
            wrapper.setSemOptimizerType((String) box.getSelectedItem());
          }
        });

    scoreBox = new JComboBox();
    restarts = new IntTextField(1, 2);

    scoreBox.addItem("Fgls");
    scoreBox.addItem("Fml");

    scoreBox.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            JComboBox box = (JComboBox) e.getSource();
            String type = (String) box.getSelectedItem();
            if ("Fgls".equals(type)) {
              wrapper.setScoreType(SemIm.ScoreType.Fgls);
            } else if ("Fml".equals(type)) {
              wrapper.setScoreType(SemIm.ScoreType.Fml);
            }
          }
        });

    restarts.setFilter(
        new IntTextField.Filter() {
          public int filter(int value, int oldValue) {
            try {
              wrapper.setNumRestarts(value);
              return value;
            } catch (Exception e) {
              return oldValue;
            }
          }
        });

    String semOptimizerType = wrapper.getParams().getString("semOptimizerType", "Regression");

    optimizerCombo.setSelectedItem(semOptimizerType);
    SemIm.ScoreType scoreType =
        (SemIm.ScoreType) wrapper.getParams().get("scoreType", SemIm.ScoreType.Fgls);
    if (scoreType == null) scoreType = SemIm.ScoreType.Fgls;
    scoreBox.setSelectedItem(scoreType.toString());
    restarts.setValue(wrapper.getParams().getInt("numRestarts", 1));

    JButton estimateButton = new JButton("Estimate Again");

    estimateButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            Window owner = (Window) getTopLevelAncestor();

            new WatchedProcess(owner) {
              public void watch() {
                reestimate();
              }
            };
          }
        });

    JButton report = new JButton("Report");

    report.addActionListener(
        (new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            final JTextArea textArea = new JTextArea();
            JScrollPane scroll = new JScrollPane(textArea);

            textArea.append(compileReport());

            Box b = Box.createVerticalBox();
            Box b2 = Box.createHorizontalBox();
            b2.add(scroll);
            textArea.setCaretPosition(0);
            b.add(b2);

            JPanel panel = new JPanel();
            panel.setLayout(new BorderLayout());
            panel.add(b);

            EditorWindow window =
                new EditorWindow(panel, "All Paths", "Close", false, SemEstimatorEditor.this);
            DesktopController.getInstance().addEditorWindow(window, JLayeredPane.PALETTE_LAYER);
            window.setVisible(true);
          }
        }));

    Box lowerBarA = Box.createHorizontalBox();
    lowerBarA.add(new JLabel("Score"));
    lowerBarA.add(scoreBox);
    lowerBarA.add(Box.createHorizontalGlue());
    lowerBarA.add(new JLabel("Random Restarts"));
    lowerBarA.add(restarts);

    Box lowerBarB = Box.createHorizontalBox();
    lowerBarB.add(new JLabel("Choose Optimizer:  "));
    lowerBarB.add(optimizerCombo);
    lowerBarB.add(Box.createHorizontalGlue());
    lowerBarB.add(estimateButton);

    Box lowerBar = Box.createVerticalBox();
    lowerBar.add(lowerBarA);
    lowerBar.add(lowerBarB);

    if (wrapper.getMultipleResultList().size() > 1) {
      lowerBar.add(report);
    }

    add(lowerBar, BorderLayout.SOUTH);

    resetSemImEditor();

    add(panel, BorderLayout.CENTER);
    validate();
  }