bug[ats_V5JWA]: Publish with Diff BLAM not working

Change-Id: I283aa38761ad0678c6d2a36f646948cfe2bc0e1c
diff --git a/plugins/org.eclipse.osee.define/src/org/eclipse/osee/define/blam/operation/PublishWithSpecifiedTemplate.java b/plugins/org.eclipse.osee.define/src/org/eclipse/osee/define/blam/operation/PublishWithSpecifiedTemplate.java
index 44d1ca5..d51f7b0 100644
--- a/plugins/org.eclipse.osee.define/src/org/eclipse/osee/define/blam/operation/PublishWithSpecifiedTemplate.java
+++ b/plugins/org.eclipse.osee.define/src/org/eclipse/osee/define/blam/operation/PublishWithSpecifiedTemplate.java
@@ -17,8 +17,8 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.osee.framework.core.data.IOseeBranch;
 import org.eclipse.osee.framework.core.exception.OseeArgumentException;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
 import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
-import org.eclipse.osee.framework.skynet.core.artifact.BranchManager;
 import org.eclipse.osee.framework.skynet.core.linking.LinkType;
 import org.eclipse.osee.framework.skynet.core.transaction.SkynetTransaction;
 import org.eclipse.osee.framework.skynet.core.transaction.TransactionManager;
@@ -28,6 +28,17 @@
 import org.eclipse.osee.framework.ui.skynet.render.ITemplateRenderer;
 import org.eclipse.osee.framework.ui.skynet.render.WordTemplateRenderer;
 import org.eclipse.osee.framework.ui.skynet.templates.TemplateManager;
