/*
 * Copyright (c) 2014-2016 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 *    Ericsson AB (Julian Enoch) - Bug 434525 - Allow prompted variables to be pre-populated
 */
package org.eclipse.oomph.setup.ui.wizards;

import org.eclipse.oomph.base.Annotation;
import org.eclipse.oomph.base.util.BaseUtil;
import org.eclipse.oomph.internal.setup.SetupPrompter;
import org.eclipse.oomph.internal.ui.AccessUtil;
import org.eclipse.oomph.preferences.util.PreferencesUtil;
import org.eclipse.oomph.setup.AnnotationConstants;
import org.eclipse.oomph.setup.Installation;
import org.eclipse.oomph.setup.SetupTask;
import org.eclipse.oomph.setup.SetupTaskContext;
import org.eclipse.oomph.setup.Trigger;
import org.eclipse.oomph.setup.User;
import org.eclipse.oomph.setup.VariableChoice;
import org.eclipse.oomph.setup.VariableTask;
import org.eclipse.oomph.setup.Workspace;
import org.eclipse.oomph.setup.internal.core.SetupContext;
import org.eclipse.oomph.setup.internal.core.SetupTaskPerformer;
import org.eclipse.oomph.setup.internal.core.util.Authenticator;
import org.eclipse.oomph.setup.internal.core.util.SetupCoreUtil;
import org.eclipse.oomph.setup.ui.PropertyField;
import org.eclipse.oomph.setup.ui.PropertyField.AuthenticatedField;
import org.eclipse.oomph.setup.ui.PropertyField.ValueListener;
import org.eclipse.oomph.setup.ui.SetupUIPlugin;
import org.eclipse.oomph.setup.ui.wizards.SetupWizard.IndexLoader;
import org.eclipse.oomph.setup.util.StringExpander;
import org.eclipse.oomph.ui.ButtonBar;
import org.eclipse.oomph.ui.ErrorDialog;
import org.eclipse.oomph.ui.UICallback;
import org.eclipse.oomph.ui.UIUtil;
import org.eclipse.oomph.util.CollectionUtil;
import org.eclipse.oomph.util.OS;
import org.eclipse.oomph.util.StringUtil;
import org.eclipse.oomph.util.UserCallback;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;

import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Eike Stepper
 */
public class VariablePage extends SetupWizardPage implements SetupPrompter
{
  private static final String SETUP_TASK_ANALYSIS_TITLE = "Setup Task Analysis";

  private static final URI INSTALLATION_ID_URI = URI.createURI("#~installation.id");

  private static final URI WORKSPACE_ID_URI = URI.createURI("#~workspace.id");

  private Composite composite;

  private ScrolledComposite scrolledComposite;

  private final FieldHolderManager manager = new FieldHolderManager();

  private final Set<String> unusedVariables = new HashSet<String>();

  private boolean prompted;

  private boolean fullPrompt;

  private boolean updating;

  private Set<SetupTaskPerformer> incompletePerformers = new LinkedHashSet<SetupTaskPerformer>();

  private Set<SetupTaskPerformer> allPromptedPerfomers = new LinkedHashSet<SetupTaskPerformer>();

  private SetupTaskPerformer performer;

  private Control focusControl;

  private SetupContext originalContext;

  private boolean save = true;

  private boolean defaultsSet;

  private UserCallback userCallback;

  private final Validator validator = new Validator();

  private FocusListener focusListener = new FocusAdapter()
  {
    @Override
    public void focusGained(FocusEvent e)
    {
      focusControl = (Control)e.widget;
    }
  };

  private PerformerCreationJob performerCreationJob;

  private long delay;

  public VariablePage()
  {
    super("VariablePage");
    setTitle("Variables");
    setDescription("Enter values for the required variables.");
  }

