public RuleAttributeWidget(
      final RuleModeller parent, final RuleModel model, final boolean isReadOnly) {
    this.parent = parent;
    this.model = model;
    FormStyleLayout layout = new FormStyleLayout();
    // Adding metadata here, seems redundant to add a new widget for metadata. Model does handle
    // meta data separate.
    RuleMetadata[] meta = model.metadataList;
    if (meta.length > 0) {
      HorizontalPanel hp = new HorizontalPanel();
      hp.add(new SmallLabel(Constants.INSTANCE.Metadata2()));
      layout.addRow(hp);
    }
    for (int i = 0; i < meta.length; i++) {
      RuleMetadata rmd = meta[i];
      layout.addAttribute(rmd.getAttributeName(), getEditorWidget(rmd, i, isReadOnly));
    }
    RuleAttribute[] attrs = model.attributes;
    if (attrs.length > 0) {
      HorizontalPanel hp = new HorizontalPanel();
      hp.add(new SmallLabel(Constants.INSTANCE.Attributes1()));
      layout.addRow(hp);
    }
    for (int i = 0; i < attrs.length; i++) {
      RuleAttribute at = attrs[i];
      layout.addAttribute(at.getAttributeName(), getEditorWidget(at, i, isReadOnly));
    }

    initWidget(layout);
  }
  private Widget getEditorWidget(final RuleMetadata rm, final int idx, final boolean isReadOnly) {
    Widget editor;

    if (rm.getAttributeName().equals(LOCK_LHS) || rm.getAttributeName().equals(LOCK_RHS)) {
      editor =
          new InfoPopup(Constants.INSTANCE.FrozenAreas(), Constants.INSTANCE.FrozenExplanation());
    } else {
      editor = textBoxEditor(rm, isReadOnly);
    }

    DirtyableHorizontalPane horiz = new DirtyableHorizontalPane();
    horiz.add(editor);
    if (!isReadOnly) {
      horiz.add(getRemoveMetaIcon(idx));
    }

    return horiz;
  }