+import org.eclipse.osee.framework.ui.skynet.widgets.XBranchSelectWidget;
+import org.eclipse.osee.framework.ui.skynet.widgets.XCheckBox;
+import org.eclipse.osee.framework.ui.skynet.widgets.XCombo;
+import org.eclipse.osee.framework.ui.skynet.widgets.XModifiedListener;
+import org.eclipse.osee.framework.ui.skynet.widgets.XWidget;
+import org.eclipse.osee.framework.ui.skynet.widgets.util.SwtXWidgetRenderer;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.ui.forms.widgets.FormToolkit;
 
 /**
  * @author Jeff C. Phillips
@@ -35,6 +46,16 @@
  */
 public class PublishWithSpecifiedTemplate extends AbstractBlam {
    private List<Artifact> templates;
+   private XBranchSelectWidget branchWidget;
+   private XCombo slaveWidget;
+   private final String USE_ARTIFACT_NAMES = "Use Artifact Names";
+   private final String USE_PARAGRAPH_NUMBERS = "Use Paragram Numbers";
+   private final String UPDATE_PARAGRAPH_NUMBERS = "Update Paragraph Numbers (If authorized)";
+   private final String MASTER_TEMPLATE = "Master Template";
+   private final String SLAVE_TEMPLATE = "Slave Template";
+   private final String IS_ARTIFACTS = "IS Artifacts";
+   private final String PUBLISH_AS_DIFF = "Publish As Diff";
+   private final String WAS_BRANCH = "WAS Branch";
 
    @Override
    public String getName() {
@@ -45,8 +66,8 @@
    public void runOperation(VariableMap variableMap, IProgressMonitor monitor) throws Exception {
       populateTemplateList();
 
-      boolean useArtifactNameInLinks = variableMap.getBoolean("Use Artifact Names");
-      boolean useParagraphNumbersInLinks = variableMap.getBoolean("Use Paragraph Numbers");
+      boolean useArtifactNameInLinks = variableMap.getBoolean(USE_ARTIFACT_NAMES);
+      boolean useParagraphNumbersInLinks = variableMap.getBoolean(USE_PARAGRAPH_NUMBERS);
 
       if (!useParagraphNumbersInLinks && !useArtifactNameInLinks) {
          throw new OseeArgumentException("Please select at least one Document Link Format");
@@ -60,15 +81,28 @@
          linkType = LinkType.INTERNAL_DOC_REFERENCE_USE_NAME;
       }
 
-      Artifact master = getTemplate(variableMap.getString("Master Template"));
-      Artifact slave = getTemplate(variableMap.getString("Slave Template"));
-      IOseeBranch branch = variableMap.getBranch("Branch (If Template specifies Artifacts)");
-      List<Artifact> artifacts = variableMap.getArtifacts("Artifacts (If Not Specified in Template)");
+      Artifact master = getTemplate(variableMap.getString(MASTER_TEMPLATE));
+      if (master == null) {
+         throw new OseeArgumentException("Must select a Master Template");
+      }
+      Artifact slave = getTemplate(variableMap.getString(SLAVE_TEMPLATE));
+      IOseeBranch branch = null;
+      List<Artifact> artifacts;
+      try {
+         artifacts = variableMap.getArtifacts(IS_ARTIFACTS);
+      } catch (NullPointerException e) {
+         throw new OseeArgumentException("Must provide an IS artifact.  Please add an IS artifact and rerun.");
+      }
       if (artifacts != null && !artifacts.isEmpty()) {
          branch = artifacts.get(0).getBranch();
-      }
-      if (artifacts != null && artifacts.isEmpty()) {
+      } else if (artifacts != null && artifacts.isEmpty()) {
          artifacts = null;
+      } else {
+         throw new OseeArgumentException("Must provide an artifact");
+      }
+
+      if (branch == null) {
+         throw new OseeArgumentException("Cannot determine IS branch.");
       }
 
       WordTemplateRenderer renderer = new WordTemplateRenderer();
@@ -79,19 +113,25 @@
             "Branch",
             branch,
             "compareBranch",
-            variableMap.getBranch("Compare Against Another Branch"),
+            variableMap.getBranch(WAS_BRANCH),
             "Publish As Diff",
-            variableMap.getValue("Publish As Diff"),
+            variableMap.getValue(PUBLISH_AS_DIFF),
             "linkType",
             linkType,
             WordTemplateRenderer.UPDATE_PARAGRAPH_NUMBER_OPTION,
-            variableMap.getBoolean("Update Paragraph Numbers"),
+            variableMap.getBoolean(UPDATE_PARAGRAPH_NUMBERS),
             ITemplateRenderer.TRANSACTION_OPTION,
             transaction,
             IRenderer.SKIP_ERRORS,
             true,
             "Exclude Folders",
-            variableMap.getBoolean("Exclude Folders")};
+            true,
+            "Recurse On Load",
+            true,
+            "Maintain Order",
+            true,
+            "Progress Monitor",
+            monitor};
 
       renderer.publish(master, slave, artifacts, options);
 
@@ -101,7 +141,14 @@
    @Override
    public String getDescriptionUsage() {
       StringBuilder sb = new StringBuilder();
-      sb.append("Select a Master or Master/Slave template and click the play button at the top right.\n");
+      sb.append("<form>Use a template to publish a document or diff the document against a different version.<br/>");
+      sb.append("Select Parameters<br/>");
+      sb.append("<li>Select Update Paragraph Numbers if authorized to update them</li>");
+      sb.append("<li>Select the Document Link format(s)</li>");
+      sb.append("<li>Select Master or Master/Slave (for SRS) template.  Only use non-recursive templates</li>");
+      sb.append("<li>Drag &amp; Drop the IS Artifacts into the box</li>");
+      sb.append("<li>Decide to Publish as Diff and select WAS branch as desired</li>");
+      sb.append("<br/>Click the play button at the top right or in the Execute section.</form>");
       return sb.toString();
    }
 
@@ -109,38 +156,91 @@
    public String getXWidgetsXml() {
       populateTemplateList();
       StringBuilder builder = new StringBuilder();
-      builder.append("<xWidgets><XWidget xwidgetType=\"XCheckBox\" horizontalLabel=\"true\" labelAfter=\"true\" displayName=\"Update Paragraph Numbers\" />");
+      builder.append(String.format(
+         "<xWidgets><XWidget xwidgetType=\"XCheckBox\" horizontalLabel=\"true\" labelAfter=\"true\" displayName=\"%s\" />",
+         UPDATE_PARAGRAPH_NUMBERS));
 
       builder.append("<XWidget xwidgetType=\"XLabel\" displayName=\"Document Link Format:\"/>");
-      builder.append("<XWidget xwidgetType=\"XCheckBox\" horizontalLabel=\"true\" labelAfter=\"true\" displayName=\"Use Artifact Names\" />");
-      builder.append("<XWidget xwidgetType=\"XCheckBox\" horizontalLabel=\"true\" labelAfter=\"true\" displayName=\"Use Paragraph Numbers\" />");
-      builder.append("<XWidget xwidgetType=\"XCheckBox\" horizontalLabel=\"true\" labelAfter=\"true\" displayName=\"Exclude Folders\" defaultValue=\"true\"/>");
+      builder.append(String.format(
+         "<XWidget xwidgetType=\"XCheckBox\" horizontalLabel=\"true\" labelAfter=\"true\" displayName=\"%s\" defaultValue=\"true\"/>",
+         USE_ARTIFACT_NAMES));
+      builder.append(String.format(
+         "<XWidget xwidgetType=\"XCheckBox\" horizontalLabel=\"true\" labelAfter=\"true\" displayName=\"%s\" />",
+         USE_PARAGRAPH_NUMBERS));
 
       builder.append("<XWidget xwidgetType=\"XLabel\" displayName=\" \" /><XWidget xwidgetType=\"XCombo(");
       for (Artifact art : templates) {
          builder.append(art.getSafeName());
          builder.append(",");
       }
-      builder.append(")\" displayName=\"Master Template\" horizontalLabel=\"true\"/>");
+      builder.append(String.format(")\" displayName=\"%s\" horizontalLabel=\"true\"/>", MASTER_TEMPLATE));
       builder.append("<XWidget xwidgetType=\"XCombo(");
       for (Artifact art : templates) {
          builder.append(art.getSafeName());
          builder.append(",");
       }
 
-      builder.append(")\" displayName=\"Slave Template\" horizontalLabel=\"true\"/><XWidget xwidgetType=\"XLabel\" displayName=\" \" />");
-      builder.append("<XWidget xwidgetType=\"XBranchSelectWidget\" displayName=\"Branch (If Template specifies Artifacts)\" defaultValue=\"" + BranchManager.getLastBranch().getGuid() + "\" /><XWidget xwidgetType=\"XListDropViewer\" displayName=\"Artifacts (If Not Specified in Template)\" />");
+      builder.append(String.format(
+         ")\" displayName=\"%s\" horizontalLabel=\"true\"/><XWidget xwidgetType=\"XLabel\" displayName=\" \" />",
+         SLAVE_TEMPLATE));
+      builder.append(String.format("<XWidget xwidgetType=\"XListDropViewer\" displayName=\"%s\" />", IS_ARTIFACTS));
+
       builder.append("<XWidget xwidgetType=\"XLabel\" displayName=\"Generate Differences:\"/>");
-      builder.append("<XWidget xwidgetType=\"XLabel\" displayName=\"Note: If a Compare Against branch is selected, diffs will be between selected artifacts and current version on compare branch\"/>");
-      builder.append("<XWidget xwidgetType=\"XLabel\" displayName=\"If a Compare Against branch is NOT selected, diffs will be between selected artifacts and baseline version on same branch\"/>");
-      builder.append("<XWidget xwidgetType=\"XCheckBox\" horizontalLabel=\"true\" labelAfter=\"true\" displayName=\"Publish As Diff\" />");
-      //      builder.append("<XWidget xwidgetType=\"XCheckBox\" horizontalLabel=\"true\" labelAfter=\"true\" displayName=\"Diff from Baseline\" />");
-      builder.append("<XWidget xwidgetType=\"XBranchSelectWidget\" displayName=\"Compare Against Another Branch\"/>");
+      builder.append(String.format(
+         "<XWidget xwidgetType=\"XCheckBox\" horizontalLabel=\"true\" labelAfter=\"true\" displayName=\"%s\" />",
+         PUBLISH_AS_DIFF));
+      builder.append(String.format("<XWidget xwidgetType=\"XBranchSelectWidget\" displayName=\"%s\"/>", WAS_BRANCH));
+      builder.append("<XWidget xwidgetType=\"XLabel\" displayName=\"Note: If a WAS branch is selected, diffs will be between selected IS artifacts and current version on WAS branch\"/>");
+      builder.append("<XWidget xwidgetType=\"XLabel\" displayName=\"If a WAS branch is NOT selected, diffs will be between selected IS artifacts and baseline version on IS branch\"/>");
       builder.append("</xWidgets>");
 
       return builder.toString();
    }
 
+   @Override
+   public void widgetCreated(XWidget xWidget, FormToolkit toolkit, Artifact art, SwtXWidgetRenderer dynamicXWidgetLayout, XModifiedListener modListener, boolean isEditable) throws OseeCoreException {
+      super.widgetCreated(xWidget, toolkit, art, dynamicXWidgetLayout, modListener, isEditable);
+      if (xWidget.getLabel().equals(WAS_BRANCH)) {
+         branchWidget = (XBranchSelectWidget) xWidget;
+         branchWidget.setEditable(false);
+      } else if (xWidget.getLabel().equals(PUBLISH_AS_DIFF)) {
+         final XCheckBox checkBox = (XCheckBox) xWidget;
+         checkBox.addSelectionListener(new SelectionAdapter() {
+
+            // Link the editable setting of the branch widget to the 'Publish As Diff' checkbox
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+               super.widgetSelected(e);
+               branchWidget.setEditable(checkBox.isChecked());
+
+               if (!checkBox.isChecked()) {
+                  // reset branchwidget selection when checkbox is unchecked
+                  branchWidget.setSelection(null);
+               }
+            }
+
+         });
+      } else if (xWidget.getLabel().equals(MASTER_TEMPLATE)) {
+         final XCombo masterCombo = (XCombo) xWidget;
+         masterCombo.addModifyListener(new ModifyListener() {
+
+            @Override
+            public void modifyText(ModifyEvent e) {
+               // only enable slave template selection if Master is for SRS.
+               if (masterCombo.get().contains("srsMaster")) {
+                  slaveWidget.setEnabled(true);
+               } else {
+                  slaveWidget.setEnabled(false);
+                  slaveWidget.set("");
+               }
+            }
+         });
+      } else if (xWidget.getLabel().equals(SLAVE_TEMPLATE)) {
+         slaveWidget = (XCombo) xWidget;
+         slaveWidget.setEnabled(false);
+      }
+   }
+
    private void populateTemplateList() {
       templates = TemplateManager.getAllTemplates();
       Collections.sort(templates);
diff --git a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/change/ArtifactDelta.java b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/change/ArtifactDelta.java
index d40d937..793a1e2 100644
--- a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/change/ArtifactDelta.java
+++ b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/change/ArtifactDelta.java
@@ -22,6 +22,7 @@
 
    private final Artifact startArt;
    private final Artifact endArt;
+   private final Artifact baseArt;
    private final TransactionDelta txDelta;
 
    public ArtifactDelta(TransactionDelta txDelta, Artifact startArt, Artifact endArt) throws OseeArgumentException {
@@ -30,6 +31,17 @@
       }
       this.startArt = startArt;
       this.endArt = endArt;
+      this.baseArt = startArt;
+      this.txDelta = txDelta;
+   }
+
+   public ArtifactDelta(TransactionDelta txDelta, Artifact startArt, Artifact endArt, Artifact baseArt) throws OseeArgumentException {
+      if (startArt == null && endArt == null) {
+         throw new OseeArgumentException("the start and end artifacts can not both be null.");
+      }
+      this.startArt = startArt;
+      this.endArt = endArt;
+      this.baseArt = baseArt;
       this.txDelta = txDelta;
    }
 
