diff --git a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/adapters/analysis/gui/AnalysisBeanGui.java b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/adapters/analysis/gui/AnalysisBeanGui.java
index 36df0a9f0cd3d56bc29490f2af27df829b8b76b7..019cbcebf4622b398c1f4b04adff7d05f293d113 100644
--- a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/adapters/analysis/gui/AnalysisBeanGui.java
+++ b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/adapters/analysis/gui/AnalysisBeanGui.java
@@ -86,6 +86,7 @@ import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.WeakHashMap;
 
 
 public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, AnalysisManager>
@@ -128,6 +129,7 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi
 
    private boolean editMessageInGui;
 
+   private transient WeakHashMap<Analysis,GazelleTreeNodeImpl<AnalysisPart>> nodes;
 
    public AnalysisBeanGui(AnalysisManager analysisManager, AnalysisPartManager analysisPartManager,
                           McaConfigManager mcaConfigManager,
@@ -181,6 +183,7 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi
          }
          defineMessagePart(part, selectedObject);
       }
+      this.nodes = new WeakHashMap<>();
    }
 
    private void defineMessagePart(AnalysisPart part, Analysis analysis) {
@@ -236,7 +239,14 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi
    }
 
    public GazelleTreeNodeImpl<AnalysisPart> buildTree() {
+      if (selectedObject==null) {
+         return new GazelleTreeNodeImpl<>();
+      }
+      if (nodes.containsKey(selectedObject)) {
+         return nodes.get(selectedObject);
+      }
       final GazelleTreeNodeImpl<AnalysisPart> tree = new GazelleTreeNodeImpl<>();
+      nodes.put(selectedObject,tree);
       tree.setData(selectedObject.getRootAnalysisPart());
       int index = 0;
       for (final AnalysisPart analysisPart : selectedObject.getRootAnalysisPart().getChildPart()) {
@@ -301,19 +311,17 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi
       setDocumentText(displayedMessagePart);
    }
 
+   public boolean isDisplayablePart(AnalysisPart part) {
+      return part!=null && !isFolder(part);
+   }
+
    private void setEnhancedDocumentContent(byte[] content) {
       setDocumentContent(content);
-      if ((analysisPartToDisplay.getDocType().equals(DocType.ZIP.getValue())
-              || (analysisPartToDisplay.getDocType().equals(DocType.DOCUMENT.getValue())
-                  && !analysisPartToDisplay.getChildPart().isEmpty()
-                  && analysisPartToDisplay.getChildPart().get(0).getDocType().equals("ZIP")))
-           || (mcaConfigManager.getZipStructureWithDocType(analysisPartToDisplay.getDocType()) != null
-              || (analysisPartToDisplay.getDocType().equals(DocType.DOCUMENT.getValue())
-                  && !analysisPartToDisplay.getChildPart().isEmpty()
-                  && mcaConfigManager.getZipStructureWithDocType(analysisPartToDisplay.getChildPart().get(0).getDocType()) != null))) {
+      if (isZipPart(analysisPartToDisplay)) {
          getDocument().setSyntax(HandledDocument.Syntax.ZIP);
-      } else if (analysisPartToDisplay.getDocType().endsWith("/")) {
+      } else if (isFolder(analysisPartToDisplay)) {
          GuiMessage.logMessage(StatusMessage.Severity.INFO, "net.ihe.gazelle.mca.ThisIsADirectory");
+         return;
       } else if (isDisplayedPartXml() && !HandledDocument.Syntax.XML.equals(getDocument().getSyntax())) {
          getDocument().setSyntax(HandledDocument.Syntax.XML);
       }
@@ -332,8 +340,19 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi
       }
    }
 
-
-
+   private boolean isZipPart(AnalysisPart node) {
+      return node!=null && StringUtils.isNotEmpty(node.getDocType())
+              && (
+                      (node.getDocType().equals(DocType.ZIP.getValue())
+                        || (node.getDocType().equals(DocType.DOCUMENT.getValue())
+                              && !node.getChildPart().isEmpty()
+                              && node.getChildPart().get(0).getDocType().equals("ZIP")))
+                   || (mcaConfigManager.getZipStructureWithDocType(node.getDocType()) != null
+                        || (node.getDocType().equals(DocType.DOCUMENT.getValue())
+                              && !node.getChildPart().isEmpty()
+                            && mcaConfigManager.getZipStructureWithDocType(node.getChildPart().get(0).getDocType()) != null))
+               );
+   }
 
    @Override
    public String performAnotherValidation() {
@@ -469,7 +488,7 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi
 
       byte[] bytes;
 
-      if (node.getDocType().startsWith(MimeTypeDetector.FOLDER_PREFIX)) {
+      if (!isDownloadable(node)) {
          logFolderDownloadError();
          return;
       } else {
@@ -517,6 +536,14 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi
       }
    }
 
+   public boolean isDownloadable(AnalysisPart node) {
+      return node!=null && StringUtils.isNotEmpty(node.getDocType()) && !isFolder(node);
+   }
+
+   public boolean isFolder(AnalysisPart node) {
+      return node.getDocType().endsWith("/") || node.getDocType().startsWith(MimeTypeDetector.FOLDER_PREFIX);
+   }
+
    public String getIconForNode(final AnalysisPart node) {
       if (node == null || StringUtils.isEmpty(node.getDocType()) || StringUtils.isEmpty(node.getOid())) {
          return "gzl-icon-globe";
@@ -613,18 +640,9 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi
 
    String validate(final String objectPath, final AnalysisPart node) {
       try {
-         if ((node.getDocType().equals("ZIP")
-                 || (node.getDocType().equals("DOCUMENT")
-                    && !node.getChildPart().isEmpty()
-                    && node.getChildPart().get(0).getDocType().equals("ZIP")))
-              || (mcaConfigManager.getZipStructureWithDocType(node.getDocType()) != null
-                  || (node.getDocType().equals("DOCUMENT")
-                     && !node.getChildPart().isEmpty()
-                     && mcaConfigManager.getZipStructureWithDocType(node.getChildPart().get(0).getDocType()) != null
-               ))) {
+         if (!isValidable(node)) {
             GuiMessage.logMessage(StatusMessage.Severity.ERROR, "net.ihe.gazelle.mca.CannotValidateAZipFile");
-            return McaVueFileNaming.DETAILED_RESULT.getMenuLink() + "?" + QueryParam.PROCESSING_OID + "=" + findAnalysisOid(
-                  node);
+            return McaVueFileNaming.DETAILED_RESULT.getMenuLink() + "?" + QueryParam.PROCESSING_OID + "=" + findAnalysisOid(node);
          }
 
          if (node.getDecodedPartFilePath() != null) {
@@ -779,6 +797,20 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi
       }
    }
 
+   public boolean isValidable(AnalysisPart node) {
+      return node!=null && StringUtils.isNotEmpty(node.getDocType()) && !(
+              "ZIP".equals(node.getDocType())
+               || ("DOCUMENT".equals(node.getDocType())
+                    && !node.getChildPart().isEmpty()
+                    && "ZIP".equals(node.getChildPart().get(0).getDocType()))
+               || mcaConfigManager.getZipStructureWithDocType(node.getDocType()) != null
+               || ("DOCUMENT".equals(node.getDocType())
+                     && !node.getChildPart().isEmpty()
+                     && mcaConfigManager.getZipStructureWithDocType(node.getChildPart().get(0).getDocType()) != null)
+              || (node.getDecodedPartFilePath() == null && EncodedType.ZIP_ENCODED.equals(node.getEncodedType()) && node.getDocType().contains(MimeTypeDetector.FOLDER_PREFIX))
+              );
+   }
+
    private String readFileContent(String path) throws UnexpectedAnalysisException {
       try {
          return new ContentConverter().toString(FileUtils.readFileToByteArray(new File(path)),
@@ -858,11 +890,16 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi
       List<EVSClientCrossValidatedObject> crossValidationInputList = new ArrayList<>();
       for (AnalysisPart l_o_input : xValInputsList) {
          try {
-            crossValidationInputList.add(new CrossValidationInput(l_o_input.getxValInputType(),
-                  mcaApi.getOriginalPartContent(
-                        ((HandledObjectFile) analysisPart.getAnalysis().getObject()).getFilePath(), l_o_input),
-                  "xml"));
-         } catch (UnexpectedAnalysisException e) {
+            Analysis analysis = findAnalysis(analysisPart);
+            HandledObjectFile file =  ((HandledObjectFile) analysis.getObject());
+            crossValidationInputList.add(
+                    new CrossValidationInput(
+                            l_o_input.getxValInputType(),
+                            mcaApi.getOriginalPartContent(
+                                  file.getFilePath(),
+                                  l_o_input),
+                           "xml"));
+         } catch (Exception e) {
             logUnexpectedException(e);
          }
       }
diff --git a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/McaApi.java b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/McaApi.java
index e6cbfbe9d3a9a2641154727c648ec5e7bca30b49..66c737a7f3c1774c2554920f3fc4d35b0fb53b69 100644
--- a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/McaApi.java
+++ b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/McaApi.java
@@ -177,7 +177,7 @@ public class McaApi implements Serializable {
                 bytes = dicomToTxtConverter.dicom2txt(bytes);
                 return bytes;
             }
-        } else if (node.getDocType().equals(MimeTypeConfigEnum.ZIP.getDocType())) {
+        } else if (isZipPart(node)) {
 
             try {
                 return FileUtils.readFileToByteArray(file);
@@ -198,4 +198,12 @@ public class McaApi implements Serializable {
         }
         return "Error retrieving string content".getBytes(StandardCharsets.UTF_8);
     }
+
+    private boolean isZipPart(AnalysisPart node) {
+        return node.getDocType().equals(MimeTypeConfigEnum.ZIP.getDocType())
+                || messageContentAnalyzer.isZipDocType(node.getDocType())
+                || (node.getDocType().equals(DocType.DOCUMENT.getValue())
+                    && !node.getChildPart().isEmpty()
+                    && messageContentAnalyzer.isZipDocType(node.getChildPart().get(0).getDocType()));
+    }
 }
diff --git a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MessageContentAnalyzer.java b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MessageContentAnalyzer.java
index 17ec8bdb0cd4e3fcdfd06ad3673dcb2efc5d0b87..ddddf42b6d97beb796a16080b903fae29b8d341a 100644
--- a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MessageContentAnalyzer.java
+++ b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MessageContentAnalyzer.java
@@ -8,7 +8,6 @@ import net.ihe.gazelle.mca.contentanalyzer.business.model.EncodedType;
 
 import java.io.Serializable;
 import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
 
 public class MessageContentAnalyzer implements Serializable {
     private static final long serialVersionUID = -333802749228093354L;
@@ -32,6 +31,10 @@ public class MessageContentAnalyzer implements Serializable {
         this(xmlAnalyzer, contentAnalysisTypeDetector, mimeTypeDetector, b64Analyzer, null);
     }
 
+    public boolean isZipDocType(String docType) {
+        return ((MimeTypeDetector)mimeTypeDetector).getZipStructureWithDocType(docType)!=null;
+    }
+
     public MessageContentAnalyzer(Analyzer xmlAnalyzer, Analyzer contentAnalysisTypeDetector,
                                   Analyzer mimeTypeDetector, Analyzer b64Analyzer, byte[] messageName) {
         this.xmlAnalyzer = xmlAnalyzer;
diff --git a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MimeTypeDetector.java b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MimeTypeDetector.java
index 17b1a2a44c0b0b3f433f2f1558176a1a5c1e36bd..e1efcab8fda5cdc1500baf3baf484cdcd52fbd19 100644
--- a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MimeTypeDetector.java
+++ b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MimeTypeDetector.java
@@ -373,4 +373,8 @@ public class MimeTypeDetector implements Analyzer {
         }
         return prefixInPart;
     }
+
+    public ZipStructureInterface getZipStructureWithDocType(String docType) {
+        return mcaConfigDao.getZipStructureWithDocType(docType);
+    }
 }
diff --git a/MessageContentAnalyzer-war/src/main/messages/MessageContentAnalyzer.properties b/MessageContentAnalyzer-war/src/main/messages/MessageContentAnalyzer.properties
index 96064ae9357fb91bac87c9ae4166f0b79a6efd53..e5ed7aa5b07e812da13c33354a1489f24d7c1303 100644
--- a/MessageContentAnalyzer-war/src/main/messages/MessageContentAnalyzer.properties
+++ b/MessageContentAnalyzer-war/src/main/messages/MessageContentAnalyzer.properties
@@ -129,4 +129,9 @@ net.ihe.gazelle.document.invalid-file-type=Invalid file type. Expected file type
 net.ihe.gazelle.document.prettify-content=Prettify content
 net.ihe.gazelle.document.view-lines-numbers=View lines numbers
 net.ihe.gazelle.document.prettified-content=The following content has been modified for better visualization. Validation will be performed on original content
-net.ihe.gazelle.document.emptyContent=Content object must be defined and not empty
\ No newline at end of file
+net.ihe.gazelle.document.emptyContent=Content object must be defined and not empty
+
+net.ihe.gazelle.document.download-fragment=Download
+net.ihe.gazelle.document.view-fragment=View
+net.ihe.gazelle.document.cant-download-fragment=Fragment download failed.
+net.ihe.gazelle.document.cant-show-fragment=Unable to show fragment.
diff --git a/MessageContentAnalyzer-war/src/main/webapp/common/_messageContentAnalyzerResultDiv.xhtml b/MessageContentAnalyzer-war/src/main/webapp/common/_messageContentAnalyzerResultDiv.xhtml
index bfcb32104ee587db92163f217757cae61a705eae..74a2c6e5098d522a8c3878fc23a216403d4f0074 100644
--- a/MessageContentAnalyzer-war/src/main/webapp/common/_messageContentAnalyzerResultDiv.xhtml
+++ b/MessageContentAnalyzer-war/src/main/webapp/common/_messageContentAnalyzerResultDiv.xhtml
@@ -53,10 +53,14 @@
                                         title="#{messages['net.ihe.gazelle.evs.ViewPart']}"
                                         ignoreDupResponses="true"
                                         action="#{analysisBeanGui.setMessagePart(analysisBeanGui.selectedObject.object.filePath, node.data)}"
-                                        render="panelPartArea">
+                                        render="panelPartArea"
+                                        rendered="#{analysisBeanGui.isDisplayablePart(node.data)}">
                                     <h:outputText value="#{node.data.docType}"/>
                                     <s:span styleClass="gzl-icon-eye"/>
                                 </a4j:commandLink>
+                                <s:span rendered="#{not analysisBeanGui.isDisplayablePart(node.data)}">
+                                    <h:outputText value="#{node.data.docType}"/>
+                                </s:span>
 
                                 <h:outputLink
                                         value="#{analysisBeanGui.getValidationPermanentLinkFromDb(node.data.oid)}"
@@ -65,15 +69,6 @@
                                     <s:span title="#{messages['gazelle.evs.ClickToViewValidationOutcome']}" styleClass="#{analysisBeanGui.getIconForNode(node.data)}"/>
                                 </h:outputLink>
 
-                                <!--XVal result-->
-                                <h:outputLink
-                                        value="#{analysisBeanGui.getCrossValidationPermanentLink(node.data.oid)}"
-                                        target="_blank"
-                                        rendered="#{node.data.xValMatch.xValidatorOid != null and not empty node.data.xValMatch.xValidatorOid}">
-                                    <s:span title="#{messages['net.ihe.gazelle.mca.ClickToViewCrossValidationOutcome']}" styleClass="#{analysisBeanGui.getIconForXNode(node.data.oid)}"/>
-                                </h:outputLink>
-
-
                                 <a4j:commandLink
                                         action="#{analysisBeanGui.validate(node.data)}"
                                         target="_blank"
@@ -86,34 +81,43 @@
                                         action="#{analysisBeanGui.validate(node.data)}"
                                         target="_blank"
                                         execute="resultFormTokenId"
-                                        rendered="#{empty node.data.validationType}">
+                                        rendered="#{empty node.data.validationType and analysisBeanGui.isValidable(node.data)}">
                                     <span class="gzl-icon-stack" title="#{messages['net.ihe.gazelle.xval.Validate']}">
                                         <em class="gzl-icon-play gzl-icon-stack-1x gzl-icon-stack-up "/>
                                         <em class="gzl-icon-question-circle gzl-icon-stack-1x gzl-icon-stack-small-bottom-right"/>
                                     </span>
                                 </a4j:commandLink>
 
-                                <h:commandLink actionListener="#{analysisBeanGui.sendToXValidation(node.data)}"
-                                               rendered="#{node.data.xValidatorOid != null and not empty node.data.xValidatorOid and
-                                                analysisBeanGui.crossValidatorAvailable(node.data.xValidatorOid)}">
-                                    <span class="gzl-icon-stack" title="#{messages['net.ihe.gazelle.mca.SendToCrossValidation']}">
-                                        <em class="gzl-icon-play gzl-icon-stack-1x gzl-icon-stack-up "/>
-                                        <em class="gzl-icon-times-blue gzl-icon-stack-1x gzl-icon-stack-small-bottom-right"/>
-                                    </span>
-                                </h:commandLink>
-
-                                <s:span styleClass="gzl-icon-stack" title="#{messages['net.ihe.gazelle.mca.CrossValidatorNotAvailable']}"
-                                    rendered="#{node.data.xValidatorOid != null and not empty node.data.xValidatorOid and
-                                                not analysisBeanGui.crossValidatorAvailable(node.data.xValidatorOid)}">
-                                        <em style="color:C6C6C6" class="gzl-icon-play gzl-icon-stack-1x gzl-icon-stack-up "/>
-                                        <em style="color:C6C6C6" class="gzl-icon-times-blue gzl-icon-stack-1x gzl-icon-stack-small-bottom-right"/>
+                                <!-- XVal -->
+                                <s:span rendered="#{node.data.xValMatch.xValidatorOid != null and not empty node.data.xValMatch.xValidatorOid}">
+                                    <s:span rendered="#{analysisBeanGui.crossValidatorAvailable(node.data.xValidatorOid)}">
+                                            <h:commandLink actionListener="#{analysisBeanGui.sendToXValidation(node.data)}">
+                                                <span class="gzl-icon-stack" title="#{messages['net.ihe.gazelle.mca.SendToCrossValidation']}">
+                                                    <em class="gzl-icon-play gzl-icon-stack-1x gzl-icon-stack-up "/>
+                                                    <em class="gzl-icon-times-blue gzl-icon-stack-1x gzl-icon-stack-small-bottom-right"/>
+                                                </span>
+                                            </h:commandLink>
+                                    </s:span>
+                                    <s:span rendered="#{not analysisBeanGui.crossValidatorAvailable(node.data.xValidatorOid)}">
+                                            <h:outputLink
+                                                    value="#{analysisBeanGui.getCrossValidationPermanentLink(node.data.oid)}"
+                                                    target="_blank">
+                                                <s:span title="#{messages['net.ihe.gazelle.mca.ClickToViewCrossValidationOutcome']}" styleClass="#{analysisBeanGui.getIconForXNode(node.data.oid)}"/>
+                                            </h:outputLink>
+                                            <s:span styleClass="gzl-icon-stack" title="#{messages['net.ihe.gazelle.mca.CrossValidatorNotAvailable']}">
+                                                <em style="color:C6C6C6" class="gzl-icon-play gzl-icon-stack-1x gzl-icon-stack-up "/>
+                                                <em style="color:C6C6C6" class="gzl-icon-times-blue gzl-icon-stack-1x gzl-icon-stack-small-bottom-right"/>
+                                            </s:span>
+                                    </s:span>
                                 </s:span>
 
+
+
                                 <h:commandLink
                                         title="#{messages['net.ihe.gazelle.evs.DownloadPart']}"
                                         ignoreDupResponses="true"
                                         action="#{analysisBeanGui.downloadFile(node.data, false)}"
-                                        rendered="#{analysisBeanGui.getNameSpaces().isEmpty()}">
+                                        rendered="#{analysisBeanGui.getNameSpaces().isEmpty() and analysisBeanGui.isDownloadable(node.data)}">
                                     <s:span title="#{messages['net.ihe.gazelle.xval.Download']}" styleClass="gzl-icon-download"/>
                                 </h:commandLink>