  @Override
  protected Control createUI(Composite parent)
  {
    Composite mainComposite = new Composite(parent, SWT.NONE);
    mainComposite.setLayout(UIUtil.createGridLayout(1));
    mainComposite.setLayoutData(new GridData(GridData.FILL_BOTH));

    GridLayout outerLayout = (GridLayout)parent.getParent().getLayout();
    outerLayout.marginLeft = outerLayout.marginWidth;
    outerLayout.marginWidth = 0;

    scrolledComposite = new ScrolledComposite(mainComposite, SWT.VERTICAL);
    scrolledComposite.setExpandHorizontal(true);
    scrolledComposite.setExpandVertical(true);
    scrolledComposite.setShowFocusedControl(true);
    scrolledComposite.setLayoutData(new GridData(GridData.FILL_BOTH));

    GridLayout layout = UIUtil.createGridLayout(3);
    layout.horizontalSpacing = 10;
    layout.verticalSpacing = 10;
    layout.marginRight = outerLayout.marginLeft;

    composite = new Composite(scrolledComposite, SWT.NONE);
    composite.setLayout(layout);
    scrolledComposite.setContent(composite);
    composite.setLayoutData(new GridData(GridData.FILL_BOTH));

    ControlAdapter resizeListener = new ControlAdapter()
    {
      @Override
      public void controlResized(ControlEvent event)
      {
        Point size = composite.computeSize(scrolledComposite.getClientArea().width, SWT.DEFAULT);
        scrolledComposite.setMinSize(size);
      }
    };

    scrolledComposite.addControlListener(resizeListener);
    composite.addControlListener(resizeListener);
    composite.notifyListeners(SWT.Resize, new Event());

    return mainComposite;
  }

  @Override
  protected void createCheckButtons(ButtonBar buttonBar)
  {
    final Button fullPromptButton = buttonBar.addCheckButton("Show all variables", "", false, "fullPrompt");
    fullPrompt = fullPromptButton.getSelection();
    fullPromptButton.addSelectionListener(new SelectionAdapter()
    {
      @Override
      public void widgetSelected(SelectionEvent e)
      {
        fullPrompt = fullPromptButton.getSelection();
        validator.schedule(false);
      }
    });

    AccessUtil.setKey(fullPromptButton, "showAll");
  }

