public CopyAllDatasetsWrapper(DataWrapper wrapper) {
    LogDataUtils.logDataModelList(
        "Parent data in which constant columns have been removed.", getDataModelList());

    DataModelList inList = wrapper.getDataModelList();
    DataModelList outList = new DataModelList();

    for (DataModel model : inList) {
      if (!(model instanceof DataSet)) {
        throw new IllegalArgumentException("Not a data set: " + model.getName());
      }

      this.setDataModel(model);
      outList.add(model);
    }

    setDataModel(outList);
    setSourceGraph(wrapper.getSourceGraph());
  }
  /** Builds the panel. */
  public void setup() {
    DataModelList dataModelList = null;

    for (Object parentModel : parentModels) {
      if (parentModel instanceof DataWrapper) {
        DataWrapper dataWrapper = (DataWrapper) parentModel;
        dataModelList = dataWrapper.getDataModelList();
      }
    }

    if (dataModelList == null) {
      throw new NullPointerException("Null data model list.");
    }

    for (DataModel model : dataModelList) {
      if (!(model instanceof DataSet)) {
        JOptionPane.showMessageDialog(
            JOptionUtils.centeringComp(),
            "For the shift search, all of the data in the data box must be in the form of data sets.");
        return;
      }
    }

    final List<DataSet> dataSets = new ArrayList<DataSet>();

    for (Object aDataModelList : dataModelList) {
      dataSets.add((DataSet) aDataModelList);
    }

    SpinnerModel maxVarsModel =
        new SpinnerNumberModel(
            Preferences.userRoot().getInt("shiftSearchMaxNumShifts", 3), 1, 50, 1);
    JSpinner maxVarsSpinner = new JSpinner(maxVarsModel);
    maxVarsSpinner.setMaximumSize(maxVarsSpinner.getPreferredSize());

    maxVarsSpinner.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent e) {
            JSpinner spinner = (JSpinner) e.getSource();
            SpinnerNumberModel model = (SpinnerNumberModel) spinner.getModel();
            int value = (Integer) model.getValue();
            Preferences.userRoot().putInt("shiftSearchMaxNumShifts", value);
          }
        });

    SpinnerModel maxShiftModel =
        new SpinnerNumberModel(Preferences.userRoot().getInt("shiftSearchMaxShift", 2), 1, 50, 1);
    JSpinner maxShiftSpinner = new JSpinner(maxShiftModel);
    maxShiftSpinner.setMaximumSize(maxShiftSpinner.getPreferredSize());

    maxShiftSpinner.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent e) {
            JSpinner spinner = (JSpinner) e.getSource();
            SpinnerNumberModel model = (SpinnerNumberModel) spinner.getModel();
            int value = (Integer) model.getValue();
            Preferences.userRoot().putInt("shiftSearchMaxShift", value);
          }
        });

    JButton searchButton = new JButton("Search");
    final JButton stopButton = new JButton("Stop");

    final JTextArea textArea = new JTextArea();
    JScrollPane textScroll = new JScrollPane(textArea);
    textScroll.setPreferredSize(new Dimension(500, 200));

    searchButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent actionEvent) {
            final Thread thread =
                new Thread() {
                  public void run() {
                    textArea.setText("");
                    doShiftSearch(dataSets, textArea);
                  }
                };

            thread.start();
          }
        });

    stopButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent actionEvent) {
            if (search != null) {
              search.stop();
            }
          }
        });

    JComboBox directionBox = new JComboBox(new String[] {"forward", "backward"});
    directionBox.setSelectedItem(params.isForwardSearch() ? "forward" : "backward");
    directionBox.setMaximumSize(directionBox.getPreferredSize());

    directionBox.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent actionEvent) {
            JComboBox source = (JComboBox) actionEvent.getSource();
            String selected = (String) source.getSelectedItem();
            params.setForwardSearch("forward".equals(selected));
          }
        });

    Box b1 = Box.createVerticalBox();

    Box b2 = Box.createHorizontalBox();
    b2.add(new JLabel("Maximum number of variables in shift set is: "));
    b2.add(maxVarsSpinner);
    b2.add(Box.createHorizontalGlue());
    b1.add(b2);

    Box b3 = Box.createHorizontalBox();
    b3.add(new JLabel("Maximum "));
    b3.add(directionBox);
    b3.add(new JLabel(" shift: "));
    b3.add(maxShiftSpinner);
    b3.add(Box.createHorizontalGlue());
    b1.add(b3);

    Box b4 = Box.createHorizontalBox();
    b4.add(new JLabel("Output:"));
    b4.add(Box.createHorizontalGlue());
    b1.add(b4);

    Box b5 = Box.createHorizontalBox();
    b5.add(textScroll);
    b1.add(b5);

    Box b6 = Box.createHorizontalBox();
    b6.add(searchButton);
    b6.add(stopButton);
    b1.add(b6);

    final Box a1 = Box.createVerticalBox();

    Box a2 = Box.createHorizontalBox();
    a2.add(new JLabel("Specify the shift (positive or negative) for each variable:"));
    a2.add(Box.createHorizontalGlue());
    a1.add(a2);

    a1.add(Box.createVerticalStrut(20));

    setUpA1(dataSets, a1);

    JTabbedPane tabbedPane = new JTabbedPane();
    tabbedPane.addTab("Shift", new JScrollPane(a1));
    tabbedPane.addTab("Search", new JScrollPane(b1));

    add(tabbedPane, BorderLayout.CENTER);

    tabbedPane.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent changeEvent) {
            System.out.println("a1 shown");
            a1.removeAll();
            setUpA1(dataSets, a1);
          }
        });
  }