feature[TW19451]: Confirm transition validation

Change-Id: I7f04252232da2721351487449e069bb19daa2508
diff --git a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workdef/IAtsWorkDefinitionService.java b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workdef/IAtsWorkDefinitionService.java
index ddfcd34..b6e68e9 100644
--- a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workdef/IAtsWorkDefinitionService.java
+++ b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/workdef/IAtsWorkDefinitionService.java
@@ -106,4 +106,9 @@
 
    IAtsWorkDefinition computeWorkDefinition(IAtsWorkItem workItem, boolean useAttr);
 
+   /**
+    * @return widget defintions from header and all states
+    */
+   Collection<IAtsWidgetDefinition> getWidgets(IAtsWorkDefinition workDef);
+
 }
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/AtsWorkDefinitionServiceImpl.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/AtsWorkDefinitionServiceImpl.java
index dc81df3..e717531 100644
--- a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/AtsWorkDefinitionServiceImpl.java
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/AtsWorkDefinitionServiceImpl.java
@@ -44,6 +44,7 @@
 import org.eclipse.osee.ats.api.workdef.IAtsWorkDefinition;
 import org.eclipse.osee.ats.api.workdef.IAtsWorkDefinitionBuilder;
 import org.eclipse.osee.ats.api.workdef.IAtsWorkDefinitionService;
+import org.eclipse.osee.ats.api.workdef.model.HeaderDefinition;
 import org.eclipse.osee.ats.api.workdef.model.RuleDefinitionOption;
 import org.eclipse.osee.ats.api.workflow.IAtsGoal;
 import org.eclipse.osee.ats.api.workflow.IAtsTask;
@@ -344,16 +345,36 @@
       return widgets;
    }
 