  private synchronized boolean updateFields()
  {
    unusedVariables.clear();

    for (FieldHolder fieldHolder : manager)
    {
      fieldHolder.clear();
    }

    Set<SetupTaskPerformer> performers = new LinkedHashSet<SetupTaskPerformer>();
    if (incompletePerformers.isEmpty())
    {
      if (performer != null)
      {
        performers.add(performer);
      }

      performers.addAll(allPromptedPerfomers);
    }
    else
    {
      performers.addAll(incompletePerformers);
      performers.addAll(allPromptedPerfomers);
    }

    Set<String> usedVariables = new HashSet<String>();
    for (FieldHolder fieldHolder : manager)
    {
      String value = fieldHolder.getValue();
      if (!StringUtil.isEmpty(value))
      {
        usedVariables.addAll(SetupTaskPerformer.getVariables(value));
      }
    }

    for (SetupTaskPerformer setupTaskPerformer : performers)
    {
      List<VariableTask> variables = setupTaskPerformer.getUnresolvedVariables();
      for (VariableTask variable : variables)
      {
        VariableTask ruleVariable = setupTaskPerformer.getRuleVariable(variable);
        if (ruleVariable == null)
        {
          if (variable.getAnnotation(AnnotationConstants.ANNOTATION_UNDECLARED_VARIABLE) != null)
          {
            String name = variable.getName();
            if (!usedVariables.contains(name))
            {
              Trigger trigger = getTrigger();
              boolean isUsedInActualTriggeredTask = false;
              for (SetupTask setupTask : setupTaskPerformer.getTriggeredSetupTasks())
              {
                if (setupTask.getTriggers().contains(trigger) && setupTaskPerformer.isVariableUsed(name, setupTask, true))
                {
                  isUsedInActualTriggeredTask = true;
                  break;
                }
              }

              if (!isUsedInActualTriggeredTask)
              {
                unusedVariables.add(name);
                continue;
              }
            }
          }

          manager.getFieldHolder(variable, true, false);
        }
        else
        {
          FieldHolder fieldHolder = manager.getFieldHolder(ruleVariable, true, false);
          fieldHolder.add(variable);
          manager.associate(variable, fieldHolder);
        }
      }
    }

    boolean setDefault = false;
    for (FieldHolder fieldHolder : manager)
    {
      if (StringUtil.isEmpty(fieldHolder.getValue()))
      {
        String initialValue = null;
        String initialDefaultValue = null;
        for (VariableTask variable : fieldHolder.getVariables())
        {
          if (initialValue == null)
          {
            String value = variable.getValue();
            if (!StringUtil.isEmpty(value))
            {
              initialValue = value;

              // Check the choices for ones that specify "match choice" annotations.
              for (VariableChoice choice : variable.getChoices())
              {
                Annotation annotation = choice.getAnnotation(AnnotationConstants.ANNOTATION_MATCH_CHOICE);
                if (annotation != null)
                {
                  String choiceValue = choice.getValue();
                  if (choiceValue != null)
                  {
                    // Expand the choice into a pattern where the variables expand to ".*" and the rest of the value is quoted as literal.
                    StringBuffer result = new StringBuffer("\\Q");
                    Matcher matcher = StringExpander.STRING_EXPANSION_PATTERN.matcher(choiceValue);
                    while (matcher.find())
                    {
                      matcher.appendReplacement(result, "\\\\E.*\\\\Q");
                    }

                    matcher.appendTail(result);

                    try
                    {
                      // If the pattern matches, use the value of the choice as the initial value.
                      Pattern pattern = Pattern.compile(result.toString());
                      if (pattern.matcher(value).matches())
                      {
                        initialValue = choiceValue;
                        setDefault = true;
                        break;
                      }
                    }
                    catch (Throwable throwable)
                    {
                      // Ignore.
                    }
                  }
                }
              }
            }
          }

          if (initialDefaultValue == null)
          {
            String defaultValue = variable.getDefaultValue();
            if (!StringUtil.isEmpty(defaultValue))
            {
              initialDefaultValue = defaultValue;
            }
          }
        }

        if (!StringUtil.isEmpty(initialValue))
        {
          fieldHolder.setValue(initialValue);
        }
        else if (!StringUtil.isEmpty(initialDefaultValue))
        {
          setDefault = true;
          fieldHolder.setValue(initialDefaultValue);
        }
        else
        {
          String defaultValue = fieldHolder.getDefaultValue();
          if (!StringUtil.isEmpty(defaultValue))
          {
            setDefault = true;
            fieldHolder.setValue(defaultValue);
          }
        }
      }
    }

    try
    {
      for (FieldHolder fieldHolder : manager)
      {
        updating = true;
        fieldHolder.update();
      }
    }
    finally
    {
      updating = false;
    }

    for (FieldHolder fieldHolder : manager)
    {
      fieldHolder.recordInitialValue();
    }

    // Determine the URIs of all the variables actually being used.
    Set<URI> uris = new HashSet<URI>();
    if (performer != null)
    {
      for (VariableTask variable : performer.getUnresolvedVariables())
      {
        uris.add(manager.getURI(variable));
        VariableTask ruleVariable = performer.getRuleVariable(variable);
        if (ruleVariable != null)
        {
          uris.add(manager.getURI(ruleVariable));
        }
      }
    }

    manager.cleanup(uris);

    ScrolledComposite parent = (ScrolledComposite)composite.getParent();
    Point origin = parent.getOrigin();
    parent.setRedraw(false);

    List<SetupTaskPerformer> allPerformers = new ArrayList<SetupTaskPerformer>(allPromptedPerfomers);
    if (performer != null)
    {
      allPerformers.add(0, performer);
    }

    // Determine an appropriate field order.
    manager.reorder(allPerformers);

    parent.pack();
    parent.getParent().layout();
    parent.setOrigin(origin);
    parent.setRedraw(true);

    FieldHolder firstField = null;
    FieldHolder firstEmptyField = null;
    for (FieldHolder fieldHolder : manager)
    {
      if (!fieldHolder.isDisposed())
      {
        if (firstField == null)
        {
          firstField = fieldHolder;
        }

        if (firstEmptyField == null && StringUtil.isEmpty(fieldHolder.getValue()))
        {
          firstEmptyField = fieldHolder;
        }
      }
    }

    if (focusControl != null && !focusControl.isDisposed())
    {
      focusControl.setFocus();
      parent.showControl(focusControl);
    }
    else
    {
      FieldHolder field = firstEmptyField;
      if (field == null)
      {
        field = firstField;
      }

      if (field != null)
      {
        field.setFocus();
        parent.showControl(field.getControl());
      }
    }

    for (FieldHolder fieldHolder : manager)
    {
      if (!fieldHolder.isDisposed())
      {
        Control control = fieldHolder.getControl();
        PropertyField field = fieldHolder.field;
        Label label = field.getLabel();
        Control helper = field.getHelper();
        for (VariableTask variable : fieldHolder.getVariables())
        {
          String name = variable.getName();
          if (name.startsWith("@<id>"))
          {
            name = name.substring(name.indexOf("name: ") + 6, name.indexOf(')'));
          }

          AccessUtil.setKey(label, name + ".label");
          AccessUtil.setKey(control, name + ".control");
          AccessUtil.setKey(helper, name + ".helper");

          break;
        }
      }
    }

    if (setDefault)
    {
      defaultsSet = true;
    }

    if (isPageComplete() ? setDefault : firstEmptyField == null || setDefault)
    {
      // If the page isn't complete but there are no empty fields, then the last change introduced a new field.
      // So we should validate again to be sure there really needs to be more information prompted from the user.
      return true;
    }

    return false;
  }

