public void validate() {

    super.validate();
    Validity v = interfaceForm().valid();
    if (!v.valid()) {
      selectTab(INTERFACE_TAB_NAME);
      Dialog.inform(
          "Error", "Invalid or incomplete values in the interface form: " + v.reasonForIssue());
      return;
    }
    if (_privateMetaForm != null) {
      _privateMetaForm.validate();
      Validity valid = _privateMetaForm.valid();
      if (!valid.valid()) {
        selectTab(PRIVATE_META_TAB_NAME);
        Dialog.inform(
            "Error",
            "Invalid or incomplete values in the private meta form: " + valid.reasonForIssue());
        return;
      }
    }
    if (_publicMetaForm != null) {
      _publicMetaForm.validate();
      Validity valid = _publicMetaForm.valid();
      if (!valid.valid()) {
        selectTab(PUBLIC_META_TAB_NAME);
        Dialog.inform(
            "Error",
            "Invalid or incomplete values in the public meta form: " + valid.reasonForIssue());
        return;
      }
    }
  }
  public boolean valid() {

    boolean valid = super.valid();
    if (_privateMetaForm != null) {
      valid = valid && _privateMetaForm.valid().valid();
    }
    if (_publicMetaForm != null) {
      valid = valid && _publicMetaForm.valid().valid();
    }
    return valid;
  }
  private void updatePrivateMetaTab(XmlElement me, FormListener formListener) {

    if (me != null) {
      _privateMetaForm = XmlMetaForm.formFor(me, mode());
      if (formListener != null) {
        _privateMetaForm.addListener(formListener);
      }
      putTab(PRIVATE_META_TAB_NAME, new ScrollPanel(_privateMetaForm, ScrollPolicy.AUTO), false);
    } else {
      removeTab(PRIVATE_META_TAB_NAME);
    }
  }
  @Override
  protected void addInterfaceFields(Form interfaceForm) {

    super.addInterfaceFields(interfaceForm);

    DataSet dso = (DataSet) object();
    Field<String> mimeTypeField =
        new Field<String>(new FieldDefinition("type", StringType.DEFAULT, "MIME Type", null, 1, 1));
    mimeTypeField.setValue(dso.type());
    interfaceForm.add(mimeTypeField);

    FieldGroup fg =
        new FieldGroup(new FieldDefinition("source", ConstantType.DEFAULT, null, null, 1, 1));
    Field<SourceType> sourceTypeField =
        new Field<SourceType>(
            new FieldDefinition("type", StringType.DEFAULT, "Source Type", null, 1, 1));
    sourceTypeField.setValue(dso.sourceType());
    fg.add(sourceTypeField);
    interfaceForm.add(fg);
    Field<String> vidField =
        new Field<String>(new FieldDefinition("vid", StringType.DEFAULT, null, null, 1, 1));
    vidField.setValue(dso.vid());
    interfaceForm.add(vidField);
    if (dso instanceof PrimaryDataSet) {
      FieldGroup fgAcquisition =
          new FieldGroup(
              new FieldDefinition("acquisition", ConstantType.DEFAULT, null, null, 1, 1));
      FieldGroup fgSubject =
          new FieldGroup(new FieldDefinition("subject", ConstantType.DEFAULT, null, null, 1, 1));
      Field<String> subjectIdField =
          new Field<String>(new FieldDefinition("id", StringType.DEFAULT, null, null, 1, 1));
      subjectIdField.setValue(((PrimaryDataSet) dso).subjectId());
      fgSubject.add(subjectIdField);
      Field<String> subjectStateField =
          new Field<String>(new FieldDefinition("state", StringType.DEFAULT, null, null, 1, 1));
      subjectStateField.setValue(((PrimaryDataSet) dso).subjectState());
      fgSubject.add(subjectStateField);
      fgAcquisition.add(fgSubject);
      interfaceForm.add(fgAcquisition);
    }
    if (dso instanceof DerivationDataSet) {
      FieldGroup fgDerivation =
          new FieldGroup(new FieldDefinition("derivation", ConstantType.DEFAULT, null, null, 1, 1));
      FieldGroup fgMethod =
          new FieldGroup(new FieldDefinition("method", ConstantType.DEFAULT, null, null, 1, 1));
      Field<String> methodIdField =
          new Field<String>(new FieldDefinition("id", StringType.DEFAULT, "Method id", null, 1, 1));
      methodIdField.setValue(((DerivationDataSet) dso).methodId());
      fgMethod.add(methodIdField);
      Field<String> methodStepField =
          new Field<String>(
              new FieldDefinition("step", StringType.DEFAULT, "Method step", null, 1, 1));
      methodStepField.setValue(((DerivationDataSet) dso).methodStep());
      fgMethod.add(methodStepField);
      fgDerivation.add(fgMethod);
      interfaceForm.add(fgDerivation);
    }
    if (dso.data() != null) {
      interfaceForm.add(DataContentFieldGroup.fieldGroupFor(dso.data()));
    }
  }
  @Override
  protected void addToInterfaceForm(final Form interfaceForm) {

    //
    // data-use field
    //
    Field<String> dataUseField =
        new Field<String>(
            new FieldDefinition(
                "data-use",
                new EnumerationType<String>(DataUseEnum.get()),
                "Data Use",
                null,
                0,
                1));
    dataUseField.setValue(subject().dataUse());
    if (mode() != FormEditMode.READ_ONLY) {
      dataUseField.addListener(
          new FormItemListener<String>() {

            @Override
            public void itemValueChanged(FormItem<String> f) {

              subject().setDataUse(f.value());
            }

            @Override
            public void itemPropertyChanged(FormItem<String> f, FormItem.Property p) {}
          });
    }
    interfaceForm.add(dataUseField);

    //
    // method field
    //
    if (mode() == FormEditMode.READ_ONLY || mode() == FormEditMode.UPDATE) {
      // We do not allow to change subject method at the moment.
      Field<MethodRef> methodField =
          new Field<MethodRef>(
              new FieldDefinition("method", ConstantType.DEFAULT, "Method", null, 1, 1));
      methodField.setValue(subject().method());
      interfaceForm.add(methodField);
    } else {
      subject()
          .availableMethods(
              new ObjectResolveHandler<List<MethodRef>>() {
                @Override
                public void resolved(List<MethodRef> ms) {

                  if (ms != null) {
                    if (!ms.isEmpty()) {
                      Field<MethodRef> methodField;
                      if (ms.size() == 1) {
                        subject().setMethod(ms.get(0));
                        methodField =
                            new Field<MethodRef>(
                                new FieldDefinition(
                                    "method", ConstantType.DEFAULT, "Method", null, 1, 1));
                      } else {
                        String projectId = IDUtil.getParentId(subject().id());
                        EnumerationType<MethodRef> methodEnumType =
                            new EnumerationType<MethodRef>(
                                new MethodEnum(subject().proute(), projectId));
                        methodField =
                            new Field<MethodRef>(
                                new FieldDefinition(
                                    "method", methodEnumType, "Method", null, 1, 1));
                        methodField.addListener(
                            new FormItemListener<MethodRef>() {

                              @Override
                              public void itemValueChanged(FormItem<MethodRef> f) {

                                if (f.value() != null) {
                                  subject().setMethod(f.value());
                                  updatePrivateMetaTab();
                                  updatePublicMetaTab();
                                }
                              }

                              @Override
                              public void itemPropertyChanged(
                                  FormItem<MethodRef> f, FormItem.Property p) {}
                            });
                      }
                      methodField.setValue(subject().method());
                      updatePrivateMetaTab();
                      updatePublicMetaTab();
                      interfaceForm.add(methodField);
                    }
                  }
                }
              });
    }
  }
  private ProjectMemberRoleSelector(
      final int x, final int y, int width, int height, final RoleSelectionListener rsl) {

    VerticalPanel vp = new VerticalPanel();
    vp.setBorderRadius(3);
    vp.setBoxShadow(1, 1, 5, 5, "rgba(0,0,0,0.2)");
    vp.fitToParent();

    HorizontalPanel header = new HorizontalPanel();
    header.setWidth100();
    header.setHeight(20);
    header.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
    header.setBackgroundImage(
        new LinearGradient(LinearGradient.Orientation.TOP_TO_BOTTOM, "#cdcdcd", "#979797"));

    Label headerLabel = new Label("Select project role and data-use ...");
    headerLabel.setFontSize(10);
    headerLabel.setFontWeight(FontWeight.BOLD);
    headerLabel.setHeight100();
    header.add(headerLabel);

    vp.add(header);

    final Form form =
        new Form() {

          @Override
          public Validity valid() {

            Validity v = super.valid();
            if (!v.valid()) {
              return v;
            }
            if ((_role.equals(ProjectRole.MEMBER) || _role.equals(ProjectRole.GUEST))
                && _dataUse == null) {
              return new Validity() {
                @Override
                public boolean valid() {

                  return false;
                }

                @Override
                public String reasonForIssue() {

                  return "data-use is not set for " + _role;
                }
              };
            }
            return v;
          }
        };
    form.fitToParent();
    Field<ProjectRole> roleField =
        new Field<ProjectRole>(
            new FieldDefinition(
                "Role", ProjectRole.asEnumerationType(), "Project role", null, 1, 1));
    roleField.addListener(
        new FormItemListener<ProjectRole>() {

          @Override
          public void itemValueChanged(FormItem<ProjectRole> f) {

            _role = f.value();
            if (form.valid().valid()) {
              _okButton.enable();
            } else {
              _okButton.disable();
            }
          }

          @Override
          public void itemPropertyChanged(FormItem<ProjectRole> f, Property property) {}
        });
    form.add(roleField);
    Field<DataUse> dataUseField =
        new Field<DataUse>(
            new FieldDefinition(
                "Data Use", DataUse.asEnumerationType(), "Project data use", null, 0, 1));
    dataUseField.addListener(
        new FormItemListener<DataUse>() {

          @Override
          public void itemValueChanged(FormItem<DataUse> f) {

            _dataUse = f.value();
            if (form.valid().valid()) {
              _okButton.enable();
            } else {
              _okButton.disable();
            }
          }

          @Override
          public void itemPropertyChanged(FormItem<DataUse> f, Property property) {}
        });
    form.add(dataUseField);
    form.render();
    vp.add(form);

    ButtonBar bb = new ButtonBar(ButtonBar.Position.BOTTOM, ButtonBar.Alignment.RIGHT);
    bb.setHeight(26);
    _okButton = new Button("OK");
    _okButton.disable();
    _okButton.addClickHandler(
        new ClickHandler() {

          @Override
          public void onClick(ClickEvent event) {

            _succeeded = true;
            _pp.hide();
          }
        });
    bb.add(_okButton);
    Button cancelButton = new Button("Cancel");
    cancelButton.addClickHandler(
        new ClickHandler() {

          @Override
          public void onClick(ClickEvent event) {

            _succeeded = false;
            _pp.hide();
          }
        });
    bb.add(cancelButton);
    bb.setMarginRight(5);
    vp.add(bb);

    _pp = new PopupPanel();
    _pp.setAutoHideEnabled(true);
    _pp.setWidth(width > MIN_WIDTH ? width : MIN_WIDTH);
    _pp.setHeight(height > MIN_HEIGHT ? height : MIN_HEIGHT);
    _pp.setBackgroundColour("#f0f0f0");
    _pp.setBorder(1, "#a0a080");
    _pp.setContent(vp);
    _pp.addCloseHander(
        new PopupCloseHandler() {

          @Override
          public void closed(PopupPanel p) {

            if (_succeeded) {
              rsl.roleSelected(_role, _dataUse);
            } else {
              rsl.roleSelected(null, null);
            }
          }
        });
    _pp.setPopupPositionAndShow(
        new PositionCallback() {

          @Override
          public void setPosition(int offsetWidth, int offsetHeight) {

            _pp.setPopupPosition(x - offsetWidth / 2, y - offsetHeight / 2);
          }
        });
  }
  private void updateForm() {

    if (_form != null) {
      removeMustBeValid(_form);
    }

    _formSP.clear();

    _form = new Form(editable() ? FormEditMode.UPDATE : FormEditMode.READ_ONLY);
    int nbCols = 1;
    ACLOperator op = filter().operator();
    if (op != null) {
      if (ACLOperator.FOR_ROLE.equals(op)) {
        nbCols = 2;
      }
    }
    _form.setNumberOfColumns(nbCols);
    _form.setShowLabels(false);
    _form.setShowDescriptions(false);
    _form.setShowHelp(false);

    Field<ACLOperator> opField =
        new Field<ACLOperator>(
            new FieldDefinition(
                "operator",
                new EnumerationType<ACLOperator>(ACLOperator.VALUES),
                null,
                null,
                1,
                1));
    opField.setInitialValue(filter().operator(), false);
    opField.addListener(
        new FormItemListener<ACLOperator>() {

          @Override
          public void itemValueChanged(FormItem<ACLOperator> f) {
            if (ACLOperator.ACTOR_INVALID.equals(f.value())) {
              filter().setActorInvalid();
            } else {
              filter().setForRole(filter().role());
            }
            updateForm();
          }

          @Override
          public void itemPropertyChanged(FormItem<ACLOperator> f, Property property) {}
        });
    _form.add(opField);

    if (ACLOperator.FOR_ROLE.equals(filter().operator())) {

      Field<RoleRef> roleField =
          new Field<RoleRef>(
              new FieldDefinition(
                  "role",
                  new EnumerationType<RoleRef>(new RoleEnumerationDataSource()),
                  null,
                  null,
                  1,
                  1));
      roleField.setInitialValue(new RoleRef(filter().role(), null, Scope.REPOSITORY), false);
      roleField.addListener(
          new FormItemListener<RoleRef>() {

            @Override
            public void itemValueChanged(FormItem<RoleRef> f) {
              filter().setForRole(f.value() == null ? null : f.value().name());
            }

            @Override
            public void itemPropertyChanged(FormItem<RoleRef> f, Property property) {}
          });
      FieldRenderOptions fro = new FieldRenderOptions();
      fro.setWidth(300);
      roleField.setRenderOptions(fro);
      _form.add(roleField);
    }
    addMustBeValid(_form);
    _form.render();
    _formSP.setContent(_form);
  }