@@ -49,6 +61,10 @@
       return endArt;
    }
 
+   public Artifact getBaseArtifact() {
+      return baseArt;
+   }
+
    public IOseeBranch getBranch() {
       return getStartArtifact() != null ? getStartArtifact().getBranch() : getEndArtifact().getBranch();
    }
diff --git a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/revision/ChangeDataLoader.java b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/revision/ChangeDataLoader.java
index f77bfc1..808bf34 100644
--- a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/revision/ChangeDataLoader.java
+++ b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/revision/ChangeDataLoader.java
@@ -71,7 +71,7 @@
 
    @Override
    protected void doWork(IProgressMonitor monitor) throws Exception {
-      ChangeReportResponse response = requestChanges(monitor, txDelta);
+      ChangeReportResponse response = requestChanges(txDelta);
       Collection<ChangeItem> changeItems = response.getChangeItems();
 
       monitor.worked(calculateWork(0.20));
@@ -81,10 +81,11 @@
       } else {
          monitor.setTaskName("Bulk load changed artifacts");
 
+         checkForCancelledStatus(monitor);
          CompositeKeyHashMap<TransactionRecord, Integer, Artifact> bulkLoaded =
             new CompositeKeyHashMap<TransactionRecord, Integer, Artifact>();
 
-         bulkLoadArtifactDeltas(monitor, bulkLoaded, changeItems);
+         bulkLoadArtifactDeltas(bulkLoaded, changeItems);
          monitor.worked(calculateWork(0.20));
 
          monitor.setTaskName("Compute artifact deltas");
@@ -99,20 +100,80 @@
       }
    }
 