  private void validate()
  {
    try
    {
      performer = null;
      incompletePerformers.clear();
      allPromptedPerfomers.clear();

      setButtonState(IDialogConstants.NEXT_ID, false);

      performerCreationJob = new PerformerCreationJob(SETUP_TASK_ANALYSIS_TITLE)
      {
        @Override
        protected SetupTaskPerformer createPerformer() throws Exception
        {
          return VariablePage.this.createPerformer(VariablePage.this, fullPrompt);
        }

        @Override
        protected Dialog createDialog()
        {
          return createDialog(getShell(), SETUP_TASK_ANALYSIS_TITLE, null,
              "Analyzing the needed setup tasks has taken more than " + (System.currentTimeMillis() - getStart()) / 1000
                  + " seconds.  The Next button will be disabled, though animated, until it completes.  You may continue to modify the values of the variables.",
              MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0);
        }

        @Override
        protected void handleDialogResult(int result)
        {
          if (result == 0)
          {
            setDelay(Integer.MAX_VALUE);
          }
          else
          {
            setDelay(2 * getDelay());
          }
        }
      };

      if (delay != 0)
      {
        performerCreationJob.setDelay(delay);
      }

      performerCreationJob.create();
      delay = performerCreationJob.getDelay();

      Throwable throwable = performerCreationJob.getThrowable();
      if (throwable != null)
      {
        if (throwable instanceof OperationCanceledException)
        {
          performerCreationJob = null;
          return;
        }

        throw throwable;
      }

      performer = performerCreationJob.getPerformer();

      UIUtil.asyncExec(getControl(), new Runnable()
      {
        public void run()
        {
          performerCreationJob = null;
          if (updateFields())
          {
            validate();
          }
        }
      });

      if (performer == null)
      {
        setPageComplete(false);
      }
      else
      {
        setPageComplete(true);

        if (!prompted)
        {
          prompted = true;
          gotoNextPage();
        }
      }
    }
    catch (Throwable t)
    {
      performerCreationJob = null;
      SetupUIPlugin.INSTANCE.log(t);
      ErrorDialog.open(t);
    }
  }

  private void clearSpecialFieldHolders()
  {
    clearSpecialFieldHolders(INSTALLATION_ID_URI);
    clearSpecialFieldHolders(WORKSPACE_ID_URI);
  }

  private void clearSpecialFieldHolders(URI uri)
  {
    FieldHolderRecord fieldHolderRecord = manager.getFieldHolderRecord(uri);
    if (fieldHolderRecord != null)
    {
      FieldHolder fieldHolder = fieldHolderRecord.getFieldHolder();
      if (fieldHolder != null && !fieldHolder.isDirty())
      {
        fieldHolder.clearValue();
      }
    }
  }

  @Override
  public void enterPage(boolean forward)
  {
    if (forward)
    {
      if (userCallback == null)
      {
        Shell shell = getShell();
        userCallback = new UICallback(shell, shell.getText());
      }

      clearSpecialFieldHolders();
    }

    performer = getWizard().getPerformer();
    if (performer != null && forward)
    {
      performer.setPrompter(this);
      setPageComplete(true);
      gotoNextPage();
    }
    else
    {
      if (!forward)
      {
        getWizard().setSetupContext(originalContext);
        originalContext = null;
      }

      IndexLoader indexLoader = getWizard().getIndexLoader();
      if (indexLoader != null)
      {
        indexLoader.awaitIndexLoad();
      }

      setPageComplete(false);
      validate();
      if (forward && getPreviousPage() == null)
      {
        UIUtil.asyncExec(getControl(), new Runnable()
        {
          public void run()
          {
            if (isPageComplete() && !defaultsSet)
            {
              gotoNextPage();
            }
          }
        });
      }
    }
  }