-   private static void getWidgets(IAtsStateDefinition stateDef, List<IAtsWidgetDefinition> widgets, List<IAtsLayoutItem> stateItems) {
-      for (IAtsLayoutItem stateItem : stateItems) {
-         if (stateItem instanceof IAtsCompositeLayoutItem) {
-            getWidgets(stateDef, widgets, ((IAtsCompositeLayoutItem) stateItem).getaLayoutItems());
-         } else if (stateItem instanceof IAtsWidgetDefinition) {
-            widgets.add((IAtsWidgetDefinition) stateItem);
+   private static void getWidgets(IAtsStateDefinition stateDef, List<IAtsWidgetDefinition> widgets, List<IAtsLayoutItem> layoutItems) {
+      for (IAtsLayoutItem lItem : layoutItems) {
+         if (lItem instanceof IAtsCompositeLayoutItem) {
+            getWidgets(stateDef, widgets, ((IAtsCompositeLayoutItem) lItem).getaLayoutItems());
+         } else if (lItem instanceof IAtsWidgetDefinition) {
+            widgets.add((IAtsWidgetDefinition) lItem);
          }
       }
    }
 
+   private static void getWidgets(HeaderDefinition headerDef, List<IAtsWidgetDefinition> widgets, List<IAtsLayoutItem> layoutItems) {
+      for (IAtsLayoutItem lItem : layoutItems) {
+         if (lItem instanceof IAtsCompositeLayoutItem) {
+            getWidgets(headerDef, widgets, ((IAtsCompositeLayoutItem) lItem).getaLayoutItems());
+         } else if (lItem instanceof IAtsWidgetDefinition) {
+            widgets.add((IAtsWidgetDefinition) lItem);
+         }
+      }
+   }
+
+   @Override
+   public Collection<IAtsWidgetDefinition> getWidgets(IAtsWorkDefinition workDef) {
+      List<IAtsWidgetDefinition> widgets = new ArrayList<>();
+      getWidgets(workDef.getHeaderDef(), widgets, workDef.getHeaderDef().getLayoutItems());
+      for (IAtsStateDefinition stateDef : workDef.getStates()) {
+         getWidgets(stateDef, widgets, stateDef.getLayoutItems());
+      }
+      return widgets;
+   }
+
    @Override
    public boolean hasWidgetNamed(IAtsStateDefinition stateDef, String name) {
       for (IAtsWidgetDefinition widgetDef : getWidgetsFromLayoutItems(stateDef)) {
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/internal/workdefs/WorkDefTeamDemoChangeRequest.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/internal/workdefs/WorkDefTeamDemoChangeRequest.java
index 09a441d..48b95a2 100644
--- a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/internal/workdefs/WorkDefTeamDemoChangeRequest.java
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/internal/workdefs/WorkDefTeamDemoChangeRequest.java
@@ -48,7 +48,7 @@
          .andColor(StateColor.BLACK) //
          .andLayout( //
 
-            new WidgetDefinition("Found-In Version", "XFoundInVersionWidget"), //
+            new WidgetDefinition("Found-In Version", "XFoundInVersionWithPersistWidget"), //
             new WidgetDefinition("Create/Open Change Request Analysis Workflow", "XCreateEscapementDemoWfXButton"), //
 
             new WidgetDefinition(AtsAttributeTypes.Description, "XTextDam", FILL_VERTICALLY, REQUIRED_FOR_TRANSITION,
@@ -69,7 +69,7 @@
          .andColor(StateColor.BLACK) //
          .andLayout( //
 
-            new WidgetDefinition("Found-In Version", "XFoundInVersionWidget"), //
+            new WidgetDefinition("Found-In Version", "XFoundInVersionWithPersistWidget"), //
             new WidgetDefinition("Create/Open Change Request Analysis Workflow", "XCreateEscapementDemoWfXButton"), //
 
             new WidgetDefinition(AtsAttributeTypes.Description, "XTextDam", FILL_VERTICALLY, REQUIRED_FOR_TRANSITION,
@@ -115,7 +115,7 @@
          .andRules(RuleDefinitionOption.AllowEditToAll, RuleDefinitionOption.AddDecisionValidateBlockingReview) //
          .andColor(StateColor.DARK_GREEN) //
          .andLayout( //
-            new WidgetDefinition("Sibling Workflows", "XSiblingWorldWidget"));
+            new WidgetDefinition("Sibling Workflows", "XTaskEstSiblingWorldDemoWidget"));
 
       bld.andState(6, "Cancelled", StateType.Cancelled) //
          .andRules(RuleDefinitionOption.AllowEditToAll) //
diff --git a/plugins/org.eclipse.osee.ats.ide.integration.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.osee.ats.ide.integration.tests/META-INF/MANIFEST.MF
index 7968699..ceaf2b8 100644
--- a/plugins/org.eclipse.osee.ats.ide.integration.tests/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.osee.ats.ide.integration.tests/META-INF/MANIFEST.MF
@@ -168,4 +168,5 @@
  org.osgi.framework,
  org.osgi.service.event
 Service-Component: OSGI-INF/*.xml
+Export-Package: org.eclipse.osee.ats.ide.integration.tests.ats.workdef
 
diff --git a/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/column/FoundInVersionColumnTest.java b/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/column/FoundInVersionColumnTest.java
index 530bb81..54e71be 100644
--- a/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/column/FoundInVersionColumnTest.java
+++ b/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/column/FoundInVersionColumnTest.java
@@ -20,7 +20,7 @@
 import org.eclipse.osee.ats.ide.column.FoundInVersionColumnUI;
 import org.eclipse.osee.ats.ide.integration.tests.AtsApiService;
 import org.eclipse.osee.ats.ide.integration.tests.util.DemoTestUtil;
-import org.eclipse.osee.ats.ide.util.widgets.XFoundInVersionWidget;
+import org.eclipse.osee.ats.ide.util.widgets.XFoundInVersionWithPersistWidget;
 import org.eclipse.osee.ats.ide.workflow.teamwf.TeamWorkFlowArtifact;
 import org.eclipse.osee.framework.logging.SevereLoggingMonitor;
 import org.eclipse.osee.support.test.util.TestUtil;
@@ -45,7 +45,7 @@
 
       // FIV set
       IAtsChangeSet changes = AtsApiService.get().createChangeSet("Update Found-In-Version Test");
-      changes.setRelation(codeArt, XFoundInVersionWidget.FOUND_VERSION_RELATION, demoVersion);
+      changes.setRelation(codeArt, XFoundInVersionWithPersistWidget.FOUND_VERSION_RELATION, demoVersion);
       changes.executeIfNeeded();
       Assert.assertEquals(demoVersion.toString(),
          FoundInVersionColumnUI.getInstance().getColumnText(codeArt, FoundInVersionColumnUI.getInstance(), 0));
diff --git a/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/workdef/AtsTest_WorkDef_Suite.java b/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/workdef/AtsTest_WorkDef_Suite.java
index fab4308..d7cf85d 100644
--- a/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/workdef/AtsTest_WorkDef_Suite.java
+++ b/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/workdef/AtsTest_WorkDef_Suite.java
@@ -19,7 +19,7 @@
 import org.junit.runners.Suite;
 
 @RunWith(Suite.class)
-@Suite.SuiteClasses({AtsWorkDefinitionServiceImplTest.class})
+@Suite.SuiteClasses({AtsWorkDefinitionServiceImplTest.class, AtsWorkDefinitionXWidgetTest.class})
 
 /**
  * @author Donald G. Dunne
diff --git a/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/workdef/AtsWorkDefinitionXWidgetTest.java b/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/workdef/AtsWorkDefinitionXWidgetTest.java
new file mode 100644
index 0000000..c64a434
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/workdef/AtsWorkDefinitionXWidgetTest.java
@@ -0,0 +1,65 @@
+/*********************************************************************
+ * Copyright (c) 2021 Boeing
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Boeing - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.osee.ats.ide.integration.tests.ats.workdef;
+
+import org.eclipse.osee.ats.api.AtsApi;
+import org.eclipse.osee.ats.api.workdef.IAtsWidgetDefinition;
+import org.eclipse.osee.ats.api.workdef.IAtsWorkDefinition;
+import org.eclipse.osee.ats.ide.integration.tests.AtsApiService;
+import org.eclipse.osee.framework.jdk.core.result.XResultData;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.ui.skynet.widgets.XOption;
+import org.eclipse.osee.framework.ui.skynet.widgets.XWidget;
+import org.eclipse.osee.framework.ui.skynet.widgets.util.DefaultXWidgetOptionResolver;
+import org.eclipse.osee.framework.ui.skynet.widgets.util.FrameworkXWidgetProvider;
+import org.eclipse.osee.framework.ui.skynet.widgets.util.SwtXWidgetRenderer;
+import org.eclipse.osee.framework.ui.skynet.widgets.util.XWidgetRendererItem;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test that all XWidgetName values specified in Workflow Definitions are provided by an IXWidgetProvider
+ *
+ * @author Donald G. Dunne
+ */
+public class AtsWorkDefinitionXWidgetTest {
+
+   @Test
+   public void workDefXWidgetTest() {
+
+      AtsApi atsApi = AtsApiService.get();
+      XResultData rd = new XResultData();
+      for (IAtsWorkDefinition workDef : atsApi.getWorkDefinitionService().getAllWorkDefinitions()) {
+         for (IAtsWidgetDefinition widgetDef : atsApi.getWorkDefinitionService().getWidgets(workDef)) {
+            String xWidgetName = widgetDef.getXWidgetName();
+            if (Strings.isValid(xWidgetName)) {
+               XWidget widget = getWidget(xWidgetName);
+               if (widget == null || widget.getLabel().contains("Unhandled XWidget")) {
+                  rd.errorf("Widget not found for [%s] in WorkDef %s\n", xWidgetName, workDef.toStringWithId());
+               }
+            }
+         }
+      }
+      Assert.assertTrue(rd.toString(), rd.isSuccess());
+
+   }
+
+   public XWidget getWidget(String xWidgetName) {
+      SwtXWidgetRenderer dynamicXWidgetLayout = new SwtXWidgetRenderer(null, new DefaultXWidgetOptionResolver());
+      XWidgetRendererItem dummyItem = new XWidgetRendererItem(dynamicXWidgetLayout, XOption.NONE);
+      XWidget widget = FrameworkXWidgetProvider.getXWidget(dummyItem, xWidgetName, "IsInTest", null);
+      return widget;
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/header/WfeAttachmentsComposite.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/header/WfeAttachmentsComposite.java
index db8a3d2..aa124bb 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/header/WfeAttachmentsComposite.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/header/WfeAttachmentsComposite.java
@@ -68,6 +68,7 @@
    private final Map<Long, Composite> relIdToComp = new HashMap<>();
    private final Set<Long> existingRels = new HashSet<>();
    private final AtsApi atsApi;
+   private Label label;
 
    public WfeAttachmentsComposite(Composite parent, int style, WorkflowEditor editor) {
       super(parent, style);
@@ -82,8 +83,8 @@
       setLayoutData(gd);
       editor.getToolkit().adapt(this);
 
-      Label label = new Label(this, SWT.NONE);
-      label.setText("Attachments: ");
+      label = new Label(this, SWT.NONE);
+      label.setText("No Attachments");
       label.setBackground(Displays.getSystemColor(SWT.COLOR_WHITE));
       label.setFont(FontManager.getCourierNew12Bold());
 
@@ -137,6 +138,7 @@
             createDeleteHyperlink(thisArt, thatArt, relation, lComp, editor);
 
             linkHandled.add(supportEntry.getKey().getId());
+            label.setText("Attachments: ");
          } catch (Exception ex) {
             OseeLog.log(Activator.class, Level.WARNING, "Error showing link " + supportEntry.getKey(), ex);
          }
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/AtsWidgetProvider.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/AtsWidgetProvider.java
index 7c3a81ce..f0b0c44 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/AtsWidgetProvider.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/AtsWidgetProvider.java
@@ -87,12 +87,12 @@
          toReturn = new XStateCombo();
       } else if (widgetName.equals(XStateSearchCombo.WIDGET_ID)) {
          toReturn = new XStateSearchCombo();
-      } else if (widgetName.equals(XFoundInVersionWidget.WIDGET_ID)) {
-         toReturn = new XFoundInVersionWidget(name);
-      } else if (widgetName.equals(XTargetedVersionWidget.WIDGET_ID)) {
-         toReturn = new XTargetedVersionWidget(name);
-      } else if (widgetName.equals(XIntroducedInVersionWidget.WIDGET_ID)) {
-         toReturn = new XIntroducedInVersionWidget(name);
+      } else if (widgetName.equals(XFoundInVersionWithPersistWidget.WIDGET_ID)) {
+         toReturn = new XFoundInVersionWithPersistWidget(name);
+      } else if (widgetName.equals(XTargetedVersionWithPersistWidget.WIDGET_ID)) {
+         toReturn = new XTargetedVersionWithPersistWidget(name);
+      } else if (widgetName.equals(XIntroducedInVersionWithPersistWidget.WIDGET_ID)) {
+         toReturn = new XIntroducedInVersionWithPersistWidget(name);
       } else if (widgetName.equals(XCommitManager.WIDGET_NAME)) {
          toReturn = new XCommitManager();
       } else if (widgetName.equals(XWorkingBranchLabel.WIDGET_NAME)) {
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XFoundInVersionWidget.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XFoundInVersionWithPersistWidget.java
similarity index 74%
rename from plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XFoundInVersionWidget.java
rename to plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XFoundInVersionWithPersistWidget.java
index 8fab991..86908f7 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XFoundInVersionWidget.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XFoundInVersionWithPersistWidget.java
@@ -17,15 +17,17 @@
 import org.eclipse.osee.framework.core.data.RelationTypeSide;
 
 /**
+ * Select and persist with clear button
+ *
  * @author Jeremy A. Midvidy
  * @author Donald G. Dunne
  */
-public class XFoundInVersionWidget extends XHyperlabelVersionSelection {
+public class XFoundInVersionWithPersistWidget extends XHyperlabelVersionSelectionWithPersist {
 
-   public static final String WIDGET_ID = XFoundInVersionWidget.class.getSimpleName();
+   public static final String WIDGET_ID = XFoundInVersionWithPersistWidget.class.getSimpleName();
    public static RelationTypeSide FOUND_VERSION_RELATION = AtsRelationTypes.TeamWorkflowToFoundInVersion_Version;
 
-   public XFoundInVersionWidget(String label) {
+   public XFoundInVersionWithPersistWidget(String label) {
       super("Found In Version", FOUND_VERSION_RELATION);
    }
 
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XHyperlabelVersionSelection.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XHyperlabelVersionSelection.java
index c970d89..ce921c6 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XHyperlabelVersionSelection.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XHyperlabelVersionSelection.java
@@ -1,5 +1,5 @@
 /*********************************************************************
- * Copyright (c) 2017 Boeing
+ * Copyright (c) 2021 Boeing
  *
  * This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License 2.0
@@ -14,82 +14,61 @@
 package org.eclipse.osee.ats.ide.util.widgets;
 
 import java.util.Collection;
-import java.util.HashSet;
 import org.eclipse.osee.ats.api.AtsApi;
-import org.eclipse.osee.ats.api.team.IAtsTeamDefinition;
-import org.eclipse.osee.ats.api.util.IAtsChangeSet;
 import org.eclipse.osee.ats.api.version.IAtsVersion;
 import org.eclipse.osee.ats.api.version.Version;
-import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
 import org.eclipse.osee.ats.ide.internal.Activator;
 import org.eclipse.osee.ats.ide.internal.AtsApiService;
 import org.eclipse.osee.ats.ide.util.widgets.dialog.VersionListDialog;
-import org.eclipse.osee.ats.ide.workflow.teamwf.TeamWorkFlowArtifact;
-import org.eclipse.osee.framework.core.data.RelationTypeSide;
-import org.eclipse.osee.framework.core.data.TransactionToken;
-import org.eclipse.osee.framework.core.util.Result;
-import org.eclipse.osee.framework.jdk.core.util.Collections;
 import org.eclipse.osee.framework.logging.OseeLevel;
 import org.eclipse.osee.framework.logging.OseeLog;
-import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
-import org.eclipse.osee.framework.ui.skynet.widgets.ArtifactWidget;
 import org.eclipse.osee.framework.ui.skynet.widgets.XHyperlinkLabelValueSelection;
 import org.eclipse.osee.framework.ui.swt.Widgets;
 
 /**
- * Single version selection dialog that persists upon selection. Clear and Close button shown by default to un-select.
+ * Single version selection dialog. No persist and no clear button. Must be implemented to provide needed inforamtion
+ * and handle method.
  *
- * @author Megumi Telles
  * @author Donald G. Dunne
  */
-public abstract class XHyperlabelVersionSelection extends XHyperlinkLabelValueSelection implements ArtifactWidget {
+public class XHyperlabelVersionSelection extends XHyperlinkLabelValueSelection {
 
    public static final String WIDGET_ID = XHyperlabelVersionSelection.class.getSimpleName();
-   Collection<Version> selectedVersions = new HashSet<>();
-   Collection<IAtsVersion> versions;
+   Version selectedVersion = null;
+   Collection<IAtsVersion> selectableVersions;
    VersionListDialog dialog = null;
-   private Artifact artifact;
-   private final RelationTypeSide relType;
    protected AtsApi atsApi;
-   protected boolean removeAllAllowed = true;
 
-   public XHyperlabelVersionSelection(String label, RelationTypeSide relType) {
+   public XHyperlabelVersionSelection(String label) {
       super(label);
-      this.relType = relType;
       atsApi = AtsApiService.get();
    }
 
-   public Collection<Version> getSelectedVersions() {
-      return selectedVersions;
+   public Version getSelectedVersion() {
+      return selectedVersion;
    }
 
    @Override
    public Object getData() {
-      return getSelectedVersions();
+      return getSelectedVersion();
    }
 
    @Override
    public String getCurrentValue() {
-      if (getArtifact() != null) {
-         selectedVersions = (Collections.castAll(getArtifact().getRelatedArtifacts(relType)));
-      }
-      if (selectedVersions.isEmpty()) {
+      if (selectedVersion == null) {
          return "Not Set";
       }
-      return Collections.toString(",", selectedVersions);
+      return selectedVersion.getName();
    }
 
    public boolean handleClear() {
-      selectedVersions.clear();
-      IAtsChangeSet changes = AtsApiService.get().createChangeSet("Update Found-In-Version");
-      changes.unrelateAll(getArtifact(), relType);
-      changes.executeIfNeeded();
+      selectedVersion = null;
       notifyXModifiedListeners();
       return true;
    }
 
-   public void setSelectedVersions(Collection<Version> selectedVersions) {
-      this.selectedVersions = selectedVersions;
+   public void setSelectedVersion(Version selectedVersion) {
+      this.selectedVersion = selectedVersion;
       refresh();
       notifyXModifiedListeners();
    }
@@ -97,20 +76,16 @@
    @Override
    public boolean handleSelection() {
       try {
-         if (versions == null) {
+         if (selectableVersions == null) {
             dialog = new VersionListDialog("Select Version", "Select Version", getSelectableVersions());
          } else {
-            dialog = new VersionListDialog("Select Version", "Select Version", getSelectableVersions());
+            dialog = new VersionListDialog("Select Version", "Select Version", selectableVersions);
          }
-         dialog.setRemoveAllAllowed(removeAllAllowed);
+         dialog.setRemoveAllAllowed(false);
          int result = dialog.open();
          if (result == 0) {
-            IAtsChangeSet changes = AtsApiService.get().createChangeSet("Update Found-In-Version");
-            changes.setRelation(getArtifact(), relType, dialog.getSelectedFirst());
-            TransactionToken transaction = changes.executeIfNeeded();
-            if (transaction.isValid()) {
-               notifyXModifiedListeners();
-            }
+            Version version = dialog.getSelectedFirst();
+            handleSelectedVersion(version);
          }
          return true;
       } catch (Exception ex) {
@@ -119,27 +94,21 @@
       return false;
    }
 
-   private Collection<IAtsVersion> getSelectableVersions() {
-      if (artifact instanceof IAtsTeamWorkflow) {
-         IAtsTeamDefinition teamDefHoldingVersion = atsApi.getTeamDefinitionService().getTeamDefHoldingVersions(
-            ((IAtsTeamWorkflow) artifact).getTeamDefinition());
-         if (teamDefHoldingVersion != null) {
-            return atsApi.getTeamDefinitionService().getVersions(teamDefHoldingVersion);
-         }
-      }
-      return java.util.Collections.emptyList();
+   private void handleSelectedVersion(Version version) {
+      this.selectedVersion = version;
    }
 
-   public void setVersions(Collection<IAtsVersion> versions) {
-      this.versions = versions;
-      if (dialog != null) {
-         dialog.setInput(versions);
-      }
+   private Collection<IAtsVersion> getSelectableVersions() {
+      return selectableVersions;
+   }
+
+   public void setSelectableVersions(Collection<IAtsVersion> versions) {
+      this.selectableVersions = versions;
    }
 
    @Override
    public boolean isEmpty() {
-      return selectedVersions.isEmpty();
+      return selectedVersion == null;
    }
 
    public void setEnableHyperLink() {
@@ -154,39 +123,4 @@
       }
    }
 
-   @Override
-   public void setArtifact(Artifact art) {
-      if (art instanceof TeamWorkFlowArtifact) {
-         this.artifact = art;
-      }
-   }
-
-   @Override
-   public Artifact getArtifact() {
-      return this.artifact;
-   }
-
-   @Override
-   public void revert() {
-      //
-   }
-
-   @Override
-   public void saveToArtifact() {
-      //
-   }
-
-   @Override
-   public Result isDirty() {
-      return Result.FalseResult;
-   }
-
-   public boolean isRemoveAllAllowed() {
-      return removeAllAllowed;
-   }
-
-   public void setRemoveAllAllowed(boolean removeAllAllowed) {
-      this.removeAllAllowed = removeAllAllowed;
-   }
-
 }
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XHyperlabelVersionSelectionWithPersist.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XHyperlabelVersionSelectionWithPersist.java
new file mode 100644
index 0000000..8d3264e
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XHyperlabelVersionSelectionWithPersist.java
@@ -0,0 +1,187 @@
+/*********************************************************************
+ * Copyright (c) 2017 Boeing
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Boeing - initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.osee.ats.ide.util.widgets;
+
+import java.util.Collection;
+import org.eclipse.osee.ats.api.AtsApi;
+import org.eclipse.osee.ats.api.team.IAtsTeamDefinition;
+import org.eclipse.osee.ats.api.util.IAtsChangeSet;
+import org.eclipse.osee.ats.api.version.IAtsVersion;
+import org.eclipse.osee.ats.api.version.Version;
+import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
+import org.eclipse.osee.ats.ide.internal.Activator;
+import org.eclipse.osee.ats.ide.internal.AtsApiService;
+import org.eclipse.osee.ats.ide.util.widgets.dialog.VersionListDialog;
+import org.eclipse.osee.ats.ide.workflow.teamwf.TeamWorkFlowArtifact;
+import org.eclipse.osee.framework.core.data.RelationTypeSide;
+import org.eclipse.osee.framework.core.data.TransactionToken;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.ui.skynet.widgets.ArtifactWidget;
+import org.eclipse.osee.framework.ui.skynet.widgets.XHyperlinkLabelValueSelection;
+import org.eclipse.osee.framework.ui.swt.Widgets;
+
+/**
+ * Single version selection dialog that persists upon selection. Clear and Close button shown by default to un-select.
+ *
+ * @author Megumi Telles
+ * @author Donald G. Dunne
+ */
+public abstract class XHyperlabelVersionSelectionWithPersist extends XHyperlinkLabelValueSelection implements ArtifactWidget {
+
+   public static final String WIDGET_ID = XHyperlabelVersionSelectionWithPersist.class.getSimpleName();
+   Version selectedVersion = null;
+   Collection<IAtsVersion> selectableVersions;
+   VersionListDialog dialog = null;
+   private Artifact artifact;
+   private final RelationTypeSide relType;
+   protected AtsApi atsApi;
+   protected boolean removeAllAllowed = true;
+
+   public XHyperlabelVersionSelectionWithPersist(String label, RelationTypeSide relType) {
+      super(label);
+      this.relType = relType;
+      atsApi = AtsApiService.get();
+   }
+
+   public Version getSelectedVersion() {
+      return selectedVersion;
+   }
+
+   @Override
+   public Object getData() {
+      return getSelectedVersion();
+   }
+
+   @Override
+   public String getCurrentValue() {
+      if (selectedVersion == null) {
+         return "Not Set";
+      }
+      return selectedVersion.getName();
+   }
+
+   public boolean handleClear() {
+      selectedVersion = null;
+      IAtsChangeSet changes = AtsApiService.get().createChangeSet("Update " + relType.getName());
+      changes.unrelateAll(getArtifact(), relType);
+      changes.executeIfNeeded();
+      notifyXModifiedListeners();
+      return true;
+   }
+
+   public void setSelectedVersions(Version selectedVersion) {
+      this.selectedVersion = selectedVersion;
+      refresh();
+      notifyXModifiedListeners();
+   }
+
+   @Override
+   public boolean handleSelection() {
+      try {
+         if (selectableVersions == null) {
+            dialog = new VersionListDialog("Select Version", "Select Version", getSelectableVersions());
+         } else {
+            dialog = new VersionListDialog("Select Version", "Select Version", selectableVersions);
+         }
+         dialog.setRemoveAllAllowed(removeAllAllowed);
+         int result = dialog.open();
+         if (result == 0) {
+            IAtsChangeSet changes = AtsApiService.get().createChangeSet("Update " + relType.getName());
+            changes.setRelation(getArtifact(), relType, dialog.getSelectedFirst());
+            TransactionToken transaction = changes.executeIfNeeded();
+            if (transaction.isValid()) {
+               notifyXModifiedListeners();
+            }
+         }
+         return true;
+      } catch (Exception ex) {
+         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+      }
+      return false;
+   }
+
+   private Collection<IAtsVersion> getSelectableVersions() {
+      if (artifact instanceof IAtsTeamWorkflow) {
+         IAtsTeamDefinition teamDefHoldingVersion = atsApi.getTeamDefinitionService().getTeamDefHoldingVersions(
+            ((IAtsTeamWorkflow) artifact).getTeamDefinition());
+         if (teamDefHoldingVersion != null) {
+            return atsApi.getTeamDefinitionService().getVersions(teamDefHoldingVersion);
+         }
+      }
+      return java.util.Collections.emptyList();
+   }
+
+   public void setVersions(Collection<IAtsVersion> versions) {
+      this.selectableVersions = versions;
+      if (dialog != null) {
+         dialog.setInput(versions);
+      }
+   }
+
+   @Override
+   public boolean isEmpty() {
+      return selectedVersion == null;
+   }
+
+   public void setEnableHyperLink() {
+      if (Widgets.isAccessible(labelHyperlink)) {
+         labelHyperlink.setEnabled(true);
+      }
+   }
+
+   public void setDisableHyperLink() {
+      if (Widgets.isAccessible(labelHyperlink)) {
+         labelHyperlink.setEnabled(false);
+      }
+   }
+
+   @Override
+   public void setArtifact(Artifact art) {
+      if (art instanceof TeamWorkFlowArtifact) {
+         this.artifact = art;
+      }
+   }
+
+   @Override
+   public Artifact getArtifact() {
+      return this.artifact;
+   }
+
+   @Override
+   public void revert() {
+      //
+   }
+
+   @Override
+   public void saveToArtifact() {
+      //
+   }
+
+   @Override
+   public Result isDirty() {
+      return Result.FalseResult;
+   }
+
+   public boolean isRemoveAllAllowed() {
+      return removeAllAllowed;
+   }
+
+   public void setRemoveAllAllowed(boolean removeAllAllowed) {
+      this.removeAllAllowed = removeAllAllowed;
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XIntroducedInVersionWidget.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XIntroducedInVersionWithPersistWidget.java
similarity index 76%
rename from plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XIntroducedInVersionWidget.java
rename to plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XIntroducedInVersionWithPersistWidget.java
index 45bd173..39f9433 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XIntroducedInVersionWidget.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XIntroducedInVersionWithPersistWidget.java
@@ -17,19 +17,21 @@
 import org.eclipse.osee.framework.core.data.RelationTypeSide;
 
 /**
+ * Select and persist with clear button
+ *
  * @author Donald G. Dunne
  */
-public class XIntroducedInVersionWidget extends XHyperlabelVersionSelection {
+public class XIntroducedInVersionWithPersistWidget extends XHyperlabelVersionSelectionWithPersist {
 
-   public static final String WIDGET_ID = XIntroducedInVersionWidget.class.getSimpleName();
+   public static final String WIDGET_ID = XIntroducedInVersionWithPersistWidget.class.getSimpleName();
    public static RelationTypeSide INTRODUCED_VERSION_RELATION =
       AtsRelationTypes.TeamWorkflowToIntroducedInVersion_Version;
 
-   public XIntroducedInVersionWidget() {
+   public XIntroducedInVersionWithPersistWidget() {
       this("Introduced In Version");
    }
 
-   public XIntroducedInVersionWidget(String label) {
+   public XIntroducedInVersionWithPersistWidget(String label) {
       super(label, INTRODUCED_VERSION_RELATION);
    }
 
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XTargetedVersionWidget.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XTargetedVersionWithPersistWidget.java
similarity index 71%
rename from plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XTargetedVersionWidget.java
rename to plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XTargetedVersionWithPersistWidget.java
index 9c1a807..a15e5c3 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XTargetedVersionWidget.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XTargetedVersionWithPersistWidget.java
@@ -17,18 +17,20 @@
 import org.eclipse.osee.framework.core.data.RelationTypeSide;
 
 /**
+ * Select and persist with clear button
+ *
  * @author Donald G. Dunne
  */
-public class XTargetedVersionWidget extends XHyperlabelVersionSelection {
+public class XTargetedVersionWithPersistWidget extends XHyperlabelVersionSelectionWithPersist {
 
-   public static final String WIDGET_ID = XTargetedVersionWidget.class.getSimpleName();
+   public static final String WIDGET_ID = XTargetedVersionWithPersistWidget.class.getSimpleName();
    public static RelationTypeSide TARGETED_VERSION_RELATION = AtsRelationTypes.TeamWorkflowTargetedForVersion_Version;
 
-   public XTargetedVersionWidget() {
+   public XTargetedVersionWithPersistWidget() {
       this("Targeted Version");
    }
 
-   public XTargetedVersionWidget(String label) {
+   public XTargetedVersionWithPersistWidget(String label) {
       super(label, TARGETED_VERSION_RELATION);
    }
 
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XWorkingBranchWidgetAbstract.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XWorkingBranchWidgetAbstract.java
index e857fc7..eb4708b 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XWorkingBranchWidgetAbstract.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XWorkingBranchWidgetAbstract.java
@@ -36,8 +36,8 @@
 import org.eclipse.osee.framework.skynet.core.event.model.ArtifactEvent;
 import org.eclipse.osee.framework.skynet.core.event.model.BranchEvent;
 import org.eclipse.osee.framework.skynet.core.event.model.Sender;
-import org.eclipse.osee.framework.ui.skynet.widgets.GenericXWidget;
 import org.eclipse.osee.framework.ui.skynet.widgets.ArtifactWidget;
+import org.eclipse.osee.framework.ui.skynet.widgets.GenericXWidget;
 import org.eclipse.swt.widgets.Control;
 
 /**
@@ -136,23 +136,25 @@
    }
 
    private void updateBranchState() {
-      workingBranch = AtsApiService.get().getBranchService().getWorkingBranch(teamArt, true);
-      workingBranchCreationInProgress =
-         AtsApiService.get().getBranchService().isWorkingBranchCreationInProgress(teamArt);
-      workingBranchInWork = AtsApiService.get().getBranchService().isWorkingBranchInWork(teamArt);
+      if (teamArt != null) {
+         workingBranch = AtsApiService.get().getBranchService().getWorkingBranch(teamArt, true);
+         workingBranchCreationInProgress =
+            AtsApiService.get().getBranchService().isWorkingBranchCreationInProgress(teamArt);
+         workingBranchInWork = AtsApiService.get().getBranchService().isWorkingBranchInWork(teamArt);
 
-      if (workingBranch.isInvalid()) {
-         workingBranchCommitInProgress = false;
-      } else {
-         BranchState state = BranchManager.getState(workingBranch);
-         workingBranchCreationInProgress |= state.isCreationInProgress();
-         workingBranchCommitInProgress = AtsApiService.get().getBranchService().isWorkingBranchCommitInProgress(
-            teamArt) || state.isCommitInProgress();
-         workingBranchCommitWithMergeInProgress =
-            BranchManager.hasMergeBranches(workingBranch) && !state.isRebaselineInProgress();
+         if (workingBranch.isInvalid()) {
+            workingBranchCommitInProgress = false;
+         } else {
+            BranchState state = BranchManager.getState(workingBranch);
+            workingBranchCreationInProgress |= state.isCreationInProgress();
+            workingBranchCommitInProgress = AtsApiService.get().getBranchService().isWorkingBranchCommitInProgress(
+               teamArt) || state.isCommitInProgress();
+            workingBranchCommitWithMergeInProgress =
+               BranchManager.hasMergeBranches(workingBranch) && !state.isRebaselineInProgress();
+         }
+         committedBranchExists = AtsApiService.get().getBranchService().isCommittedBranchExists(teamArt);
+         disableAll = workingBranchCommitInProgress;
       }
-      committedBranchExists = AtsApiService.get().getBranchService().isCommittedBranchExists(teamArt);
-      disableAll = workingBranchCommitInProgress;
    }
 
    protected BranchStatus getStatus() {
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/commit/XCommitManager.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/commit/XCommitManager.java
index 4d461b8..e0308cc 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/commit/XCommitManager.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/commit/XCommitManager.java
@@ -42,8 +42,8 @@
 import org.eclipse.osee.framework.skynet.core.event.model.Sender;
 import org.eclipse.osee.framework.ui.plugin.PluginUiImage;
 import org.eclipse.osee.framework.ui.skynet.results.ResultsEditor;
-import org.eclipse.osee.framework.ui.skynet.widgets.GenericXWidget;
 import org.eclipse.osee.framework.ui.skynet.widgets.ArtifactWidget;
+import org.eclipse.osee.framework.ui.skynet.widgets.GenericXWidget;
 import org.eclipse.osee.framework.ui.swt.ALayout;
 import org.eclipse.osee.framework.ui.swt.Displays;
 import org.eclipse.osee.framework.ui.swt.FontManager;
@@ -375,23 +375,27 @@
 
    @Override
    public void handleBranchEvent(Sender sender, final BranchEvent branchEvent) {
-      Displays.ensureInDisplayThread(new Runnable() {
-         @Override
-         public void run() {
-            redrawComposite();
-         }
-      });
+      if (Widgets.isAccessible(mainComp)) {
+         Displays.ensureInDisplayThread(new Runnable() {
+            @Override
+            public void run() {
+               redrawComposite();
+            }
+         });
+      }
    }
 
    @Override
    public void handleArtifactEvent(ArtifactEvent artifactEvent, Sender sender) {
-      if (artifactEvent.isModified(getTeamArt())) {
-         Displays.ensureInDisplayThread(new Runnable() {
-            @Override
-            public void run() {
-               loadTable();
-            }
-         });
+      if (Widgets.isAccessible(mainComp)) {
+         if (artifactEvent.isModified(getTeamArt())) {
+            Displays.ensureInDisplayThread(new Runnable() {
+               @Override
+               public void run() {
+                  loadTable();
+               }
+            });
+         }
       }
    }
 
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/sibling/XSiblingWorldWidget.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/sibling/XSiblingWorldWidget.java
index 3746ee7..5f56316 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/sibling/XSiblingWorldWidget.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/sibling/XSiblingWorldWidget.java
@@ -30,6 +30,7 @@
 import org.eclipse.osee.framework.skynet.core.event.model.Sender;
 import org.eclipse.osee.framework.ui.skynet.widgets.ArtifactWidget;
 import org.eclipse.osee.framework.ui.swt.Displays;
+import org.eclipse.osee.framework.ui.swt.Widgets;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.DisposeEvent;
 import org.eclipse.swt.events.DisposeListener;
@@ -131,20 +132,22 @@
    @Override
    public void handleArtifactEvent(ArtifactEvent artifactEvent, Sender sender) {
       try {
-         // Handle case where new sibling created/deleted
-         if (artifactEvent.isHasEvent((Artifact) teamWf.getParentAction().getStoreObject())) {
-            refresh();
-            return;
-         }
-         // Handle case where sibling changed
-         for (IAtsTeamWorkflow siblingWf : atsApi.getActionService().getSiblingTeamWorkflows(teamWf)) {
-            if (artifactEvent.isHasEvent((Artifact) siblingWf.getStoreObject())) {
+         if (teamWf != null && Widgets.isAccessible(mainComp)) {
+            // Handle case where new sibling created/deleted
+            if (artifactEvent.isHasEvent((Artifact) teamWf.getParentAction().getStoreObject())) {
                refresh();
                return;
             }
-            if (artifactEvent.isReloaded((Artifact) siblingWf.getStoreObject())) {
-               refresh();
-               return;
+            // Handle case where sibling changed
+            for (IAtsTeamWorkflow siblingWf : atsApi.getActionService().getSiblingTeamWorkflows(teamWf)) {
+               if (artifactEvent.isHasEvent((Artifact) siblingWf.getStoreObject())) {
+                  refresh();
+                  return;
+               }
+               if (artifactEvent.isReloaded((Artifact) siblingWf.getStoreObject())) {
+                  refresh();
+                  return;
+               }
             }
          }
       } catch (Exception ex) {
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/mini/XMiniTaskWidget.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/mini/XMiniTaskWidget.java
index cbd419f..b5d0c2a 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/mini/XMiniTaskWidget.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/mini/XMiniTaskWidget.java
@@ -299,20 +299,22 @@
    @Override
    public void handleArtifactEvent(ArtifactEvent artifactEvent, Sender sender) {
       try {
-         // Handle case where new task created/deleted
-         if (artifactEvent.isHasEvent((Artifact) teamWf.getStoreObject())) {
-            refresh();
-            return;
-         }
-         // Handle case where task changed
-         for (IAtsTask task : atsApi.getTaskService().getTasks(teamWf)) {
-            if (artifactEvent.isHasEvent((Artifact) task.getStoreObject())) {
+         if (teamWf != null && Widgets.isAccessible(mainComp)) {
+            // Handle case where new task created/deleted
+            if (artifactEvent.isHasEvent((Artifact) teamWf.getStoreObject())) {
                refresh();
                return;
             }
-            if (artifactEvent.isReloaded((Artifact) task.getStoreObject())) {
-               refresh();
-               return;
+            // Handle case where task changed
+            for (IAtsTask task : atsApi.getTaskService().getTasks(teamWf)) {
+               if (artifactEvent.isHasEvent((Artifact) task.getStoreObject())) {
+                  refresh();
+                  return;
+               }
+               if (artifactEvent.isReloaded((Artifact) task.getStoreObject())) {
+                  refresh();
+                  return;
+               }
             }
          }
       } catch (Exception ex) {
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/world/mini/XMiniWorldWidget.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/world/mini/XMiniWorldWidget.java
index b7dc0f2..2a1cd64 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/world/mini/XMiniWorldWidget.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/world/mini/XMiniWorldWidget.java
@@ -54,7 +54,7 @@
    private Label extraInfoLabel;
    private int lastSize = 0;
    private final int MAX_TABLE_SIZE = 10;
-   private Composite mainComp;
+   protected Composite mainComp;
    private Composite parentComp;
    protected final AtsApi atsApi;
    private Collection<IAtsWorkItem> workItems;
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/util/FrameworkXWidgetProvider.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/util/FrameworkXWidgetProvider.java
index 75768d7..6f37ac7 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/util/FrameworkXWidgetProvider.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/util/FrameworkXWidgetProvider.java
@@ -23,6 +23,7 @@
 import org.eclipse.osee.framework.core.data.ArtifactTypeToken;
 import org.eclipse.osee.framework.core.data.AttributeTypeToken;
 import org.eclipse.osee.framework.core.data.BranchToken;
+import org.eclipse.osee.framework.core.data.ComputedCharacteristicToken;
 import org.eclipse.osee.framework.core.enums.BranchArchivedState;
 import org.eclipse.osee.framework.core.enums.BranchType;
 import org.eclipse.osee.framework.jdk.core.type.OseeArgumentException;
@@ -148,361 +149,23 @@
             xWidgetName = getXWidgetNameBasedOnAttribute(artType, attributeType);
          }
 
-         // Look for widget provider to create widget
-         for (IXWidgetProvider widgetProvider : getXWidgetProviders()) {
-            xWidget = widgetProvider.createXWidget(xWidgetName, name, xWidgetLayoutData);
-            if (xWidget != null) {
-               break;
-            }
-         }
-
-         XOptionHandler options = xWidgetLayoutData.getXOptionHandler();
-         if (xWidget == null) {
-            // Otherwise, use default widget creation
-
-            if (xWidgetName.equals("XText")) {
-               xWidget = new XText(name);
-               if (Strings.isValid(xWidgetLayoutData.getDefaultValue())) {
-                  ((XText) xWidget).set(xWidgetLayoutData.getDefaultValue());
-               }
-            } else if (xWidgetName.equals("XSelectFromMultiChoiceBranch")) {
-               XSelectFromMultiChoiceBranch multiBranchSelect = new XSelectFromMultiChoiceBranch(name);
-               try {
-                  List<? extends BranchToken> branches =
-                     BranchManager.getBranches(BranchArchivedState.ALL, BranchType.WORKING, BranchType.BASELINE);
-                  Collections.sort(branches);
-
-                  multiBranchSelect.setSelectableItems(branches);
-               } catch (OseeCoreException ex) {
-                  OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
-               }
-               multiBranchSelect.setRequiredEntry(true);
-               xWidget = multiBranchSelect;
-            } else if (xWidgetName.equals("XInteger")) {
-               xWidget = new XInteger(name);
-            } else if (xWidgetName.equals("XLong")) {
-               xWidget = new XLong(name);
-            } else if (xWidgetName.equals("XTextDam")) {
-               xWidget = new XTextDam(name);
-            } else if (xWidgetName.equals("XButton")) {
-               xWidget = new XButton(name);
-            } else if (xWidgetName.equals("XButtonPush")) {
-               xWidget = new XButtonPush(name);
-            } else if (xWidgetName.startsWith("XRadioButtons")) {
-               String values[] =
-                  xWidgetLayoutData.getDynamicXWidgetLayout().getOptionResolver().getWidgetOptions(xWidgetLayoutData);
-               if (values.length > 0) {
-                  XRadioButtons radio = new XRadioButtons(name, "");
-
-                  if (options.contains(XOption.SORTED)) {
-                     Arrays.sort(values);
-                  }
-
-                  String defaultValue = xWidgetLayoutData.getDefaultValue();
-                  for (String value : values) {
-                     XRadioButton button = radio.addButton(value);
-                     if (Strings.isValid(defaultValue) && value.equals(defaultValue)) {
-                        button.setSelected(true);
-                     }
-                  }
-
-                  xWidget = radio;
-               } else {
-                  throw new OseeArgumentException(
-                     "Invalid XRadioButtons.  Must be \"XRadioButtons(option1,option2,option3)\"");
-               }
-            } else if (xWidgetName.equals("XLabelDam")) {
-               xWidget = new XLabelDam(name);
-            } else if (xWidgetName.equals("XMembersList")) {
-               try {
-                  xWidget = new XMembersList(name);
-               } catch (Exception ex) {
-                  OseeLog.log(Activator.class, Level.SEVERE, ex);
-               }
-            } else if (xWidgetName.equals("XMembersCombo")) {
-               xWidget = new XMembersCombo(name);
-            } else if (xWidgetName.equals("XMembersComboAll")) {
-               xWidget = new XMembersCombo(name, true);
-            } else if (xWidgetName.equals("XDate")) {
-               xWidget = new XDate(name);
-               xWidget.setDefaultValueObj(xWidgetLayoutData.getDefaultValueObj());
-            } else if (xWidgetName.equals("XFileSelectionDialog")) {
-               xWidget = new XFileTextWithSelectionDialog(name);
-            } else if (xWidgetName.equals("XDirectorySelectionDialog")) {
-               String defaultValue = xWidgetLayoutData.getDefaultValue();
-               if (Strings.isValid(defaultValue)) {
-                  xWidget = new XFileTextWithSelectionDialog(name, Type.Directory, defaultValue);
-               } else {
-                  xWidget = new XFileTextWithSelectionDialog(name, Type.Directory);
-               }
-            } else if (xWidgetName.equals("XDateDam")) {
-               xWidget = new XDateDam(name);
-            } else if (xWidgetName.equals("XTextResourceDropDam")) {
-               xWidget = new XTextResourceDropDam(name);
-            } else if (xWidgetName.equals("XFloat")) {
-               xWidget = new XFloat(name);
-            } else if (xWidgetName.equals("XFloatDam")) {
-               xWidget = new XFloatDam(name);
-            } else if (xWidgetName.equals("XIntegerDam")) {
-               xWidget = new XIntegerDam(name);
-            } else if (xWidgetName.equals("XLongDam")) {
-               xWidget = new XLongDam(name);
-            } else if (xWidgetName.equals("XFileTextWithSelectionDialog")) {
-               xWidget = new XFileTextWithSelectionDialog(name);
-            } else if (xWidgetName.equals("XLabel")) {
-               String defaultValue = xWidgetLayoutData.getDefaultValue();
-               if (Strings.isValid(defaultValue)) {
-                  xWidget = new XLabel(name, xWidgetLayoutData.getDefaultValue());
-               } else {
-                  xWidget = new XLabel(name);
-               }
-            } else if (xWidgetName.equals(XCheckBox.WIDGET_ID)) {
-               XCheckBox checkBox = new XCheckBox(name);
-               checkBox.setLabelAfter(options.contains(XOption.LABEL_AFTER));
-               if (Strings.isValid(xWidgetLayoutData.getDefaultValue())) {
-                  checkBox.set(Boolean.valueOf(xWidgetLayoutData.getDefaultValue()));
-               }
-               xWidget = checkBox;
-            } else if (xWidgetName.equals(XCheckBoxDam.WIDGET_ID)) {
-               XCheckBoxDam checkBox = new XCheckBoxDam(name);
-               checkBox.setLabelAfter(options.contains(XOption.LABEL_AFTER));
-               xWidget = checkBox;
-            } else if (xWidgetName.equals(XCheckBoxThreeState.WIDGET_ID)) {
-               XCheckBoxThreeState checkBox = new XCheckBoxThreeState(name);
-               checkBox.setLabelAfter(options.contains(XOption.LABEL_AFTER));
-               xWidget = checkBox;
-            } else if (xWidgetName.equals(XCheckBoxThreeStateDam.WIDGET_ID)) {
-               XCheckBoxThreeStateDam checkBox = new XCheckBoxThreeStateDam(name);
-               checkBox.setLabelAfter(options.contains(XOption.LABEL_AFTER));
-               xWidget = checkBox;
-            } else if (xWidgetName.equals(XComboEnumDam.WIDGET_ID)) {
-               XComboEnumDam combo = new XComboEnumDam(name);
-               xWidget = combo;
-            } else if (xWidgetName.startsWith("XComboDam")) {
-               if (xWidgetLayoutData.getDynamicXWidgetLayout() != null) {
-                  String values[] = xWidgetLayoutData.getDynamicXWidgetLayout().getOptionResolver().getWidgetOptions(
-                     xWidgetLayoutData);
-                  if (values.length > 0) {
-                     xWidget = new XComboDam(name);
-                     XComboDam combo = new XComboDam(name);
-                     combo.setDataStrings(values);
-                     if (options.contains(XOption.NO_DEFAULT_VALUE)) {
-                        combo.setDefaultSelectionAllowed(false);
-                     }
-                     if (options.contains(XOption.ADD_DEFAULT_VALUE)) {
-                        combo.setDefaultSelectionAllowed(true);
-                     }
-                     xWidget = combo;
-                  } else {
-                     throw new OseeArgumentException(
-                        "Invalid XComboDam.  Must be \"XComboDam(option1,option2,option3)\"");
-                  }
-               }
-            } else if (xWidgetName.startsWith("XSelectFromMultiChoiceDam")) {
-               if (xWidgetLayoutData.getDynamicXWidgetLayout() != null) {
-                  String values[] = xWidgetLayoutData.getDynamicXWidgetLayout().getOptionResolver().getWidgetOptions(
-                     xWidgetLayoutData);
-                  if (values.length > 0) {
-                     XSelectFromMultiChoiceDam widget = new XSelectFromMultiChoiceDam(name);
-                     widget.setSelectableItems(Arrays.asList(values));
-                     xWidget = widget;
-                  } else {
-                     throw new OseeArgumentException(
-                        "Invalid XSelectFromMultiChoiceDam.  Must be \"XSelectFromMultiChoiceDam(option1,option2,option3)\"");
-                  }
-               }
-            } else if (xWidgetName.startsWith("XStackedDam")) {
-               xWidget = new XStackedDam(name);
-            } else if (xWidgetName.startsWith("XFlatDam")) {
-               xWidget = new XTextFlatDam(name);
-            } else if (xWidgetName.startsWith("XComboBooleanDam")) {
-               xWidget = new XComboBooleanDam(name);
-               XComboBooleanDam combo = new XComboBooleanDam(name);
-               combo.setDataStrings(BooleanAttribute.booleanChoices);
-               xWidget = combo;
-               if (Strings.isValid(xWidgetLayoutData.getDefaultValue())) {
-                  String value = xWidgetLayoutData.getDefaultValue();
-                  if ("true".equals(value)) {
-                     combo.set("true");
-                  } else if ("false".equals(value)) {
-                     combo.set("false");
-                  } else {
-                     combo.set("");
-                  }
-               }
-               if (options.contains(XOption.NO_DEFAULT_VALUE)) {
-                  combo.setDefaultSelectionAllowed(false);
-               }
-               if (options.contains(XOption.ADD_DEFAULT_VALUE)) {
-                  combo.setDefaultSelectionAllowed(true);
-               }
-            } else if (xWidgetName.startsWith("XComboViewer")) {
-               xWidget = new XComboViewer(name, SWT.NONE);
-            } else if (xWidgetName.startsWith("XCombo")) {
-               String values[] =
-                  xWidgetLayoutData.getDynamicXWidgetLayout().getOptionResolver().getWidgetOptions(xWidgetLayoutData);
-               if (values.length > 0) {
-                  XCombo combo = new XCombo(name);
-
-                  if (options.contains(XOption.SORTED)) {
-                     Arrays.sort(values);
-                  }
-                  combo.setDataStrings(values);
-
-                  if (options.contains(XOption.NO_DEFAULT_VALUE)) {
-                     combo.setDefaultSelectionAllowed(false);
-                  }
-                  if (options.contains(XOption.ADD_DEFAULT_VALUE)) {
-                     combo.setDefaultSelectionAllowed(true);
-                  }
-                  xWidget = combo;
-                  String defaultValue = xWidgetLayoutData.getDefaultValue();
-                  if (Strings.isValid(defaultValue)) {
-                     combo.setDefaultValue(defaultValue);
-                  }
-               } else {
-                  throw new OseeArgumentException("Invalid XCombo.  Must be \"XCombo(option1,option2,option3)\"");
-               }
-            } else if (xWidgetName.startsWith("XListDam")) {
-               if (xWidgetLayoutData.getDynamicXWidgetLayout() != null) {
-                  String values[] = xWidgetLayoutData.getDynamicXWidgetLayout().getOptionResolver().getWidgetOptions(
-                     xWidgetLayoutData);
-                  XListDam list = new XListDam(name);
-                  if (values.length > 0) {
-                     list.add(values);
-                  }
-                  xWidget = list;
-               }
-            } else if (xWidgetName.equals("XHyperlabelMemberSelDam")) {
-               xWidget = new XHyperlabelMemberSelDam(name);
-            } else if (xWidgetName.equals("XHyperlabelMemberSelection")) {
-               xWidget = new XHyperlabelMemberSelection(name);
-            } else if (xWidgetName.startsWith("XListDropViewer")) {
-               if ("XListDropViewerWithSave".equals(xWidgetName)) {
-                  xWidget = new XListDropViewWithSave(name);
-               } else {
-                  xWidget = new XListDropViewer(name);
-               }
-            } else if (xWidgetName.equals(XListRelationWidget.WIDGET_ID)) {
-               return new XListRelationWidget(artifact, name, xWidgetLayoutData.getRelationTypeSide());
-            } else if (xWidgetName.equals(XComputedCharacteristicWidget.WIDGET_ID)) {
-               return new XComputedCharacteristicWidget(xWidgetLayoutData.getComputedCharacteristic());
-            } else if (xWidgetName.startsWith("XList")) {
-               String values[] =
-                  xWidgetLayoutData.getDynamicXWidgetLayout().getOptionResolver().getWidgetOptions(xWidgetLayoutData);
-               if (values.length > 0) {
-                  XList list = new XList(name);
-                  list.add(values);
-                  xWidget = list;
-                  String defaultValue = xWidgetLayoutData.getDefaultValue();
-                  if (Strings.isValid(defaultValue)) {
-                     list.setSelected(Arrays.asList(defaultValue.split(",")));
-                  }
-               } else {
-                  throw new OseeArgumentException("Invalid XList.  Must be \"XList(option1,option2,option3)\"");
-               }
-            } else if (xWidgetName.startsWith("XArtifactList")) {
-               XArtifactList artifactList = new XArtifactList(name);
-               artifactList.setMultiSelect(options.contains(XOption.MULTI_SELECT));
-               xWidget = artifactList;
-            } else if (xWidgetName.equals(XBranchSelectWidgetDam.WIDGET_ID)) {
-               xWidget = new XBranchSelectWidgetDam();
-            } else if (xWidgetName.startsWith(XBranchSelectWidget.WIDGET_ID)) {
-               XBranchSelectWidget widget = null;
-
-               if (xWidgetName.endsWith("WithSave")) {
-                  widget = new XBranchSelectWidgetWithSave(name);
-               } else {
-                  widget = new XBranchSelectWidget(name);
-               }
-
-               widget.setToolTip(xWidgetLayoutData.getToolTip());
-               try {
-                  String branchUuid = xWidgetLayoutData.getDefaultValue();
-                  if (Strings.isValid(branchUuid)) {
-                     try {
-                        Long uuid = Long.valueOf(branchUuid);
-                        widget.setSelection(BranchManager.getBranchToken(uuid));
-                     } catch (Exception ex) {
-                        // do nothing
-                     }
-                  }
-               } catch (OseeCoreException ex) {
-                  OseeLog.log(Activator.class, Level.SEVERE, ex);
-               }
-               xWidget = widget;
-            } else if (xWidgetName.equals(XArtifactTypeComboViewer.WIDGET_ID)) {
-               XArtifactTypeComboViewer widget = new XArtifactTypeComboViewer();
-               xWidget = widget;
-            } else if (xWidgetName.equals(XAttributeTypeComboViewer.WIDGET_ID)) {
-               XAttributeTypeComboViewer widget = new XAttributeTypeComboViewer();
-               xWidget = widget;
-            } else if (xWidgetName.equals(XAttributeTypeMultiChoiceSelect.WIDGET_ID)) {
-               XAttributeTypeMultiChoiceSelect widget = new XAttributeTypeMultiChoiceSelect();
-               xWidget = widget;
-            } else if (xWidgetName.equals(XArtifactTypeMultiChoiceSelect.WIDGET_ID)) {
-               XArtifactTypeMultiChoiceSelect widget = new XArtifactTypeMultiChoiceSelect();
-               String defaultType = xWidgetLayoutData.getDefaultValue();
-               if (Strings.isValid(defaultType)) {
-                  List<ArtifactTypeToken> types = new LinkedList<>();
-                  for (String type : defaultType.split(",")) {
-                     try {
-                        types.add(ServiceUtil.getTokenService().getArtifactType(type));
-                     } catch (Exception ex) {
-                        // do nothing
-                     }
-                  }
-                  widget.setSelected(types);
-               }
-               xWidget = widget;
-            } else if (xWidgetName.equals(XArtifactMultiChoiceSelect.WIDGET_ID)) {
-               xWidget = new XArtifactMultiChoiceSelect();
-
-            } else if (xWidgetName.equals(XTextFlatDam.WIDGET_ID)) {
-               XTextFlatDam widget = new XTextFlatDam();
-               xWidget = widget;
-            } else if (xWidgetName.equals("XHyperlinkLabel")) {
-               xWidget = new XHyperlinkLabel(name);
-               String defaultValue = xWidgetLayoutData.getDefaultValue();
-               if (Strings.isValid(defaultValue)) {
-                  XHyperlinkLabel widget = (XHyperlinkLabel) xWidget;
-                  widget.setUrl(xWidgetLayoutData.getDefaultValue());
-               }
-            } else if (xWidgetName.equals(XRadioButton.WIDGET_ID)) {
-               xWidget = new XRadioButton(name);
-            } else if (xWidgetName.equals(XCheckBoxesExample.WIDGET_ID)) {
-               xWidget = new XCheckBoxesExample();
-            } else if (xWidgetName.equals(XLabelValue.WIDGET_ID)) {
-               String defaultValue = xWidgetLayoutData.getDefaultValue();
-               xWidget = new XLabelValue(name, defaultValue);
-            } else {
-               xWidget = new XLabel("Error: Unhandled XWidget \"" + xWidgetName + "\"");
-            }
-         }
-
-         if (xWidget instanceof XText) {
-            ((XText) xWidget).addXTextSpellModifyDictionary(new SkynetSpellModifyDictionary());
-         }
-
-         if (xWidget != null && options.contains(XOption.NO_LABEL)) {
-            xWidget.setDisplayLabel(false);
-         }
-         if (artifact != null) {
-            AttributeTypeToken attributeType = AttributeTypeToken.SENTINEL;
-            if (xWidget instanceof AttributeWidget && xWidgetLayoutData.getStoreId() > 0) {
-               attributeType = tokenService.getAttributeType(xWidgetLayoutData.getStoreId());
-            }
-            if (attributeType == AttributeTypeToken.SENTINEL && Strings.isValid(xWidgetLayoutData.getStoreName())) {
-               attributeType = tokenService.getAttributeType(xWidgetLayoutData.getStoreName());
-            }
-            if (attributeType != AttributeTypeToken.SENTINEL && xWidget instanceof AttributeWidget) {
-               ((AttributeWidget) xWidget).setAttributeType(artifact, attributeType);
-            }
-            if (xWidget instanceof ArtifactWidget) {
-               ((ArtifactWidget) xWidget).setArtifact(artifact);
-            }
-         }
+         xWidget = getXWidget(xWidgetLayoutData, xWidgetName, name, artifact);
          if (xWidget != null) {
+            if (artifact != null) {
+               AttributeTypeToken attributeType = AttributeTypeToken.SENTINEL;
+               if (xWidget instanceof AttributeWidget && xWidgetLayoutData.getStoreId() > 0) {
+                  attributeType = tokenService.getAttributeType(xWidgetLayoutData.getStoreId());
+               }
+               if (attributeType == AttributeTypeToken.SENTINEL && Strings.isValid(xWidgetLayoutData.getStoreName())) {
+                  attributeType = tokenService.getAttributeType(xWidgetLayoutData.getStoreName());
+               }
+               if (attributeType != AttributeTypeToken.SENTINEL && xWidget instanceof AttributeWidget) {
+                  ((AttributeWidget) xWidget).setAttributeType(artifact, attributeType);
+               }
+               if (xWidget instanceof ArtifactWidget) {
+                  ((ArtifactWidget) xWidget).setArtifact(artifact);
+               }
+            }
             xWidget.setObject(xWidgetLayoutData.getObject());
          }
       } catch (Exception ex) {
@@ -514,6 +177,359 @@
       return xWidget;
    }
 
+   public static XWidget getXWidget(XWidgetRendererItem xWidgetLayoutData, String xWidgetName, String name, Artifact artifact) {
+      XWidget xWidget = null;
+      // Look for widget provider to create widget
+      for (IXWidgetProvider widgetProvider : getXWidgetProviders()) {
+         xWidget = widgetProvider.createXWidget(xWidgetName, name, xWidgetLayoutData);
+         if (xWidget != null) {
+            break;
+         }
+      }
+
+      XOptionHandler options = xWidgetLayoutData.getXOptionHandler();
+      if (xWidget == null) {
+         // Otherwise, use default widget creation
+
+         if (xWidgetName.equals("XText")) {
+            xWidget = new XText(name);
+            if (Strings.isValid(xWidgetLayoutData.getDefaultValue())) {
+               ((XText) xWidget).set(xWidgetLayoutData.getDefaultValue());
+            }
+         } else if (xWidgetName.equals("XSelectFromMultiChoiceBranch")) {
+            XSelectFromMultiChoiceBranch multiBranchSelect = new XSelectFromMultiChoiceBranch(name);
+            try {
+               List<? extends BranchToken> branches =
+                  BranchManager.getBranches(BranchArchivedState.ALL, BranchType.WORKING, BranchType.BASELINE);
+               Collections.sort(branches);
+
+               multiBranchSelect.setSelectableItems(branches);
+            } catch (OseeCoreException ex) {
+               OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+            }
+            multiBranchSelect.setRequiredEntry(true);
+            xWidget = multiBranchSelect;
+         } else if (xWidgetName.equals("XInteger")) {
+            xWidget = new XInteger(name);
+         } else if (xWidgetName.equals("XLong")) {
+            xWidget = new XLong(name);
+         } else if (xWidgetName.equals("XTextDam")) {
+            xWidget = new XTextDam(name);
+         } else if (xWidgetName.equals("XButton")) {
+            xWidget = new XButton(name);
+         } else if (xWidgetName.equals("XButtonPush")) {
+            xWidget = new XButtonPush(name);
+         } else if (xWidgetName.startsWith("XRadioButtons")) {
+            String values[] =
+               xWidgetLayoutData.getDynamicXWidgetLayout().getOptionResolver().getWidgetOptions(xWidgetLayoutData);
+            if (values.length > 0) {
+               XRadioButtons radio = new XRadioButtons(name, "");
+
+               if (options.contains(XOption.SORTED)) {
+                  Arrays.sort(values);
+               }
+
+               String defaultValue = xWidgetLayoutData.getDefaultValue();
+               for (String value : values) {
+                  XRadioButton button = radio.addButton(value);
+                  if (Strings.isValid(defaultValue) && value.equals(defaultValue)) {
+                     button.setSelected(true);
+                  }
+               }
+
+               xWidget = radio;
+            } else {
+               throw new OseeArgumentException(
+                  "Invalid XRadioButtons.  Must be \"XRadioButtons(option1,option2,option3)\"");
+            }
+         } else if (xWidgetName.equals("XLabelDam")) {
+            xWidget = new XLabelDam(name);
+         } else if (xWidgetName.equals("XMembersList")) {
+            try {
+               xWidget = new XMembersList(name);
+            } catch (Exception ex) {
+               OseeLog.log(Activator.class, Level.SEVERE, ex);
+            }
+         } else if (xWidgetName.equals("XMembersCombo")) {
+            xWidget = new XMembersCombo(name);
+         } else if (xWidgetName.equals("XMembersComboAll")) {
+            xWidget = new XMembersCombo(name, true);
+         } else if (xWidgetName.equals("XDate")) {
+            xWidget = new XDate(name);
+            xWidget.setDefaultValueObj(xWidgetLayoutData.getDefaultValueObj());
+         } else if (xWidgetName.equals("XFileSelectionDialog")) {
+            xWidget = new XFileTextWithSelectionDialog(name);
+         } else if (xWidgetName.equals("XDirectorySelectionDialog")) {
+            String defaultValue = xWidgetLayoutData.getDefaultValue();
+            if (Strings.isValid(defaultValue)) {
+               xWidget = new XFileTextWithSelectionDialog(name, Type.Directory, defaultValue);
+            } else {
+               xWidget = new XFileTextWithSelectionDialog(name, Type.Directory);
+            }
+         } else if (xWidgetName.equals("XDateDam")) {
+            xWidget = new XDateDam(name);
+         } else if (xWidgetName.equals("XTextResourceDropDam")) {
+            xWidget = new XTextResourceDropDam(name);
+         } else if (xWidgetName.equals("XFloat")) {
+            xWidget = new XFloat(name);
+         } else if (xWidgetName.equals("XFloatDam")) {
+            xWidget = new XFloatDam(name);
+         } else if (xWidgetName.equals("XIntegerDam")) {
+            xWidget = new XIntegerDam(name);
+         } else if (xWidgetName.equals("XLongDam")) {
+            xWidget = new XLongDam(name);
+         } else if (xWidgetName.equals("XFileTextWithSelectionDialog")) {
+            xWidget = new XFileTextWithSelectionDialog(name);
+         } else if (xWidgetName.equals("XLabel")) {
+            String defaultValue = xWidgetLayoutData.getDefaultValue();
+            if (Strings.isValid(defaultValue)) {
+               xWidget = new XLabel(name, xWidgetLayoutData.getDefaultValue());
+            } else {
+               xWidget = new XLabel(name);
+            }
+         } else if (xWidgetName.equals(XCheckBox.WIDGET_ID)) {
+            XCheckBox checkBox = new XCheckBox(name);
+            checkBox.setLabelAfter(options.contains(XOption.LABEL_AFTER));
+            if (Strings.isValid(xWidgetLayoutData.getDefaultValue())) {
+               checkBox.set(Boolean.valueOf(xWidgetLayoutData.getDefaultValue()));
+            }
+            xWidget = checkBox;
+         } else if (xWidgetName.equals(XCheckBoxDam.WIDGET_ID)) {
+            XCheckBoxDam checkBox = new XCheckBoxDam(name);
+            checkBox.setLabelAfter(options.contains(XOption.LABEL_AFTER));
+            xWidget = checkBox;
+         } else if (xWidgetName.equals(XCheckBoxThreeState.WIDGET_ID)) {
+            XCheckBoxThreeState checkBox = new XCheckBoxThreeState(name);
+            checkBox.setLabelAfter(options.contains(XOption.LABEL_AFTER));
+            xWidget = checkBox;
+         } else if (xWidgetName.equals(XCheckBoxThreeStateDam.WIDGET_ID)) {
+            XCheckBoxThreeStateDam checkBox = new XCheckBoxThreeStateDam(name);
+            checkBox.setLabelAfter(options.contains(XOption.LABEL_AFTER));
+            xWidget = checkBox;
+         } else if (xWidgetName.equals(XComboEnumDam.WIDGET_ID)) {
+            XComboEnumDam combo = new XComboEnumDam(name);
+            xWidget = combo;
+         } else if (xWidgetName.startsWith("XComboDam")) {
+            if (name.equals("IsInTest")) {
+               return new XComboDam(name);
+            }
+            if (xWidgetLayoutData.getDynamicXWidgetLayout() != null) {
+               String values[] =
+                  xWidgetLayoutData.getDynamicXWidgetLayout().getOptionResolver().getWidgetOptions(xWidgetLayoutData);
+               if (values.length > 0) {
+                  xWidget = new XComboDam(name);
+                  XComboDam combo = new XComboDam(name);
+                  combo.setDataStrings(values);
+                  if (options.contains(XOption.NO_DEFAULT_VALUE)) {
+                     combo.setDefaultSelectionAllowed(false);
+                  }
+                  if (options.contains(XOption.ADD_DEFAULT_VALUE)) {
+                     combo.setDefaultSelectionAllowed(true);
+                  }
+                  xWidget = combo;
+               } else {
+                  throw new OseeArgumentException("Invalid XComboDam.  Must be \"XComboDam(option1,option2,option3)\"");
+               }
+            }
+         } else if (xWidgetName.startsWith("XSelectFromMultiChoiceDam")) {
+            if (name.equals("IsInTest")) {
+               XSelectFromMultiChoiceDam widget = new XSelectFromMultiChoiceDam(name);
+               return widget;
+            }
+            if (xWidgetLayoutData.getDynamicXWidgetLayout() != null) {
+               String values[] =
+                  xWidgetLayoutData.getDynamicXWidgetLayout().getOptionResolver().getWidgetOptions(xWidgetLayoutData);
+               if (values.length > 0) {
+                  XSelectFromMultiChoiceDam widget = new XSelectFromMultiChoiceDam(name);
+                  widget.setSelectableItems(Arrays.asList(values));
+                  xWidget = widget;
+               } else {
+                  throw new OseeArgumentException(
+                     "Invalid XSelectFromMultiChoiceDam.  Must be \"XSelectFromMultiChoiceDam(option1,option2,option3)\"");
+               }
+            }
+         } else if (xWidgetName.startsWith("XStackedDam")) {
+            xWidget = new XStackedDam(name);
+         } else if (xWidgetName.startsWith("XFlatDam")) {
+            xWidget = new XTextFlatDam(name);
+         } else if (xWidgetName.startsWith("XComboBooleanDam")) {
+            xWidget = new XComboBooleanDam(name);
+            XComboBooleanDam combo = new XComboBooleanDam(name);
+            combo.setDataStrings(BooleanAttribute.booleanChoices);
+            xWidget = combo;
+            if (Strings.isValid(xWidgetLayoutData.getDefaultValue())) {
+               String value = xWidgetLayoutData.getDefaultValue();
+               if ("true".equals(value)) {
+                  combo.set("true");
+               } else if ("false".equals(value)) {
+                  combo.set("false");
+               } else {
+                  combo.set("");
+               }
+            }
+            if (options.contains(XOption.NO_DEFAULT_VALUE)) {
+               combo.setDefaultSelectionAllowed(false);
+            }
+            if (options.contains(XOption.ADD_DEFAULT_VALUE)) {
+               combo.setDefaultSelectionAllowed(true);
+            }
+         } else if (xWidgetName.startsWith("XComboViewer")) {
+            xWidget = new XComboViewer(name, SWT.NONE);
+         } else if (xWidgetName.startsWith("XCombo")) {
+            String values[] =
+               xWidgetLayoutData.getDynamicXWidgetLayout().getOptionResolver().getWidgetOptions(xWidgetLayoutData);
+            if (values.length > 0) {
+               XCombo combo = new XCombo(name);
+
+               if (options.contains(XOption.SORTED)) {
+                  Arrays.sort(values);
+               }
+               combo.setDataStrings(values);
+
+               if (options.contains(XOption.NO_DEFAULT_VALUE)) {
+                  combo.setDefaultSelectionAllowed(false);
+               }
+               if (options.contains(XOption.ADD_DEFAULT_VALUE)) {
+                  combo.setDefaultSelectionAllowed(true);
+               }
+               xWidget = combo;
+               String defaultValue = xWidgetLayoutData.getDefaultValue();
+               if (Strings.isValid(defaultValue)) {
+                  combo.setDefaultValue(defaultValue);
+               }
+            } else {
+               throw new OseeArgumentException("Invalid XCombo.  Must be \"XCombo(option1,option2,option3)\"");
+            }
+         } else if (xWidgetName.startsWith("XListDam")) {
+            if (xWidgetLayoutData.getDynamicXWidgetLayout() != null) {
+               String values[] =
+                  xWidgetLayoutData.getDynamicXWidgetLayout().getOptionResolver().getWidgetOptions(xWidgetLayoutData);
+               XListDam list = new XListDam(name);
+               if (values.length > 0) {
+                  list.add(values);
+               }
+               xWidget = list;
+            }
+         } else if (xWidgetName.equals("XHyperlabelMemberSelDam")) {
+            xWidget = new XHyperlabelMemberSelDam(name);
+         } else if (xWidgetName.equals("XHyperlabelMemberSelection")) {
+            xWidget = new XHyperlabelMemberSelection(name);
+         } else if (xWidgetName.startsWith("XListDropViewer")) {
+            if ("XListDropViewerWithSave".equals(xWidgetName)) {
+               xWidget = new XListDropViewWithSave(name);
+            } else {
+               xWidget = new XListDropViewer(name);
+            }
+         } else if (xWidgetName.equals(XListRelationWidget.WIDGET_ID)) {
+            return new XListRelationWidget(artifact, name, xWidgetLayoutData.getRelationTypeSide());
+         } else if (xWidgetName.equals(XComputedCharacteristicWidget.WIDGET_ID)) {
+            if (name.equals("IsInTest")) {
+               return new XComputedCharacteristicWidget(ComputedCharacteristicToken.SENTINEL);
+            }
+            return new XComputedCharacteristicWidget(xWidgetLayoutData.getComputedCharacteristic());
+         } else if (xWidgetName.startsWith("XList")) {
+            String values[] =
+               xWidgetLayoutData.getDynamicXWidgetLayout().getOptionResolver().getWidgetOptions(xWidgetLayoutData);
+            if (values.length > 0) {
+               XList list = new XList(name);
+               list.add(values);
+               xWidget = list;
+               String defaultValue = xWidgetLayoutData.getDefaultValue();
+               if (Strings.isValid(defaultValue)) {
+                  list.setSelected(Arrays.asList(defaultValue.split(",")));
+               }
+            } else {
+               throw new OseeArgumentException("Invalid XList.  Must be \"XList(option1,option2,option3)\"");
+            }
+         } else if (xWidgetName.startsWith("XArtifactList")) {
+            XArtifactList artifactList = new XArtifactList(name);
+            artifactList.setMultiSelect(options.contains(XOption.MULTI_SELECT));
+            xWidget = artifactList;
+         } else if (xWidgetName.equals(XBranchSelectWidgetDam.WIDGET_ID)) {
+            xWidget = new XBranchSelectWidgetDam();
+         } else if (xWidgetName.startsWith(XBranchSelectWidget.WIDGET_ID)) {
+            XBranchSelectWidget widget = null;
+
+            if (xWidgetName.endsWith("WithSave")) {
+               widget = new XBranchSelectWidgetWithSave(name);
+            } else {
+               widget = new XBranchSelectWidget(name);
+            }
+
+            widget.setToolTip(xWidgetLayoutData.getToolTip());
+            try {
+               String branchUuid = xWidgetLayoutData.getDefaultValue();
+               if (Strings.isValid(branchUuid)) {
+                  try {
+                     Long uuid = Long.valueOf(branchUuid);
+                     widget.setSelection(BranchManager.getBranchToken(uuid));
+                  } catch (Exception ex) {
+                     // do nothing
+                  }
+               }
+            } catch (OseeCoreException ex) {
+               OseeLog.log(Activator.class, Level.SEVERE, ex);
+            }
+            xWidget = widget;
+         } else if (xWidgetName.equals(XArtifactTypeComboViewer.WIDGET_ID)) {
+            XArtifactTypeComboViewer widget = new XArtifactTypeComboViewer();
+            xWidget = widget;
+         } else if (xWidgetName.equals(XAttributeTypeComboViewer.WIDGET_ID)) {
+            XAttributeTypeComboViewer widget = new XAttributeTypeComboViewer();
+            xWidget = widget;
+         } else if (xWidgetName.equals(XAttributeTypeMultiChoiceSelect.WIDGET_ID)) {
+            XAttributeTypeMultiChoiceSelect widget = new XAttributeTypeMultiChoiceSelect();
+            xWidget = widget;
+         } else if (xWidgetName.equals(XArtifactTypeMultiChoiceSelect.WIDGET_ID)) {
+            XArtifactTypeMultiChoiceSelect widget = new XArtifactTypeMultiChoiceSelect();
+            String defaultType = xWidgetLayoutData.getDefaultValue();
+            if (Strings.isValid(defaultType)) {
+               List<ArtifactTypeToken> types = new LinkedList<>();
+               for (String type : defaultType.split(",")) {
+                  try {
+                     types.add(ServiceUtil.getTokenService().getArtifactType(type));
+                  } catch (Exception ex) {
+                     // do nothing
+                  }
+               }
+               widget.setSelected(types);
+            }
+            xWidget = widget;
+         } else if (xWidgetName.equals(XArtifactMultiChoiceSelect.WIDGET_ID)) {
+            xWidget = new XArtifactMultiChoiceSelect();
+
+         } else if (xWidgetName.equals(XTextFlatDam.WIDGET_ID)) {
+            XTextFlatDam widget = new XTextFlatDam();
+            xWidget = widget;
+         } else if (xWidgetName.equals("XHyperlinkLabel")) {
+            xWidget = new XHyperlinkLabel(name);
+            String defaultValue = xWidgetLayoutData.getDefaultValue();
+            if (Strings.isValid(defaultValue)) {
+               XHyperlinkLabel widget = (XHyperlinkLabel) xWidget;
+               widget.setUrl(xWidgetLayoutData.getDefaultValue());
+            }
+         } else if (xWidgetName.equals(XRadioButton.WIDGET_ID)) {
+            xWidget = new XRadioButton(name);
+         } else if (xWidgetName.equals(XCheckBoxesExample.WIDGET_ID)) {
+            xWidget = new XCheckBoxesExample();
+         } else if (xWidgetName.equals(XLabelValue.WIDGET_ID)) {
+            String defaultValue = xWidgetLayoutData.getDefaultValue();
+            xWidget = new XLabelValue(name, defaultValue);
+         } else {
+            xWidget = new XLabel("Error: Unhandled XWidget \"" + xWidgetName + "\"");
+         }
+      }
+
+      if (xWidget instanceof XText) {
+         ((XText) xWidget).addXTextSpellModifyDictionary(new SkynetSpellModifyDictionary());
+      }
+
+      if (xWidget != null && options.contains(XOption.NO_LABEL)) {
+         xWidget.setDisplayLabel(false);
+      }
+      return xWidget;
+   }
+
    private static Collection<IXWidgetProvider> getXWidgetProviders() {
       ExtensionDefinedObjects<IXWidgetProvider> contributions =
          new ExtensionDefinedObjects<>(Activator.PLUGIN_ID + ".XWidgetProvider", "XWidgetProvider", "classname", true);