+   public void determineChanges(IProgressMonitor monitor) throws OseeCoreException {
+      monitor.setTaskName("Retrieve Change Items");
+      ChangeReportResponse response = requestChanges(txDelta);
+      Collection<ChangeItem> changeItems = response.getChangeItems();
+
+      checkForCancelledStatus(monitor);
+      monitor.setTaskName("Bulk load changed artifacts");
+      CompositeKeyHashMap<TransactionRecord, Integer, Artifact> bulkLoaded =
+         new CompositeKeyHashMap<TransactionRecord, Integer, Artifact>();
+
+      bulkLoadArtifactDeltas(bulkLoaded, changeItems);
+
+      monitor.setTaskName("Compute artifact deltas");
+      double workAmount = 0.30 / changeItems.size();
+      IOseeBranch startTxBranch = txDelta.getStartTx().getBranch();
+      for (ChangeItem item : changeItems) {
+         checkForCancelledStatus(monitor);
+         Change change = computeChangeFromGamma(bulkLoaded, startTxBranch, item);
+         changes.add(change);
+         monitor.worked(calculateWork(workAmount));
+      }
+   }
+
+   private Change computeChangeFromGamma(CompositeKeyHashMap<TransactionRecord, Integer, Artifact> bulkLoaded, IOseeBranch startTxBranch, ChangeItem item) {
+      Change change = null;
+      try {
+         int artId = item.getArtId();
+         Long destGamma = item.getDestinationVersion().getGammaId();
+         Long baseGamma = item.getBaselineVersion().getGammaId();
+         Artifact startTxArtifact;
+         Artifact endTxArtifact;
+         // When start and end transactions are on same branch set them to start and end respectfully
+         // When they are on different branches, they are switched so the difference between them
+         // will be detected and represented appropriately.
+         if (txDelta.areOnTheSameBranch()) {
+            startTxArtifact = bulkLoaded.get(txDelta.getStartTx(), artId);
+            endTxArtifact = bulkLoaded.get(txDelta.getEndTx(), artId);
+         } else {
+            startTxArtifact = bulkLoaded.get(txDelta.getEndTx(), artId);
+            endTxArtifact = bulkLoaded.get(txDelta.getStartTx(), artId);
+         }
+         Artifact baseTxArtifact;
+         if ((baseGamma != null) && baseGamma.equals(destGamma)) {
+            // change must be only on IS branch
+            baseTxArtifact = startTxArtifact;
+         } else {
+            // if basGamma is null then this must be a new artifact
+            // Otherwise, change must be on IS branch and WAS branch.
+            // In either case, set the baseTxArtifact to the base of the start branch
+            baseTxArtifact = bulkLoaded.get(txDelta.getStartTx().getBranch().getBaseTransaction(), artId);
+         }
+
+         ArtifactDelta artifactDelta = new ArtifactDelta(txDelta, startTxArtifact, endTxArtifact, baseTxArtifact);
+         change = createChangeObject(bulkLoaded, item, txDelta, startTxBranch, artifactDelta);
+         change.setChangeItem(item);
+
+      } catch (Exception ex) {
+         OseeLog.log(Activator.class, Level.SEVERE, ex);
+         change = new ErrorChange(startTxBranch, item.getArtId(), ex.toString());
+      }
+      return change;
+   }
+
    private Change computeChange(CompositeKeyHashMap<TransactionRecord, Integer, Artifact> bulkLoaded, IOseeBranch startTxBranch, ChangeItem item) {
       Change change = null;
       try {
          int artId = item.getArtId();
          Artifact startTxArtifact;
-         if (txDelta.areOnTheSameBranch()) {
-            startTxArtifact = bulkLoaded.get(txDelta.getStartTx(), artId);
-         } else {
-            startTxArtifact = bulkLoaded.get(txDelta.getStartTx().getBranch().getBaseTransaction(), artId);
-         }
          Artifact endTxArtifact;
          if (txDelta.areOnTheSameBranch()) {
+            startTxArtifact = bulkLoaded.get(txDelta.getStartTx(), artId);
             endTxArtifact = bulkLoaded.get(txDelta.getEndTx(), artId);
          } else {
+            startTxArtifact = bulkLoaded.get(txDelta.getStartTx().getBranch().getBaseTransaction(), artId);
             endTxArtifact = bulkLoaded.get(txDelta.getStartTx(), artId);
          }
 
@@ -182,8 +243,7 @@
       return change;
    }
 
-   private void bulkLoadArtifactDeltas(IProgressMonitor monitor, CompositeKeyHashMap<TransactionRecord, Integer, Artifact> bulkLoaded, Collection<ChangeItem> changeItems) throws OseeCoreException {
-      checkForCancelledStatus(monitor);
+   private void bulkLoadArtifactDeltas(CompositeKeyHashMap<TransactionRecord, Integer, Artifact> bulkLoaded, Collection<ChangeItem> changeItems) throws OseeCoreException {
       Set<Integer> artIds = asArtIds(changeItems);
 
       preloadArtifacts(bulkLoaded, artIds, txDelta.getStartTx(), txDelta.areOnTheSameBranch());
@@ -220,7 +280,7 @@
       return artIds;
    }
 
-   private static ChangeReportResponse requestChanges(IProgressMonitor monitor, TransactionDelta txDelta) throws OseeCoreException {
+   private static ChangeReportResponse requestChanges(TransactionDelta txDelta) throws OseeCoreException {
       Map<String, String> parameters = new HashMap<String, String>();
       parameters.put("function", Function.CHANGE_REPORT.name());
 
@@ -230,10 +290,6 @@
       ChangeReportResponse response =
          HttpClientMessage.send(OseeServerContext.BRANCH_CONTEXT, parameters, CoreTranslatorId.CHANGE_REPORT_REQUEST,
             requestData, CoreTranslatorId.CHANGE_REPORT_RESPONSE);
-      if (response.wasSuccessful()) {
-         // OseeEventManager.kickBranchEvent(HttpBranchCreation.class, ,
-         // branch.getId());
-      }
       return response;
    }
 }
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet.test/src/org/eclipse/osee/framework/ui/skynet/util/VbaWordDiffGeneratorTest.java b/plugins/org.eclipse.osee.framework.ui.skynet.test/src/org/eclipse/osee/framework/ui/skynet/util/VbaWordDiffGeneratorTest.java
index 3b4200a..5429d12 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet.test/src/org/eclipse/osee/framework/ui/skynet/util/VbaWordDiffGeneratorTest.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet.test/src/org/eclipse/osee/framework/ui/skynet/util/VbaWordDiffGeneratorTest.java
@@ -13,6 +13,8 @@
 import java.io.File;
 import java.io.IOException;
 import junit.framework.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.osee.framework.jdk.core.util.Lib;
 import org.eclipse.osee.framework.ui.skynet.render.compare.CompareData;
 import org.junit.Rule;
@@ -48,7 +50,8 @@
       boolean executeVbs = Lib.isWindows();
 
       VbaWordDiffGenerator diff = new VbaWordDiffGenerator(false, false, false, executeVbs, false);
-      diff.generate(compareData);
+      IProgressMonitor monitor = new NullProgressMonitor();
+      diff.generate(monitor, compareData);
 
       String actualVbs = Lib.fileToString(scriptFile);
       String expectedVbs =
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/branch/BranchSelectComposite.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/branch/BranchSelectComposite.java
index 0e2061a..039045e 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/branch/BranchSelectComposite.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/branch/BranchSelectComposite.java
@@ -128,11 +128,11 @@
    }
 
    public void setSelected(IOseeBranch branch) {
-      if (branch != null) {
-         selectedBranch = branch;
-         branchSelectTextWidget.setText(selectedBranch.getName());
-      } else {
+      selectedBranch = branch;
+      if (branch == null) {
          branchSelectTextWidget.setText(" -- Select A Branch -- ");
+      } else {
+         branchSelectTextWidget.setText(selectedBranch.getName());
       }
    }
 
@@ -169,4 +169,11 @@
    public Text getBranchSelectText() {
       return branchSelectTextWidget;
    }
+
+   /**
+    * @return the branchSelectLabel
+    */
+   public Button getBranchSelectButton() {
+      return branchSelectButton;
+   }
 }
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/RendererManager.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/RendererManager.java
index 508e159..857ede5 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/RendererManager.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/RendererManager.java
@@ -239,6 +239,13 @@
    public static void diff(Collection<ArtifactDelta> artifactDeltas, String pathPrefix, Object... options) {
       CompareDataCollector collector = new NoOpCompareDataCollector();
       IOperation operation = new DiffUsingRenderer(collector, artifactDeltas, pathPrefix, options);
-      Operations.executeWork(operation);
+      IProgressMonitor monitor = null;
+      for (int i = 0; i < options.length; i += 2) {
+         if (((String) options[i]).equals("Progress Monitor")) {
+            monitor = (IProgressMonitor) options[i + 1];
+            break;
+         }
+      }
+      Operations.executeWork(operation, monitor);
    }
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/WordTemplateRenderer.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/WordTemplateRenderer.java
index 3704823..454a745 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/WordTemplateRenderer.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/WordTemplateRenderer.java
@@ -216,8 +216,8 @@
       }
 
       template = WordUtil.removeGUIDFromTemplate(template);