  @Override
  public void leavePage(boolean forward)
  {
    if (forward)
    {
      originalContext = getWizard().getSetupContext();

      final List<VariableTask> unresolvedVariables = performer.getUnresolvedVariables();
      for (FieldHolder fieldHolder : manager)
      {
        unresolvedVariables.addAll(fieldHolder.getVariables());
      }

      final ResourceSet resourceSet = SetupCoreUtil.createResourceSet();

      User user = getUser();
      final User copiedUser = EcoreUtil.copy(user);
      URI userResourceURI = user.eResource().getURI();
      Resource userResource = resourceSet.createResource(userResourceURI);
      userResource.getContents().add(copiedUser);

      Installation installation = performer.getInstallation();
      Resource installationResource = installation.eResource();
      URI installationResourceURI = installationResource.getURI();
      installationResource
          .setURI(URI.createFileURI(new File(performer.getProductConfigurationLocation(), "org.eclipse.oomph.setup/installation.setup").toString()));

      Workspace workspace = performer.getWorkspace();
      Resource workspaceResource = null;
      URI workspaceResourceURI = null;
      if (workspace != null)
      {
        workspaceResource = workspace.eResource();
        workspaceResourceURI = workspaceResource.getURI();
        workspaceResource
            .setURI(URI.createFileURI(new File(performer.getWorkspaceLocation(), ".metadata/.plugins/org.eclipse.oomph.setup/workspace.setup").toString()));
      }

      Installation copiedInstallation = EcoreUtil.copy(installation);
      URI copiedInstallationResourceURI = installation.eResource().getURI();
      Resource copiedInstallationResource = resourceSet.createResource(copiedInstallationResourceURI);
      copiedInstallationResource.getContents().add(copiedInstallation);

      Workspace copiedWorkspace = EcoreUtil.copy(workspace);
      if (workspace != null)
      {
        URI copiedWorkspaceResourceURI = workspace.eResource().getURI();
        Resource copiedWorkspaceResource = resourceSet.createResource(copiedWorkspaceResourceURI);
        copiedWorkspaceResource.getContents().add(copiedWorkspace);
      }

      performer.recordVariables(copiedInstallation, copiedWorkspace, copiedUser);

      unresolvedVariables.clear();

      getWizard().setSetupContext(SetupContext.create(copiedInstallation, copiedWorkspace, copiedUser));
      setPerformer(performer);

      if (save)
      {
        BaseUtil.saveEObject(copiedUser);

        performer.savePasswords();
      }

      installationResource.setURI(installationResourceURI);
      if (workspaceResource != null)
      {
        workspaceResource.setURI(workspaceResourceURI);
      }
    }
    else
    {
      originalContext = null;

      setPerformer(null);

      validator.cancel();
    }
  }

  public synchronized String getValue(VariableTask variable)
  {
    FieldHolder fieldHolder = manager.getFieldHolder(variable, false, true);
    if (fieldHolder != null && (updating || fieldHolder.isDirty()))
    {
      String value = fieldHolder.getValue();
      if (!"".equals(value))
      {
        return value;
      }
    }

    if (updating && performer != null)
    {
      Object value = performer.getMap().get(variable.getName());
      if (value != null)
      {
        return value.toString();
      }
    }

    return null;
  }

  public OS getOS()
  {
    return getWizard().getOS();
  }

  public String getVMPath()
  {
    return getWizard().getVMPath();
  }

  public synchronized boolean promptVariables(List<? extends SetupTaskContext> contexts)
  {
    prompted = true;

    @SuppressWarnings("unchecked")
    List<SetupTaskPerformer> performers = (List<SetupTaskPerformer>)contexts;
    allPromptedPerfomers.addAll(performers);

    for (SetupTaskPerformer performer : performers)
    {
      boolean resolvedAll = true;
      List<VariableTask> unresolvedVariables = performer.getUnresolvedVariables();
      for (VariableTask variable : unresolvedVariables)
      {
        FieldHolder fieldHolder = manager.getFieldHolder(variable, false, true);
        if (fieldHolder != null)
        {
          String value = fieldHolder.getValue();
          if (!"".equals(value))
          {
            variable.setValue(value);
          }
          else
          {
            resolvedAll = false;
          }
        }
        else if (unusedVariables.contains(variable.getName()))
        {
          variable.setValue(" ");
        }
        else
        {
          resolvedAll = false;
        }
      }

      if (!resolvedAll)
      {
        incompletePerformers.add(performer);
      }
    }

    boolean isComplete = incompletePerformers.isEmpty();
    return isComplete;
  }

  public UserCallback getUserCallback()
  {
    return userCallback;
  }

