Merge branch 'dev' of https://git.eclipse.org/r/osee/org.eclipse.osee into java11

Change-Id: Ia331ad598b92f2d20ace6b290d3f0098fa208fb5
diff --git a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/agile/IAgileService.java b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/agile/IAgileService.java
index 95d2b35..6295f2e 100644
--- a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/agile/IAgileService.java
+++ b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/agile/IAgileService.java
@@ -35,6 +35,11 @@
    public static String FEATURE_GROUP_FOLDER_NAME = "Feature Groups";
    public static long EMPTY_VALUE = -1;
 
+   /**
+    * @return Points Attr type defined if agile team, else default points attribute type
+    */
+   AttributeTypeToken getPointsAttrType(IAtsWorkItem workItem);
+
    IAgileTeam getAgileTeam(ArtifactId artifact);
 
    IAgileTeam updateAgileTeam(JaxAgileTeam team);
diff --git a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/util/AtsUtil.java b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/util/AtsUtil.java
index b6900b7..d11b06c 100644
--- a/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/util/AtsUtil.java
+++ b/plugins/org.eclipse.osee.ats.api/src/org/eclipse/osee/ats/api/util/AtsUtil.java
@@ -63,7 +63,7 @@
    }
 
    public static String getActionUrl(String atsIdOrid, AtsApi atsApi) {
-      return getActionUrl(atsIdOrid, ATS_DEFAULT_ACTION_URL, atsApi);
+      return getActionUrl(atsIdOrid, "", atsApi);
    }
 
    public static String getActionUrl(String atsIdOrid, String defaultUrl, AtsApi atsApi) {
@@ -73,7 +73,11 @@
    }
 
    public static String getBaseActionUiUrl(String defaultUrl, AtsApi atsApi) {
-      return atsApi.getConfigValue(AtsUtil.ATS_CONFIG_ACTION_URL_KEY, defaultUrl);
+      String configUrl = atsApi.getConfigValue(AtsUtil.ATS_CONFIG_ACTION_URL_KEY, defaultUrl);
+      if (Strings.isInValid(configUrl)) {
+         configUrl = System.getProperty("osee.application.server") + ATS_DEFAULT_ACTION_URL;
+      }
+      return configUrl;
    }
 
    public static String resolveAjaxToBaseApplicationServer(String html, AtsApi atsApi) {
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/agile/AgileService.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/agile/AgileService.java
index 79adfd0..e080ed3 100644
--- a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/agile/AgileService.java
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/agile/AgileService.java
@@ -91,6 +91,22 @@
    }
 
    @Override