-      return templateProcessor.applyTemplate(artifacts, template, null, getStringOption("paragraphNumber"),
-         getStringOption("outlineType"), presentationType);
+      return templateProcessor.applyTemplate(artifacts, template, null, null, getStringOption("outlineType"),
+         presentationType);
    }
 
    protected String getTemplate(Artifact artifact, PresentationType presentationType) throws OseeCoreException {
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/AbstractWordCompare.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/AbstractWordCompare.java
index ddd7687..36ddda3 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/AbstractWordCompare.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/AbstractWordCompare.java
@@ -14,8 +14,10 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.regex.Pattern;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.osee.framework.core.data.IAttributeType;
 import org.eclipse.osee.framework.core.data.IOseeBranch;
 import org.eclipse.osee.framework.core.exception.OseeCoreException;
@@ -40,6 +42,8 @@
    private final FileSystemRenderer renderer;
    private final ArtifactDeltaToFileConverter converter;
    private final List<IAttributeType> wordAttributeType = new ArrayList<IAttributeType>();
+   private static final Pattern authorPattern = Pattern.compile("aml:author=\".*?\"",
+      Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE);
 
    public AbstractWordCompare(FileSystemRenderer renderer, IAttributeType... wordAttributeType) {
       this.renderer = renderer;
@@ -80,7 +84,7 @@
 
       addToCompare(monitor, data, presentationType, artifactDelta);
 
-      diffGenerator.generate(data);
+      diffGenerator.generate(monitor, data);
       collector.onCompare(data);
    }
 
@@ -97,7 +101,8 @@
       IVbaDiffGenerator diffGenerator =
          createGenerator(Collections.singletonList(newerVersion), branch, presentationType);
 
-      diffGenerator.generate(data);
+      IProgressMonitor monitor = new NullProgressMonitor();
+      diffGenerator.generate(monitor, data);
       collector.onCompare(data);
    }
 
@@ -121,10 +126,21 @@
       if (!UserManager.getBooleanSetting(MsWordPreferencePage.IDENTFY_IMAGE_CHANGES)) {
          originalValue = WordImageChecker.checkForImageDiffs(baseContent, newerContent);
       }
+      monitor.setTaskName("Preparing comparison for: " + (newerArtifact == null ? baseArtifact.getName() : newerArtifact.getName()));
 
-      Pair<IFile, IFile> compareFiles = converter.convertToFile(presentationType, artifactDelta);
+      Pair<IFile, IFile> compareFiles;
+      if (artifactDelta.getStartArtifact() == artifactDelta.getBaseArtifact()) {
+         compareFiles = converter.convertToFile(presentationType, artifactDelta);
+      } else {
+         // The artifactDelta should be a 3 Way Merge
+         List<IFile> outputFiles = new ArrayList<IFile>();
+         converter.convertToFileForMerge(outputFiles, artifactDelta.getBaseArtifact(), artifactDelta.getStartArtifact());
+         converter.convertToFileForMerge(outputFiles, artifactDelta.getBaseArtifact(), artifactDelta.getEndArtifact());
+
+         compareFiles = new Pair<IFile, IFile>(outputFiles.get(0), outputFiles.get(1));
+         data.addMerge(outputFiles.get(0).getLocation().toOSString());
+      }
       WordImageChecker.restoreOriginalValue(baseContent, originalValue);
-      monitor.setTaskName("Adding to Diff Script: " + (newerArtifact == null ? baseArtifact.getName() : newerArtifact.getName()));
       data.add(compareFiles.getFirst().getLocation().toOSString(), compareFiles.getSecond().getLocation().toOSString());
    }
 
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/ArtifactDeltaToFileConverter.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/ArtifactDeltaToFileConverter.java
index 69eb7be..c0a0b82 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/ArtifactDeltaToFileConverter.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/ArtifactDeltaToFileConverter.java
@@ -10,14 +10,20 @@
  *******************************************************************************/
 package org.eclipse.osee.framework.ui.skynet.render.compare;
 
+import static org.eclipse.osee.framework.ui.skynet.render.ITemplateRenderer.TEMPLATE_OPTION;
+import java.util.Collection;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.osee.framework.core.data.IOseeBranch;
 import org.eclipse.osee.framework.core.exception.OseeCoreException;
 import org.eclipse.osee.framework.jdk.core.type.Pair;
+import org.eclipse.osee.framework.plugin.core.util.AIFile;
 import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
 import org.eclipse.osee.framework.skynet.core.change.ArtifactDelta;
 import org.eclipse.osee.framework.ui.skynet.render.FileSystemRenderer;
+import org.eclipse.osee.framework.ui.skynet.render.IRenderer;
+import org.eclipse.osee.framework.ui.skynet.render.ITemplateRenderer;
 import org.eclipse.osee.framework.ui.skynet.render.PresentationType;