  /**
   * @author Ed Merks
   */
  private final class FieldHolder implements ValueListener
  {
    private final Set<VariableTask> variables = new LinkedHashSet<VariableTask>();

    private PropertyField field;

    private String initialValue;

    public FieldHolder(VariableTask variable)
    {
      field = PropertyField.createField(variable);
      field.fill(composite);
      field.addValueListener(this);
      field.getControl().addFocusListener(focusListener);
      variables.add(variable);
    }

    public boolean isDisposed()
    {
      return field == null;
    }

    private Control getControl()
    {
      if (field == null)
      {
        return null;
      }

      Control control = field.getControl();
      Control parent = control.getParent();
      if (parent == composite)
      {
        return control;
      }

      return null;
    }

    public void setFocus()
    {
      if (field == null)
      {
        throw new IllegalStateException("Can't set the value of a disposed field");
      }

      field.setFocus();
    }

    public String getValue()
    {
      return field == null ? initialValue : field.getValue();
    }

    public String getDefaultValue()
    {
      return field == null ? null : field.getDefaultValue();
    }

    public void clearValue()
    {
      initialValue = "";

      if (field != null)
      {
        field.setValue("", false, false);
      }
    }

    public void setValue(String value)
    {
      if (field == null)
      {
        throw new IllegalStateException("Can't set the value of a disposed field");
      }

      initialValue = null;

      field.setValue(value, false);
    }

    public Set<VariableTask> getVariables()
    {
      return Collections.unmodifiableSet(variables);
    }

    public void clear()
    {
      variables.clear();

      if (field instanceof AuthenticatedField)
      {
        AuthenticatedField authenticatedField = (AuthenticatedField)field;
        authenticatedField.clear();
      }
    }

    public void add(VariableTask variable)
    {
      if (variables.add(variable))
      {
        String value = field.getValue();
        if (!"".equals(value))
        {
          variable.setValue(value);
        }
      }
    }

    public void update()
    {
      if (field instanceof AuthenticatedField)
      {
        AuthenticatedField authenticatedField = (AuthenticatedField)field;
        String value = field.getValue();
        Set<Authenticator> allAuthenticators = new LinkedHashSet<Authenticator>();
        for (VariableTask variable : variables)
        {
          if (!StringUtil.isEmpty(value))
          {
            variable.setValue(value);
          }

          Set<? extends Authenticator> authenticators = SetupTaskPerformer.getAuthenticators(variable);
          if (authenticators != null)
          {
            allAuthenticators.addAll(authenticators);
          }
        }

        if (!allAuthenticators.isEmpty())
        {
          for (Iterator<Authenticator> it = allAuthenticators.iterator(); it.hasNext();)
          {
            Authenticator authenticator = it.next();
            if (authenticator.isFiltered())
            {
              it.remove();
            }
          }

          authenticatedField.addAll(allAuthenticators);

          if (allAuthenticators.isEmpty())
          {
            dispose(PreferencesUtil.encrypt(" "));
          }
        }
      }
    }

    public void valueChanged(String oldValue, String newValue) throws Exception
    {
      synchronized (VariablePage.this)
      {
        for (VariableTask variable : variables)
        {
          variable.setValue(newValue);
        }
      }

      validator.schedule(true);
    }

    public void recordInitialValue()
    {
      if (initialValue == null && field != null)
      {
        initialValue = field.getValue();
      }
    }

    public boolean isDirty()
    {
      return field != null && initialValue != null && !initialValue.equals(field.getValue());
    }

    public void dispose(String value)
    {
      if (field != null)
      {
        field.dispose();
        field = null;
      }

      if (StringUtil.isEmpty(initialValue))
      {
        initialValue = value;
      }
    }

    public void dispose()
    {
      if (field != null)
      {
        field.dispose();
        field = null;
      }
    }

    @Override
    public String toString()
    {
      return field == null ? "<disposed>" : field.toString();
    }
  }

  /**
   * @author Ed Merks
   */
  private static class FieldHolderRecord
  {
    private FieldHolder fieldHolder;

    private final Set<URI> variableURIs = new HashSet<URI>();

    public FieldHolderRecord()
    {
    }

    public FieldHolder getFieldHolder()
    {
      return fieldHolder;
    }

    public void setFieldHolder(FieldHolder fieldHolder)
    {
      this.fieldHolder = fieldHolder;
    }

    public Set<URI> getVariableURIs()
    {
      return variableURIs;
    }

    @Override
    public String toString()
    {
      return variableURIs.toString();
    }
  }