+   public AttributeTypeToken getPointsAttrType(IAtsWorkItem workItem) {
+      AttributeTypeToken pointsAttrType = AttributeTypeToken.SENTINEL;
+      IAtsTeamWorkflow teamWf = workItem.getParentTeamWorkflow();
+      if (teamWf != null) {
+         IAgileTeam agileTeam = atsApi.getAgileService().getAgileTeam(teamWf);
+         if (agileTeam != null) {
+            pointsAttrType = atsApi.getAgileService().getAgileTeamPointsAttributeType(agileTeam);
+         }
+      }
+      if (pointsAttrType.isInvalid()) {
+         pointsAttrType = AtsAttributeTypes.PointsNumeric;
+      }
+      return pointsAttrType;
+   }
+
+   @Override
    public IAgileTeam getAgileTeamById(ArtifactId agileTeamId) {
       AgileTeam program = null;
       if (agileTeamId instanceof AgileTeam) {
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AtsCoreXWidgetValidatorProvider.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AtsCoreXWidgetValidatorProvider.java
index 908531a..e04c716 100644
--- a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AtsCoreXWidgetValidatorProvider.java
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AtsCoreXWidgetValidatorProvider.java
@@ -34,7 +34,8 @@
       atsValidators.add(new AtsXComboValidator());
       atsValidators.add(new AtsXComboBooleanValidator());
       atsValidators.add(new AtsXListValidator());
-      atsValidators.add(new AtsXSignAndDateValidator());
+      atsValidators.add(new AtsXWidgetAttrValidator());
+      atsValidators.add(new AtsXPointsAttrValidator());
    }
 
    @Override
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AtsXPointsAttrValidator.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AtsXPointsAttrValidator.java
new file mode 100644
index 0000000..62ddfa7
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AtsXPointsAttrValidator.java
@@ -0,0 +1,50 @@
+/*********************************************************************
+ * 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.core.validator;
+
+import java.util.Arrays;
+import org.eclipse.osee.ats.api.AtsApi;
+import org.eclipse.osee.ats.api.IAtsWorkItem;
+import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
+import org.eclipse.osee.ats.api.util.IValueProvider;
+import org.eclipse.osee.ats.api.workdef.IAtsStateDefinition;
+import org.eclipse.osee.ats.api.workdef.IAtsWidgetDefinition;
+import org.eclipse.osee.ats.api.workdef.WidgetResult;
+import org.eclipse.osee.ats.api.workdef.WidgetStatus;
+import org.eclipse.osee.framework.core.data.AttributeTypeToken;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class AtsXPointsAttrValidator extends AtsXWidgetValidator {
+
+   @Override
+   public WidgetResult validateTransition(IAtsWorkItem workItem, IValueProvider provider, IAtsWidgetDefinition widgetDef, IAtsStateDefinition fromStateDef, IAtsStateDefinition toStateDef, AtsApi atsApi) {
+      WidgetResult result = WidgetResult.Success;
+      if ("XEstimatedPointsWidget".equals(widgetDef.getXWidgetName())) {
+         boolean found = false;
+         for (AttributeTypeToken attrType : Arrays.asList(AtsAttributeTypes.Points, AtsAttributeTypes.PointsNumeric)) {
+            if (atsApi.getAttributeResolver().getAttributeCount(workItem, attrType) > 0) {
+               found = true;
+               break;
+            }
+         }
+         if (!found) {
+            result = new WidgetResult(WidgetStatus.Invalid_Incompleted, "[%s] is required for transition to [%s]",
+               widgetDef.getName(), toStateDef.getName());
+         }
+      }
+      return result;
+   }
+}
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AtsXSignAndDateValidator.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AtsXWidgetAttrValidator.java
similarity index 80%
rename from plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AtsXSignAndDateValidator.java
rename to plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AtsXWidgetAttrValidator.java
index 80e6354..eacbe24 100644
--- a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AtsXSignAndDateValidator.java
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AtsXWidgetAttrValidator.java
@@ -23,28 +23,23 @@
 import org.eclipse.osee.ats.api.workdef.IAtsWidgetDefinition;
 import org.eclipse.osee.ats.api.workdef.WidgetResult;
 import org.eclipse.osee.ats.api.workdef.WidgetStatus;
-import org.eclipse.osee.ats.core.internal.AtsApiService;
 import org.eclipse.osee.framework.core.data.AttributeTypeToken;
 
 /**
+ * Add any xwidgets that need attr type(s) to be valid
+ *
  * @author Donald G. Dunne
  */
-public class AtsXSignAndDateValidator extends AtsXWidgetValidator {
+public class AtsXWidgetAttrValidator extends AtsXWidgetValidator {
 
-   AtsApi atsApi;
-
-   private final List<SignAndDateWidget> widgets = Arrays.asList( //
-      new SignAndDateWidget("XTleReviewedWidget", AtsAttributeTypes.TleReviewedBy, AtsAttributeTypes.TleReviewedDate) //
+   private final List<AttributeWidget> widgets = Arrays.asList( //
+      new AttributeWidget("XTleReviewedWidget", AtsAttributeTypes.TleReviewedBy, AtsAttributeTypes.TleReviewedDate) //
    );
 
-   public AtsXSignAndDateValidator() {
-      atsApi = AtsApiService.get();
-   }
-
    @Override
-   public WidgetResult validateTransition(IAtsWorkItem workItem, IValueProvider provider, IAtsWidgetDefinition widgetDef, IAtsStateDefinition fromStateDef, IAtsStateDefinition toStateDef, AtsApi atsServices) {
+   public WidgetResult validateTransition(IAtsWorkItem workItem, IValueProvider provider, IAtsWidgetDefinition widgetDef, IAtsStateDefinition fromStateDef, IAtsStateDefinition toStateDef, AtsApi atsApi) {
       WidgetResult result = WidgetResult.Success;
-      for (SignAndDateWidget sdWidget : widgets) {
+      for (AttributeWidget sdWidget : widgets) {
          if (sdWidget.getWidgetName().equals(widgetDef.getXWidgetName())) {
             result = validateWidgetIsRequired(provider, widgetDef, fromStateDef, toStateDef);
             if (!result.isSuccess()) {
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/SignAndDateWidget.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AttributeWidget.java
similarity index 91%
rename from plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/SignAndDateWidget.java
rename to plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AttributeWidget.java
index dcda016..8f74c41 100644
--- a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/SignAndDateWidget.java
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/validator/AttributeWidget.java
@@ -19,11 +19,11 @@
 /**
  * @author Donald G. Dunne
  */
-public class SignAndDateWidget {
+public class AttributeWidget {
    private String widgetName;
    private List<AttributeTypeToken> attrTypes = new ArrayList<>();
 
-   public SignAndDateWidget(String widgetName, AttributeTypeToken... attrTypes) {
+   public AttributeWidget(String widgetName, AttributeTypeToken... attrTypes) {
       this.widgetName = widgetName;
       for (AttributeTypeToken type : attrTypes) {
          this.attrTypes.add(type);
diff --git a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefTaskDemoForCrEstimating.java b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefTaskDemoForCrEstimating.java
index ea9992e..afe93c3 100644
--- a/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefTaskDemoForCrEstimating.java
+++ b/plugins/org.eclipse.osee.ats.core/src/org/eclipse/osee/ats/core/workdef/WorkDefTaskDemoForCrEstimating.java
@@ -59,7 +59,7 @@
             new WidgetDefinition(Description, "XTextDam", FILL_VERTICALLY, AUTO_SAVE), //
             new WidgetDefinition(Assumptions, "XTextDam", FILL_VERTICALLY, AUTO_SAVE), //
             new CompositeLayoutItem(4, //
-               new WidgetDefinition("Estimated Points", "XPointsWidget", AUTO_SAVE), //
+               new WidgetDefinition("Estimated Points", "XEstimatedPointsWidget", REQUIRED_FOR_TRANSITION, AUTO_SAVE), //
                new WidgetDefinition(EstimatedCompletionDate, "XDateDam", AUTO_SAVE) //
             ), //
             new WidgetDefinition("TLE Reviewed Estimate", AtsAttributeTypes.TleReviewedDate, "XTleReviewedWidget",
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 714dd90..05e3fbb 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
@@ -84,7 +84,8 @@
                   REQUIRED_FOR_TRANSITION, AUTO_SAVE), //
                new WidgetDefinition(AtsAttributeTypes.NeedBy, "XDateDam", HORIZONTAL_LABEL, AUTO_SAVE) //
             ), //
-            new WidgetDefinition("Task Estimating Manager", "XTaskEstManagerDemo"));
+            new WidgetDefinition("Task Estimating", "XTaskEstDemoWidget") //
+         );
 
       bld.andState(3, "Authorize", StateType.Working) //
          .andToStates(StateToken.Implement, StateToken.Cancelled) //
@@ -92,13 +93,16 @@
          .andColor(StateColor.BLACK) //
          .andLayout( //
             new WidgetDefinition(AtsAttributeTypes.WorkPackage, "XTextDam", AUTO_SAVE), //
-            new WidgetDefinition(AtsAttributeTypes.EstimatedCompletionDate, "XDateDam", HORIZONTAL_LABEL, AUTO_SAVE));
+            new WidgetDefinition(AtsAttributeTypes.EstimatedCompletionDate, "XDateDam", HORIZONTAL_LABEL, AUTO_SAVE), //
+            new WidgetDefinition("Sibling Workflows", "XSiblingWorldWidget") //
+         );
 
       bld.andState(4, "Implement", StateType.Working) //
          .andToStates(StateToken.Completed, StateToken.Cancelled) //
          .andRules(RuleDefinitionOption.AllowAssigneeToAll, RuleDefinitionOption.AllowEditToAll) //
          .andColor(StateColor.BLACK) //
          .andLayout( //
+            new WidgetDefinition("Sibling Workflows", "XSiblingWorldWidget"), //
             getWorkingBranchWidgetComposite(), //
             new WidgetDefinition("Commit Manager", "XCommitManager"), //
             new WidgetDefinition(AtsAttributeTypes.WorkPackage, "XTextDam", AUTO_SAVE), //
@@ -107,7 +111,9 @@
 
       bld.andState(5, "Completed", StateType.Completed) //
          .andRules(RuleDefinitionOption.AllowEditToAll, RuleDefinitionOption.AddDecisionValidateBlockingReview) //
-         .andColor(StateColor.DARK_GREEN);
+         .andColor(StateColor.DARK_GREEN) //
+         .andLayout( //
+            new WidgetDefinition("Sibling Workflows", "XSiblingWorldWidget"));
 
       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 99cb36b..9d56c0b 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
@@ -89,7 +89,6 @@
  org.eclipse.osee.ats.ide.workflow.review.defect,
  org.eclipse.osee.ats.ide.workflow.review.role,
  org.eclipse.osee.ats.ide.workflow.task,
- org.eclipse.osee.ats.ide.workflow.task.widgets.estimates.demo,
  org.eclipse.osee.ats.ide.workflow.teamwf,
  org.eclipse.osee.ats.ide.workflow.transition,
  org.eclipse.osee.ats.ide.world,
diff --git a/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/workflow/cr/XTaskEstManagerTest.java b/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/workflow/cr/XTaskEstManagerTest.java
index 800b3c8..75f0d49 100644
--- a/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/workflow/cr/XTaskEstManagerTest.java
+++ b/plugins/org.eclipse.osee.ats.ide.integration.tests/src/org/eclipse/osee/ats/ide/integration/tests/ats/workflow/cr/XTaskEstManagerTest.java
@@ -22,10 +22,10 @@
 import org.eclipse.osee.ats.api.workflow.IAtsTask;
 import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
 import org.eclipse.osee.ats.ide.integration.tests.AtsApiService;
-import org.eclipse.osee.ats.ide.workflow.task.widgets.estimates.TaskEstDefinition;
-import org.eclipse.osee.ats.ide.workflow.task.widgets.estimates.TaskEstNameProvider;
-import org.eclipse.osee.ats.ide.workflow.task.widgets.estimates.TaskEstOperations;
-import org.eclipse.osee.ats.ide.workflow.task.widgets.estimates.demo.XTaskEstManagerDemo;
+import org.eclipse.osee.ats.ide.workflow.cr.estimates.TaskEstDefinition;
+import org.eclipse.osee.ats.ide.workflow.cr.estimates.TaskEstNameProvider;
+import org.eclipse.osee.ats.ide.workflow.cr.estimates.TaskEstOperations;
+import org.eclipse.osee.ats.ide.workflow.cr.estimates.demo.XTaskEstDemoWidget;
 import org.eclipse.osee.framework.core.data.ArtifactToken;
 import org.eclipse.osee.framework.core.enums.DemoUsers;
 import org.junit.Assert;
@@ -60,8 +60,8 @@
       Assert.assertNotNull(artifactByName);
       IAtsTeamWorkflow teamWf = atsApi.getWorkItemService().getTeamWf(artifactByName);
 
-      XTaskEstManagerDemo mgr = new XTaskEstManagerDemo();
-      Collection<TaskEstDefinition> taskDefs = mgr.getTaskDefs();
+      XTaskEstDemoWidget mgr = new XTaskEstDemoWidget();
+      Collection<TaskEstDefinition> taskDefs = mgr.getTaskEstDefs();
 
       Assert.assertEquals("3 UserGroup tasks and 2 code tasks should be found", 5, taskDefs.size());
 
diff --git a/plugins/org.eclipse.osee.ats.ide/META-INF/MANIFEST.MF b/plugins/org.eclipse.osee.ats.ide/META-INF/MANIFEST.MF
index d672382..e38ff71 100644
--- a/plugins/org.eclipse.osee.ats.ide/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.osee.ats.ide/META-INF/MANIFEST.MF
@@ -67,6 +67,8 @@
  org.eclipse.osee.ats.ide.workflow,
  org.eclipse.osee.ats.ide.workflow.action,
  org.eclipse.osee.ats.ide.workflow.cr,
+ org.eclipse.osee.ats.ide.workflow.cr.estimates,
+ org.eclipse.osee.ats.ide.workflow.cr.estimates.demo,
  org.eclipse.osee.ats.ide.workflow.duplicate,
  org.eclipse.osee.ats.ide.workflow.goal,
  org.eclipse.osee.ats.ide.workflow.hooks,
@@ -74,9 +76,8 @@
  org.eclipse.osee.ats.ide.workflow.review.defect,
  org.eclipse.osee.ats.ide.workflow.review.role,
  org.eclipse.osee.ats.ide.workflow.task,
+ org.eclipse.osee.ats.ide.workflow.task.mini,
  org.eclipse.osee.ats.ide.workflow.task.related,
- org.eclipse.osee.ats.ide.workflow.task.widgets.estimates,
- org.eclipse.osee.ats.ide.workflow.task.widgets.estimates.demo,
  org.eclipse.osee.ats.ide.workflow.teamwf,
  org.eclipse.osee.ats.ide.workflow.transition,
  org.eclipse.osee.ats.ide.world,
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/actions/AddTaskAction.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/actions/AddTaskAction.java
index eec64ca..c1cfb84 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/actions/AddTaskAction.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/actions/AddTaskAction.java
@@ -24,7 +24,8 @@
  * @author Donald G. Dunne
  */
 public class AddTaskAction extends AbstractAtsAction {
-   private final ISelectedTeamWorkflowArtifacts selectedTeamWfs;
+
+   protected final ISelectedTeamWorkflowArtifacts selectedTeamWfs;
 
    public AddTaskAction(ISelectedTeamWorkflowArtifacts selectedTeamWfs) {
       super("Add Task", IAction.AS_PUSH_BUTTON);
@@ -33,7 +34,11 @@
       setToolTipText(getText());
    }
 
-   public void updateEnablement() {
+   public void updateEnablement(boolean enabled) {
+      if (!enabled) {
+         setEnabled(enabled);
+         return;
+      }
       Collection<TeamWorkFlowArtifact> teamWfs = selectedTeamWfs.getSelectedTeamWorkflowArtifacts();
       setEnabled(teamWfs.size() == 1 && teamWfs.iterator().next().isInWork());
    }
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/actions/DeleteTasksAction.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/actions/DeleteTasksAction.java
index 933922d..a94b2d1 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/actions/DeleteTasksAction.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/actions/DeleteTasksAction.java
@@ -50,13 +50,17 @@
    }
 
    public void updateEnablement(Collection<Artifact> selected) {
-      for (Artifact art : selected) {
-         if (!(art instanceof TaskArtifact)) {
-            setEnabled(false);
-            return;
+      if (selected.isEmpty()) {
+         setEnabled(false);
+      } else {
+         for (Artifact art : selected) {
+            if (!(art instanceof TaskArtifact)) {
+               setEnabled(false);
+               return;
+            }
          }
+         setEnabled(true);
       }
-      setEnabled(true);
    }
 
    @Override
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/agile/AbstractXOpenSprintBurnupButton.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/agile/AbstractXOpenSprintBurnupButton.java
index 1edfcca..755c98d 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/agile/AbstractXOpenSprintBurnupButton.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/agile/AbstractXOpenSprintBurnupButton.java
@@ -73,7 +73,7 @@
       super.createControls(parent, horizontalSpan);
 
       XHyperlinkLabel external = new XHyperlinkLabel("Open Externally", getUrl(), true);
-      external.createWidgets(bComp, horizontalSpan);
+      external.createWidgets(comp, horizontalSpan);
       external.getControl().setForeground(Displays.getSystemColor(SWT.COLOR_BLUE));
       external.addXModifiedListener(new XModifiedListener() {
 
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/agile/XOpenSprintReportsButton.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/agile/XOpenSprintReportsButton.java
index f22ca5b..a637238 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/agile/XOpenSprintReportsButton.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/agile/XOpenSprintReportsButton.java
@@ -61,7 +61,7 @@
 
       XHyperlinkLabel external = new XHyperlinkLabel("Open Externally");
       external.setAddDefaultListener(false);
-      external.createWidgets(bComp, horizontalSpan);
+      external.createWidgets(comp, horizontalSpan);
       external.getControl().setForeground(Displays.getSystemColor(SWT.COLOR_BLUE));
       external.getControl().addListener(SWT.MouseUp, new Listener() {
          @Override
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/agile/XOpenStoredSprintReportsButton.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/agile/XOpenStoredSprintReportsButton.java
index 6fa39ad..9a36441 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/agile/XOpenStoredSprintReportsButton.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/agile/XOpenStoredSprintReportsButton.java
@@ -75,7 +75,7 @@
 
       XHyperlinkLabel external = new XHyperlinkLabel("Open Externally");
       external.setAddDefaultListener(false);
-      external.createWidgets(bComp, horizontalSpan);
+      external.createWidgets(comp, horizontalSpan);
       external.getControl().setForeground(Displays.getSystemColor(SWT.COLOR_BLUE));
       external.getControl().addListener(SWT.MouseUp, new Listener() {
          @Override
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/column/AssumptionsColumn.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/column/AssumptionsColumn.java
new file mode 100644
index 0000000..7f4644e
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/column/AssumptionsColumn.java
@@ -0,0 +1,53 @@
+/*********************************************************************
+ * 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.column;
+
+import org.eclipse.nebula.widgets.xviewer.core.model.SortDataType;
+import org.eclipse.nebula.widgets.xviewer.core.model.XViewerAlign;
+import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
+import org.eclipse.osee.ats.ide.util.xviewer.column.XViewerAtsAttributeValueColumn;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class AssumptionsColumn extends XViewerAtsAttributeValueColumn {
+
+   public static AssumptionsColumn instance = new AssumptionsColumn();
+
+   public static AssumptionsColumn getInstance() {
+      return instance;
+   }
+
+   private AssumptionsColumn() {
+      super(AtsAttributeTypes.Assumptions, 150, XViewerAlign.Left, false, SortDataType.String, true, "");
+      setActionRollup(true);
+   }
+
+   /**
+    * XViewer uses copies of column definitions so originals that are registered are not corrupted. Classes extending
+    * XViewerValueColumn MUST extend this constructor so the correct sub-class is created
+    */
+   @Override
+   public AssumptionsColumn copy() {
+      AssumptionsColumn newXCol = new AssumptionsColumn();
+      super.copy(this, newXCol);
+      return newXCol;
+   }
+
+   @Override
+   public boolean isMultiLineStringAttribute() {
+      return true;
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/column/PointsColumn.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/column/PointsColumn.java
index d187365..a3753a8 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/column/PointsColumn.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/column/PointsColumn.java
@@ -13,24 +13,58 @@
 
 package org.eclipse.osee.ats.ide.column;
 
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import org.eclipse.jface.window.Window;
+import org.eclipse.nebula.widgets.xviewer.IAltLeftClickProvider;
+import org.eclipse.nebula.widgets.xviewer.IMultiColumnEditProvider;
+import org.eclipse.nebula.widgets.xviewer.IXViewerValueColumn;
+import org.eclipse.nebula.widgets.xviewer.XViewer;
 import org.eclipse.nebula.widgets.xviewer.core.model.SortDataType;
 import org.eclipse.nebula.widgets.xviewer.core.model.XViewerAlign;
+import org.eclipse.nebula.widgets.xviewer.core.model.XViewerColumn;
+import org.eclipse.osee.ats.api.AtsApi;
+import org.eclipse.osee.ats.api.IAtsWorkItem;
+import org.eclipse.osee.ats.api.data.AtsArtifactTypes;
 import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
-import org.eclipse.osee.ats.ide.util.xviewer.column.XViewerAtsAttributeValueColumn;
+import org.eclipse.osee.ats.api.util.IAtsChangeSet;
+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.xviewer.column.XViewerAtsColumn;
+import org.eclipse.osee.framework.core.data.AttributeTypeToken;
+import org.eclipse.osee.framework.core.enums.EnumToken;
+import org.eclipse.osee.framework.jdk.core.type.OseeArgumentException;
+import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.Collections;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+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.skynet.core.utility.Artifacts;
+import org.eclipse.osee.framework.ui.plugin.util.ListSelectionDialog;
+import org.eclipse.osee.framework.ui.skynet.util.LogUtil;
+import org.eclipse.osee.framework.ui.skynet.widgets.dialog.EntryDialog;
+import org.eclipse.osee.framework.ui.swt.Displays;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
 
 /**
  * @author Donald G. Dunne
  */
-public class PointsColumn extends XViewerAtsAttributeValueColumn {
+public class PointsColumn extends XViewerAtsColumn implements IXViewerValueColumn, IAltLeftClickProvider, IMultiColumnEditProvider {
 
    public static PointsColumn instance = new PointsColumn();
+   private final AtsApi atsApi;
 
    public static PointsColumn getInstance() {
       return instance;
    }
 
    private PointsColumn() {
-      super(AtsAttributeTypes.Points, 40, XViewerAlign.Left, false, SortDataType.Integer, true, "");
+      super("ats.wi.points", "Points", 40, XViewerAlign.Left, false, SortDataType.Integer, true, "");
+      atsApi = AtsApiService.get();
    }
 
    /**
@@ -44,4 +78,147 @@
       return newXCol;
    }
 
+   @Override
+   public boolean handleAltLeftClick(TreeColumn treeColumn, TreeItem treeItem) {
+      try {
+         if (treeItem.getData() instanceof Artifact) {
+            Artifact useArt = AtsApiService.get().getQueryServiceIde().getArtifact(treeItem);
+            if (useArt.isOfType(AtsArtifactTypes.Action)) {
+               if (AtsApiService.get().getWorkItemService().getTeams(useArt).size() == 1) {
+                  useArt = AtsApiService.get().getQueryServiceIde().getArtifact(
+                     AtsApiService.get().getWorkItemService().getFirstTeam(useArt));
+               } else {
+                  return false;
+               }
+            }
+
+            if (!(useArt instanceof IAtsWorkItem)) {
+               return false;
+            }
+
+            IAtsWorkItem workItem = (IAtsWorkItem) useArt;
+
+            AttributeTypeToken pointsAttrType = atsApi.getAgileService().getPointsAttrType(workItem);
+            if (!atsApi.getAttributeResolver().isAttributeTypeValid(workItem, pointsAttrType)) {
+               return false;
+            }
+
+            boolean modified = promptChangePoints(workItem, pointsAttrType, atsApi);
+            XViewer xViewer = (XViewer) ((XViewerColumn) treeColumn.getData()).getXViewer();
+            if (modified) {
+               xViewer.update(useArt, null);
+               return true;
+            }
+         }
+      } catch (OseeCoreException ex) {
+         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+      }
+
+      return false;
+   }
+
+   public static boolean promptChangePoints(IAtsWorkItem workItem, AttributeTypeToken pointsAttrType, AtsApi atsApi) {
+      return promptChangePoints(java.util.Collections.singleton(workItem), pointsAttrType, atsApi);
+   }
+
+   public static boolean promptChangePoints(Collection<IAtsWorkItem> workItems, AttributeTypeToken pointsAttrType, AtsApi atsApi) {
+      if (pointsAttrType == AtsAttributeTypes.PointsNumeric) {
+         EntryDialog dialog = new EntryDialog("Enter Points", "Enter Points");
+         if (dialog.open() == Window.OK) {
+            String entry = dialog.getEntry();
+            if (org.eclipse.osee.framework.jdk.core.util.Strings.isNumeric(entry)) {
+               try {
+                  double points = Double.valueOf(entry);
+                  IAtsChangeSet changes = atsApi.createChangeSet("Set Points");
+                  for (IAtsWorkItem workItem : workItems) {
+                     changes.setSoleAttributeValue(workItem, pointsAttrType, points);
+                  }
+                  changes.executeIfNeeded();
+                  return true;
+               } catch (Exception ex) {
+                  // do nothing
+               }
+            }
+         }
+      } else {
+         Collection<EnumToken> enumValues = pointsAttrType.toEnum().getEnumValues();
+         Object[] values = enumValues.toArray(new Object[enumValues.size()]);
+         ListSelectionDialog dialog = new ListSelectionDialog(values, Displays.getActiveShell(), "Enter Points", null,
+            "Enter Points", 3, new String[] {"OK", "Cancel"}, 0);
+         if (dialog.open() == Window.OK) {
+            EnumToken entry = (EnumToken) values[dialog.getSelection()];
+            try {
+               IAtsChangeSet changes = atsApi.createChangeSet("Set Points");
+               for (IAtsWorkItem workItem : workItems) {
+                  changes.setSoleAttributeValue(workItem, pointsAttrType, entry.getName());
+               }
+               changes.executeIfNeeded();
+               return true;
+            } catch (Exception ex) {
+               // do nothing
+            }
+         }
+      }
+      return false;
+   }
+
+   @Override
+   public String getColumnText(Object element, XViewerColumn column, int columnIndex) {
+      try {
+         if (Artifacts.isOfType(element, AtsArtifactTypes.Action)) {
+            Set<String> strs = new HashSet<>();
+            for (IAtsTeamWorkflow teamWf : AtsApiService.get().getWorkItemService().getTeams(element)) {
+               AttributeTypeToken pointsAttrType = atsApi.getAgileService().getPointsAttrType(teamWf);
+               String ptsStr = atsApi.getAttributeResolver().getSoleAttributeValue(teamWf, pointsAttrType, "");
+               if (Strings.isValid(ptsStr)) {
+                  strs.add(ptsStr);
+               }
+            }
+            return Collections.toString("; ", strs);
+         }
+
+         if (!(element instanceof IAtsWorkItem)) {
+            return "";
+         }
+         IAtsWorkItem workItem = (IAtsWorkItem) element;
+         AttributeTypeToken pointsAttrType = atsApi.getAgileService().getPointsAttrType(workItem);
+         if (!atsApi.getAttributeResolver().isAttributeTypeValid(workItem, pointsAttrType)) {
+            return "";
+         }
+
+         String ptsStr = atsApi.getAttributeResolver().getSoleAttributeValueAsString(workItem, pointsAttrType, "");
+         return ptsStr;
+      } catch (OseeCoreException ex) {
+         return LogUtil.getCellExceptionString(ex);
+      }
+   }
+
+   @Override
+   public void handleColumnMultiEdit(TreeColumn treeColumn, Collection<TreeItem> treeItems) {
+      try {
+         AttributeTypeToken pointsAttrType = null;
+         Set<IAtsWorkItem> workItems = new HashSet<>();
+         for (TreeItem item : treeItems) {
+            if (item.getData() instanceof IAtsWorkItem) {
+               IAtsWorkItem workItem = (IAtsWorkItem) item.getData();
+               AttributeTypeToken ptsAttrType = atsApi.getAgileService().getPointsAttrType(workItem);
+               if (pointsAttrType == null) {
+                  pointsAttrType = ptsAttrType;
+               } else if (!pointsAttrType.equals(ptsAttrType)) {
+                  throw new OseeArgumentException(
+                     "Can not change points attribute for workflows of different attr types");
+               }
+               Artifact art = AtsApiService.get().getQueryServiceIde().getArtifact(item);
+               if (art instanceof IAtsWorkItem) {
+                  workItems.add((IAtsWorkItem) art);
+               }
+            }
+         }
+         promptChangePoints(workItems, pointsAttrType, atsApi);
+         return;
+      } catch (OseeCoreException ex) {
+         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+      }
+   }
+
 }
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/column/TleReviewedColumn.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/column/TleReviewedColumn.java
new file mode 100644
index 0000000..918accc
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/column/TleReviewedColumn.java
@@ -0,0 +1,198 @@
+/*********************************************************************
+ * Copyright (c) 2010 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.column;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.nebula.widgets.xviewer.IAltLeftClickProvider;
+import org.eclipse.nebula.widgets.xviewer.IMultiColumnEditProvider;
+import org.eclipse.nebula.widgets.xviewer.IXViewerValueColumn;
+import org.eclipse.nebula.widgets.xviewer.XViewer;
+import org.eclipse.nebula.widgets.xviewer.core.model.SortDataType;
+import org.eclipse.nebula.widgets.xviewer.core.model.XViewerAlign;
+import org.eclipse.nebula.widgets.xviewer.core.model.XViewerColumn;
+import org.eclipse.osee.ats.api.AtsApi;
+import org.eclipse.osee.ats.api.IAtsWorkItem;
+import org.eclipse.osee.ats.api.data.AtsArtifactTypes;
+import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
+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.XTleReviewedWidget;
+import org.eclipse.osee.ats.ide.util.xviewer.column.XViewerAtsColumn;
+import org.eclipse.osee.framework.core.data.AttributeTypeToken;
+import org.eclipse.osee.framework.core.operation.Operations;
+import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.Collections;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+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.skynet.core.utility.Artifacts;
+import org.eclipse.osee.framework.ui.skynet.util.LogUtil;
+import org.eclipse.osee.framework.ui.skynet.widgets.XAbstractSignDateAndByButton;
+import org.eclipse.osee.framework.ui.swt.Displays;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class TleReviewedColumn extends XViewerAtsColumn implements IXViewerValueColumn, IAltLeftClickProvider, IMultiColumnEditProvider {
+
+   public static TleReviewedColumn instance = new TleReviewedColumn();
+   private final AtsApi atsApi;
+
+   public static TleReviewedColumn getInstance() {
+      return instance;
+   }
+
+   private TleReviewedColumn() {
+      super("ats.taskest.reviewed", "TLE Reviewed", 20, XViewerAlign.Left, true, SortDataType.String, true, "");
+      atsApi = AtsApiService.get();
+   }
+
+   /**
+    * XViewer uses copies of column definitions so originals that are registered are not corrupted. Classes extending
+    * XViewerValueColumn MUST extend this constructor so the correct sub-class is created
+    */
+   @Override
+   public TleReviewedColumn copy() {
+      TleReviewedColumn newXCol = new TleReviewedColumn();
+      super.copy(this, newXCol);
+      return newXCol;
+   }
+
+   @Override
+   public boolean handleAltLeftClick(TreeColumn treeColumn, TreeItem treeItem) {
+      try {
+         if (treeItem.getData() instanceof Artifact) {
+            Artifact useArt = AtsApiService.get().getQueryServiceIde().getArtifact(treeItem);
+            if (useArt.isOfType(AtsArtifactTypes.Action)) {
+               if (AtsApiService.get().getWorkItemService().getTeams(useArt).size() == 1) {
+                  useArt = AtsApiService.get().getQueryServiceIde().getArtifact(
+                     AtsApiService.get().getWorkItemService().getFirstTeam(useArt));
+               } else {
+                  return false;
+               }
+            }
+
+            if (!(useArt instanceof IAtsWorkItem)) {
+               return false;
+            }
+
+            IAtsWorkItem workItem = (IAtsWorkItem) useArt;
+
+            XTleReviewedWidget widget = new XTleReviewedWidget();
+            widget.setArtifact((Artifact) workItem.getStoreObject());
+            widget.handleSelection();
+            XViewer xViewer = (XViewer) ((XViewerColumn) treeColumn.getData()).getXViewer();
+            xViewer.update(useArt, null);
+            return true;
+         }
+      } catch (OseeCoreException ex) {
+         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+      }
+
+      return false;
+   }
+
+   public static boolean promptChange(IAtsWorkItem workItem, AtsApi atsApi) {
+      return promptChange(java.util.Collections.singleton(workItem), atsApi);
+   }
+
+   public static boolean promptChange(final Collection<IAtsWorkItem> workItems, AtsApi atsApi) {
+      try {
+         // Ok --> 0, Cancel --> 1, Clear --> 2
+         int res = MessageDialog.open(3, Displays.getActiveShell(), "TLE Reviewed", "Has TLE Reviewed", SWT.NONE,
+            new String[] {"Ok", "Cancel", "Clear"});
+         Job signJob = new Job("Set TLE Reviewed") {
+
+            @Override
+            protected IStatus run(IProgressMonitor monitor) {
+               List<Artifact> artifacts = new ArrayList<>();
+               for (IAtsWorkItem workItem : workItems) {
+                  artifacts.add((Artifact) workItem.getStoreObject());
+               }
+               if (res == 2) {
+                  XAbstractSignDateAndByButton.setSigned(artifacts, AtsAttributeTypes.TleReviewedDate,
+                     AtsAttributeTypes.TleReviewedBy, "TLE Reviewed", false);
+               } else if (res == 0) {
+                  XAbstractSignDateAndByButton.setSigned(artifacts, AtsAttributeTypes.TleReviewedDate,
+                     AtsAttributeTypes.TleReviewedBy, "TLE Reviewed", true);
+               }
+               return Status.OK_STATUS;
+            }
+         };
+         Operations.scheduleJob(signJob, false, Job.SHORT, null);
+      } catch (OseeCoreException ex) {
+         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+      }
+      return true;
+   }
+
+   @Override
+   public String getColumnText(Object element, XViewerColumn column, int columnIndex) {
+      try {
+         if (Artifacts.isOfType(element, AtsArtifactTypes.Action)) {
+            Set<String> strs = new HashSet<>();
+            for (IAtsTeamWorkflow teamWf : AtsApiService.get().getWorkItemService().getTeams(element)) {
+               AttributeTypeToken pointsAttrType = atsApi.getAgileService().getPointsAttrType(teamWf);
+               String ptsStr = atsApi.getAttributeResolver().getSoleAttributeValue(teamWf, pointsAttrType, "");
+               if (Strings.isValid(ptsStr)) {
+                  strs.add(ptsStr);
+               }
+            }
+            return Collections.toString("; ", strs);
+         }
+
+         if (!(element instanceof IAtsWorkItem)) {
+            return "";
+         }
+         IAtsWorkItem workItem = (IAtsWorkItem) element;
+         return XAbstractSignDateAndByButton.getText((Artifact) workItem.getStoreObject(),
+            AtsAttributeTypes.TleReviewedDate, AtsAttributeTypes.TleReviewedBy);
+      } catch (OseeCoreException ex) {
+         return LogUtil.getCellExceptionString(ex);
+      }
+   }
+
+   @Override
+   public void handleColumnMultiEdit(TreeColumn treeColumn, Collection<TreeItem> treeItems) {
+      try {
+         Set<IAtsWorkItem> workItems = new HashSet<>();
+         for (TreeItem item : treeItems) {
+            if (item.getData() instanceof IAtsWorkItem) {
+               Artifact art = AtsApiService.get().getQueryServiceIde().getArtifact(item);
+               if (art instanceof IAtsWorkItem) {
+                  workItems.add((IAtsWorkItem) art);
+               }
+            }
+         }
+         promptChange(workItems, atsApi);
+      } catch (OseeCoreException ex) {
+         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+      }
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/header/WfeTransitionHeader.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/header/WfeTransitionHeader.java
index 2d72a16..70708d1 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/header/WfeTransitionHeader.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/editor/tab/workflow/header/WfeTransitionHeader.java
@@ -281,10 +281,12 @@
          @Override
          public void done(IJobChangeEvent event) {
             TransitionResults results = operation.getResults();
-            results.setAtsApi(AtsApiService.get());
-            if (results.isErrors()) {
-               TransitionResultsUi.reportDialog("Transition Failed", results);
-               AtsUtilClient.logExceptions(results);
+            if (results != null) {
+               results.setAtsApi(AtsApiService.get());
+               if (results.isErrors()) {
+                  TransitionResultsUi.reportDialog("Transition Failed", results);
+                  AtsUtilClient.logExceptions(results);
+               }
             }
             editor.getWorkFlowTab().setLoading(false);
             transitionHeader.refresh();
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 ced00f3..fdeced1 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
@@ -41,10 +41,11 @@
 import org.eclipse.osee.ats.ide.util.widgets.role.XUserRoleViewer;
 import org.eclipse.osee.ats.ide.util.widgets.task.XCreateChangeReportTasksXButton;
 import org.eclipse.osee.ats.ide.workflow.cr.XCreateEscapementDemoWfXButton;
+import org.eclipse.osee.ats.ide.workflow.cr.estimates.demo.XTaskEstDemoWidget;
+import org.eclipse.osee.ats.ide.workflow.cr.sibling.XSiblingWorldWidget;
 import org.eclipse.osee.ats.ide.workflow.review.defect.AtsXDefectValidator;
 import org.eclipse.osee.ats.ide.workflow.review.role.AtsXUserRoleValidator;
 import org.eclipse.osee.ats.ide.workflow.task.widgets.XCheckBoxesWithTaskGenExample;
-import org.eclipse.osee.ats.ide.workflow.task.widgets.estimates.demo.XTaskEstManagerDemo;
 import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
 import org.eclipse.osee.framework.logging.OseeLevel;
 import org.eclipse.osee.framework.logging.OseeLog;
@@ -91,8 +92,6 @@
          toReturn = new XIntroducedInVersionWidget(name);
       } else if (widgetName.equals(XCommitManager.WIDGET_NAME)) {
          toReturn = new XCommitManager();
-      } else if (widgetName.equals(XTaskEstManagerDemo.WIDGET_ID)) {
-         toReturn = new XTaskEstManagerDemo();
       } else if (widgetName.equals(XWorkingBranchLabel.WIDGET_NAME)) {
          toReturn = new XWorkingBranchLabel();
       } else if (widgetName.equals(XWorkingBranchButtonCreate.WIDGET_NAME)) {
@@ -216,10 +215,14 @@
          return new XHyperlinkFeatureDam(name);
       } else if (widgetName.equals(XDateWithValidateDam.WIDGET_ID)) {
          return new XDateWithValidateDam(name);
-      } else if (widgetName.equals(XPointsWidget.WIDGET_ID)) {
-         return new XPointsWidget();
+      } else if (widgetName.equals(XEstimatedPointsWidget.WIDGET_ID)) {
+         return new XEstimatedPointsWidget();
+      } else if (widgetName.equals(XTaskEstDemoWidget.WIDGET_ID)) {
+         return new XTaskEstDemoWidget();
       } else if (widgetName.equals(XTleReviewedWidget.WIDGET_ID)) {
          return new XTleReviewedWidget();
+      } else if (widgetName.equals(XSiblingWorldWidget.WIDGET_ID)) {
+         return new XSiblingWorldWidget();
       }
 
       return toReturn;
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XEstimatedPointsWidget.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XEstimatedPointsWidget.java
new file mode 100644
index 0000000..51086e4
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XEstimatedPointsWidget.java
@@ -0,0 +1,100 @@
+/*********************************************************************
+ * 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.util.widgets;
+
+import org.eclipse.osee.ats.api.AtsApi;
+import org.eclipse.osee.ats.api.IAtsWorkItem;
+import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
+import org.eclipse.osee.ats.api.util.IAtsChangeSet;
+import org.eclipse.osee.ats.ide.column.PointsColumn;
+import org.eclipse.osee.ats.ide.internal.AtsApiService;
+import org.eclipse.osee.framework.core.data.AttributeTypeToken;
+import org.eclipse.osee.framework.core.util.Result;
+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.XHyperlinkLabelValueSelDam;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class XEstimatedPointsWidget extends XHyperlinkLabelValueSelDam implements ArtifactWidget {
+
+   public static final Object WIDGET_ID = XEstimatedPointsWidget.class.getSimpleName();
+   public float points = 0;
+   private final AtsApi atsApi;
+   private IAtsWorkItem workItem;
+   private AttributeTypeToken pointsAttrType = null;
+
+   public XEstimatedPointsWidget() {
+      super("Estimated Points", true, 50);
+      atsApi = AtsApiService.get();
+   }
+
+   @Override
+   public String getCurrentValue() {
+      AttributeTypeToken pointsAttrType = getAttributeType();
+      if (pointsAttrType.isInvalid()) {
+         pointsAttrType = AtsAttributeTypes.PointsNumeric;
+      }
+      return atsApi.getAttributeResolver().getSoleAttributeValueAsString(workItem, pointsAttrType, "");
+   }
+
+   @Override
+   public boolean handleSelection() {
+      return PointsColumn.promptChangePoints(workItem, getPointsAttrType(), atsApi);
+   }
+
+   @Override
+   public boolean handleClear() {
+      IAtsChangeSet changes = atsApi.createChangeSet("Remove Points");
+      changes.deleteAttributes(workItem, getAttributeType());
+      changes.executeIfNeeded();
+      return true;
+   }
+
+   private AttributeTypeToken getPointsAttrType() {
+      if (pointsAttrType == null) {
+         pointsAttrType = atsApi.getAgileService().getPointsAttrType(workItem);
+      }
+      return pointsAttrType;
+   }
+
+   @Override
+   public Artifact getArtifact() {
+      return (Artifact) workItem.getStoreObject();
+   }
+
+   @Override
+   public void saveToArtifact() {
+      // do nothing
+   }
+
+   @Override
+   public void revert() {
+      // do nothing
+   }
+
+   @Override
+   public Result isDirty() {
+      return Result.FalseResult;
+   }
+
+   @Override
+   public void setArtifact(Artifact artifact) {
+      if (artifact instanceof IAtsWorkItem) {
+         workItem = (IAtsWorkItem) artifact;
+      }
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XPointsWidget.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XPointsWidget.java
deleted file mode 100644
index 9a2ce08..0000000
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/XPointsWidget.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*********************************************************************
- * 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.util.widgets;
-
-import java.util.Collection;
-import org.eclipse.jface.window.Window;
-import org.eclipse.osee.ats.api.AtsApi;
-import org.eclipse.osee.ats.api.IAtsWorkItem;
-import org.eclipse.osee.ats.api.agile.IAgileTeam;
-import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
-import org.eclipse.osee.ats.api.util.IAtsChangeSet;
-import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
-import org.eclipse.osee.ats.ide.internal.AtsApiService;
-import org.eclipse.osee.framework.core.data.AttributeTypeToken;
-import org.eclipse.osee.framework.core.enums.EnumToken;
-import org.eclipse.osee.framework.core.util.Result;
-import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
-import org.eclipse.osee.framework.ui.plugin.util.ListSelectionDialog;
-import org.eclipse.osee.framework.ui.skynet.widgets.ArtifactWidget;
-import org.eclipse.osee.framework.ui.skynet.widgets.XHyperlinkLabelCmdValueSelection;
-import org.eclipse.osee.framework.ui.skynet.widgets.dialog.EntryDialog;
-import org.eclipse.osee.framework.ui.swt.Displays;
-
-/**
- * @author Donald G. Dunne
- */
-public class XPointsWidget extends XHyperlinkLabelCmdValueSelection implements ArtifactWidget {
-
-   public static final Object WIDGET_ID = XPointsWidget.class.getSimpleName();
-   public float points = 0;
-   private final AtsApi atsApi;
-   private IAtsWorkItem workItem;
-   private AttributeTypeToken pointsAttrType = AttributeTypeToken.SENTINEL;
-
-   public XPointsWidget() {
-      super("Points", true, 50);
-      atsApi = AtsApiService.get();
-   }
-
-   @Override
-   public String getCurrentValue() {
-      AttributeTypeToken pointsAttrType = getPointsAttrType();
-      if (pointsAttrType == null) {
-         pointsAttrType = AtsAttributeTypes.PointsNumeric;
-      }
-      return atsApi.getAttributeResolver().getSoleAttributeValueAsString(workItem, pointsAttrType, "");
-   }
-
-   @Override
-   public boolean handleSelection() {
-      AttributeTypeToken pointsAttrType = getPointsAttrType();
-      if (pointsAttrType == AtsAttributeTypes.PointsNumeric) {
-         EntryDialog dialog = new EntryDialog("Enter Points", "Enter Points");
-         if (dialog.open() == Window.OK) {
-            String entry = dialog.getEntry();
-            if (org.eclipse.osee.framework.jdk.core.util.Strings.isNumeric(entry)) {
-               try {
-                  double points = Double.valueOf(entry);
-                  IAtsChangeSet changes = atsApi.createChangeSet("Set Points");
-                  changes.setSoleAttributeValue(workItem, pointsAttrType, points);
-                  changes.executeIfNeeded();
-                  return true;
-               } catch (Exception ex) {
-                  // do nothing
-               }
-            }
-         }
-      } else {
-         Collection<EnumToken> enumValues = pointsAttrType.toEnum().getEnumValues();
-         Object[] values = enumValues.toArray(new Object[enumValues.size()]);
-         ListSelectionDialog dialog = new ListSelectionDialog(values, Displays.getActiveShell(), "Enter Points", null,
-            "Enter Points", 3, new String[] {"OK", "Cancel"}, 0);
-         if (dialog.open() == Window.OK) {
-            EnumToken entry = (EnumToken) values[dialog.getSelection()];
-            try {
-               IAtsChangeSet changes = atsApi.createChangeSet("Set Points");
-               changes.setSoleAttributeValue(workItem, pointsAttrType, entry.getName());
-               changes.executeIfNeeded();
-               return true;
-            } catch (Exception ex) {
-               // do nothing
-            }
-         }
-      }
-      return false;
-   }
-
-   @Override
-   public boolean handleClear() {
-      IAtsChangeSet changes = atsApi.createChangeSet("Remove Points");
-      changes.deleteAttributes(workItem, getPointsAttrType());
-      changes.executeIfNeeded();
-      return true;
-   }
-
-   public AttributeTypeToken getPointsAttrType() {
-      if (pointsAttrType.isInvalid()) {
-         IAtsTeamWorkflow teamWf = workItem.getParentTeamWorkflow();
-         if (teamWf != null) {
-            IAgileTeam agileTeam = atsApi.getAgileService().getAgileTeam(teamWf);
-            if (agileTeam != null) {
-               pointsAttrType = atsApi.getAgileService().getAgileTeamPointsAttributeType(agileTeam);
-            }
-         }
-         if (pointsAttrType.isInvalid()) {
-            pointsAttrType = AtsAttributeTypes.PointsNumeric;
-         }
-      }
-      return pointsAttrType;
-   }
-
-   @Override
-   public Artifact getArtifact() {
-      return (Artifact) workItem.getStoreObject();
-   }
-
-   @Override
-   public void saveToArtifact() {
-      // do nothing
-   }
-
-   @Override
-   public void revert() {
-      // do nothing
-   }
-
-   @Override
-   public Result isDirty() {
-      return Result.FalseResult;
-   }
-
-   @Override
-   public void setArtifact(Artifact artifact) {
-      if (artifact instanceof IAtsWorkItem) {
-         workItem = (IAtsWorkItem) artifact;
-      }
-   }
-
-}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/task/XCreateChangeReportTasksXButton.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/task/XCreateChangeReportTasksXButton.java
index e0cfe04..dcadcd5 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/task/XCreateChangeReportTasksXButton.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/util/widgets/task/XCreateChangeReportTasksXButton.java
@@ -108,7 +108,7 @@
          @Override
          public void run() {
             setLabel(fName + " - Creating...");
-            bComp.layout(true);
+            comp.layout(true);
             parent.layout(true);
          }
       });
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/CreateNewChangeRequestBlam.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/CreateNewChangeRequestBlam.java
index b78216d..3872e9f 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/CreateNewChangeRequestBlam.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/CreateNewChangeRequestBlam.java
@@ -13,6 +13,7 @@
 package org.eclipse.osee.ats.ide.workflow.cr;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
@@ -184,10 +185,12 @@
          descWidget = (XText) xWidget;
       } else if (xWidget.getLabel().equals(CHANGE_TYPE)) {
          changeWidget = (XCombo) xWidget;
+         changeWidget.setDataStrings(Arrays.asList("Improvement", "Problem"));
       } else if (xWidget.getLabel().equals(PRIORITY)) {
          priorityWidget = (XCombo) xWidget;
       } else if (xWidget.getLabel().equals(PROGRAM)) {
          XCombo programCombo = (XCombo) xWidget;
+         programCombo.setToolTip("Selection if multiple Change Request programs exist");
          List<String> aiStrs = new ArrayList<String>();
          for (IAtsActionableItem ai : getProgramCrAis()) {
             aiStrs.add(ai.getName());
@@ -196,6 +199,9 @@
          if (aiStrs.size() == 1) {
             programCombo.getComboBox().select(1);
          }
+         if (aiStrs.size() == 1) {
+            programCombo.setEditable(false);
+         }
          programCombo.getLabelWidget().addMouseListener(new MouseAdapter() {
 
             @Override
@@ -242,6 +248,11 @@
    }
 
    @Override
+   public String getTitle() {
+      return getName();
+   }
+
+   @Override
    public boolean showInBlamSection() {
       return false;
    }
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/XCreateEscapementWfXButton.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/XCreateEscapementWfXButton.java
index dbc5615..0e4ca2d 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/XCreateEscapementWfXButton.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/XCreateEscapementWfXButton.java
@@ -123,7 +123,7 @@
          @Override
          public void run() {
             setLabel(fName + " - Creating...");
-            bComp.layout(true);
+            comp.layout(true);
             parent.layout(true);
          }
       });
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstDefinition.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/TaskEstDefinition.java
similarity index 96%
rename from plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstDefinition.java
rename to plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/TaskEstDefinition.java
index 7ede1cb..7dc8aa9 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstDefinition.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/TaskEstDefinition.java
@@ -10,7 +10,7 @@
  * Contributors:
  *     Boeing - initial API and implementation
  *******************************************************************************/
-package org.eclipse.osee.ats.ide.workflow.task.widgets.estimates;
+package org.eclipse.osee.ats.ide.workflow.cr.estimates;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstNameProvider.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/TaskEstNameProvider.java
similarity index 90%
rename from plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstNameProvider.java
rename to plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/TaskEstNameProvider.java
index df09a2f..7d09f8f 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstNameProvider.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/TaskEstNameProvider.java
@@ -10,7 +10,7 @@
  * Contributors:
  *     Boeing - initial API and implementation
  *******************************************************************************/
-package org.eclipse.osee.ats.ide.workflow.task.widgets.estimates;
+package org.eclipse.osee.ats.ide.workflow.cr.estimates;
 
 /**
  * @author Donald G. Dunne
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstOperations.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/TaskEstOperations.java
similarity index 97%
rename from plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstOperations.java
rename to plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/TaskEstOperations.java
index af19762..cc2ac8a 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstOperations.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/TaskEstOperations.java
@@ -10,7 +10,7 @@
  * Contributors:
  *     Boeing - initial API and implementation
  *******************************************************************************/
-package org.eclipse.osee.ats.ide.workflow.task.widgets.estimates;
+package org.eclipse.osee.ats.ide.workflow.cr.estimates;
 
 import java.util.Collection;
 import java.util.Date;
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstActionBar.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstActionBar.java
similarity index 76%
rename from plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstActionBar.java
rename to plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstActionBar.java
index 883d736..435218e 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstActionBar.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstActionBar.java
@@ -10,12 +10,11 @@
  * Contributors:
  *     Boeing - initial API and implementation
  *******************************************************************************/
-package org.eclipse.osee.ats.ide.workflow.task.widgets.estimates;
+package org.eclipse.osee.ats.ide.workflow.cr.estimates;
 
 import java.util.Date;
 import org.eclipse.jface.window.Window;
 import org.eclipse.osee.ats.api.AtsApi;
-import org.eclipse.osee.ats.api.demo.DemoWorkDefinitions;
 import org.eclipse.osee.ats.api.task.JaxAtsTask;
 import org.eclipse.osee.ats.api.task.NewTaskData;
 import org.eclipse.osee.ats.api.task.NewTaskSet;
@@ -43,19 +42,18 @@
 /**
  * @author Donald G. Dunne
  */
-public class TaskEstActionBar implements TaskEstNameProvider {
+public class XTaskEstActionBar implements TaskEstNameProvider {
 
-   private final XTaskEstManager xTaskEstManager;
+   private final XTaskEstWidget xTaskEstWidget;
    private Label extraInfoLabel;
    private ToolItem refreshItem;
-   private ToolItem addItem;
    private final AtsApi atsApi;
    private final IAtsTeamWorkflow teamWf;
 
-   public TaskEstActionBar(XTaskEstManager xTaskEstManager) {
-      this.xTaskEstManager = xTaskEstManager;
+   public XTaskEstActionBar(XTaskEstWidget xTaskEstWidget) {
+      this.xTaskEstWidget = xTaskEstWidget;
       atsApi = AtsApiService.get();
-      this.teamWf = xTaskEstManager.getArtifact();
+      this.teamWf = xTaskEstWidget.getTeamWf();
    }
 
    public ToolBar createTaskActionBar(Composite parent) {
@@ -72,7 +70,7 @@
       extraInfoLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
       extraInfoLabel.setText("");
       extraInfoLabel.setForeground(Displays.getSystemColor(SWT.COLOR_RED));
-      xTaskEstManager.setExtraInfoLabel(extraInfoLabel);
+      xTaskEstWidget.setExtraInfoLabel(extraInfoLabel);
 
       Composite rightComp = new Composite(bComp, SWT.NONE);
       rightComp.setLayout(new GridLayout());
@@ -82,10 +80,11 @@
       GridData gd = new GridData(GridData.FILL_HORIZONTAL);
       toolBar.setLayoutData(gd);
 
-      addItem = new ToolItem(toolBar, SWT.PUSH);
-      addItem.setImage(ImageManager.getImage(FrameworkImage.GREEN_PLUS));
-      addItem.setToolTipText("Create Checked Estimating Task(s)");
-      addItem.addSelectionListener(new SelectionAdapter() {
+      ToolItem addCannedItem = new ToolItem(toolBar, SWT.PUSH);
+      addCannedItem.setText("Create Checked Task(s)");
+      addCannedItem.setImage(ImageManager.getImage(FrameworkImage.GREEN_PLUS));
+      addCannedItem.setToolTipText("Create Checked Estimating Task(s)");
+      addCannedItem.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
             createCannedTasks();
@@ -93,10 +92,11 @@
 
       });
 
-      addItem = new ToolItem(toolBar, SWT.PUSH);
-      addItem.setImage(ImageManager.getImage(AtsImage.NEW_TASK));
-      addItem.setToolTipText("Create Manual Estimating Task(s)");
-      addItem.addSelectionListener(new SelectionAdapter() {
+      ToolItem addManualItem = new ToolItem(toolBar, SWT.PUSH);
+      addManualItem.setText("Create Manual Task(s)");
+      addManualItem.setImage(ImageManager.getImage(AtsImage.NEW_TASK));
+      addManualItem.setToolTipText("Create Manual Estimating Task(s) from entered list");
+      addManualItem.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
             createManualTasks();
@@ -104,13 +104,15 @@
 
       });
 
+      new ToolItem(toolBar, SWT.SEPARATOR);
+
       refreshItem = new ToolItem(toolBar, SWT.PUSH);
       refreshItem.setImage(ImageManager.getImage(PluginUiImage.REFRESH));
       refreshItem.setToolTipText("Refresh");
       refreshItem.addSelectionListener(new SelectionAdapter() {
          @Override
          public void widgetSelected(SelectionEvent e) {
-            xTaskEstManager.loadTable();
+            xTaskEstWidget.loadTable();
          }
       });
 
@@ -130,7 +132,7 @@
       NewTaskData newTaskData = NewTaskData.create(newTaskSet, teamWf);
       for (String name : dialog.getEntry().split("\r\n")) {
          if (Strings.isValid(name)) {
-            newTaskData.setTaskWorkDef(xTaskEstManager.getTaskWorkDefTok());
+            newTaskData.setTaskWorkDef(xTaskEstWidget.getTaskWorkDefTok());
             JaxAtsTask task = new JaxAtsTask();
             task.setName(name);
             task.setCreatedByUserId(atsApi.getUserService().getCurrentUserId());
@@ -143,7 +145,7 @@
       } else {
          newTaskSet = atsApi.getTaskService().createTasks(newTaskSet);
          if (newTaskSet.isErrors() || newTaskSet.getTaskData().isEmpty()) {
-            XResultDataUI.report(newTaskSet.getResults(), XTaskEstManager.NAME);
+            XResultDataUI.report(newTaskSet.getResults(), XTaskEstWidget.NAME);
          } else {
             AWorkbench.popup("New Tasks Created");
          }
@@ -151,16 +153,15 @@
    }
 
    protected void createCannedTasks() {
-      if (xTaskEstManager.getItems().isEmpty()) {
+      if (xTaskEstWidget.getTaskEstDefsFromTableChecked().isEmpty()) {
          AWorkbench.popup("No Tasks Selected");
          return;
       }
-      TaskEstOperations ops =
-         new TaskEstOperations(atsApi, DemoWorkDefinitions.WorkDef_Task_Demo_For_CR_Estimating, this);
-      NewTaskSet newTaskSet = ops.createCannedTasks(teamWf, xTaskEstManager.getItems());
+      TaskEstOperations ops = new TaskEstOperations(atsApi, xTaskEstWidget.getTaskWorkDefTok(), this);
+      NewTaskSet newTaskSet = ops.createCannedTasks(teamWf, xTaskEstWidget.getTaskEstDefsFromTableChecked());
 
       if (newTaskSet.isErrors() || newTaskSet.getTaskData().isEmpty()) {
-         XResultDataUI.report(newTaskSet.getResults(), XTaskEstManager.NAME);
+         XResultDataUI.report(newTaskSet.getResults(), XTaskEstWidget.NAME);
       } else {
          AWorkbench.popup("New Tasks Created");
       }
@@ -168,7 +169,7 @@
 
    @Override
    public String getTaskName(TaskEstDefinition ted) {
-      return String.format(xTaskEstManager.getTaskNameFormat(), ted.getName());
+      return String.format(xTaskEstWidget.getTaskNameFormat(), ted.getName());
    }
 
 }
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstContentProvider.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstContentProvider.java
new file mode 100644
index 0000000..8ceba13
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstContentProvider.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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.workflow.cr.estimates;
+
+import java.util.Collection;
+import org.eclipse.osee.ats.ide.world.WorldContentProvider;
+import org.eclipse.osee.ats.ide.world.WorldXViewer;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class XTaskEstContentProvider extends WorldContentProvider {
+
+   public XTaskEstContentProvider(WorldXViewer WorldXViewer) {
+      super(WorldXViewer);
+   }
+
+   @Override
+   public Object[] getChildren(Object parentElement) {
+      if (parentElement instanceof Collection<?>) {
+         return ((Collection<?>) parentElement).toArray();
+      }
+      return org.eclipse.osee.framework.jdk.core.util.Collections.EMPTY_ARRAY;
+   }
+
+   @Override
+   public boolean hasChildren(Object element) {
+      if (element instanceof Collection<?>) {
+         return true;
+      }
+      return false;
+   }
+
+   @Override
+   public Object getParent(Object element) {
+      return null;
+   }
+
+   @Override
+   public Object[] getElements(Object inputElement) {
+      if (inputElement instanceof String) {
+         return new Object[] {inputElement};
+      }
+      return getChildren(inputElement);
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstLabelProvider.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstLabelProvider.java
new file mode 100644
index 0000000..1d94060
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstLabelProvider.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * 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.workflow.cr.estimates;
+
+import org.eclipse.nebula.widgets.xviewer.core.model.XViewerColumn;
+import org.eclipse.osee.ats.api.AtsApi;
+import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
+import org.eclipse.osee.ats.api.util.AtsImage;
+import org.eclipse.osee.ats.api.workflow.IAtsTask;
+import org.eclipse.osee.ats.ide.internal.AtsApiService;
+import org.eclipse.osee.ats.ide.world.WorldLabelProvider;
+import org.eclipse.osee.framework.core.enums.CoreRelationTypes;
+import org.eclipse.osee.framework.ui.skynet.FrameworkImage;
+import org.eclipse.osee.framework.ui.swt.ImageManager;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class XTaskEstLabelProvider extends WorldLabelProvider {
+
+   private final AtsApi atsApi;
+
+   public XTaskEstLabelProvider(XTaskEstViewer xTaskEstViewer) {
+      super(xTaskEstViewer);
+      this.atsApi = AtsApiService.get();
+   }
+
+   @Override
+   public Color getForeground(Object element, XViewerColumn xCol, int columnIndex) {
+      if (element instanceof TaskEstDefinition) {
+         return null;
+      }
+      return super.getForeground(element, xCol, columnIndex);
+   }
+
+   @Override
+   public Color getBackground(Object element, XViewerColumn xCol, int columnIndex) {
+      if (element instanceof TaskEstDefinition) {
+         return null;
+      }
+      return super.getBackground(element, xCol, columnIndex);
+   }
+
+   @Override
+   public String getColumnText(Object element, int columnIndex) {
+      XViewerColumn xViewerColumn = getTreeColumnOffIndex(columnIndex);
+      if (element instanceof TaskEstDefinition) {
+         TaskEstDefinition ted = (TaskEstDefinition) element;
+         if (xViewerColumn.getName().equals("Title")) {
+            return ted.getName();
+         } else if (xViewerColumn.getName().equals("Select")) {
+            return ted.isChecked() ? "Selected" : "";
+         }
+      } else if (element instanceof IAtsTask) {
+         IAtsTask task = (IAtsTask) element;
+         if (xViewerColumn.getName().equals("Select")) {
+            if (task.getTags().contains("canned")) {
+               return "Canned";
+            } else {
+               return "Manual ";
+            }
+         } else if (xViewerColumn.getName().equals("Attachments")) {
+            int count =
+               atsApi.getRelationResolver().getRelatedCount(task, CoreRelationTypes.SupportingInfo_SupportingInfo);
+            if (count > 0) {
+               return String.valueOf(count);
+            } else {
+               return "";
+            }
+         } else if (xViewerColumn.getName().equals("TLE Reviewed")) {
+            return "";
+         }
+      }
+      return super.getColumnText(element, columnIndex);
+   }
+
+   @Override
+   public Image getColumnImage(Object element, XViewerColumn xCol, int columnIndex) {
+      XViewerColumn xViewerColumn = getTreeColumnOffIndex(columnIndex);
+      if (element instanceof TaskEstDefinition) {
+         TaskEstDefinition ted = (TaskEstDefinition) element;
+         if (xViewerColumn.getName().equals("Select")) {
+            if (ted.isChecked()) {
+               return ImageManager.getImage(FrameworkImage.CHECKBOX_CHECK_TRUE);
+            } else {
+               return ImageManager.getImage(FrameworkImage.CHECKBOX_CHECK_UNSET);
+            }
+         }
+      } else if (element instanceof IAtsTask) {
+         IAtsTask task = (IAtsTask) element;
+         if (xViewerColumn.getName().equals("Select")) {
+            return ImageManager.getImage(AtsImage.TASK);
+         } else if (xViewerColumn.getName().equals("TLE Reviewed")) {
+            if (atsApi.getAttributeResolver().getAttributeCount(task, AtsAttributeTypes.TleReviewedBy) > 0) {
+               return ImageManager.getImage(AtsImage.CHECK_BLUE);
+            }
+         }
+      }
+      return null;
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstViewer.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstViewer.java
new file mode 100644
index 0000000..b76b19f
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstViewer.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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.workflow.cr.estimates;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.nebula.widgets.xviewer.IXViewerFactory;
+import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
+import org.eclipse.osee.ats.ide.workflow.task.TaskXViewer;
+import org.eclipse.osee.framework.ui.swt.IDirtiableEditor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class XTaskEstViewer extends TaskXViewer {
+
+   public XTaskEstViewer(Composite parent, int style, IXViewerFactory xViewerFactory, IDirtiableEditor editor, IAtsTeamWorkflow teamWf) {
+      super(parent, style, xViewerFactory, editor, teamWf);
+   }
+
+   @Override
+   public boolean handleLeftClickInIconArea(TreeColumn treeColumn, TreeItem treeItem) {
+      List<TaskEstDefinition> selected = getSelected();
+      if (selected.isEmpty()) {
+         return false;
+      }
+      TaskEstDefinition ted = selected.iterator().next();
+      if (ted.hasTask()) {
+         return false;
+      }
+      ted.setChecked(!ted.isChecked());
+      refresh(ted);
+      return true;
+   }
+
+   @Override
+   protected boolean isAddTaskEnabled() {
+      return false;
+   }
+
+   public List<TaskEstDefinition> getSelected() {
+      List<TaskEstDefinition> teds = new ArrayList<>();
+      TreeItem items[] = getTree().getSelection();
+      if (items.length > 0) {
+         for (TreeItem item : items) {
+            if (item.getData() instanceof TaskEstDefinition) {
+               teds.add((TaskEstDefinition) item.getData());
+            }
+         }
+      }
+      return teds;
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstWidget.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstWidget.java
new file mode 100644
index 0000000..9f5f817
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstWidget.java
@@ -0,0 +1,268 @@
+/*******************************************************************************
+ * 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.workflow.cr.estimates;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osee.ats.api.agile.IAgileTeam;
+import org.eclipse.osee.ats.api.config.tx.IAtsTeamDefinitionArtifactToken;
+import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
+import org.eclipse.osee.ats.api.workflow.IAtsTask;
+import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
+import org.eclipse.osee.ats.api.workflow.cr.TaskEstUtil;
+import org.eclipse.osee.ats.ide.internal.Activator;
+import org.eclipse.osee.ats.ide.workflow.task.TaskXViewer;
+import org.eclipse.osee.ats.ide.workflow.task.mini.XMiniTaskWidget;
+import org.eclipse.osee.ats.ide.world.WorldContentProvider;
+import org.eclipse.osee.ats.ide.world.WorldLabelProvider;
+import org.eclipse.osee.framework.core.data.ArtifactId;
+import org.eclipse.osee.framework.core.data.ArtifactToken;
+import org.eclipse.osee.framework.core.data.AttributeTypeToken;
+import org.eclipse.osee.framework.core.data.UserToken;
+import org.eclipse.osee.framework.core.enums.CoreAttributeTypes;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.type.Pair;
+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.swt.Displays;
+import org.eclipse.osee.framework.ui.swt.Widgets;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.ToolBar;
+
+/**
+ * Table showing siblings and roll-up for Team Workflow
+ *
+ * @author Donald G. Dunne
+ */
+public abstract class XTaskEstWidget extends XMiniTaskWidget {
+
+   public static final String WIDGET_ID = XTaskEstWidget.class.getSimpleName();
+   private static final String INFO_STRING =
+      "Select to create estimating tasks.  Complete all estimates/tasks.  Double-Click to open/edit task/fields.";
+   private AttributeTypeToken pointsAttrType;
+   private final List<Object> input = new ArrayList<>();
+   private XTaskEstViewer xTaskEstViewer;
+   public static String NAME = "Estimate Manager";
+
+   public XTaskEstWidget() {
+      super(NAME, new XTaskEstXViewerFactory());
+   }
+
+   @Override
+   public ToolBar createActionBar(Composite tableComp) {
+      XTaskEstActionBar actionBar = new XTaskEstActionBar(this);
+      ToolBar toolBar = actionBar.createTaskActionBar(tableComp);
+      return toolBar;
+   }
+
+   @Override
+   protected TaskXViewer createXTaskViewer(Composite tableComp) {
+      xTaskEstViewer = new XTaskEstViewer(tableComp, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION,
+         new XTaskEstXViewerFactory(), null, teamWf);
+      xTaskViewer = xTaskEstViewer;
+      return xTaskViewer;
+   }
+
+   @Override
+   protected WorldLabelProvider getWorldLabelProvider() {
+      return new XTaskEstLabelProvider(xTaskEstViewer);
+   }
+
+   @Override
+   protected WorldContentProvider getWorldContentProvider() {
+      return new XTaskEstContentProvider(xTaskViewer);
+   }
+
+   @Override
+   public Artifact getArtifact() {
+      return (Artifact) teamWf.getStoreObject();
+   }
+
+   @Override
+   public void revert() {
+      // do nothing
+   }
+
+   @Override
+   public Result isDirty() {
+      return Result.FalseResult;
+   }
+
+   @Override
+   public Pair<Integer, String> getExtraInfoString() {
+      return new Pair<Integer, String>(SWT.COLOR_BLACK, "Edit (most) fields here or double-click to open.");
+   }
+
+   public IAtsTeamWorkflow getTeamWf() {
+      return teamWf;
+   }
+
+   @Override
+   public void saveToArtifact() {
+      // do nothing
+   }
+
+   public abstract Collection<TaskEstDefinition> getTaskEstDefs();
+
+   public Collection<TaskEstDefinition> getTaskEstDefsFromTable() {
+      List<TaskEstDefinition> teds = new ArrayList<>();
+      for (Object obj : input) {
+         if (obj instanceof TaskEstDefinition) {
+            teds.add((TaskEstDefinition) obj);
+         }
+      }
+      return teds;
+   }
+
+   public Collection<TaskEstDefinition> getTaskEstDefsFromTableChecked() {
+      List<TaskEstDefinition> teds = new ArrayList<>();
+      for (TaskEstDefinition ted : getTaskEstDefsFromTable()) {
+         if (ted.isChecked()) {
+            teds.add(ted);
+         }
+      }
+      return teds;
+   }
+
+   /**
+    * @return TaskEstDefinitions for missing tasks or IAtsTask for created tasks
+    */
+   private Collection<Object> getInput() {
+      input.clear();
+      Collection<TaskEstDefinition> taskDefs = getTaskEstDefs();
+      Collection<IAtsTask> tasks = atsApi.getTaskService().getTasks(teamWf);
+      // For any task matching ted, remove ted from list and add task
+      for (IAtsTask task : atsApi.getTaskService().getTasks(teamWf)) {
+         for (TaskEstDefinition ted : getTaskEstDefs()) {
+            if (task.hasTag(ted.getIdString())) {
+               taskDefs.remove(ted);
+               tasks.remove(task);
+               input.add(task);
+               break;
+            }
+         }
+      }
+      // Add remaining tasks and teds
+      input.addAll(tasks);
+      input.addAll(taskDefs);
+      return input;
+   }
+
+   @Override
+   public void loadTable() {
+      try {
+         if (xTaskViewer != null && xTaskViewer.getContentProvider() != null) {
+            xTaskViewer.setInput(getInput());
+            xTaskViewer.refresh();
+         }
+      } catch (Exception ex) {
+         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+      }
+   }
+
+   @Override
+   public void refresh() {
+      if (xTaskViewer == null || xTaskViewer.getTree() == null || xTaskViewer.getTree().isDisposed()) {
+         return;
+      }
+      super.refresh();
+
+      float points = 0;
+      for (IAtsTask task : atsApi.getTaskService().getTasks(teamWf)) {
+         points +=
+            Float.valueOf(atsApi.getAttributeResolver().getSoleAttributeValueAsString(task, getPointsAttrType(), "0"));
+      }
+      pointsLabel.setValueText(String.valueOf(points));
+   }
+
+   public AttributeTypeToken getPointsAttrType() {
+      if (pointsAttrType == null) {
+         IAgileTeam agileTeam = atsApi.getAgileService().getAgileTeam(teamWf);
+         if (agileTeam != null) {
+            pointsAttrType = atsApi.getAgileService().getAgileTeamPointsAttributeType(agileTeam);
+         }
+         if (pointsAttrType == null) {
+            pointsAttrType = AtsAttributeTypes.PointsNumeric;
+         }
+      }
+      return pointsAttrType;
+   }
+
+   private void updateExtraInfoLabel(final int color, final String infoStr) {
+      Displays.ensureInDisplayThread(new Runnable() {
+         @Override
+         public void run() {
+            if (Widgets.isAccessible(extraInfoLabel)) {
+               String currentString = extraInfoLabel.getText();
+               if (infoStr == null && currentString != null || //
+               infoStr != null && currentString == null || //
+               infoStr != null && currentString != null && !infoStr.equals(currentString)) {
+                  extraInfoLabel.setText(INFO_STRING);
+               }
+               extraInfoLabel.setForeground(Displays.getSystemColor(color));
+            }
+         }
+      });
+   }
+
+   /**
+    * Create dynamic TEDs from children UserGroups off given teamDef where UserGroup has TaskEst static id
+    */
+   protected void getTaskDefsFromUserGroupsOff(IAtsTeamDefinitionArtifactToken teamDef, List<TaskEstDefinition> taskDefs) {
+      for (ArtifactToken childArt : atsApi.getRelationResolver().getChildren(teamDef)) {
+         if (atsApi.getAttributeResolver().getAttributesToStringList(childArt, CoreAttributeTypes.StaticId).contains(
+            TaskEstUtil.TASK_EST_STATIC_ID)) {
+            String desc = atsApi.getAttributeResolver().getSoleAttributeValueAsString(childArt,
+               CoreAttributeTypes.Description, "");
+            List<ArtifactId> assigneeAccountIds = new LinkedList<>();
+            for (UserToken user : atsApi.getUserGroupService().getUserGroup(childArt).getMembers()) {
+               assigneeAccountIds.add(ArtifactId.valueOf(user.getId()));
+            }
+            taskDefs.add(new TaskEstDefinition(childArt.getId(), childArt.getName(), desc, assigneeAccountIds));
+         }
+      }
+   }
+
+   @Override
+   public IStatus isValid() {
+      Status returnStatus = new Status(IStatus.OK, getClass().getSimpleName(), "");
+      try {
+         int backgroundColor = SWT.COLOR_BLACK;
+         boolean inWork = false;
+         for (IAtsTask task : atsApi.getTaskService().getTasks(teamWf)) {
+            if (task.isInWork()) {
+               inWork = true;
+               returnStatus =
+                  new Status(IStatus.ERROR, getClass().getSimpleName(), "All tasks must be completed/cancelled.");
+               break;
+            }
+         }
+         if (inWork) {
+            backgroundColor = SWT.COLOR_RED;
+         }
+         updateExtraInfoLabel(backgroundColor, INFO_STRING);
+      } catch (OseeCoreException ex) {
+         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+         return new Status(IStatus.ERROR, getClass().getSimpleName(), ex.getLocalizedMessage());
+      }
+      return returnStatus;
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/XTaskEstManagerDesign.adoc b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstWidgetDesign.adoc
similarity index 65%
rename from plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/XTaskEstManagerDesign.adoc
rename to plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstWidgetDesign.adoc
index 710d1a9..3345754 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/XTaskEstManagerDesign.adoc
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstWidgetDesign.adoc
@@ -2,9 +2,9 @@
 
 == Usage
 
-XTaskEstManager is an XViewer based widget that can be used to generate a configured set of tasks.  One use cases is in the Change Request workflow where you want to create an Estimating task for a selected set of team and have them auto-assigned based on UserGroups.
+XTaskEstWidget is an XViewer based widget that can be used to generate a configured set of tasks.  One use cases is in the Change Request workflow where you want to create an Estimating task for a selected set of team and have them auto-assigned based on UserGroups.
 
-To use this widget, you must extend XTaskEstManager and implement the required methods.  See XTaskEstManagerDemo for an example.
+To use this widget, you must extend XTaskEstWidget and implement the required methods.  See XTaskEstDemoWidget for an example.
 
 There are 3 ways to create tasks
 * Create TaskEstimatingDefinitions in code.  This will add these items in the table and allow the user to check a box and create the task(s)
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstNameProvider.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstXViewerFactory.java
similarity index 61%
copy from plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstNameProvider.java
copy to plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstXViewerFactory.java
index df09a2f..af7291e 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstNameProvider.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/XTaskEstXViewerFactory.java
@@ -10,13 +10,19 @@
  * Contributors:
  *     Boeing - initial API and implementation
  *******************************************************************************/
-package org.eclipse.osee.ats.ide.workflow.task.widgets.estimates;
+package org.eclipse.osee.ats.ide.workflow.cr.estimates;
+
+import org.eclipse.osee.ats.ide.workflow.task.mini.MiniTaskXViewerFactory;
 
 /**
  * @author Donald G. Dunne
  */
-public interface TaskEstNameProvider {
+public class XTaskEstXViewerFactory extends MiniTaskXViewerFactory {
 
-   public String getTaskName(TaskEstDefinition ted);
+   public final static String NAMESPACE = "TaskEstXViewer";
+
+   public XTaskEstXViewerFactory() {
+      super(NAMESPACE);
+   }
 
 }
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/demo/XTaskEstManagerDemo.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/demo/XTaskEstDemoWidget.java
similarity index 69%
rename from plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/demo/XTaskEstManagerDemo.java
rename to plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/demo/XTaskEstDemoWidget.java
index e2714e4..e07b8f2 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/demo/XTaskEstManagerDemo.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/estimates/demo/XTaskEstDemoWidget.java
@@ -10,7 +10,7 @@
  * Contributors:
  *     Boeing - initial API and implementation
  *******************************************************************************/
-package org.eclipse.osee.ats.ide.workflow.task.widgets.estimates.demo;
+package org.eclipse.osee.ats.ide.workflow.cr.estimates.demo;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -18,18 +18,18 @@
 import org.eclipse.osee.ats.api.demo.DemoArtifactToken;
 import org.eclipse.osee.ats.api.demo.DemoWorkDefinitions;
 import org.eclipse.osee.ats.api.workdef.AtsWorkDefinitionToken;
-import org.eclipse.osee.ats.ide.workflow.task.widgets.estimates.TaskEstDefinition;
-import org.eclipse.osee.ats.ide.workflow.task.widgets.estimates.XTaskEstManager;
+import org.eclipse.osee.ats.api.workflow.IAtsTask;
+import org.eclipse.osee.ats.ide.workflow.cr.estimates.TaskEstDefinition;
+import org.eclipse.osee.ats.ide.workflow.cr.estimates.XTaskEstWidget;
 
 /**
  * @author Donald G. Dunne
  */
-public class XTaskEstManagerDemo extends XTaskEstManager {
-
-   public static final String WIDGET_ID = XTaskEstManagerDemo.class.getSimpleName();
+public class XTaskEstDemoWidget extends XTaskEstWidget {
+   public static final String WIDGET_ID = XTaskEstDemoWidget.class.getSimpleName();
 
    @Override
-   public Collection<TaskEstDefinition> getTaskDefs() {
+   public Collection<TaskEstDefinition> getTaskEstDefs() {
       List<TaskEstDefinition> taskDefs = new ArrayList<TaskEstDefinition>();
       taskDefs.add(new TaskEstDefinition(111L, "Integration Test", "Description", null));
       taskDefs.add(new TaskEstDefinition(112L, "Quality", "Description", null));
@@ -42,4 +42,9 @@
       return DemoWorkDefinitions.WorkDef_Task_Demo_For_CR_Estimating;
    }
 
+   @Override
+   public Collection<IAtsTask> getTasks() {
+      return atsApi.getTaskService().getTasks(teamWf);
+   }
+
 }
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/sibling/XSiblingActionBar.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/sibling/XSiblingActionBar.java
new file mode 100644
index 0000000..c7e8727
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/sibling/XSiblingActionBar.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * 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.workflow.cr.sibling;
+
+import java.util.Collection;
+import org.eclipse.osee.ats.api.IAtsWorkItem;
+import org.eclipse.osee.ats.api.util.AtsImage;
+import org.eclipse.osee.ats.ide.world.WorldEditor;
+import org.eclipse.osee.ats.ide.world.WorldEditorSimpleProvider;
+import org.eclipse.osee.framework.jdk.core.util.Collections;
+import org.eclipse.osee.framework.ui.plugin.PluginUiImage;
+import org.eclipse.osee.framework.ui.swt.Displays;
+import org.eclipse.osee.framework.ui.swt.ImageManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+/**
+ * @author Donald G. Dunne
+ */
+public class XSiblingActionBar {
+
+   private Label extraInfoLabel;
+   private ToolItem refreshItem;
+   private ToolItem addItem;
+   private final XSiblingWorldWidget siblingWorldWidget;
+
+   public XSiblingActionBar(XSiblingWorldWidget siblingWorldWidget) {
+      this.siblingWorldWidget = siblingWorldWidget;
+   }
+
+   public ToolBar createTaskActionBar(Composite parent) {
+
+      Composite bComp = new Composite(parent, SWT.NONE);
+      bComp.setLayout(new GridLayout(2, false));
+      bComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+      Composite leftComp = new Composite(bComp, SWT.NONE);
+      leftComp.setLayout(new GridLayout());
+      leftComp.setLayoutData(new GridData(GridData.BEGINNING | GridData.FILL_HORIZONTAL));
+
+      extraInfoLabel = new Label(leftComp, SWT.NONE);
+      extraInfoLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+      extraInfoLabel.setText("");
+      extraInfoLabel.setForeground(Displays.getSystemColor(SWT.COLOR_RED));
+      siblingWorldWidget.setExtraInfoLabel(extraInfoLabel);
+
+      Composite rightComp = new Composite(bComp, SWT.NONE);
+      rightComp.setLayout(new GridLayout());
+      rightComp.setLayoutData(new GridData(GridData.END));
+
+      ToolBar toolBar = new ToolBar(rightComp, SWT.FLAT | SWT.RIGHT);
+      GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+      toolBar.setLayoutData(gd);
+
+      addItem = new ToolItem(toolBar, SWT.PUSH);
+      addItem.setImage(ImageManager.getImage(AtsImage.GLOBE));
+      addItem.setToolTipText("Open in ATS World Editor");
+      addItem.addSelectionListener(new SelectionAdapter() {
+         @Override
+         public void widgetSelected(SelectionEvent e) {
+            Collection<IAtsWorkItem> items = siblingWorldWidget.getItems();
+            WorldEditorSimpleProvider provider =
+               new WorldEditorSimpleProvider("Sibling Workflows", Collections.castAll(items));
+            WorldEditor.open(provider);
+         }
+
+      });
+
+      addItem = new ToolItem(toolBar, SWT.PUSH);
+      addItem.setImage(ImageManager.getImage(AtsImage.GLOBE_SELECT));
+      addItem.setToolTipText("Open Selected in ATS World Editor");
+      addItem.addSelectionListener(new SelectionAdapter() {
+         @Override
+         public void widgetSelected(SelectionEvent e) {
+            Collection<IAtsWorkItem> items =
+               Collections.castAll(siblingWorldWidget.getxWorldViewer().getSelectedTeamWorkflowArtifacts());
+            WorldEditorSimpleProvider provider =
+               new WorldEditorSimpleProvider("Selected Sibling Workflows", Collections.castAll(items));
+            WorldEditor.open(provider);
+         }
+
+      });
+
+      new ToolItem(toolBar, SWT.SEPARATOR);
+
+      refreshItem = new ToolItem(toolBar, SWT.PUSH);
+      refreshItem.setImage(ImageManager.getImage(PluginUiImage.REFRESH));
+      refreshItem.setToolTipText("Refresh");
+      refreshItem.addSelectionListener(new SelectionAdapter() {
+         @Override
+         public void widgetSelected(SelectionEvent e) {
+            siblingWorldWidget.loadTable();
+         }
+      });
+
+      new ToolItem(toolBar, SWT.SEPARATOR);
+
+      return toolBar;
+   }
+
+}
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
new file mode 100644
index 0000000..0ea8ff3
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/sibling/XSiblingWorldWidget.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * 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.workflow.cr.sibling;
+
+import java.util.Collection;
+import org.eclipse.osee.ats.api.IAtsWorkItem;
+import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
+import org.eclipse.osee.ats.ide.world.mini.XMiniWorldWidget;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.jdk.core.type.Pair;
+import org.eclipse.osee.framework.jdk.core.util.Collections;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.ui.skynet.widgets.ArtifactWidget;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.ToolBar;
+
+/**
+ * Table showing siblings and roll-up for Team Workflow
+ *
+ * @author Donald G. Dunne
+ */
+public class XSiblingWorldWidget extends XMiniWorldWidget implements ArtifactWidget {
+
+   public static final String WIDGET_ID = XSiblingWorldWidget.class.getSimpleName();
+   private IAtsTeamWorkflow teamWf;
+
+   public XSiblingWorldWidget() {
+      super("Sibling Workflows", new XSiblingXViewerFactory());
+   }
+
+   @Override
+   public ToolBar createActionBar(Composite tableComp) {
+      XSiblingActionBar actionBar = new XSiblingActionBar(this);
+      ToolBar toolBar = actionBar.createTaskActionBar(tableComp);
+      return toolBar;
+   }
+
+   @Override
+   public Collection<IAtsWorkItem> getWorkItems() {
+      Collection<IAtsTeamWorkflow> teamWfs = atsApi.getWorkItemService().getTeams(teamWf.getParentAction());
+      teamWfs.remove(teamWf);
+      return Collections.castAll(teamWfs);
+   }
+
+   @Override
+   public Artifact getArtifact() {
+      return (Artifact) teamWf.getStoreObject();
+   }
+
+   @Override
+   public void saveToArtifact() {
+      // do nothing
+   }
+
+   @Override
+   public void revert() {
+      // do nothing
+   }
+
+   @Override
+   public Result isDirty() {
+      return Result.FalseResult;
+   }
+
+   @Override
+   public void setArtifact(Artifact artifact) {
+      if (artifact instanceof IAtsTeamWorkflow) {
+         teamWf = (IAtsTeamWorkflow) artifact;
+      }
+   }
+
+   public IAtsTeamWorkflow getTeamWf() {
+      return teamWf;
+   }
+
+   @Override
+   public Pair<Integer, String> getExtraInfoString() {
+      return new Pair<Integer, String>(SWT.COLOR_BLACK, "Edit (most) fields here or double-click to open.");
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstNameProvider.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/sibling/XSiblingXViewerFactory.java
similarity index 61%
copy from plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstNameProvider.java
copy to plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/sibling/XSiblingXViewerFactory.java
index df09a2f..763706a 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstNameProvider.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/cr/sibling/XSiblingXViewerFactory.java
@@ -10,13 +10,19 @@
  * Contributors:
  *     Boeing - initial API and implementation
  *******************************************************************************/
-package org.eclipse.osee.ats.ide.workflow.task.widgets.estimates;
+package org.eclipse.osee.ats.ide.workflow.cr.sibling;
+
+import org.eclipse.osee.ats.ide.world.mini.MiniWorldXViewerFactory;
 
 /**
  * @author Donald G. Dunne
  */
-public interface TaskEstNameProvider {
+public class XSiblingXViewerFactory extends MiniWorldXViewerFactory {
 
-   public String getTaskName(TaskEstDefinition ted);
+   public final static String NAMESPACE = "SiblingXViewer";
+
+   public XSiblingXViewerFactory() {
+      super(NAMESPACE);
+   }
 
 }
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/TaskXViewer.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/TaskXViewer.java
index 2d38e46..d2ca782 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/TaskXViewer.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/TaskXViewer.java
@@ -21,7 +21,6 @@
 import org.eclipse.nebula.widgets.xviewer.IXViewerFactory;
 import org.eclipse.nebula.widgets.xviewer.XViewer;
 import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
-import org.eclipse.osee.ats.ide.actions.AddTaskAction;
 import org.eclipse.osee.ats.ide.actions.EditAssigneeAction;
 import org.eclipse.osee.ats.ide.actions.EditBlockedStatusAction;
 import org.eclipse.osee.ats.ide.actions.EditHoldStatusAction;
@@ -41,7 +40,6 @@
 public class TaskXViewer extends WorldXViewer {
 
    Action editAssigneeAction;
-   Action addNewTaskAction;
    EditBlockedStatusAction editBlockedStatusAction;
    EditHoldStatusAction editHoldStatusAction;
    private boolean tasksEditable = true;
@@ -60,7 +58,6 @@
       editAssigneeAction = new EditAssigneeAction(this, this);
       editBlockedStatusAction = new EditBlockedStatusAction(this);
       editHoldStatusAction = new EditHoldStatusAction(this);
-      addNewTaskAction = new AddTaskAction(this);
    }
 
    @Override
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/mini/MiniTaskXViewerFactory.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/mini/MiniTaskXViewerFactory.java
new file mode 100644
index 0000000..4356c83
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/mini/MiniTaskXViewerFactory.java
@@ -0,0 +1,120 @@
+/*********************************************************************
+ * 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.workflow.task.mini;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.nebula.widgets.xviewer.XViewer;
+import org.eclipse.nebula.widgets.xviewer.XViewerSorter;
+import org.eclipse.nebula.widgets.xviewer.core.model.SortDataType;
+import org.eclipse.nebula.widgets.xviewer.core.model.XViewerAlign;
+import org.eclipse.nebula.widgets.xviewer.core.model.XViewerColumn;
+import org.eclipse.osee.ats.api.column.AtsColumnIdValueColumn;
+import org.eclipse.osee.ats.api.config.AtsAttributeValueColumn;
+import org.eclipse.osee.ats.core.column.AtsColumnToken;
+import org.eclipse.osee.ats.ide.column.AssigneeColumnUI;
+import org.eclipse.osee.ats.ide.column.AssumptionsColumn;
+import org.eclipse.osee.ats.ide.column.AtsColumnIdUi;
+import org.eclipse.osee.ats.ide.column.DescriptionColumn;
+import org.eclipse.osee.ats.ide.column.PointsColumn;
+import org.eclipse.osee.ats.ide.column.TargetedVersionColumnUI;
+import org.eclipse.osee.ats.ide.column.TleReviewedColumn;
+import org.eclipse.osee.ats.ide.internal.AtsApiService;
+import org.eclipse.osee.ats.ide.util.xviewer.column.XViewerAtsAttributeValueColumn;
+import org.eclipse.osee.ats.ide.world.WorldXViewerFactory;
+import org.eclipse.osee.ats.ide.world.WorldXViewerSorter;
+import org.eclipse.osee.framework.ui.skynet.widgets.xviewer.skynet.SkynetXViewerFactory;
+
+/**
+ * @author Donald G. Dunne
+ */
+public abstract class MiniTaskXViewerFactory extends SkynetXViewerFactory {
+
+   public static XViewerColumn Check_Col = new XViewerColumn("ats.taskest.check", "Select", 53, XViewerAlign.Left, true,
+      SortDataType.String, false, "Check and plus to create canned tasks.  Add task to create manual tasks.");
+   public static XViewerColumn Attachments_Col = new XViewerColumn("ats.taskest.attachments", "Attachments", 20,
+      XViewerAlign.Left, true, SortDataType.String, false, "Shows number of attachments.  Double-click to open task.");
+
+   public static final String COLUMN_NAMESPACE = "ats.column";
+   private final String namespace2;
+
+   public MiniTaskXViewerFactory(String namespace) {
+      super(namespace, null);
+      namespace2 = namespace;
+   }
+
+   @Override
+   public List<XViewerColumn> getColumns() {
+      List<XViewerColumn> cols = new ArrayList<>();
+      cols.add(Check_Col);
+      cols.add(Attachments_Col);
+      cols.add(getAttributeConfigColumn(AtsColumnToken.TitleColumn));
+      cols.add(getColumnServiceColumn(AtsColumnToken.StateColumn));
+      cols.add(AssigneeColumnUI.getInstance());
+      cols.add(PointsColumn.instance);
+      cols.add(TleReviewedColumn.instance);
+      cols.add(DescriptionColumn.instance);
+      cols.add(AssumptionsColumn.instance);
+      cols.add(getAttributeConfigColumn(AtsColumnToken.NotesColumn));
+      cols.add(getColumnServiceColumn(AtsColumnToken.AtsIdColumnShow));
+      cols.add(TargetedVersionColumnUI.getInstance());
+
+      for (XViewerColumn col : cols) {
+         col.setShow(true);
+         if (col.getName().equals(AtsColumnToken.TitleColumn.getName())) {
+            col.setWidth(250);
+         } else if (col.getName().equals(AtsColumnToken.NotesColumn.getName())) {
+            col.setWidth(150);
+         } else if (col.getName().equals(AtsColumnToken.TargtedVersionColumn.getName())) {
+            col.setWidth(120);
+         } else if (col.getName().equals("Points")) {
+            col.setWidth(30);
+         }
+      }
+      for (XViewerColumn col : WorldXViewerFactory.getWorldViewColumns()) {
+         if (!cols.contains(col)) {
+            col.setShow(false);
+            cols.add(col);
+         }
+      }
+      return cols;
+   }
+
+   /**
+    * Provides XViewerColumn for non-attribute based columns like Type and State
+    */
+   public XViewerColumn getColumnServiceColumn(AtsColumnIdValueColumn columnToken) {
+      return new AtsColumnIdUi(columnToken, AtsApiService.get());
+   }
+
+   private XViewerColumn getAttributeConfigColumn(AtsAttributeValueColumn attrValueColumn) {
+      XViewerColumn result = null;
+      for (AtsAttributeValueColumn column : AtsApiService.get().getConfigService().getConfigurations().getViews().getAttrColumns()) {
+         if (column.getNamespace().equals(namespace2) && column.getId().equals(attrValueColumn.getId())) {
+            result = new XViewerAtsAttributeValueColumn(column);
+            break;
+         }
+      }
+      if (result == null) {
+         result = new XViewerAtsAttributeValueColumn(attrValueColumn);
+      }
+      return result;
+   }
+
+   @Override
+   public XViewerSorter createNewXSorter(XViewer xViewer) {
+      return new WorldXViewerSorter(xViewer);
+   }
+
+}
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
new file mode 100644
index 0000000..1008a85
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/mini/XMiniTaskWidget.java
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * 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.workflow.task.mini;
+
+import java.util.Collection;
+import java.util.logging.Level;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.nebula.widgets.xviewer.IXViewerFactory;
+import org.eclipse.osee.ats.api.AtsApi;
+import org.eclipse.osee.ats.api.workdef.AtsWorkDefinitionToken;
+import org.eclipse.osee.ats.api.workflow.IAtsTask;
+import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
+import org.eclipse.osee.ats.ide.editor.WorkflowEditor;
+import org.eclipse.osee.ats.ide.internal.Activator;
+import org.eclipse.osee.ats.ide.internal.AtsApiService;
+import org.eclipse.osee.ats.ide.workflow.task.TaskXViewer;
+import org.eclipse.osee.ats.ide.world.WorldContentProvider;
+import org.eclipse.osee.ats.ide.world.WorldLabelProvider;
+import org.eclipse.osee.ats.ide.world.WorldXViewer;
+import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.type.Pair;
+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.GenericXWidget;
+import org.eclipse.osee.framework.ui.skynet.widgets.XLabelValue;
+import org.eclipse.osee.framework.ui.swt.ALayout;
+import org.eclipse.osee.framework.ui.swt.Displays;
+import org.eclipse.osee.framework.ui.swt.FontManager;
+import org.eclipse.osee.framework.ui.swt.Widgets;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.Tree;
+
+/**
+ * XWidget XViewer to hold tasks and provide full world capabilities for tasks
+ *
+ * @author Donald G. Dunne
+ */
+public abstract class XMiniTaskWidget extends GenericXWidget implements ArtifactWidget {
+
+   protected TaskXViewer xTaskViewer;
+   public final static String normalColor = "#EEEEEE";
+   private static final int paddedTableHeightHint = 2;
+   protected Label extraInfoLabel;
+   private int lastSize = 0;
+   private final int MAX_TABLE_SIZE = 10;
+   private Composite mainComp;
+   private Composite parentComp;
+   protected final AtsApi atsApi;
+   protected XLabelValue pointsLabel;
+   private final IXViewerFactory xViewerFactory;
+   protected IAtsTeamWorkflow teamWf;
+
+   public XMiniTaskWidget(String label, IXViewerFactory xViewerFactory) {
+      super(label);
+      this.xViewerFactory = xViewerFactory;
+      atsApi = AtsApiService.get();
+   }
+
+   abstract public Collection<IAtsTask> getTasks();
+
+   abstract public AtsWorkDefinitionToken getTaskWorkDefTok();
+
+   /**
+    * @return String.format for related task name
+    */
+   public String getTaskNameFormat() {
+      return "Estimate for %s";
+   }
+
+   @Override
+   protected void createControls(Composite parent, int horizontalSpan) {
+      // parentComp needs to be created and remain intact; mainComp will be disposed and re-created as necessary
+      parentComp = new Composite(parent, SWT.FLAT);
+      parentComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+      parentComp.setLayout(ALayout.getZeroMarginLayout());
+
+      redrawComposite();
+   }
+
+   protected WorldLabelProvider getWorldLabelProvider() {
+      return new WorldLabelProvider(xTaskViewer);
+   }
+
+   protected WorldContentProvider getWorldContentProvider() {
+      return new WorldContentProvider(xTaskViewer);
+   }
+
+   private void redrawComposite() {
+      if (parentComp == null || !Widgets.isAccessible(parentComp)) {
+         return;
+      }
+      if (mainComp != null && Widgets.isAccessible(mainComp)) {
+         mainComp.dispose();
+         xTaskViewer = null;
+      }
+      mainComp = new Composite(parentComp, SWT.FLAT);
+      mainComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+      mainComp.setLayout(new GridLayout(1, true));
+      if (toolkit != null) {
+         toolkit.paintBordersFor(mainComp);
+      }
+
+      labelWidget = new Label(mainComp, SWT.NONE);
+      labelWidget.setText(getLabel() + ":");
+      if (getToolTip() != null) {
+         labelWidget.setToolTipText(getToolTip());
+      }
+
+      try {
+         Composite tableComp = new Composite(mainComp, SWT.BORDER);
+         GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+         tableComp.setLayoutData(gd);
+         tableComp.setLayout(ALayout.getZeroMarginLayout());
+         if (toolkit != null) {
+            toolkit.paintBordersFor(tableComp);
+         }
+
+         ToolBar toolBar = createActionBar(tableComp);
+
+         xTaskViewer = createXTaskViewer(tableComp);
+         xTaskViewer.getTree().setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+         xTaskViewer.setContentProvider(getWorldContentProvider());
+         xTaskViewer.setLabelProvider(getWorldLabelProvider());
+
+         new ActionContributionItem(xTaskViewer.getCustomizeAction()).fill(toolBar, -1);
+
+         if (toolkit != null && xTaskViewer.getStatusLabel() != null) {
+            toolkit.adapt(xTaskViewer.getStatusLabel(), false, false);
+         }
+
+         pointsLabel = new XLabelValue("Total Estimated Points", "0");
+         pointsLabel.createWidgets(tableComp, 2);
+         pointsLabel.getComp().setLayout(new GridLayout(2, false));
+         pointsLabel.getLabelWidget().setFont(FontManager.getCourierNew12Bold());
+         if (toolkit != null) {
+            toolkit.adapt(pointsLabel.getLabelWidget(), false, false);
+            toolkit.adapt(pointsLabel.getValueTextWidget(), false, false);
+         }
+
+         refresh();
+      } catch (OseeCoreException ex) {
+         OseeLog.log(Activator.class, Level.SEVERE, ex);
+      }
+      // reset bold for label
+      WorkflowEditor.setLabelFonts(labelWidget, FontManager.getDefaultLabelFont());
+
+      parentComp.layout();
+   }
+
+   protected TaskXViewer createXTaskViewer(Composite tableComp) {
+      return new TaskXViewer(tableComp, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION, xViewerFactory, null, teamWf);
+   }
+
+   public abstract ToolBar createActionBar(Composite tableComp);
+
+   public void setXviewerTreeSize() {
+      Tree tree = xTaskViewer.getTree();
+      int size = xTaskViewer.getTree().getItemCount();
+      if (size > MAX_TABLE_SIZE) {
+         size = MAX_TABLE_SIZE;
+      }
+      if (size == lastSize) {
+         return;
+      }
+      lastSize = size;
+      int treeItemHeight = xTaskViewer.getTree().getItemHeight();
+      GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+      gridData.heightHint = treeItemHeight * (paddedTableHeightHint + size);
+      tree.setLayout(ALayout.getZeroMarginLayout());
+      tree.setLayoutData(gridData);
+      tree.setHeaderVisible(true);
+      tree.setLinesVisible(true);
+   }
+
+   public void loadTable() {
+      try {
+         if (xTaskViewer != null && xTaskViewer.getContentProvider() != null) {
+            xTaskViewer.setInput(getTasks());
+            xTaskViewer.refresh();
+         }
+      } catch (Exception ex) {
+         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+      }
+   }
+
+   @Override
+   public Control getControl() {
+      return labelWidget;
+   }
+
+   @Override
+   public void refresh() {
+      if (xTaskViewer == null || xTaskViewer.getTree() == null || xTaskViewer.getTree().isDisposed()) {
+         return;
+      }
+      loadTable();
+      setXviewerTreeSize();
+      updateExtraInfoLabel();
+      pointsLabel.setValueText("Put Label Here");
+   }
+
+   public WorldXViewer getxWorldViewer() {
+      return xTaskViewer;
+   }
+
+   public Label getExtraInfoLabel() {
+      return extraInfoLabel;
+   }
+
+   public void setExtraInfoLabel(Label extraInfoLabel) {
+      this.extraInfoLabel = extraInfoLabel;
+   }
+
+   public abstract Pair<Integer, String> getExtraInfoString();
+
+   private void updateExtraInfoLabel() {
+      Pair<Integer, String> entry = getExtraInfoString();
+      updateExtraInfoLabel(entry.getFirst(), entry.getSecond());
+   }
+
+   private void updateExtraInfoLabel(final int color, final String infoStr) {
+      Displays.ensureInDisplayThread(new Runnable() {
+         @Override
+         public void run() {
+            if (Widgets.isAccessible(extraInfoLabel)) {
+               String currentString = extraInfoLabel.getText();
+               if (infoStr == null && currentString != null || //
+               infoStr != null && currentString == null || //
+               infoStr != null && currentString != null && !infoStr.equals(currentString)) {
+                  extraInfoLabel.setText(infoStr);
+               }
+               extraInfoLabel.setForeground(Displays.getSystemColor(color));
+            }
+         }
+      });
+   }
+
+   @Override
+   public void setArtifact(Artifact artifact) {
+      if (artifact instanceof IAtsTeamWorkflow) {
+         teamWf = (IAtsTeamWorkflow) artifact;
+      }
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstContentProvider.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstContentProvider.java
deleted file mode 100644
index f91e1b0..0000000
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstContentProvider.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*********************************************************************
- * 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.workflow.task.widgets.estimates;
-
-import java.util.Collection;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.osee.framework.jdk.core.util.Collections;
-
-/**
- * @author Donald G. Dunne
- */
-public class TaskEstContentProvider implements ITreeContentProvider {
-
-   public TaskEstContentProvider() {
-      super();
-   }
-
-   @Override
-   @SuppressWarnings("rawtypes")
-   public Object[] getChildren(Object parentElement) {
-      if (parentElement instanceof Collection) {
-         return ((Collection) parentElement).toArray();
-      }
-      return Collections.EMPTY_ARRAY;
-   }
-
-   @Override
-   public Object getParent(Object element) {
-      return null;
-   }
-
-   @Override
-   public boolean hasChildren(Object element) {
-      return getChildren(element).length > 0;
-   }
-
-   @Override
-   public Object[] getElements(Object inputElement) {
-      if (inputElement instanceof String) {
-         return new Object[] {inputElement};
-      }
-      return getChildren(inputElement);
-   }
-
-   @Override
-   public void dispose() {
-      // do nothing
-   }
-
-   @Override
-   public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-      // do nothing
-   }
-
-}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstFactory.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstFactory.java
deleted file mode 100644
index 1ce00e6..0000000
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstFactory.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*********************************************************************
- * 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.workflow.task.widgets.estimates;
-
-import org.eclipse.nebula.widgets.xviewer.core.model.SortDataType;
-import org.eclipse.nebula.widgets.xviewer.core.model.XViewerAlign;
-import org.eclipse.nebula.widgets.xviewer.core.model.XViewerColumn;
-import org.eclipse.osee.framework.ui.skynet.widgets.xviewer.IOseeTreeReportProvider;
-import org.eclipse.osee.framework.ui.skynet.widgets.xviewer.skynet.SkynetXViewerFactory;
-
-/**
- * @author Donald G. Dunne
- */
-public class TaskEstFactory extends SkynetXViewerFactory {
-
-   public final static String NAMESPACE = "TaskEstFactory";
-
-   public static XViewerColumn Check_Col = new XViewerColumn("ats.taskest.check", "Select", 60, XViewerAlign.Left, true,
-      SortDataType.String, false, "Check and plus to create canned tasks.  Add task to create manual tasks.");
-   public static XViewerColumn Name_Col =
-      new XViewerColumn("ats.taskest.name", "Name", 180, XViewerAlign.Left, true, SortDataType.String, false, "");
-   public static XViewerColumn Status_Col = new XViewerColumn("ats.taskest.status", "Status", 80, XViewerAlign.Left,
-      true, SortDataType.String, false, "State of the Estimating task.  Double-click to open task.");
-   public static XViewerColumn Assignee_Col =
-      new XViewerColumn("ats.taskest.assignee", "Assignees", 120, XViewerAlign.Left, true, SortDataType.String, false,
-         "Assignee(s) of Estimating task.  Double-click to open task.");
-   public static XViewerColumn Estimated_Points_Col = new XViewerColumn("ats.taskest.est.points", "Est Points", 40,
-      XViewerAlign.Left, true, SortDataType.Float, false, "Double-click to open task.");
-   public static XViewerColumn Estimated_Completion_Date_Col = new XViewerColumn("ats.taskest.est.completion.date",
-      "Est Completion Date", 60, XViewerAlign.Left, true, SortDataType.Date, false, null);
-   public static XViewerColumn Description_Col = new XViewerColumn("ats.taskest.description", "Description", 120,
-      XViewerAlign.Left, true, SortDataType.String, false, null);
-   public static XViewerColumn Assumptions_Col = new XViewerColumn("ats.taskest.assumptions", "Assumptions", 120,
-      XViewerAlign.Left, true, SortDataType.String, false, null);
-   public static XViewerColumn Notes_Col =
-      new XViewerColumn("ats.taskest.notes", "Notes", 120, XViewerAlign.Left, true, SortDataType.String, false, null);
-   public static XViewerColumn Attachments_Col = new XViewerColumn("ats.taskest.attachments", "Attachments", 120,
-      XViewerAlign.Left, true, SortDataType.String, false, "Shows number of attachments.  Double-click to open task.");
-
-   public TaskEstFactory(IOseeTreeReportProvider reportProvider) {
-      super(NAMESPACE, reportProvider);
-      registerColumns(Check_Col, Name_Col, Status_Col, Assignee_Col, Estimated_Points_Col,
-         Estimated_Completion_Date_Col, Description_Col, Assumptions_Col, Notes_Col, Attachments_Col);
-   }
-
-}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstLabelProvider.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstLabelProvider.java
deleted file mode 100644
index cc4d8a3..0000000
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstLabelProvider.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*********************************************************************
- * 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.workflow.task.widgets.estimates;
-
-import java.util.Date;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.nebula.widgets.xviewer.XViewerLabelProvider;
-import org.eclipse.nebula.widgets.xviewer.core.model.XViewerColumn;
-import org.eclipse.osee.ats.api.AtsApi;
-import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
-import org.eclipse.osee.ats.api.util.AtsImage;
-import org.eclipse.osee.ats.api.workflow.IAtsTask;
-import org.eclipse.osee.ats.core.column.AtsColumnId;
-import org.eclipse.osee.ats.ide.column.AssigneeColumnUI;
-import org.eclipse.osee.ats.ide.internal.AtsApiService;
-import org.eclipse.osee.framework.core.enums.CoreRelationTypes;
-import org.eclipse.osee.framework.jdk.core.util.DateUtil;
-import org.eclipse.osee.framework.ui.skynet.FrameworkImage;
-import org.eclipse.osee.framework.ui.swt.Displays;
-import org.eclipse.osee.framework.ui.swt.ImageManager;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * @author Donald G. Dunne
- */
-public class TaskEstLabelProvider extends XViewerLabelProvider {
-
-   private final TaskEstXViewer xTaskEstViewer;
-   private final AtsApi atsApi;
-
-   public TaskEstLabelProvider(TaskEstXViewer xTaskEstViewer) {
-      super(xTaskEstViewer);
-      this.xTaskEstViewer = xTaskEstViewer;
-      atsApi = AtsApiService.get();
-   }
-
-   @Override
-   public Image getColumnImage(Object element, XViewerColumn xCol, int columnIndex) {
-      TaskEstDefinition taskDef = (TaskEstDefinition) element;
-      if (xCol.equals(TaskEstFactory.Check_Col)) {
-         if (taskDef.isManual()) {
-            return ImageManager.getImage(AtsImage.TASK);
-         }
-         if (taskDef.hasTask()) {
-            return null;
-         }
-         if (taskDef.isChecked()) {
-            return ImageManager.getImage(FrameworkImage.CHECKBOX_CHECK_TRUE);
-         } else {
-            return ImageManager.getImage(FrameworkImage.CHECKBOX_CHECK_UNSET);
-         }
-      }
-      if (xCol.equals(TaskEstFactory.Assignee_Col)) {
-         if (taskDef.hasTask()) {
-            return AssigneeColumnUI.instance.getColumnImage(taskDef.getTask(), xCol, columnIndex);
-         }
-      }
-      return null;
-   }
-
-   @Override
-   public String getColumnText(Object element, XViewerColumn xCol, int columnIndex) {
-      TaskEstDefinition ted = (TaskEstDefinition) element;
-      if (xCol.equals(TaskEstFactory.Check_Col)) {
-         if (ted.isManual()) {
-            return "Manual";
-         }
-         return "";
-      } else if (xCol.equals(TaskEstFactory.Name_Col)) {
-         if (ted.hasTask()) {
-            return ted.getTask().getName();
-         }
-         return ted.getName();
-      } else if (xCol.equals(TaskEstFactory.Status_Col)) {
-         if (ted.hasTask()) {
-            return atsApi.getColumnService().getColumnText(AtsColumnId.State.getId(), ted.getTask());
-         }
-         return "No Task";
-      } else if (xCol.equals(TaskEstFactory.Assignee_Col)) {
-         if (ted.hasTask()) {
-            return atsApi.getColumnService().getColumnText(AtsColumnId.Assignees.getId(), ted.getTask());
-         }
-         return "";
-      } else if (xCol.equals(TaskEstFactory.Description_Col)) {
-         if (ted.hasTask()) {
-            return atsApi.getAttributeResolver().getSoleAttributeValue(ted.getTask(), AtsAttributeTypes.Description,
-               "");
-         }
-         return "";
-      } else if (xCol.equals(TaskEstFactory.Assumptions_Col)) {
-         if (ted.hasTask()) {
-            return atsApi.getAttributeResolver().getSoleAttributeValue(ted.getTask(), AtsAttributeTypes.Assumptions,
-               "");
-         }
-         return "";
-      } else if (xCol.equals(TaskEstFactory.Notes_Col)) {
-         if (ted.hasTask()) {
-            return atsApi.getAttributeResolver().getSoleAttributeValue(ted.getTask(), AtsAttributeTypes.WorkflowNotes,
-               "");
-         }
-         return "";
-      } else if (xCol.equals(TaskEstFactory.Estimated_Points_Col)) {
-         if (ted.hasTask()) {
-            return String.valueOf(atsApi.getAttributeResolver().getSoleAttributeValueAsString(ted.getTask(),
-               xTaskEstViewer.getPointsAttrType(), ""));
-         }
-         return "";
-      } else if (xCol.equals(TaskEstFactory.Attachments_Col)) {
-         if (ted.hasTask()) {
-            int count = atsApi.getRelationResolver().getRelated(ted.getTask(),
-               CoreRelationTypes.SupportingInfo_SupportingInfo).size();
-            if (count > 0) {
-               return String.valueOf(count);
-            }
-         }
-         return "";
-      } else if (xCol.equals(TaskEstFactory.Estimated_Completion_Date_Col)) {
-         if (ted.hasTask()) {
-            Date date = atsApi.getAttributeResolver().getSoleAttributeValue(ted.getTask(),
-               AtsAttributeTypes.EstimatedCompletionDate, null);
-            if (date != null) {
-               return DateUtil.getMMDDYY(date);
-            }
-         }
-         return "";
-      }
-      return "";
-   }
-
-   @Override
-   public Color getForeground(Object element, XViewerColumn xCol, int columnIndex) {
-      TaskEstDefinition taskDef = (TaskEstDefinition) element;
-      if (xCol.equals(TaskEstFactory.Status_Col)) {
-         if (taskDef.hasTask()) {
-            IAtsTask task = taskDef.getTask();
-            if (task.isInWork()) {
-               return Displays.getSystemColor(SWT.COLOR_BLUE);
-            } else if (task.isCompleted()) {
-               return Displays.getSystemColor(SWT.COLOR_DARK_GREEN);
-            } else if (task.isCancelled()) {
-               return Displays.getSystemColor(SWT.COLOR_DARK_RED);
-            }
-         }
-      }
-      return null;
-   }
-
-   @Override
-   public void dispose() {
-      // do nothing
-   }
-
-   @Override
-   public boolean isLabelProperty(Object element, String property) {
-      return false;
-   }
-
-   @Override
-   public void addListener(ILabelProviderListener listener) {
-      // do nothing
-   }
-
-   @Override
-   public void removeListener(ILabelProviderListener listener) {
-      // do nothing
-   }
-
-}
\ No newline at end of file
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstXViewer.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstXViewer.java
deleted file mode 100644
index 1171c64..0000000
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/TaskEstXViewer.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*********************************************************************
- * 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.workflow.task.widgets.estimates;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.eclipse.nebula.widgets.xviewer.XViewer;
-import org.eclipse.osee.ats.api.AtsApi;
-import org.eclipse.osee.ats.api.agile.IAgileTeam;
-import org.eclipse.osee.ats.api.data.AtsAttributeTypes;
-import org.eclipse.osee.ats.api.workflow.IAtsTeamWorkflow;
-import org.eclipse.osee.ats.ide.editor.WorkflowEditor;
-import org.eclipse.osee.ats.ide.internal.Activator;
-import org.eclipse.osee.framework.core.data.AttributeTypeToken;
-import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
-import org.eclipse.osee.framework.logging.OseeLevel;
-import org.eclipse.osee.framework.logging.OseeLog;
-import org.eclipse.osee.framework.ui.skynet.widgets.xviewer.skynet.OseeTreeReportAdapter;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.TreeColumn;
-import org.eclipse.swt.widgets.TreeItem;
-
-/**
- * @author Donald G. Dunne
- */
-public class TaskEstXViewer extends XViewer {
-
-   private final XTaskEstManager xTaskEstManager;
-   private final AtsApi atsApi;
-   private final IAtsTeamWorkflow teamWf;
-   private AttributeTypeToken pointsAttrType;
-
-   public TaskEstXViewer(Composite parent, int style, XTaskEstManager xTaskEstManager, IAtsTeamWorkflow teamWf, AtsApi atsApi) {
-      super(parent, style, new TaskEstFactory(new OseeTreeReportAdapter("Table Report - " + XTaskEstManager.NAME)));
-      this.xTaskEstManager = xTaskEstManager;
-      this.teamWf = teamWf;
-      this.atsApi = atsApi;
-   }
-
-   @Override
-   public void dispose() {
-      getLabelProvider().dispose();
-   }
-
-   public List<TaskEstDefinition> getSelected() {
-      List<TaskEstDefinition> teds = new ArrayList<>();
-      TreeItem items[] = getTree().getSelection();
-      if (items.length > 0) {
-         for (TreeItem item : items) {
-            teds.add((TaskEstDefinition) item.getData());
-         }
-      }
-      return teds;
-   }
-
-   public XTaskEstManager getXCommitViewer() {
-      return xTaskEstManager;
-   }
-
-   @Override
-   public void handleDoubleClick() {
-      try {
-         TaskEstDefinition ted = getSelected().iterator().next();
-         if (ted.hasTask()) {
-            WorkflowEditor.edit(ted.getTask());
-         }
-      } catch (OseeCoreException ex) {
-         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
-      }
-   }
-
-   @Override
-   public boolean handleLeftClickInIconArea(TreeColumn treeColumn, TreeItem treeItem) {
-      TaskEstDefinition ted = getSelected().iterator().next();
-      if (ted.hasTask()) {
-         return false;
-      }
-      ted.setChecked(!ted.isChecked());
-      refresh(ted);
-      return true;
-   }
-
-   public AttributeTypeToken getPointsAttrType() {
-      if (pointsAttrType == null) {
-         IAgileTeam agileTeam = atsApi.getAgileService().getAgileTeam(teamWf);
-         if (agileTeam != null) {
-            pointsAttrType = atsApi.getAgileService().getAgileTeamPointsAttributeType(agileTeam);
-         }
-         if (pointsAttrType == null) {
-            pointsAttrType = AtsAttributeTypes.PointsNumeric;
-         }
-      }
-      return pointsAttrType;
-   }
-
-}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/XTaskEstManager.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/XTaskEstManager.java
deleted file mode 100644
index 8a4d90e..0000000
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/workflow/task/widgets/estimates/XTaskEstManager.java
+++ /dev/null
@@ -1,426 +0,0 @@
-/*********************************************************************
- * 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.workflow.task.widgets.estimates;
-
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.logging.Level;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.action.ActionContributionItem;
-import org.eclipse.osee.ats.api.AtsApi;
-import org.eclipse.osee.ats.api.config.tx.IAtsTeamDefinitionArtifactToken;
-import org.eclipse.osee.ats.api.data.AtsArtifactTypes;
-import org.eclipse.osee.ats.api.workdef.AtsWorkDefinitionToken;
-import org.eclipse.osee.ats.api.workflow.IAtsTask;
-import org.eclipse.osee.ats.api.workflow.cr.TaskEstUtil;
-import org.eclipse.osee.ats.ide.editor.WorkflowEditor;
-import org.eclipse.osee.ats.ide.internal.Activator;
-import org.eclipse.osee.ats.ide.internal.AtsApiService;
-import org.eclipse.osee.ats.ide.workflow.teamwf.TeamWorkFlowArtifact;
-import org.eclipse.osee.framework.core.data.ArtifactId;
-import org.eclipse.osee.framework.core.data.ArtifactToken;
-import org.eclipse.osee.framework.core.data.UserToken;
-import org.eclipse.osee.framework.core.enums.CoreAttributeTypes;
-import org.eclipse.osee.framework.core.util.Result;
-import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
-import org.eclipse.osee.framework.jdk.core.type.OseeStateException;
-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.skynet.core.event.OseeEventManager;
-import org.eclipse.osee.framework.skynet.core.event.filter.IEventFilter;
-import org.eclipse.osee.framework.skynet.core.event.listener.IArtifactEventListener;
-import org.eclipse.osee.framework.skynet.core.event.listener.IBranchEventListener;
-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.ArtifactWidget;
-import org.eclipse.osee.framework.ui.skynet.widgets.GenericXWidget;
-import org.eclipse.osee.framework.ui.skynet.widgets.XLabelValue;
-import org.eclipse.osee.framework.ui.swt.ALayout;
-import org.eclipse.osee.framework.ui.swt.Displays;
-import org.eclipse.osee.framework.ui.swt.FontManager;
-import org.eclipse.osee.framework.ui.swt.Widgets;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.ToolBar;
-import org.eclipse.swt.widgets.Tree;
-
-/**
- * @author Donald G. Dunne
- */
-public abstract class XTaskEstManager extends GenericXWidget implements ArtifactWidget, IBranchEventListener, IArtifactEventListener {
-
-   private static final String INFO_STRING =
-      "Select to create estimating tasks.  Complete all estimates/tasks.  Double-Click to open/edit task/fields.";
-   private TaskEstXViewer xTaskEstViewer;
-   public final static String normalColor = "#EEEEEE";
-   private TeamWorkFlowArtifact teamArt;
-   private static final int paddedTableHeightHint = 2;
-   private Label extraInfoLabel;
-   public static final String WIDGET_NAME = "XTaskEstManager";
-   public static final String NAME = "Estimate Manager";
-   public static final String DESCRIPTION = "Generate and manage estimating tasks.";
-   private int lastSize = 0;
-   private final int MAX_TABLE_SIZE = 10;
-   private Composite mainComp;
-   private Composite parentComp;
-   private final AtsApi atsApi;
-   private Collection<TaskEstDefinition> taskDefs;
-   private XLabelValue pointsLabel;
-
-   public XTaskEstManager() {
-      super(NAME);
-      OseeEventManager.addListener(this);
-      atsApi = AtsApiService.get();
-   }
-
-   abstract public Collection<TaskEstDefinition> getTaskDefs();
-
-   public Collection<TaskEstDefinition> getItems() {
-      return taskDefs;
-   }
-
-   /**
-    * @return String.format for related task name
-    */
-   public String getTaskNameFormat() {
-      return "Estimate for %s";
-   }
-
-   @Override
-   public TeamWorkFlowArtifact getArtifact() {
-      return teamArt;
-   }
-
-   @Override
-   protected void createControls(Composite parent, int horizontalSpan) {
-      // parentComp needs to be created and remain intact; mainComp will be disposed and re-created as necessary
-      parentComp = new Composite(parent, SWT.FLAT);
-      parentComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-      parentComp.setLayout(ALayout.getZeroMarginLayout());
-
-      redrawComposite();
-   }
-
-   private void redrawComposite() {
-      if (parentComp == null || !Widgets.isAccessible(parentComp)) {
-         return;
-      }
-      if (mainComp != null && Widgets.isAccessible(mainComp)) {
-         mainComp.dispose();
-         xTaskEstViewer = null;
-      }
-      mainComp = new Composite(parentComp, SWT.FLAT);
-      mainComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-      mainComp.setLayout(new GridLayout(1, true));
-      if (toolkit != null) {
-         toolkit.paintBordersFor(mainComp);
-      }
-
-      labelWidget = new Label(mainComp, SWT.NONE);
-      labelWidget.setText(getLabel() + ":");
-      if (getToolTip() != null) {
-         labelWidget.setToolTipText(getToolTip());
-      }
-
-      try {
-         Composite tableComp = new Composite(mainComp, SWT.BORDER);
-         tableComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-         tableComp.setLayout(ALayout.getZeroMarginLayout());
-         if (toolkit != null) {
-            toolkit.paintBordersFor(tableComp);
-         }
-
-         TaskEstActionBar actionBar = new TaskEstActionBar(this);
-         ToolBar toolBar = actionBar.createTaskActionBar(tableComp);
-
-         xTaskEstViewer = new TaskEstXViewer(tableComp, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION, this, teamArt,
-            AtsApiService.get());
-         xTaskEstViewer.getTree().setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-         xTaskEstViewer.setContentProvider(new TaskEstContentProvider());
-         xTaskEstViewer.setLabelProvider(new TaskEstLabelProvider(xTaskEstViewer));
-
-         new ActionContributionItem(getXViewer().getCustomizeAction()).fill(toolBar, -1);
-
-         if (toolkit != null && xTaskEstViewer.getStatusLabel() != null) {
-            toolkit.adapt(xTaskEstViewer.getStatusLabel(), false, false);
-         }
-
-         pointsLabel = new XLabelValue("Total Estimated Points", "0");
-         pointsLabel.createWidgets(tableComp, 2);
-         pointsLabel.getComp().setLayout(new GridLayout(2, false));
-         pointsLabel.getLabelWidget().setFont(FontManager.getCourierNew12Bold());
-         if (toolkit != null) {
-            toolkit.adapt(pointsLabel.getLabelWidget(), false, false);
-            toolkit.adapt(pointsLabel.getValueTextWidget(), false, false);
-         }
-
-         refresh();
-      } catch (OseeCoreException ex) {
-         OseeLog.log(Activator.class, Level.SEVERE, ex);
-      }
-      // reset bold for label
-      WorkflowEditor.setLabelFonts(labelWidget, FontManager.getDefaultLabelFont());
-
-      parentComp.layout();
-   }
-
-   public void setXviewerTreeSize() {
-      Tree tree = xTaskEstViewer.getTree();
-      int size = xTaskEstViewer.getTree().getItemCount();
-      if (size > MAX_TABLE_SIZE) {
-         size = MAX_TABLE_SIZE;
-      }
-      if (size == lastSize) {
-         return;
-      }
-      lastSize = size;
-      int treeItemHeight = xTaskEstViewer.getTree().getItemHeight();
-      GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
-      gridData.heightHint = treeItemHeight * (paddedTableHeightHint + size);
-      tree.setLayout(ALayout.getZeroMarginLayout());
-      tree.setLayoutData(gridData);
-      tree.setHeaderVisible(true);
-      tree.setLinesVisible(true);
-   }
-
-   public void loadTable() {
-      try {
-         if (xTaskEstViewer != null && teamArt != null && xTaskEstViewer.getContentProvider() != null) {
-            taskDefs = loadTaskDefs();
-            xTaskEstViewer.setInput(taskDefs);
-            xTaskEstViewer.refresh();
-         }
-      } catch (Exception ex) {
-         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
-      }
-   }
-
-   /**
-    * @return TaskEstDefinitions matched with existing tasks
-    */
-   private Collection<TaskEstDefinition> loadTaskDefs() {
-      Collection<TaskEstDefinition> taskDefs = getTaskDefs();
-      for (IAtsTask task : atsApi.getTaskService().getTasks(teamArt)) {
-         boolean found = false;
-         for (TaskEstDefinition ted : taskDefs) {
-            if (task.hasTag(ted.getIdString())) {
-               ted.setTask(task);
-               found = true;
-               break;
-            }
-         }
-         // Add TED for manually created tasks
-         if (!found && task.getWorkDefinition().getId().equals(getTaskWorkDefTok().getId())) {
-            TaskEstDefinition ted = new TaskEstDefinition(task.getId(), task.getName(), null, null);
-            ted.setTask(task);
-            ted.setManual(true);
-            taskDefs.add(ted);
-         }
-      }
-      return taskDefs;
-   }
-
-   @Override
-   public Control getControl() {
-      if (xTaskEstViewer == null) {
-         return null;
-      }
-      return xTaskEstViewer.getTree();
-   }
-
-   @Override
-   public void dispose() {
-      if (xTaskEstViewer != null) {
-         xTaskEstViewer.dispose();
-      }
-      OseeEventManager.removeListener(this);
-   }
-
-   @Override
-   public void refresh() {
-      if (xTaskEstViewer == null || xTaskEstViewer.getTree() == null || xTaskEstViewer.getTree().isDisposed()) {
-         return;
-      }
-      loadTable();
-      setXviewerTreeSize();
-
-      float points = 0;
-      for (IAtsTask task : atsApi.getTaskService().getTasks(teamArt)) {
-         points += Float.valueOf(
-            atsApi.getAttributeResolver().getSoleAttributeValueAsString(task, xTaskEstViewer.getPointsAttrType(), "0"));
-      }
-      pointsLabel.setValueText(String.valueOf(points));
-   }
-
-   private void updateExtraInfoLabel(final int color, final String infoStr) {
-      Displays.ensureInDisplayThread(new Runnable() {
-         @Override
-         public void run() {
-            if (Widgets.isAccessible(extraInfoLabel)) {
-               String currentString = extraInfoLabel.getText();
-               if (infoStr == null && currentString != null || //
-               infoStr != null && currentString == null || //
-               infoStr != null && currentString != null && !infoStr.equals(currentString)) {
-                  extraInfoLabel.setText(INFO_STRING);
-               }
-               extraInfoLabel.setForeground(Displays.getSystemColor(color));
-            }
-         }
-      });
-   }
-
-   @Override
-   public IStatus isValid() {
-      Status returnStatus = new Status(IStatus.OK, getClass().getSimpleName(), "");
-      try {
-         int backgroundColor = SWT.COLOR_BLACK;
-         boolean inWork = false;
-         for (TaskEstDefinition ted : getItems()) {
-            if (ted.hasTask()) {
-               IAtsTask task = ted.getTask();
-               if (task.isInWork()) {
-                  inWork = true;
-                  returnStatus =
-                     new Status(IStatus.ERROR, getClass().getSimpleName(), "All tasks must be completed/cancelled.");
-                  break;
-               }
-            }
-         }
-         if (inWork) {
-            backgroundColor = SWT.COLOR_RED;
-         }
-         updateExtraInfoLabel(backgroundColor, INFO_STRING);
-      } catch (OseeCoreException ex) {
-         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
-         return new Status(IStatus.ERROR, getClass().getSimpleName(), ex.getLocalizedMessage());
-      }
-      return returnStatus;
-   }
-
-   public TaskEstXViewer getXViewer() {
-      return xTaskEstViewer;
-   }
-
-   @Override
-   public Object getData() {
-      return xTaskEstViewer.getInput();
-   }
-
-   @Override
-   public void setArtifact(Artifact artifact) {
-      if (!artifact.isOfType(AtsArtifactTypes.TeamWorkflow)) {
-         throw new OseeStateException("Must be TeamWorkflowArtifact, set was a [%s]", artifact.getArtifactTypeName());
-      }
-      this.teamArt = (TeamWorkFlowArtifact) artifact;
-      loadTable();
-   }
-
-   @Override
-   public Result isDirty() {
-      return Result.FalseResult;
-   }
-
-   @Override
-   public void revert() {
-      // do nothing
-   }
-
-   @Override
-   public void saveToArtifact() {
-      // do nothing
-   }
-
-   /**
-    * @return the artifact
-    */
-   public TeamWorkFlowArtifact getTeamArt() {
-      return teamArt;
-   }
-
-   @Override
-   public Control getErrorMessageControl() {
-      return labelWidget;
-   }
-
-   @Override
-   public String toString() {
-      return String.format("%s", getLabel());
-   }
-
-   @Override
-   public void handleBranchEvent(Sender sender, final BranchEvent branchEvent) {
-      Displays.ensureInDisplayThread(new Runnable() {
-         @Override
-         public void run() {
-            redrawComposite();
-         }
-      });
-   }
-
-   @Override
-   public void handleArtifactEvent(ArtifactEvent artifactEvent, Sender sender) {
-      if (getTeamArt() != null && artifactEvent.isModified(getTeamArt())) {
-         Displays.ensureInDisplayThread(new Runnable() {
-            @Override
-            public void run() {
-               loadTable();
-            }
-         });
-      }
-   }
-
-   @Override
-   public List<? extends IEventFilter> getEventFilters() {
-      return null;
-   }
-
-   @Override
-   public boolean isEmpty() {
-      return xTaskEstViewer.getXCommitViewer().getXViewer().getTree().getItemCount() == 0;
-   }
-
-   public void setExtraInfoLabel(Label extraInfoLabel) {
-      this.extraInfoLabel = extraInfoLabel;
-   }
-
-   abstract public AtsWorkDefinitionToken getTaskWorkDefTok();
-
-   /**
-    * Create dynamic TEDs from children UserGroups off given teamDef where UserGroup has TaskEst static id
-    */
-   protected void getTaskDefsFromUserGroupsOff(IAtsTeamDefinitionArtifactToken teamDef, List<TaskEstDefinition> taskDefs) {
-      for (ArtifactToken childArt : atsApi.getRelationResolver().getChildren(teamDef)) {
-         if (atsApi.getAttributeResolver().getAttributesToStringList(childArt, CoreAttributeTypes.StaticId).contains(
-            TaskEstUtil.TASK_EST_STATIC_ID)) {
-            String desc = atsApi.getAttributeResolver().getSoleAttributeValueAsString(childArt,
-               CoreAttributeTypes.Description, "");
-            List<ArtifactId> assigneeAccountIds = new LinkedList<>();
-            for (UserToken user : atsApi.getUserGroupService().getUserGroup(childArt).getMembers()) {
-               assigneeAccountIds.add(ArtifactId.valueOf(user.getId()));
-            }
-            taskDefs.add(new TaskEstDefinition(childArt.getId(), childArt.getName(), desc, assigneeAccountIds));
-         }
-      }
-   }
-
-}
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/world/WorldXViewer.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/world/WorldXViewer.java
index 3db4b48..cfd7dc8 100644
--- a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/world/WorldXViewer.java
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/world/WorldXViewer.java
@@ -34,6 +34,7 @@
 import org.eclipse.nebula.widgets.xviewer.action.ColumnMultiEditAction;
 import org.eclipse.nebula.widgets.xviewer.core.model.XViewerColumn;
 import org.eclipse.nebula.widgets.xviewer.customize.XViewerCustomMenu;
+import org.eclipse.osee.ats.api.IAtsWorkItem;
 import org.eclipse.osee.ats.api.data.AtsArtifactTypes;
 import org.eclipse.osee.ats.api.workflow.IAtsAction;
 import org.eclipse.osee.ats.core.util.AtsObjects;
@@ -350,8 +351,11 @@
       mm.insertBefore(MENU_GROUP_PRE, editMenuManager);
 
       final Collection<TreeItem> selectedTreeItems = Arrays.asList(thisXViewer.getTree().getSelection());
-      mm.insertBefore(MENU_GROUP_PRE,
-         TransitionToMenu.createTransitionToMenuManager(thisXViewer, "Transition-To", selectedTreeItems));
+      Set<Artifact> workflowArtifacts = getSelectedWorkflowArtifacts();
+      if (!workflowArtifacts.isEmpty()) {
+         mm.insertBefore(MENU_GROUP_PRE,
+            TransitionToMenu.createTransitionToMenuManager(thisXViewer, "Transition-To", selectedTreeItems));
+      }
 
       mm.insertBefore(MENU_GROUP_PRE, editStatusAction);
       editStatusAction.setEnabled(getSelectedWorkflowArtifacts().size() > 0);
@@ -395,7 +399,7 @@
       mm.insertBefore(XViewer.MENU_GROUP_PRE, new Separator());
 
       mm.insertBefore(XViewer.MENU_GROUP_PRE, addTaskAction);
-      addTaskAction.updateEnablement();
+      addTaskAction.updateEnablement(isAddTaskEnabled());
 
       mm.insertBefore(XViewer.MENU_GROUP_PRE, deleteTasksAction);
       deleteTasksAction.updateEnablement(getSelectedArtifacts());
@@ -424,6 +428,10 @@
       }
    }
 
+   protected boolean isAddTaskEnabled() {
+      return true;
+   }
+
    @Override
    public void handleDoubleClick() {
       ArtifactDoubleClick.openArtifact(getSelection());
@@ -466,7 +474,12 @@
       TreeItem items[] = getTree().getSelection();
       if (items.length > 0) {
          for (TreeItem item : items) {
-            arts.add(AtsApiService.get().getQueryServiceIde().getArtifact(item));
+            if (item.getData() instanceof IAtsWorkItem) {
+               Artifact artifact = AtsApiService.get().getQueryServiceIde().getArtifact(item);
+               if (artifact != null) {
+                  arts.add(artifact);
+               }
+            }
          }
       }
       return arts;
diff --git a/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/world/mini/MiniWorldXViewerFactory.java b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/world/mini/MiniWorldXViewerFactory.java
new file mode 100644
index 0000000..f8209a3
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/world/mini/MiniWorldXViewerFactory.java
@@ -0,0 +1,100 @@
+/*********************************************************************
+ * 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.world.mini;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.nebula.widgets.xviewer.XViewer;
+import org.eclipse.nebula.widgets.xviewer.XViewerSorter;
+import org.eclipse.nebula.widgets.xviewer.core.model.XViewerColumn;
+import org.eclipse.osee.ats.api.column.AtsColumnIdValueColumn;
+import org.eclipse.osee.ats.api.config.AtsAttributeValueColumn;
+import org.eclipse.osee.ats.core.column.AtsColumnToken;
+import org.eclipse.osee.ats.ide.column.AssigneeColumnUI;
+import org.eclipse.osee.ats.ide.column.AtsColumnIdUi;
+import org.eclipse.osee.ats.ide.column.TargetedVersionColumnUI;
+import org.eclipse.osee.ats.ide.internal.AtsApiService;
+import org.eclipse.osee.ats.ide.util.xviewer.column.XViewerAtsAttributeValueColumn;
+import org.eclipse.osee.ats.ide.workflow.goal.GoalArtifact;
+import org.eclipse.osee.ats.ide.world.WorldXViewerFactory;
+import org.eclipse.osee.ats.ide.world.WorldXViewerSorter;
+import org.eclipse.osee.framework.ui.skynet.widgets.xviewer.skynet.SkynetXViewerFactory;
+
+/**
+ * @author Donald G. Dunne
+ */
+public abstract class MiniWorldXViewerFactory extends SkynetXViewerFactory {
+
+   public GoalArtifact soleGoalArtifact;
+   public static final String COLUMN_NAMESPACE = "ats.column";
+   private final String namespace2;
+
+   public MiniWorldXViewerFactory(String namespace) {
+      super(namespace, null);
+      namespace2 = namespace;
+   }
+
+   @Override
+   public List<XViewerColumn> getColumns() {
+      List<XViewerColumn> cols = new ArrayList<>();
+      cols.add(getColumnServiceColumn(AtsColumnToken.TypeColumn));
+      cols.add(getColumnServiceColumn(AtsColumnToken.StateColumn));
+      cols.add(AssigneeColumnUI.getInstance());
+      cols.add(getAttributeConfigColumn(AtsColumnToken.TitleColumn));
+      cols.add(getColumnServiceColumn(AtsColumnToken.AtsIdColumnShow));
+      cols.add(TargetedVersionColumnUI.getInstance());
+      cols.add(getAttributeConfigColumn(AtsColumnToken.NotesColumn));
+      for (XViewerColumn col : cols) {
+         if (col.getName().equals(AtsColumnToken.NotesColumn.getName())) {
+            col.setWidth(350);
+         } else if (col.getName().equals(AtsColumnToken.TargtedVersionColumn.getName())) {
+            col.setWidth(120);
+         }
+      }
+      for (XViewerColumn col : WorldXViewerFactory.getWorldViewColumns()) {
+         if (!cols.contains(col)) {
+            col.setShow(false);
+            cols.add(col);
+         }
+      }
+      return cols;
+   }
+
+   /**
+    * Provides XViewerColumn for non-attribute based columns like Type and State
+    */
+   public XViewerColumn getColumnServiceColumn(AtsColumnIdValueColumn columnToken) {
+      return new AtsColumnIdUi(columnToken, AtsApiService.get());
+   }
+
+   private XViewerColumn getAttributeConfigColumn(AtsAttributeValueColumn attrValueColumn) {
+      XViewerColumn result = null;
+      for (AtsAttributeValueColumn column : AtsApiService.get().getConfigService().getConfigurations().getViews().getAttrColumns()) {
+         if (column.getNamespace().equals(namespace2) && column.getId().equals(attrValueColumn.getId())) {
+            result = new XViewerAtsAttributeValueColumn(column);
+            break;
+         }
+      }
+      if (result == null) {
+         result = new XViewerAtsAttributeValueColumn(attrValueColumn);
+      }
+      return result;
+   }
+
+   @Override
+   public XViewerSorter createNewXSorter(XViewer xViewer) {
+      return new WorldXViewerSorter(xViewer);
+   }
+
+}
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
new file mode 100644
index 0000000..99d2088
--- /dev/null
+++ b/plugins/org.eclipse.osee.ats.ide/src/org/eclipse/osee/ats/ide/world/mini/XMiniWorldWidget.java
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ * 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.world.mini;
+
+import java.util.Collection;
+import java.util.logging.Level;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.nebula.widgets.xviewer.IXViewerFactory;
+import org.eclipse.osee.ats.api.AtsApi;
+import org.eclipse.osee.ats.api.IAtsWorkItem;
+import org.eclipse.osee.ats.ide.editor.WorkflowEditor;
+import org.eclipse.osee.ats.ide.internal.Activator;
+import org.eclipse.osee.ats.ide.internal.AtsApiService;
+import org.eclipse.osee.ats.ide.world.WorldContentProvider;
+import org.eclipse.osee.ats.ide.world.WorldLabelProvider;
+import org.eclipse.osee.ats.ide.world.WorldXViewer;
+import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.type.Pair;
+import org.eclipse.osee.framework.logging.OseeLevel;
+import org.eclipse.osee.framework.logging.OseeLog;
+import org.eclipse.osee.framework.ui.skynet.widgets.GenericXWidget;
+import org.eclipse.osee.framework.ui.skynet.widgets.XLabelValue;
+import org.eclipse.osee.framework.ui.swt.ALayout;
+import org.eclipse.osee.framework.ui.swt.Displays;
+import org.eclipse.osee.framework.ui.swt.FontManager;
+import org.eclipse.osee.framework.ui.swt.Widgets;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.Tree;
+
+/**
+ * @author Donald G. Dunne
+ */
+public abstract class XMiniWorldWidget extends GenericXWidget {
+
+   private WorldXViewer xWorldViewer;
+   public final static String normalColor = "#EEEEEE";
+   private static final int paddedTableHeightHint = 2;
+   private Label extraInfoLabel;
+   private int lastSize = 0;
+   private final int MAX_TABLE_SIZE = 10;
+   private Composite mainComp;
+   private Composite parentComp;
+   protected final AtsApi atsApi;
+   private Collection<IAtsWorkItem> workItems;
+   private XLabelValue pointsLabel;
+   private final IXViewerFactory xViewerFactory;
+
+   public XMiniWorldWidget(String label, IXViewerFactory xViewerFactory) {
+      super(label);
+      this.xViewerFactory = xViewerFactory;
+      atsApi = AtsApiService.get();
+   }
+
+   abstract public Collection<IAtsWorkItem> getWorkItems();
+
+   public Collection<IAtsWorkItem> getItems() {
+      return workItems;
+   }
+
+   @Override
+   protected void createControls(Composite parent, int horizontalSpan) {
+      // parentComp needs to be created and remain intact; mainComp will be disposed and re-created as necessary
+      parentComp = new Composite(parent, SWT.FLAT);
+      parentComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+      parentComp.setLayout(ALayout.getZeroMarginLayout());
+
+      redrawComposite();
+   }
+
+   private void redrawComposite() {
+      if (parentComp == null || !Widgets.isAccessible(parentComp)) {
+         return;
+      }
+      if (mainComp != null && Widgets.isAccessible(mainComp)) {
+         mainComp.dispose();
+         xWorldViewer = null;
+      }
+      mainComp = new Composite(parentComp, SWT.FLAT);
+      mainComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+      mainComp.setLayout(new GridLayout(1, true));
+      if (toolkit != null) {
+         toolkit.paintBordersFor(mainComp);
+      }
+
+      labelWidget = new Label(mainComp, SWT.NONE);
+      labelWidget.setText(getLabel() + ":");
+      if (getToolTip() != null) {
+         labelWidget.setToolTipText(getToolTip());
+      }
+
+      try {
+         Composite tableComp = new Composite(mainComp, SWT.BORDER);
+         GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+         tableComp.setLayoutData(gd);
+         tableComp.setLayout(ALayout.getZeroMarginLayout());
+         if (toolkit != null) {
+            toolkit.paintBordersFor(tableComp);
+         }
+
+         ToolBar toolBar = createActionBar(tableComp);
+
+         xWorldViewer = new WorldXViewer(tableComp, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION, xViewerFactory, null);
+         xWorldViewer.getTree().setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+         xWorldViewer.setContentProvider(new WorldContentProvider(xWorldViewer));
+         xWorldViewer.setLabelProvider(new WorldLabelProvider(xWorldViewer));
+
+         new ActionContributionItem(xWorldViewer.getCustomizeAction()).fill(toolBar, -1);
+
+         if (toolkit != null && xWorldViewer.getStatusLabel() != null) {
+            toolkit.adapt(xWorldViewer.getStatusLabel(), false, false);
+         }
+
+         pointsLabel = new XLabelValue("Total Estimated Points", "0");
+         pointsLabel.createWidgets(tableComp, 2);
+         pointsLabel.getComp().setLayout(new GridLayout(2, false));
+         pointsLabel.getLabelWidget().setFont(FontManager.getCourierNew12Bold());
+         if (toolkit != null) {
+            toolkit.adapt(pointsLabel.getLabelWidget(), false, false);
+            toolkit.adapt(pointsLabel.getValueTextWidget(), false, false);
+         }
+
+         refresh();
+      } catch (OseeCoreException ex) {
+         OseeLog.log(Activator.class, Level.SEVERE, ex);
+      }
+      // reset bold for label
+      WorkflowEditor.setLabelFonts(labelWidget, FontManager.getDefaultLabelFont());
+
+      parentComp.layout();
+   }
+
+   public abstract ToolBar createActionBar(Composite tableComp);
+
+   public void setXviewerTreeSize() {
+      Tree tree = xWorldViewer.getTree();
+      int size = xWorldViewer.getTree().getItemCount();
+      if (size > MAX_TABLE_SIZE) {
+         size = MAX_TABLE_SIZE;
+      }
+      if (size == lastSize) {
+         return;
+      }
+      lastSize = size;
+      int treeItemHeight = xWorldViewer.getTree().getItemHeight();
+      GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+      gridData.heightHint = treeItemHeight * (paddedTableHeightHint + size);
+      tree.setLayout(ALayout.getZeroMarginLayout());
+      tree.setLayoutData(gridData);
+      tree.setHeaderVisible(true);
+      tree.setLinesVisible(true);
+   }
+
+   public void loadTable() {
+      try {
+         if (xWorldViewer != null && xWorldViewer.getContentProvider() != null) {
+            workItems = getWorkItems();
+            xWorldViewer.setInput(workItems);
+            xWorldViewer.refresh();
+         }
+      } catch (Exception ex) {
+         OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+      }
+   }
+
+   @Override
+   public Control getControl() {
+      if (xWorldViewer == null) {
+         return null;
+      }
+      return xWorldViewer.getTree();
+   }
+
+   @Override
+   public void dispose() {
+      if (xWorldViewer != null) {
+         xWorldViewer.dispose();
+      }
+   }
+
+   @Override
+   public void refresh() {
+      if (xWorldViewer == null || xWorldViewer.getTree() == null || xWorldViewer.getTree().isDisposed()) {
+         return;
+      }
+      loadTable();
+      setXviewerTreeSize();
+      updateExtraInfoLabel();
+      pointsLabel.setValueText("Put Label Here");
+   }
+
+   public WorldXViewer getxWorldViewer() {
+      return xWorldViewer;
+   }
+
+   public Label getExtraInfoLabel() {
+      return extraInfoLabel;
+   }
+
+   public void setExtraInfoLabel(Label extraInfoLabel) {
+      this.extraInfoLabel = extraInfoLabel;
+   }
+
+   public abstract Pair<Integer, String> getExtraInfoString();
+
+   private void updateExtraInfoLabel() {
+      Pair<Integer, String> entry = getExtraInfoString();
+      updateExtraInfoLabel(entry.getFirst(), entry.getSecond());
+   }
+
+   private void updateExtraInfoLabel(final int color, final String infoStr) {
+      Displays.ensureInDisplayThread(new Runnable() {
+         @Override
+         public void run() {
+            if (Widgets.isAccessible(extraInfoLabel)) {
+               String currentString = extraInfoLabel.getText();
+               if (infoStr == null && currentString != null || //
+               infoStr != null && currentString == null || //
+               infoStr != null && currentString != null && !infoStr.equals(currentString)) {
+                  extraInfoLabel.setText(infoStr);
+               }
+               extraInfoLabel.setForeground(Displays.getSystemColor(color));
+            }
+         }
+      });
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/artifact/Artifact.java b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/artifact/Artifact.java
index 471a3d6..f72c0ce 100644
--- a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/artifact/Artifact.java
+++ b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/artifact/Artifact.java
@@ -1276,6 +1276,18 @@
       return transaction.execute();
    }
 
+   public void persistInThread(String comment) {
+      Thread persistThread = new Thread("Persist: [" + comment + "]") {
+
+         @Override
+         public void run() {
+            persist(comment);
+         }
+
+      };
+      persistThread.start();
+   }
+
    /**
     * <b>THIS ASSUMES YOU ARE MAINTAINING YOUR OWN TRANSACTION</b> vs {@link #SkynetTransaction.persist(String)} where
     * silently you are provided a transaction.
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XAbstractSignDateAndByButton.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XAbstractSignDateAndByButton.java
index 47839cc..8ec1f8b 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XAbstractSignDateAndByButton.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XAbstractSignDateAndByButton.java
@@ -13,6 +13,8 @@
 
 package org.eclipse.osee.framework.ui.skynet.widgets;
 
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Date;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
@@ -36,6 +38,7 @@
 import org.eclipse.osee.framework.ui.swt.ImageManager;
 import org.eclipse.osee.framework.ui.swt.KeyedImage;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Label;
 
 /**
  * XWidget that provides a label and button. Upon pressing button, user and date will be stored and displayed. Widget
@@ -47,21 +50,21 @@
 public abstract class XAbstractSignDateAndByButton extends XButtonWithLabelDam {
 
    public static final String NOT_YET_SIGNED = "Not Yet Signed";
-   private final AttributeTypeId signDateAttrType;
-   private final AttributeTypeId signByAttrType;
-   private boolean isRequiredButton = false;
+   protected final AttributeTypeId signDateAttrType;
+   protected final AttributeTypeId signByAttrType;
    protected boolean doSign = false;
+   protected boolean required = false;
 
-   public XAbstractSignDateAndByButton(String label, String toolTip, AttributeTypeId signDateAttrType, AttributeTypeId signByAttrUser, KeyedImage keyedImage) {
+   public XAbstractSignDateAndByButton(String label, String toolTip, AttributeTypeId signDateAttrType, AttributeTypeId signByAttrType, KeyedImage keyedImage) {
       super(label, toolTip, ImageManager.getImage(keyedImage));
       this.signDateAttrType = signDateAttrType;
-      this.signByAttrType = signByAttrUser;
+      this.signByAttrType = signByAttrType;
       addListener();
    }
 
-   public XAbstractSignDateAndByButton(String labelReq, String toolTipReq, AttributeTypeId signDateAttrTypeReq, AttributeTypeId signByAttrUserReq, KeyedImage keyedImageReq, boolean isRequired) {
+   public XAbstractSignDateAndByButton(String labelReq, String toolTipReq, AttributeTypeId signDateAttrTypeReq, AttributeTypeId signByAttrUserReq, KeyedImage keyedImageReq, boolean required) {
       this(labelReq, toolTipReq, signDateAttrTypeReq, signByAttrUserReq, keyedImageReq);
-      this.isRequiredButton = isRequired;
+      this.required = required;
    }
 
    protected void addListener() {
@@ -70,18 +73,16 @@
 
    @Override
    public String getResultsText() {
-      Date date = getArtifact().getSoleAttributeValue(signDateAttrType, null);
+      return getText(getArtifact(), signDateAttrType, signByAttrType);
+   }
+
+   public static String getText(Artifact artifact, AttributeTypeId signDateAttrType, AttributeTypeId signByAttrType) {
+      Date date = artifact.getSoleAttributeValue(signDateAttrType, null);
       if (date != null) {
-         User user = UserManager.getUserByArtId(
-            getArtifact().getSoleAttributeValue(signByAttrType, SystemUser.UnAssigned.getId()));
-         resultsLabelWidget.setForeground(Displays.getSystemColor(SWT.COLOR_BLACK));
+         User user =
+            UserManager.getUserByArtId(artifact.getSoleAttributeValue(signByAttrType, SystemUser.UnAssigned.getId()));
          return String.format("signed by %s on %s", user.getName(), DateUtil.getDateNow(date, DateUtil.MMDDYYHHMM));
       }
-      if (this.isRequiredButton) {
-         resultsLabelWidget.setForeground(Displays.getSystemColor(SWT.COLOR_RED));
-      } else {
-         resultsLabelWidget.setForeground(Displays.getSystemColor(SWT.COLOR_BLACK));
-      }
       return NOT_YET_SIGNED;
    }
 
@@ -92,7 +93,7 @@
       }
    };
 
-   protected void handleSelection() {
+   public void handleSelection() {
       try {
          // Ok --> 0, Cancel --> 1, Clear --> 2
          int res = MessageDialog.open(3, Displays.getActiveShell(), getLabel(), getSignMessage(), SWT.NONE,
@@ -108,9 +109,15 @@
             @Override
             protected IStatus run(IProgressMonitor monitor) {
                if (res == 2) {
-                  setUnsigned();
-               } else {
-                  setSigned();
+                  if (userHasPermission()) {
+                     setSigned(artifact, signDateAttrType, signByAttrType, getLabel(), false);
+                     refreshLabel();
+                  }
+               } else if (res == 0) {
+                  if (userHasPermission()) {
+                     setSigned(artifact, signDateAttrType, signByAttrType, getLabel(), true);
+                     refreshLabel();
+                  }
                }
                return Status.OK_STATUS;
             }
@@ -141,30 +148,24 @@
       return true;
    }
 
-   public void setSigned() {
-      if (userHasPermission()) {
-         SkynetTransaction tx =
-            TransactionManager.createTransaction(getArtifact().getBranch(), "Set signed for " + getLabel());
-         Artifact storeArt = getArtifact();
-         storeArt.setSoleAttributeValue(signByAttrType, UserManager.getUser().getId());
-         storeArt.setSoleAttributeValue(signDateAttrType, new Date());
-         tx.addArtifact(storeArt);
-         tx.execute();
-         refreshLabel();
-      }
+   public static void setSigned(Artifact artifact, AttributeTypeId signDateAttrType, AttributeTypeId signByAttrType, String label, boolean signed) {
+      setSigned(Collections.singleton(artifact), signDateAttrType, signByAttrType, label, signed);
    }
 
-   public void setUnsigned() {
-      if (userHasPermission()) {
-         SkynetTransaction tx =
-            TransactionManager.createTransaction(getArtifact().getBranch(), "Set unsigned for " + getLabel());
-         Artifact storeArt = getArtifact();
-         storeArt.deleteSoleAttribute(signByAttrType);
-         storeArt.deleteSoleAttribute(signDateAttrType);
-         tx.addArtifact(storeArt);
-         tx.execute();
-         refreshLabel();
+   public static void setSigned(Collection<Artifact> artifacts, AttributeTypeId signDateAttrType, AttributeTypeId signByAttrType, String label, boolean signed) {
+      SkynetTransaction tx =
+         TransactionManager.createTransaction(artifacts.iterator().next().getBranch(), "Set signed for " + label);
+      for (Artifact art : artifacts) {
+         if (signed) {
+            art.setSoleAttributeValue(signByAttrType, UserManager.getUser().getId());
+            art.setSoleAttributeValue(signDateAttrType, new Date());
+         } else {
+            art.deleteSoleAttribute(signByAttrType);
+            art.deleteSoleAttribute(signDateAttrType);
+         }
+         tx.addArtifact(art);
       }
+      tx.execute();
    }
 
    @Override
@@ -191,4 +192,17 @@
       return Status.OK_STATUS;
    }
 
+   public void setUnsigned() {
+      XAbstractSignDateAndByButton.setSigned(getArtifact(), signDateAttrType, signByAttrType, getLabel(), false);
+   }
+
+   public void setSigned() {
+      XAbstractSignDateAndByButton.setSigned(getArtifact(), signDateAttrType, signByAttrType, getLabel(), true);
+   }
+
+   @Override
+   public Label getControl() {
+      return labelWidget;
+   }
+
 }
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XButton.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XButton.java
index ced9187..a2e0a0a 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XButton.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XButton.java
@@ -21,6 +21,7 @@
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Listener;
@@ -32,7 +33,7 @@
 
    protected Label button;
    protected Composite parent;
-   protected Composite bComp;
+   protected Composite comp;
    private boolean labelAfter = true;
    protected int numColumns = 2;
 
@@ -45,8 +46,8 @@
    }
 
    @Override
-   public Label getControl() {
-      return button;
+   public Control getControl() {
+      return comp;
    }
 
    /**
@@ -60,23 +61,23 @@
       }
       this.parent = parent;
 
-      bComp = new Composite(parent, SWT.NONE);
-      bComp.setLayout(ALayout.getZeroMarginLayout(numColumns, false));
-      bComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+      comp = new Composite(parent, SWT.NONE);
+      comp.setLayout(ALayout.getZeroMarginLayout(numColumns, false));
+      comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
       if (toolkit != null) {
-         toolkit.adapt(bComp);
+         toolkit.adapt(comp);
       }
 
       // Create Text Widgets
       if (!labelAfter) {
-         labelWidget = new Label(bComp, SWT.NONE);
+         labelWidget = new Label(comp, SWT.NONE);
          labelWidget.setText(getLabel() + ":");
       }
 
       if (toolkit != null) {
-         button = toolkit.createLabel(bComp, "");
+         button = toolkit.createLabel(comp, "");
       } else {
-         button = new Label(bComp, SWT.PUSH);
+         button = new Label(comp, SWT.PUSH);
       }
       GridData gd2 = new GridData(GridData.BEGINNING);
       button.setLayoutData(gd2);
@@ -95,7 +96,7 @@
       gd.horizontalSpan = horizontalSpan - 1;
 
       if (labelAfter) {
-         labelWidget = new Label(bComp, SWT.NONE);
+         labelWidget = new Label(comp, SWT.NONE);
          labelWidget.setText(getLabel());
       }
       // Nice to allow user to select label or icon to kick-off action
@@ -133,7 +134,7 @@
    public void dispose() {
       labelWidget.dispose();
       button.dispose();
-      bComp.dispose();
+      comp.dispose();
       if (parent != null && !parent.isDisposed()) {
          parent.layout();
       }
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XButtonWithLabelDam.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XButtonWithLabelDam.java
index 60eb78c..be2495d 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XButtonWithLabelDam.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XButtonWithLabelDam.java
@@ -39,7 +39,7 @@
    protected void createControls(Composite parent, int horizontalSpan) {
       numColumns = 3;
       super.createControls(parent, horizontalSpan);
-      resultsLabelWidget = new Label(bComp, SWT.NONE);
+      resultsLabelWidget = new Label(comp, SWT.NONE);
       refreshLabel();
    }
 
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XCheckBoxThreeStateDam.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XCheckBoxThreeStateDam.java
index 0324e21..ffe42d0 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XCheckBoxThreeStateDam.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XCheckBoxThreeStateDam.java
@@ -92,7 +92,7 @@
                } else {
                   comment = "XCheckDam Auto-Save";
                }
-               getArtifact().persist(comment);
+               getArtifact().persistInThread(comment);
             }
          }
       } else {
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XComboDam.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XComboDam.java
index b045589..771b364 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XComboDam.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XComboDam.java
@@ -63,7 +63,7 @@
                      } else {
                         comment = "XComboDam Auto-Save";
                      }
-                     getArtifact().persist(comment);
+                     getArtifact().persistInThread(comment);
                   }
                }
             }
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XComboEnumDam.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XComboEnumDam.java
index f8246f3..5be1d47 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XComboEnumDam.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XComboEnumDam.java
@@ -68,7 +68,7 @@
                      } else {
                         comment = "XComboEnumDam Auto-Save";
                      }
-                     getArtifact().persist(comment);
+                     getArtifact().persistInThread(comment);
                   }
                }
             }
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XDateDam.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XDateDam.java
index 0b38ef9..a8e121d 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XDateDam.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XDateDam.java
@@ -58,7 +58,7 @@
                      } else {
                         comment = "XDateDam Auto-Save";
                      }
-                     getArtifact().persist(comment);
+                     getArtifact().persistInThread(comment);
                   }
                }
             }
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XFloatDam.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XFloatDam.java
index 36923bd..a77861c 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XFloatDam.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XFloatDam.java
@@ -120,7 +120,7 @@
                      } else {
                         comment = "XFloatDam Auto-Save";
                      }
-                     getArtifact().persist(comment);
+                     getArtifact().persistInThread(comment);
                   }
                }
             }
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XHyperlinkLabelCmdValueSelection.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XHyperlinkLabelCmdValueSelection.java
index cc227c0..6158179 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XHyperlinkLabelCmdValueSelection.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XHyperlinkLabelCmdValueSelection.java
@@ -34,8 +34,9 @@
 
    Label valueLabel;
    Hyperlink selectHyperLinkLabel, clearHyperLinkLabel;
-   private final boolean supportClear;
-   private Integer truncateValueLength = null;
+   protected boolean supportClear;
+   protected Integer truncateValueLength = null;
+   private Composite comp;
 
    public XHyperlinkLabelCmdValueSelection(String label) {
       this(label, false);
@@ -82,7 +83,7 @@
    @Override
    protected void createControls(Composite parent, int horizontalSpan) {
 
-      Composite comp = new Composite(parent, SWT.NONE);
+      comp = new Composite(parent, SWT.NONE);
       comp.setLayout(ALayout.getZeroMarginLayout(5, false));
       GridData gd = new GridData(GridData.FILL_HORIZONTAL);
       gd.horizontalSpan = horizontalSpan;
@@ -172,7 +173,7 @@
 
    @Override
    public Control getControl() {
-      return valueLabel;
+      return comp;
    }
 
    @Override
@@ -214,4 +215,5 @@
          clearHyperLinkLabel.setEnabled(true);
       }
    }
+
 }
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XHyperlinkLabelValueSelDam.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XHyperlinkLabelValueSelDam.java
new file mode 100644
index 0000000..817e93b
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XHyperlinkLabelValueSelDam.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * 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.framework.ui.skynet.widgets;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osee.framework.core.data.AttributeTypeToken;
+import org.eclipse.osee.framework.core.util.Result;
+import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.validation.IOseeValidator;
+import org.eclipse.osee.framework.skynet.core.validation.OseeValidator;
+import org.eclipse.osee.framework.ui.skynet.internal.Activator;
+
+/**
+ * @author Donald G. Dunne
+ */
+public abstract class XHyperlinkLabelValueSelDam extends XHyperlinkLabelCmdValueSelection implements AttributeWidget {
+
+   private Artifact artifact;
+   private AttributeTypeToken attributeType;
+
+   public XHyperlinkLabelValueSelDam(String label) {
+      this(label, false);
+   }
+
+   public XHyperlinkLabelValueSelDam(String label, boolean supportClear, Integer truncateValueLength) {
+      super(label);
+      this.supportClear = supportClear;
+      this.truncateValueLength = truncateValueLength;
+   }
+
+   public XHyperlinkLabelValueSelDam(String label, boolean supportClear) {
+      this(label, supportClear, null);
+   }
+
+   @Override
+   public Artifact getArtifact() {
+      return artifact;
+   }
+
+   /**
+    * Hyperlink Selection is save on selection
+    */
+   @Override
+   public void saveToArtifact() {
+      // do nothing
+   }
+
+   /**
+    * Hyperlink Selection is save on selection
+    */
+   @Override
+   public void revert() {
+      // do nothing
+   }
+
+   /**
+    * Hyperlink Selection is save on selection
+    */
+   @Override
+   public Result isDirty() {
+      return Result.FalseResult;
+   }
+
+   @Override
+   public void setAttributeType(Artifact artifact, AttributeTypeToken attributeType) {
+      this.artifact = artifact;
+      this.attributeType = attributeType;
+   }
+
+   @Override
+   public AttributeTypeToken getAttributeType() {
+      return attributeType;
+   }
+
+   @Override
+   public IStatus isValid() {
+      IStatus status = super.isValid();
+      if (status.isOK()) {
+         try {
+            if (getArtifact() != null && getAttributeType() != null) {
+               status = OseeValidator.getInstance().validate(IOseeValidator.SHORT, getArtifact(), getAttributeType(),
+                  getCurrentValue());
+               if (status.isOK() && isRequiredEntry() && Strings.isInValid(getCurrentValue())) {
+                  status = new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+                     String.format("Must enter [%s]", attributeType.getUnqualifiedName()));
+               }
+            }
+         } catch (OseeCoreException ex) {
+            status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error getting Artifact", ex);
+         }
+      }
+      return status;
+   }
+
+}
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XIntegerDam.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XIntegerDam.java
index a7fa328..9d69b34 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XIntegerDam.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XIntegerDam.java
@@ -126,7 +126,7 @@
                      } else {
                         comment = "XIntegerDam Auto-Save";
                      }
-                     getArtifact().persist(comment);
+                     getArtifact().persistInThread(comment);
                   }
                }
             }
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XTextDam.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XTextDam.java
index 6af429b..e5d15a4 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XTextDam.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XTextDam.java
@@ -149,7 +149,7 @@
                      } else {
                         comment = "XTextDam Auto-Save";
                      }
-                     getArtifact().persist(comment);
+                     getArtifact().persistInThread(comment);
                   }
                }
             }