+import org.eclipse.osee.framework.ui.skynet.render.RendererManager;
 
 public class ArtifactDeltaToFileConverter {
    private final FileSystemRenderer renderer;
@@ -42,4 +48,18 @@
       IFile newerFile = renderer.renderToFile(newerArtifact, branch, presentationType);
       return new Pair<IFile, IFile>(baseFile, newerFile);
    }
+
+   public void convertToFileForMerge(final Collection<IFile> outputFiles, Artifact baseVersion, Artifact newerVersion) throws OseeCoreException {
+      ArtifactDelta artifactDelta = new ArtifactDelta(baseVersion, newerVersion);
+
+      CompareDataCollector colletor = new CompareDataCollector() {
+         @Override
+         public void onCompare(CompareData data) {
+            outputFiles.add(AIFile.constructIFile(data.getOutputPath()));
+         }
+      };
+      // Set ADD MERGE TAG as an option so resulting document will indicate a merge section
+      RendererManager.diff(colletor, artifactDelta, "", IRenderer.NO_DISPLAY, true, TEMPLATE_OPTION,
+         ITemplateRenderer.DIFF_NO_ATTRIBUTES_VALUE, "ADD MERGE TAG", true);
+   }
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/CompareData.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/CompareData.java
index 42a080f..aac4b2a 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/CompareData.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/CompareData.java
@@ -10,7 +10,9 @@
  *******************************************************************************/
 package org.eclipse.osee.framework.ui.skynet.render.compare;
 
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -18,6 +20,7 @@
 public class CompareData {
 
    private final Map<String, String> dataToCompare = new LinkedHashMap<String, String>();
+   private final List<String> mergeList = new ArrayList<String>();
    private final String outputPath;
    private final String generatorScriptPath;
 
@@ -53,4 +56,14 @@
    public void clear() {
       dataToCompare.clear();
    }
+
+   public void addMerge(String fileLocation) {
+      if ((fileLocation != null) && (fileLocation.length() > 0)) {
+         mergeList.add(fileLocation);
+      }
+   }
+
+   public boolean isMerge(String fileLocation) {
+      return mergeList.contains(fileLocation);
+   }
 }
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/WordTemplateCompare.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/WordTemplateCompare.java
index 1a1aa9d..bf578af 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/WordTemplateCompare.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/compare/WordTemplateCompare.java
@@ -19,6 +19,7 @@
 import org.eclipse.osee.framework.core.enums.CoreAttributeTypes;
 import org.eclipse.osee.framework.core.exception.OseeArgumentException;
 import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.operation.Operations;
 import org.eclipse.osee.framework.logging.OseeLevel;
 import org.eclipse.osee.framework.logging.OseeLog;
 import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
@@ -63,12 +64,14 @@
       CompareData data = new CompareData(resultPath, vbsPath);
 
       addArtifactDeltas(monitor, artifactDeltas, data);
-      diffGenerator.generate(data);
+      diffGenerator.generate(monitor, data);
 
       collector.onCompare(data);
    }
 
    private void addArtifactDeltas(IProgressMonitor monitor, Collection<ArtifactDelta> artifactDeltas, CompareData data) {
+      double workAmount = 0.70 / artifactDeltas.size();
+
       for (ArtifactDelta artifactDelta : artifactDeltas) {
          if (monitor.isCanceled()) {
             throw new OperationCanceledException();
@@ -78,8 +81,10 @@
             addToCompare(monitor, data, PresentationType.DIFF, artifactDelta);
          } catch (OseeCoreException ex) {
             OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
+         } catch (Exception ex) {
+            OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, ex);
          } finally {
-            monitor.worked(1);
+            monitor.worked(Operations.calculateWork(Operations.TASK_WORK_RESOLUTION, workAmount));
          }
       }
 
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/word/WordTemplateFileDiffer.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/word/WordTemplateFileDiffer.java
index 45fa81c..e1d91aa 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/word/WordTemplateFileDiffer.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/word/WordTemplateFileDiffer.java
@@ -19,26 +19,28 @@
 import java.util.List;
 import java.util.Set;
 import java.util.logging.Level;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.osee.framework.core.exception.OseeArgumentException;
 import org.eclipse.osee.framework.core.exception.OseeCoreException;
 import org.eclipse.osee.framework.core.model.Branch;
 import org.eclipse.osee.framework.core.model.TransactionDelta;
 import org.eclipse.osee.framework.core.model.TransactionRecord;
 import org.eclipse.osee.framework.core.model.change.RelationChangeItem;
-import org.eclipse.osee.framework.core.operation.Operations;
 import org.eclipse.osee.framework.logging.OseeLog;
 import org.eclipse.osee.framework.skynet.core.artifact.Artifact;
+import org.eclipse.osee.framework.skynet.core.artifact.search.ArtifactQuery;
 import org.eclipse.osee.framework.skynet.core.change.ArtifactDelta;
 import org.eclipse.osee.framework.skynet.core.change.Change;
 import org.eclipse.osee.framework.skynet.core.revision.ChangeDataLoader;
 import org.eclipse.osee.framework.skynet.core.transaction.TransactionManager;