  /**
   * @author Ed Merks
   */
  private class FieldHolderManager implements Iterable<FieldHolder>
  {
    private final EList<FieldHolderRecord> fields = new BasicEList<FieldHolderRecord>();

    public Iterator<FieldHolder> iterator()
    {
      final Iterator<FieldHolderRecord> iterator = fields.iterator();
      return new Iterator<FieldHolder>()
      {
        public boolean hasNext()
        {
          return iterator.hasNext();
        }

        public FieldHolder next()
        {
          return iterator.next().getFieldHolder();
        }

        public void remove()
        {
          throw new UnsupportedOperationException();
        }
      };
    }

    public void reorder(List<SetupTaskPerformer> allPerformers)
    {
      List<Control> controls = new ArrayList<Control>();
      Map<FieldHolderRecord, Set<FieldHolderRecord>> ruleUses = new LinkedHashMap<FieldHolderRecord, Set<FieldHolderRecord>>();
      LOOP: for (FieldHolderRecord fieldHolderRecord : fields)
      {
        FieldHolder fieldHolder = fieldHolderRecord.getFieldHolder();
        Control control = fieldHolder.getControl();
        if (control != null)
        {
          controls.add(control);
          for (VariableTask variable : fieldHolder.getVariables())
          {
            for (SetupTaskPerformer performer : allPerformers)
            {
              EAttribute eAttribute = performer.getAttributeRuleVariableData(variable);
              if (eAttribute != null)
              {
                CollectionUtil.addAll(ruleUses, fieldHolderRecord, Collections.<FieldHolderRecord> emptySet());
                continue LOOP;
              }
            }
          }

          // for (VariableTask variable : fieldHolder.getVariables())
          // {
          // for (SetupTaskPerformer performer : allPerformers)
          // {
          // EStructuralFeature.Setting setting = performer.getImpliedVariableData(variable);
          // if (setting != null)
          // {
          // continue LOOP;
          // }
          // }
          // }

          for (VariableTask variable : fieldHolder.getVariables())
          {
            for (SetupTaskPerformer performer : allPerformers)
            {
              VariableTask dependantVariable = performer.getRuleVariableData(variable);
              if (dependantVariable != null)
              {
                VariableTask ruleVariable = performer.getRuleVariable(dependantVariable);
                if (ruleVariable != null)
                {
                  FieldHolderRecord dependantFieldHolderRecord = getFieldHolderRecord(getURI(ruleVariable));
                  if (dependantFieldHolderRecord != null)
                  {
                    CollectionUtil.add(ruleUses, dependantFieldHolderRecord, fieldHolderRecord);
                    continue LOOP;
                  }
                }
              }
            }
          }
        }
      }

      int fieldsSize = fields.size();
      if (fieldsSize > 1)
      {
        int index = 0;
        int maxPosition = fieldsSize - 1;
        for (Map.Entry<FieldHolderRecord, Set<FieldHolderRecord>> entry : ruleUses.entrySet())
        {
          FieldHolderRecord fieldHolderRecord = entry.getKey();
          fields.move(index++, fieldHolderRecord);
          Set<FieldHolderRecord> fieldHolderRecords = entry.getValue();
          for (FieldHolderRecord dependantFieldHolderRecord : fieldHolderRecords)
          {
            fields.move(Math.min(index++, maxPosition), dependantFieldHolderRecord);
          }
        }
      }

      int size = controls.size();
      if (size > 1)
      {
        List<Control> children = Arrays.asList(composite.getChildren());

        int controlOffset = 0;
        for (Control child : children)
        {
          if (controls.contains(child))
          {
            break;
          }

          ++controlOffset;
        }

        Control target = children.get(PropertyField.NUM_COLUMNS - 1);
        int count = 0;
        for (FieldHolder fieldHolder : this)
        {
          Control control = fieldHolder.getControl();
          if (control != null)
          {
            int index = children.indexOf(control) - controlOffset;
            Control newTarget = null;
            for (int j = PropertyField.NUM_COLUMNS - 1; j >= 0; --j)
            {
              Control child = children.get(index + j);
              if (newTarget == null)
              {
                newTarget = child;
                if (index == count)
                {
                  break;
                }
              }

              child.moveBelow(target);
            }

            target = newTarget;
            count += PropertyField.NUM_COLUMNS;
          }
        }
      }
    }