-import org.eclipse.osee.framework.skynet.core.utility.Artifacts;
 import org.eclipse.osee.framework.ui.skynet.internal.Activator;
 import org.eclipse.osee.framework.ui.skynet.render.DefaultArtifactRenderer;
 import org.eclipse.osee.framework.ui.skynet.render.RendererManager;
 
 /**
  * @author Jeff C. Phillips
+ * @author Mark Joy
  */
 public final class WordTemplateFileDiffer {
    private final DefaultArtifactRenderer renderer;
@@ -54,6 +56,8 @@
       renderer.setOption("Publish With Attributes", true);
       renderer.setOption("Use Artifact Names", true);
       renderer.setOption("inPublishMode", true);
+      // need to keep original value as well as reseting to false
+      renderer.setOption("Orig Publish As Diff", renderer.getBooleanOption("Publish As Diff"));
       renderer.setOption("Publish As Diff", false);
       renderer.setOption("RecurseChildren", recurseChildren);
 
@@ -73,20 +77,32 @@
 
       TransactionRecord endTransaction = TransactionManager.getHeadTransaction(endBranch);
       TransactionDelta txDelta;
-      if (startTransaction.getId() < endTransaction.getId()) {
-         txDelta = new TransactionDelta(startTransaction, endTransaction);
+
+      boolean maintainOrder = renderer.getBooleanOption("Maintain Order");
+      if ((startTransaction.getId() < endTransaction.getId()) || maintainOrder) {
+         if (compareBranch == endBranch) {
+            txDelta = new TransactionDelta(startTransaction, endTransaction);
+         } else {
+            txDelta = new TransactionDelta(endTransaction, startTransaction);
+         }
       } else {
-         txDelta = new TransactionDelta(endTransaction, startTransaction);
+         txDelta = new TransactionDelta(startTransaction, endTransaction);
       }
 
-      Collection<Artifact> toProcess = recurseChildren ? getAllArtifacts(endArtifacts) : endArtifacts;
+      boolean recurseOnLoad = renderer.getBooleanOption("Recurse On Load");
+      Collection<Artifact> toProcess =
+         (recurseChildren || recurseOnLoad) ? getAllArtifacts(endArtifacts) : endArtifacts;
       List<Change> changes = new LinkedList<Change>();
       ChangeDataLoader changeLoader = new ChangeDataLoader(changes, txDelta);
-
-      Operations.executeWorkAndCheckStatus(changeLoader);
+      IProgressMonitor monitor = (IProgressMonitor) renderer.getOption("Progress Monitor");
+      if (monitor == null) {
+         monitor = new NullProgressMonitor();
+      }
+      changeLoader.determineChanges(monitor);
 
       try {
-         diff(changes, toProcess, diffPrefix);
+         monitor.setTaskName("Compare differences");
+         diff(changes, toProcess, diffPrefix, txDelta);
       } catch (Exception ex) {
          OseeLog.log(Activator.class, Level.SEVERE, ex);
       }
@@ -101,19 +117,30 @@
       return toReturn;
    }
 
-   private void diff(List<Change> changes, Collection<Artifact> endArtifacts, String diffPrefix) {
+   private void diff(List<Change> changes, Collection<Artifact> endArtifacts, String diffPrefix, TransactionDelta txDelta) throws OseeCoreException {
 
       Collection<ArtifactDelta> artifactDeltas = new ArrayList<ArtifactDelta>();
-      Collection<Integer> endIds = Artifacts.toIds(endArtifacts);
       Set<Integer> addedIds = new HashSet<Integer>();
-
+      Set<Integer> changeIds = new HashSet<Integer>(changes.size());
       for (Change change : changes) {
-         Integer artId = change.getArtId();
-         if (!(change.getChangeItem() instanceof RelationChangeItem) && !addedIds.contains(artId)) {
-            if (endIds.contains(artId)) {
-               artifactDeltas.add(change.getDelta());
+         changeIds.add(change.getArtId());
+      }
+
+      // loop through all artifacts that are on the IS branch
+      for (Artifact art : endArtifacts) {
+         Integer artId = art.getArtId();
+         if (changeIds.contains(artId)) {
+            // If there is a change on the IS branch
+            Change newChange = findChange(artId, changes);
+            if (newChange != null && !(newChange.getChangeItem() instanceof RelationChangeItem) && !addedIds.contains(artId)) {
+               artifactDeltas.add(newChange.getDelta());
                addedIds.add(artId);
             }
+         } else {
+            // No change to this artifact, so show the WAS version as is.
+            Artifact wasArt = ArtifactQuery.getArtifactFromId(artId, txDelta.getEndTx().getBranch());
+            artifactDeltas.add(new ArtifactDelta(txDelta, wasArt, wasArt, wasArt));
+            addedIds.add(artId);
          }
       }
 
@@ -121,4 +148,15 @@
          RendererManager.diff(artifactDeltas, diffPrefix, renderer.getValues());
       }
    }
+
+   private Change findChange(Integer artId, List<Change> changes) {
+      Change toReturn = null;
+      for (Change change : changes) {
+         if (change.getArtId() == artId) {
+            toReturn = change;
+            break;
+         }
+      }
+      return toReturn;
+   }
 }
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/word/WordTemplateProcessor.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/word/WordTemplateProcessor.java
index 0f653d5..50829ad 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/word/WordTemplateProcessor.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/render/word/WordTemplateProcessor.java
@@ -178,9 +178,8 @@
 
          if (elementType.equals(ARTIFACT)) {
             extractOutliningOptions(elementValue);
-            if (artifacts == null) { // This handles the case where
-               // artifacts selected in the
-               // template
+            if (artifacts == null) {
+               // This handles the case where artifacts selected in the template
                Matcher setNameMatcher = setNamePattern.matcher(elementValue);
                setNameMatcher.find();
                artifacts = renderer.getArtifactsOption(WordUtil.textOnly(setNameMatcher.group(2)));
@@ -349,6 +348,10 @@
 
                if (outlining && !templateOnly) {
                   String headingText = artifact.getSoleAttributeValue(headingAttributeType, "");
+                  Boolean mergeTag = (Boolean) renderer.getOption("ADD MERGE TAG");
+                  if (mergeTag != null && mergeTag) {
+                     headingText = headingText.concat(" [MERGED]");
+                  }
 
                   if (!publishInline && !templateOnly) {
                      paragraphNumber = wordMl.startOutlineSubSection("Times New Roman", headingText, outlineType);
@@ -377,7 +380,8 @@
 
                processAttributes(artifact, wordMl, presentationType, multipleArtifacts, publishInline);
             }
-            if (recurseChildren) {
+            // Check for option that may have been set from Publish with Diff BLAM to recurse
+            if (recurseChildren || (renderer.getBooleanOption("Recurse On Load") && !renderer.getBooleanOption("Orig Publish As Diff"))) {
                for (Artifact childArtifact : artifact.getChildren()) {
                   processObjectArtifact(childArtifact, wordMl, outlineType, presentationType, multipleArtifacts);
                }
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/util/IVbaDiffGenerator.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/util/IVbaDiffGenerator.java
index 53f93c4..68c9f4e 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/util/IVbaDiffGenerator.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/util/IVbaDiffGenerator.java
@@ -10,6 +10,7 @@
  *******************************************************************************/
 package org.eclipse.osee.framework.ui.skynet.util;
 
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.osee.framework.core.exception.OseeCoreException;
 import org.eclipse.osee.framework.ui.skynet.render.compare.CompareData;
 
@@ -18,5 +19,5 @@
  */
 public interface IVbaDiffGenerator {
 
-   public void generate(CompareData compareData) throws OseeCoreException;
+   public void generate(IProgressMonitor monitor, CompareData compareData) throws OseeCoreException;
 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/util/VbaWordDiffGenerator.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/util/VbaWordDiffGenerator.java
index 359ef86..08bbed6 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/util/VbaWordDiffGenerator.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/util/VbaWordDiffGenerator.java
@@ -20,8 +20,11 @@
 import java.io.Writer;
 import java.util.Map.Entry;
 import java.util.logging.Level;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.osee.framework.core.exception.OseeCoreException;
 import org.eclipse.osee.framework.core.exception.OseeExceptions;
+import org.eclipse.osee.framework.core.operation.Operations;
 import org.eclipse.osee.framework.jdk.core.util.Lib;
 import org.eclipse.osee.framework.logging.OseeLevel;
 import org.eclipse.osee.framework.logging.OseeLog;
@@ -54,9 +57,15 @@
    private final static String comparisonCommandOthers =
       "    mainDoc.Range(mainDoc.Range.End-1, mainDoc.Range.End-1).FormattedText =  compareDoc.Range.FormattedText\n\n    baseDoc.close wdDoNotSaveChanges\n    set baseDoc = Nothing\n\n    compareDoc.close wdDoNotSaveChanges\n    set compareDoc = Nothing\n\n";
 
+   private final static String altComparisonCommandOthers =
+      "    mainDoc.Range(mainDoc.Range.End-1, mainDoc.Range.End-1).FormattedText =  compareDoc.Range.FormattedText\n\n    baseDoc.close wdDoNotSaveChanges\n    set baseDoc = Nothing\n\n    set compareDoc = Nothing\n\n";
+
    private final static String mergeCommand =
       "    baseDoc.Merge ver2, wdCompareTargetSelectedMerge, detectFormatChanges, wdFormattingFromCurrent, False\n    oWord.ActiveDocument.SaveAs %s, wdFormatXML, , , False\n\n";
 
+   private final static String altMergeCommand =
+      "    baseDoc.Merge ver2, wdCompareTargetSelectedMerge, detectFormatChanges, wdFormattingFromCurrent, False\n    set compareDoc = oWord.ActiveDocument\n\n";
+
    private final boolean merge;
    private final boolean show;
    private final boolean detectFormatChanges;
@@ -72,7 +81,7 @@
    }
 
    @Override
-   public void generate(CompareData compareData) throws OseeCoreException {
+   public void generate(IProgressMonitor monitor, CompareData compareData) throws OseeCoreException {
       Writer writer = null;
       try {
          writer = new BufferedWriter(new FileWriter(compareData.getGeneratorScriptPath()));
@@ -88,7 +97,7 @@
          writer.append(Boolean.toString(detectFormatChanges));
          writer.append("\n\n");
 
-         addComparison(writer, compareData, merge);
+         addComparison(monitor, writer, compareData, merge);
          writer.append("    oWord.NormalTemplate.Saved = True\n");
 
          if (show) {
@@ -111,16 +120,23 @@
       }
 
       if (executeVbScript) {
+         monitor.setTaskName("Executing Diff");
          executeScript(new File(compareData.getGeneratorScriptPath()));
       } else {
          OseeLog.logf(Activator.class, Level.INFO, "Test - Skip launch of [%s]", compareData.getGeneratorScriptPath());
       }
    }
 
-   private void addComparison(Appendable appendable, CompareData compareData, boolean merge) throws IOException {
+   private void addComparison(IProgressMonitor monitor, Appendable appendable, CompareData compareData, boolean merge) throws IOException {
       boolean first = true;
+      double workAmount = 0.20 / compareData.entrySet().size();
+      monitor.setTaskName("Creating Diff Script");
       for (Entry<String, String> entry : compareData.entrySet()) {
 
+         if (monitor.isCanceled()) {
+            throw new OperationCanceledException();
+         }
+
          //Unforunately Word seems to need a little extra time to close, otherwise Word 2007 will crash periodically if too many files are being compared.
          String propertyWordDiffSleepMs = System.getProperty(OSEE_WORD_DIFF_SLEEP_MS, "250");// Quarter second is the default sleep value
          appendable.append("WScript.sleep(" + propertyWordDiffSleepMs + ")\n");
@@ -142,17 +158,32 @@
          appendable.append("    compareDoc.Save\n");
          appendable.append("    compareDoc.Close\n\n\n");
 
-         if (merge) {
-            appendable.append(String.format(mergeCommand, "\"" + compareData.getOutputPath() + "\""));
+         boolean mergeFromCompare = compareData.isMerge(entry.getKey());
+         if (merge || mergeFromCompare) {
+            if (mergeFromCompare) {
+               if (first) {
+                  appendable.append(comparisonCommand);
+               } else {
+                  appendable.append(altMergeCommand);
+               }
+            } else {
+               appendable.append(String.format(mergeCommand, "\"" + compareData.getOutputPath() + "\""));
+            }
          } else {
             appendable.append(comparisonCommand);
-            if (first) {
-               appendable.append(comparisonCommandFirst);
-               first = false;
+         }
+         if (first) {
+            appendable.append(comparisonCommandFirst);
+            first = false;
+         } else {
+            if (mergeFromCompare) {
+               appendable.append(altComparisonCommandOthers);
             } else {
                appendable.append(comparisonCommandOthers);
             }
          }
+
+         monitor.worked(Operations.calculateWork(Operations.TASK_WORK_RESOLUTION, workAmount));
       }
    }
 
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XBranchSelectWidget.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XBranchSelectWidget.java
index 99b1adb..81db152 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XBranchSelectWidget.java
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/widgets/XBranchSelectWidget.java
@@ -92,6 +92,23 @@
       return selectComposite.getBranchSelectText();
    }
 
+   public Control getButtonControl() {
+      return selectComposite.getBranchSelectButton();
+   }
+
+   @Override
+   public void setEditable(boolean editable) {
+      super.setEditable(editable);
+      if (selectComposite != null) {
+         if (getControl() != null && !getControl().isDisposed()) {
+            getControl().setEnabled(editable);
+         }
+         if (getButtonControl() != null && !getButtonControl().isDisposed()) {
+            getButtonControl().setEnabled(editable);
+         }
+      }
+   }
+
    @Override
    public IOseeBranch getData() {
       return getSelection();