    public void cleanup(Set<URI> uris)
    {
      LOOP: for (FieldHolderRecord fieldHolderRecord : fields)
      {
        for (URI uri : fieldHolderRecord.getVariableURIs())
        {
          if (uris.contains(uri))
          {
            continue LOOP;
          }
        }

        FieldHolder fieldHolder = fieldHolderRecord.getFieldHolder();
        if (fieldHolder.getVariables().isEmpty() && !fieldHolder.isDirty())
        {
          fieldHolder.dispose();
        }
      }
    }

    public URI getURI(VariableTask variable)
    {
      String name = variable.getName();
      if (variable.getAnnotation(AnnotationConstants.ANNOTATION_GLOBAL_VARIABLE) != null)
      {
        return URI.createURI("#" + name);
      }

      Resource resource = variable.eResource();
      URI uri;
      if (resource == null)
      {
        uri = URI.createURI("#");
      }
      else
      {
        EObject eObject = resource.getContents().get(0);
        if (eObject instanceof Installation || eObject instanceof Workspace)
        {
          uri = URI.createURI(resource.getURI().lastSegment()).appendFragment(resource.getURIFragment(variable));
        }
        else
        {
          uri = EcoreUtil.getURI(variable);
        }
      }

      uri = uri.appendFragment(uri.fragment() + "~" + name);
      return uri;
    }

    private FieldHolderRecord getFieldHolderRecord(URI uri)
    {
      for (FieldHolderRecord fieldHolderRecord : fields)
      {
        if (fieldHolderRecord.getVariableURIs().contains(uri))
        {
          return fieldHolderRecord;
        }
      }

      return null;
    }

    public void associate(VariableTask variable, FieldHolder fieldHolder)
    {
      URI uri = getURI(variable);
      for (FieldHolderRecord fieldHolderRecord : fields)
      {
        if (fieldHolderRecord.getFieldHolder() == fieldHolder)
        {
          fieldHolderRecord.getVariableURIs().add(uri);
          break;
        }
      }
    }

    public FieldHolder getFieldHolder(VariableTask variable, boolean demandCreate, boolean includeDisposed)
    {
      URI uri = getURI(variable);
      FieldHolderRecord fieldHolderRecord = getFieldHolderRecord(uri);
      FieldHolder fieldHolder = null;
      if (fieldHolderRecord == null)
      {
        if (!demandCreate)
        {
          return null;
        }

        fieldHolderRecord = new FieldHolderRecord();
        fieldHolderRecord.getVariableURIs().add(uri);
        fields.add(fieldHolderRecord);
      }
      else
      {
        fieldHolder = fieldHolderRecord.getFieldHolder();
        if (fieldHolder.isDisposed())
        {
          if (includeDisposed)
          {
            return fieldHolder;
          }

          if (!demandCreate)
          {
            return null;
          }

          fieldHolder = null;
        }
      }

      if (fieldHolder == null)
      {
        fieldHolder = new FieldHolder(variable);
        fieldHolderRecord.setFieldHolder(fieldHolder);
      }
      else if (!updating)
      {
        fieldHolder.add(variable);
      }

      return fieldHolder;
    }

    @Override
    public String toString()
    {
      return fields.toString();
    }
  }

  /**
   * A class for delayed validation.
   * @author Ed Merks
   */
  private class Validator implements Runnable
  {
    private boolean canceled;

    private boolean dispatched;

    private boolean redispatch;

    private boolean clearSpecialFieldHolders;

    public void run()
    {
      if (!canceled && !getShell().isDisposed())
      {
        dispatched = false;
        if (redispatch || performerCreationJob != null)
        {
          if (performerCreationJob != null)
          {
            performerCreationJob.cancel();
          }

          schedule(clearSpecialFieldHolders);
        }
        else
        {
          if (clearSpecialFieldHolders)
          {
            clearSpecialFieldHolders();
            clearSpecialFieldHolders = false;
          }

          validate();
        }
      }
    }

    public void schedule(boolean clearSpecialFieldHolders)
    {
      canceled = false;

      if (clearSpecialFieldHolders)
      {
        this.clearSpecialFieldHolders = true;
      }

      if (dispatched)
      {
        redispatch = true;
      }
      else
      {
        dispatched = true;
        redispatch = false;

        UIUtil.timerExec(350, this);
      }
    }

    public void cancel()
    {
      canceled = true;
      dispatched = false;
      redispatch = false;
      clearSpecialFieldHolders = false;

      if (performerCreationJob != null)
      {
        performerCreationJob.cancel();
      }
    }
  }
}
