diff --git a/packages/component-email-templating/src/templates/partials/invButtons.hbs b/packages/component-email-templating/src/templates/partials/invButtons.hbs
index 7611dc03e966d4e9146cda5bd9b6a535b17ace3d..8deceffee7a2080bd626f746fc7959d815da5a67 100644
--- a/packages/component-email-templating/src/templates/partials/invButtons.hbs
+++ b/packages/component-email-templating/src/templates/partials/invButtons.hbs
@@ -12,7 +12,7 @@
       <td width="300.000px" valign="top" style="padding: 0px 0px 0px 0px;border-collapse: collapse;" >
     <![endif]-->
 
-      <table width="300.000" style="width:300.000px;border-spacing:0;border-collapse:collapse;margin:0px 0px 0px 0px;"
+      <table width="300.000" style="width:'50%';border-spacing:0;border-collapse:collapse;margin:0px 0px 0px 0px;"
         cellpadding="0" cellspacing="0" align="left" border="0" bgcolor="" class="column column-0 of-2
                   empty">
         <tr>
@@ -21,7 +21,7 @@
               role="module" style="table-layout:fixed" width="100%">
               <tbody>
                 <tr>
-                  <td align="center" class="outer-td" style="padding:0px 0px 0px 50px">
+                  <td align="center" class="outer-td padding-decline">
                     <table border="0" cellPadding="0" cellSpacing="0" class="button-css__deep-table___2OZyb wrapper-mobile"
                       style="text-align:center">
                       <tbody>
@@ -47,7 +47,7 @@
       <td width="300.000px" valign="top" style="padding: 0px 0px 0px 0px;border-collapse: collapse;" >
     <![endif]-->
 
-      <table width="300.000" style="width:300.000px;border-spacing:0;border-collapse:collapse;margin:0px 0px 0px 0px;"
+      <table width="300.000" style="width:'50%';border-spacing:0;border-collapse:collapse;margin:0px 0px 0px 0px;"
         cellpadding="0" cellspacing="0" align="left" border="0" bgcolor="" class="column column-1 of-2
                   empty">
         <tr>
@@ -56,7 +56,7 @@
               role="module" style="table-layout:fixed" width="100%">
               <tbody>
                 <tr>
-                  <td align="center" class="outer-td" style="padding:0px 50px 0px 0px">
+                  <td align="center" class="outer-td padding-agree">
                     <table border="0" cellPadding="0" cellSpacing="0" class="button-css__deep-table___2OZyb wrapper-mobile"
                       style="text-align:center">
                       <tbody>
diff --git a/packages/component-email-templating/src/templates/partials/invHeader.hbs b/packages/component-email-templating/src/templates/partials/invHeader.hbs
index d01a40ad4f0645427c966da91a011dbf8ea226a1..473d7b913b24bea5163c4e73aada31056acf8fe3 100644
--- a/packages/component-email-templating/src/templates/partials/invHeader.hbs
+++ b/packages/component-email-templating/src/templates/partials/invHeader.hbs
@@ -76,6 +76,14 @@
       text-decoration: none;
     }
 
+    .padding-decline {
+      padding:0px 0px 0px 50px;
+    }
+
+    .padding-agree {
+      padding:0px 50px 0px 0px;
+    }
+
     @media screen and (max-width:480px) {
 
       .preheader .rightColumnContent,
@@ -126,6 +134,14 @@
         margin-left: 0 !important;
         margin-right: 0 !important;
       }
+
+      .padding-decline {
+        padding: 0px;
+      }
+
+      .padding-agree {
+        padding: 10px 0px 0px 0px;
+      }
     }
   </style>
   <!--user entered Head Start-->
diff --git a/packages/component-faraday-selectors/src/index.js b/packages/component-faraday-selectors/src/index.js
index 728b2e28a08eb1572980a1879a27e4a6e5eb98f5..1493dcaf07f232dc17d2ec03e4ea9e9090719b44 100644
--- a/packages/component-faraday-selectors/src/index.js
+++ b/packages/component-faraday-selectors/src/index.js
@@ -1,6 +1,5 @@
 import { selectCurrentUser } from 'xpub-selectors'
-// eslint-disable-next-line no-unused-vars
-import { get, has, last, chain, some, isEmpty, flatten } from 'lodash'
+import { get, has, last, chain, some, isEmpty, slice, find } from 'lodash'
 
 export const isHEToManuscript = (state, collectionId = '') => {
   const { id = '', isAccepted = false } = chain(state)
@@ -49,6 +48,29 @@ export const canInviteReviewers = (state, collection = {}) => {
   return isAccepted && (userId === heId || isAdminEiC)
 }
 
+const canViewContextualBoxOnOldVersionStatuses = [
+  'submitted',
+  'heInvited',
+  'heAssigned',
+]
+const canViewContextualBoxOnOldVersion = (collection, fragmentId) => {
+  const fragments = get(collection, 'fragments', [])
+  const oldVersions = slice(fragments, 0, fragments.length - 1)
+  const isOldVersion = !!find(oldVersions, fragment => fragment === fragmentId)
+  return (
+    isOldVersion &&
+    canViewContextualBoxOnOldVersionStatuses.includes(
+      get(collection, 'status', 'draft'),
+    )
+  )
+}
+
+const canHEViewContextualBoxOnOldVersion = (collection, fragmentId) => {
+  const fragments = get(collection, 'fragments', [])
+  const oldVersions = slice(fragments, 0, fragments.length - 1)
+  const isOldVersion = !!find(oldVersions, fragment => fragment === fragmentId)
+  return isOldVersion && get(collection, 'status', 'draft') === 'heInvited'
+}
 const cannotViewReviewersDetails = [
   'draft',
   'technicalChecks',
@@ -67,12 +89,14 @@ export const canViewReviewersDetails = (state, collection = {}) => {
   return canViewReports(state, get(collection, 'id', ''))
 }
 
-const authorCanViewReportsDetailsStatuses = [
+const authorAndReviewersCanViewReportsDetailsStatuses = [
   'revisionRequested',
+  'underReview',
   'pendingApproval',
   'rejected',
   'accepted',
   'reviewCompleted',
+  'reviewersInvited',
   'inQa',
 ]
 
@@ -83,9 +107,27 @@ export const authorCanViewReportsDetails = (
 ) => {
   const isAuthor = currentUserIsAuthor(state, fragmentId)
   return (
-    authorCanViewReportsDetailsStatuses.includes(
+    isAuthor &&
+    (authorAndReviewersCanViewReportsDetailsStatuses.includes(
       get(collection, 'status', 'draft'),
-    ) && isAuthor
+    ) ||
+      canViewContextualBoxOnOldVersion(collection, fragmentId))
+  )
+}
+
+export const reviewersCanViewReviewerReports = (
+  state,
+  collection = {},
+  fragmentId,
+) => {
+  const isReviewer = currentUserIsReviewer(state, fragmentId)
+  const reviewerReports = getFragmentReviewerRecommendations(state, fragmentId)
+  return (
+    isReviewer &&
+    authorAndReviewersCanViewReportsDetailsStatuses.includes(
+      get(collection, 'status', 'draft'),
+    ) &&
+    reviewerReports.length > 0
   )
 }
 
@@ -125,6 +167,7 @@ const canReviewerViewEditorialCommentsStatuses = [
   'reviewCompleted',
   'pendingApproval',
   'revisionRequested',
+  'reviewersInvited',
 ]
 export const canReviewerViewEditorialComments = (
   state,
@@ -176,8 +219,13 @@ export const canViewEditorialComments = (
     state,
     fragmentId,
   )
+  const isHE = currentUserIs(state, 'isHE')
+  const canViewEditorialCommentsOnOldVersion = isHE
+    ? !canHEViewContextualBoxOnOldVersion(collection, fragmentId)
+    : canViewContextualBoxOnOldVersion(collection, fragmentId)
   return (
-    (canHeViewEditorialComments(state, collection) ||
+    (canViewEditorialCommentsOnOldVersion ||
+      canHeViewEditorialComments(state, collection) ||
       canEICViewEditorialComments(state, collection) ||
       canReviewerViewEditorialComments(state, collection, fragment) ||
       canAuthorViewEditorialComments(state, collection, fragmentId)) &&
@@ -185,17 +233,22 @@ export const canViewEditorialComments = (
   )
 }
 
-const cannotViewResponseFromAuthorStatuses = ['reviewersInvited']
 export const canViewResponseFromAuthor = (state, collection, fragmentId) => {
   const authorResponseToRevisonRequest = getFragmentAuthorResponse(
     state,
     fragmentId,
   )
+  const canHEViewResponseFromAuthor =
+    currentUserIs(state, 'isHE') &&
+    get(collection, 'status', 'draft') === 'heInvited'
+
+  const canReviewerViewResponsefromAuthor =
+    currentUserIsReviewerInPending(state, fragmentId) &&
+    get(collection, 'status', 'draft') === 'reviewersInvited'
   return (
     !isEmpty(authorResponseToRevisonRequest) &&
-    !cannotViewResponseFromAuthorStatuses.includes(
-      get(collection, 'status', 'draft'),
-    )
+    !canHEViewResponseFromAuthor &&
+    !canReviewerViewResponsefromAuthor
   )
 }
 
@@ -326,6 +379,13 @@ export const pendingReviewerInvitation = (state, fragmentId) =>
     )
     .value()
 
+export const currentUserIsReviewerInPending = (state, fragmentId) => {
+  const currentUser = selectCurrentUser(state)
+  const invitations = get(state, `fragments.${fragmentId}.invitations`, [])
+  return !!invitations.find(
+    i => i.userId === currentUser.id && i.role === 'reviewer' && !i.isAccepted,
+  )
+}
 export const currentUserIsReviewer = (state, fragmentId) => {
   const currentUser = selectCurrentUser(state)
   const invitations = get(state, `fragments.${fragmentId}.invitations`, [])
@@ -496,11 +556,12 @@ export const getVersionOptions = (state, collection = {}) => {
 
 export const canReview = (state, collection = {}, fragment = {}) => {
   const fragmentId = get(fragment, 'id', false)
-
   if (!fragmentId) return false
-
+  const ownRecommendation = getOwnRecommendations(state, fragmentId)
   const isReviewer = currentUserIsReviewer(state, fragmentId)
   if (!isReviewer) return false
-
-  return get(collection, 'status', 'draft') === 'underReview'
+  return (
+    get(collection, 'status', 'draft') === 'underReview' &&
+    ownRecommendation.length === 0
+  )
 }
diff --git a/packages/component-faraday-ui/src/ManuscriptCard.js b/packages/component-faraday-ui/src/ManuscriptCard.js
index fb471ea96a51267573dcf00e32d8fe422379b18d..17e9e176354403406b6066cf5b09f589a9a93cfa 100644
--- a/packages/component-faraday-ui/src/ManuscriptCard.js
+++ b/packages/component-faraday-ui/src/ManuscriptCard.js
@@ -76,7 +76,7 @@ const ManuscriptCard = ({
         <Row alignItems="center" justify="flex-start" mb={1}>
           <H4>Handling editor</H4>
           <Text ml={1} mr={3} whiteSpace="nowrap">
-            {get(handlingEditor, 'name', 'Undefined')}
+            {get(handlingEditor, 'name', 'Unassigned')}
           </Text>
           {canViewReports && (
             <Fragment>
diff --git a/packages/component-faraday-ui/src/PersonInvitation.js b/packages/component-faraday-ui/src/PersonInvitation.js
index 5b1da63fab1b7fb1b129b175fce6cd0518f4b146..492d7cbdab15ab168f2a84f8c470105d1b24bb15 100644
--- a/packages/component-faraday-ui/src/PersonInvitation.js
+++ b/packages/component-faraday-ui/src/PersonInvitation.js
@@ -9,6 +9,7 @@ const PersonInvitation = ({
   withName,
   hasAnswer,
   isFetching,
+  isLatestVersion,
   revokeInvitation,
   resendInvitation,
   person: { name, email },
@@ -57,6 +58,29 @@ const PersonInvitation = ({
           </OpenModal>
         </Fragment>
       )}
+    {hasAnswer &&
+      isLatestVersion && (
+        <Fragment>
+          <OpenModal
+            confirmText="Revoke"
+            isFetching={isFetching}
+            modalKey={`remove-${id}`}
+            onConfirm={revokeInvitation}
+            subtitle="Deleting the handling editor at this moment will also remove all his work."
+            title="Revoke invitation?"
+          >
+            {showModal => (
+              <IconButton
+                icon="x-circle"
+                iconSize={2}
+                ml={2}
+                onClick={showModal}
+                secondary
+              />
+            )}
+          </OpenModal>
+        </Fragment>
+      )}
   </Root>
 )
 
diff --git a/packages/component-faraday-ui/src/ReviewerReport.js b/packages/component-faraday-ui/src/ReviewerReport.js
index 12391694d8b8032f53d43932629ba1f4d20a12aa..fc2c942c5bb4fdee93bfcbd64cc2bb05d768d3f2 100644
--- a/packages/component-faraday-ui/src/ReviewerReport.js
+++ b/packages/component-faraday-ui/src/ReviewerReport.js
@@ -11,10 +11,11 @@ const ReviewerReport = ({
   onPreview,
   onDownload,
   reportFile,
+  currentUser,
   publicReport,
   privateReport,
   reviewerName,
-  reviewerIndex,
+  reviewerNumber,
   recommendation,
   showOwner = false,
   report: { submittedOn },
@@ -27,14 +28,12 @@ const ReviewerReport = ({
       </Item>
 
       <Item justify="flex-end">
-        {showOwner && (
-          <Fragment>
-            <Text>{reviewerName}</Text>
-            <Text customId ml={1} mr={1}>
-              {`Reviewer ${reviewerIndex}`}
-            </Text>
-          </Fragment>
-        )}
+        <Fragment>
+          {showOwner && <Text>{reviewerName}</Text>}
+          <Text customId ml={1} mr={1}>
+            {`Reviewer ${reviewerNumber}`}
+          </Text>
+        </Fragment>
         <DateParser timestamp={submittedOn}>
           {date => <Text>{date}</Text>}
         </DateParser>
@@ -76,20 +75,22 @@ const ReviewerReport = ({
   </Root>
 )
 
-export default withProps(({ report, journal: { recommendations = [] } }) => ({
-  recommendation: get(
-    recommendations.find(r => r.value === report.recommendation),
-    'label',
-  ),
-  reportFile: get(report, 'comments.0.files.0'),
-  publicReport: get(report, 'comments.0.content'),
-  privateReport: get(report, 'comments.1.content'),
-  reviewerName: `${get(report, 'reviewer.firstName', '')} ${get(
-    report,
-    'reviewer.lastName',
-    '',
-  )}`,
-}))(ReviewerReport)
+export default withProps(
+  ({ report, currentUser, journal: { recommendations = [] } }) => ({
+    recommendation: get(
+      recommendations.find(r => r.value === report.recommendation),
+      'label',
+    ),
+    reportFile: get(report, 'comments.0.files.0'),
+    publicReport: get(report, 'comments.0.content'),
+    privateReport: get(report, 'comments.1.content'),
+    reviewerName: `${get(currentUser, 'firstName', '')} ${get(
+      currentUser,
+      'lastName',
+      '',
+    )}`,
+  }),
+)(ReviewerReport)
 
 // #region styles
 const Root = styled.div`
diff --git a/packages/component-faraday-ui/src/ReviewerReportAuthor.js b/packages/component-faraday-ui/src/ReviewerReportAuthor.js
index 4df5745b8ce86a109bad547466f3fe5ff57f94de..ded36d3ae2e8128002c2bbde7a0292d172d44d66 100644
--- a/packages/component-faraday-ui/src/ReviewerReportAuthor.js
+++ b/packages/component-faraday-ui/src/ReviewerReportAuthor.js
@@ -21,7 +21,7 @@ const ReviewerReportAuthor = ({
   downloadFile,
   publicReport,
   reviewerName,
-  reviewerIndex,
+  reviewerNumber,
   recommendation,
   showOwner = false,
   report: { submittedOn },
@@ -38,7 +38,7 @@ const ReviewerReportAuthor = ({
           </Row>
         )}
         <Text customId ml={1} mr={1} whiteSpace="nowrap">
-          {`Reviewer ${reviewerIndex}`}
+          {`Reviewer ${reviewerNumber}`}
         </Text>
         <DateParser timestamp={submittedOn}>
           {date => <Text>{date}</Text>}
@@ -78,7 +78,7 @@ export default compose(
       'reviewer.lastName',
       '',
     )}`,
-    reviewerIndex: get(report, 'reviewerIndex', ''),
+    reviewerNumber: get(report, 'reviewerNumber', ''),
   })),
 )(ReviewerReportAuthor)
 
diff --git a/packages/component-faraday-ui/src/ReviewerReportAuthor.md b/packages/component-faraday-ui/src/ReviewerReportAuthor.md
index 48fdf8f4faefd2db6af22906b08d22899c94edaa..0ee98012afcf5a17ddccc438eecce6524d3f195b 100644
--- a/packages/component-faraday-ui/src/ReviewerReportAuthor.md
+++ b/packages/component-faraday-ui/src/ReviewerReportAuthor.md
@@ -29,7 +29,7 @@ const report = {
   submittedOn: 1538053600624,
   recommendation: 'publish',
   recommendationType: 'review',
-  reviewerIndex: 1
+  reviewerNumber: 1
 }
 
 const journal = {
diff --git a/packages/component-faraday-ui/src/ReviewersTable.js b/packages/component-faraday-ui/src/ReviewersTable.js
index 9f9e2aaa75309afd25084e94a65cbcf65e2c646b..e2197d20c406eeff827b6b4051f48062d7e7493e 100644
--- a/packages/component-faraday-ui/src/ReviewersTable.js
+++ b/packages/component-faraday-ui/src/ReviewersTable.js
@@ -41,9 +41,9 @@ const ReviewersTable = ({
                 invitation,
                 'person.lastName',
               )}`}</Text>
-              {invitation.isAccepted && (
+              {invitation.reviewerNumber && (
                 <Text customId ml={1}>
-                  {renderAcceptedLabel(index)}
+                  Reviewer {invitation.reviewerNumber}
                 </Text>
               )}
             </td>
@@ -102,12 +102,7 @@ export default compose(
   withProps(({ invitations = [] }) => ({
     invitations: orderBy(invitations, orderInvitations),
   })),
-  withProps(({ invitations = [] }) => ({
-    firstAccepted: invitations.findIndex(i => i.hasAnswer && i.isAccepted),
-  })),
   withHandlers({
-    renderAcceptedLabel: ({ firstAccepted, invitations }) => index =>
-      `Reviewer ${index - firstAccepted + 1}`,
     getInvitationStatus: () => ({ hasAnswer, isAccepted }) => {
       if (!hasAnswer) return 'PENDING'
       if (isAccepted) return 'ACCEPTED'
diff --git a/packages/component-faraday-ui/src/contextualBoxes/AuthorReviews.js b/packages/component-faraday-ui/src/contextualBoxes/AuthorReviews.js
index 5518b3ebfa9c3803816c871f4f8b32b717c468d3..696e8a4e405ca71b5e6844cfedf81994863060a2 100644
--- a/packages/component-faraday-ui/src/contextualBoxes/AuthorReviews.js
+++ b/packages/component-faraday-ui/src/contextualBoxes/AuthorReviews.js
@@ -1,7 +1,14 @@
 import React from 'react'
 import { withProps, compose } from 'recompose'
+import { get } from 'lodash'
 
-import { ContextualBox, ReviewerReportAuthor, Row, Text } from '../'
+import {
+  ContextualBox,
+  ReviewerReportAuthor,
+  Row,
+  Text,
+  indexReviewers,
+} from '../'
 
 const SubmittedReportsNumberForAuthorReviews = ({ reports }) => (
   <Row fitContent justify="flex-end">
@@ -16,12 +23,13 @@ const SubmittedReportsNumberForAuthorReviews = ({ reports }) => (
 )
 
 const AuthorReviews = ({
-  invitations,
+  token,
   journal,
   reports,
   fragment,
-  token,
+  invitations,
   getSignedUrl,
+  reviewerReports,
 }) =>
   reports.length > 0 && (
     <ContextualBox
@@ -43,4 +51,24 @@ const AuthorReviews = ({
     </ContextualBox>
   )
 
-export default compose(withProps())(AuthorReviews)
+export default compose(
+  withProps(
+    ({
+      invitations = [],
+      publonReviewers = [],
+      reviewerReports = [],
+      currentUser,
+    }) => ({
+      token: get(currentUser, 'token', ''),
+      publonReviewers,
+      invitations: invitations.map(i => ({
+        ...i,
+        review: reviewerReports.find(r => r.userId === i.userId),
+      })),
+      reports: indexReviewers(
+        reviewerReports.filter(r => r.submittedOn),
+        invitations,
+      ),
+    }),
+  ),
+)(AuthorReviews)
diff --git a/packages/component-faraday-ui/src/contextualBoxes/AuthorReviews.md b/packages/component-faraday-ui/src/contextualBoxes/AuthorReviews.md
index aa15139b436a8238511b82742f9202d74516f9ce..6bb32f81d1495f66987b964ce3451a619b57d2ea 100644
--- a/packages/component-faraday-ui/src/contextualBoxes/AuthorReviews.md
+++ b/packages/component-faraday-ui/src/contextualBoxes/AuthorReviews.md
@@ -28,7 +28,7 @@ const reports = [
     submittedOn: 1539339580826,
     recommendation: 'minor',
     recommendationType: 'review',
-    reviewerIndex: 1,
+    reviewerNumber: 1,
   },
   {
     id: '21258b47-aba5-4597-926e-765458c4fda2',
@@ -45,7 +45,7 @@ const reports = [
     submittedOn: 1539689169611,
     recommendation: 'publish',
     recommendationType: 'review',
-    reviewerIndex: 2,
+    reviewerNumber: 2,
   },
 ]
 
diff --git a/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js b/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js
index d8a41b821abe0639bbb6f9cfbe6ffe17b9f75189..987aa4a775f7eed363cfcfe0793c5e4baeb1468c 100644
--- a/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js
+++ b/packages/component-faraday-ui/src/contextualBoxes/ReviewerDetails.js
@@ -13,6 +13,7 @@ import {
   ContextualBox,
   ReviewersTable,
   PublonsTable,
+  indexReviewers,
   ReviewerReport,
   InviteReviewers,
   ReviewerBreakdown,
@@ -118,14 +119,14 @@ const ReviewerDetails = ({
                 {reports.length === 0 && (
                   <Text align="center">No reports submitted yet.</Text>
                 )}
-                {reports.map((report, index) => (
+                {reports.map(report => (
                   <ReviewerReport
                     journal={journal}
                     key={report.id}
                     onDownload={downloadFile}
                     onPreview={previewFile}
                     report={report}
-                    reviewerIndex={index + 1}
+                    reviewerNumber={report.reviewerNumber}
                     showOwner
                   />
                 ))}
@@ -154,7 +155,10 @@ export default compose(
         ...i,
         review: reviewerReports.find(r => r.userId === i.userId),
       })),
-      reports: reviewerReports.filter(r => r.submittedOn),
+      reports: indexReviewers(
+        reviewerReports.filter(r => r.submittedOn),
+        invitations,
+      ),
     }),
   ),
   withProps(({ currentUser }) => ({
diff --git a/packages/component-faraday-ui/src/helpers/utils.js b/packages/component-faraday-ui/src/helpers/utils.js
index 898fd3ebc62282763a1331fd359f9d8da85a732c..8b798e34e7b73272c922ab6201019b5b4b221fb9 100644
--- a/packages/component-faraday-ui/src/helpers/utils.js
+++ b/packages/component-faraday-ui/src/helpers/utils.js
@@ -1,4 +1,4 @@
-import { get, chain } from 'lodash'
+import { get, chain, find } from 'lodash'
 
 export const handleError = fn => e => {
   fn(get(JSON.parse(e.response), 'error', 'Oops! Something went wrong!'))
@@ -10,3 +10,14 @@ export const getReportComments = ({ report, isPublic = false }) =>
     .find(c => c.public === isPublic)
     .get('content')
     .value()
+
+export const indexReviewers = (reports = [], invitations = []) => {
+  reports.forEach(report => {
+    report.reviewerNumber = get(
+      find(invitations, ['userId', report.userId]),
+      'reviewerNumber',
+      0,
+    )
+  })
+  return reports
+}
diff --git a/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptHeader.js b/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptHeader.js
index 699edec06e90cfc92695a9cbec10bc2ca8e81d70..296bebafcfc99f9f765f677a90d97d74f630b3e1 100644
--- a/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptHeader.js
+++ b/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptHeader.js
@@ -1,5 +1,5 @@
 import React, { Fragment } from 'react'
-import { get, chain } from 'lodash'
+import { get, chain, isEmpty } from 'lodash'
 import { H2, H4, DateParser, Button } from '@pubsweet/ui'
 import {
   compose,
@@ -121,6 +121,7 @@ export default compose(
       revokeInvitation,
       pendingInvitation = {},
       handlingEditors = [],
+      isLatestVersion,
       currentUser: {
         permissions: { canAssignHE },
         id: currentUserId,
@@ -128,31 +129,45 @@ export default compose(
         editorInChief,
       },
       collection: { handlingEditor },
+      collection,
       currentUser,
     }) => () => {
       if (pendingInvitation.userId === currentUserId) {
         return <Text ml={1}>Invited</Text>
       }
-      if (pendingInvitation.userId && (admin || editorInChief)) {
+      const invitedHeId =
+        get(pendingInvitation, 'userId', false) ||
+        get(heInvitation, 'userId', false)
+
+      if (invitedHeId && (admin || editorInChief)) {
         const person = chain(handlingEditors)
-          .filter(he => he.id === pendingInvitation.userId)
+          .filter(he => he.id === invitedHeId)
           .map(he => ({ ...he, name: `${he.firstName} ${he.lastName}` }))
           .first()
           .value()
 
+        let invitedHe = {}
+        if (get(pendingInvitation, 'userId', false)) {
+          invitedHe = pendingInvitation
+        } else if (get(heInvitation, 'userId', false)) {
+          invitedHe = heInvitation
+        }
         return (
           <PersonInvitation
             isFetching={isFetching}
+            isLatestVersion={isLatestVersion}
             ml={1}
             withName
-            {...pendingInvitation}
+            {...invitedHe}
             onResend={resendInvitation}
             onRevoke={revokeInvitation}
             person={person}
           />
         )
       }
-
+      if (!isEmpty(pendingInvitation)) {
+        return <Text ml={1}>{handlingEditor.name}</Text>
+      }
       if (heInvitation) {
         return <Text ml={1}>{handlingEditor.name}</Text>
       }
@@ -170,7 +185,7 @@ export default compose(
           </Button>
         )
       }
-      return <Text ml={1}>Assigned</Text>
+      return <Text ml={1}>Unassigned</Text>
     },
   }),
   setDisplayName('ManuscriptHeader'),
diff --git a/packages/component-fixture-manager/src/fixtures/collectionIDs.js b/packages/component-fixture-manager/src/fixtures/collectionIDs.js
index e66bb71a232758a7de0746033ba2493745157250..a964c2c498c452599e68dd3457a24eac4c0a3b49 100644
--- a/packages/component-fixture-manager/src/fixtures/collectionIDs.js
+++ b/packages/component-fixture-manager/src/fixtures/collectionIDs.js
@@ -7,5 +7,6 @@ module.exports = {
   collectionReviewCompletedID: chance.guid(),
   collectionNoInvitesID: chance.guid(),
   twoVersionsCollectionId: chance.guid(),
+  oneReviewedFragmentCollectionID: chance.guid(),
   noEditorRecomedationCollectionID: chance.guid(),
 }
diff --git a/packages/component-fixture-manager/src/fixtures/collections.js b/packages/component-fixture-manager/src/fixtures/collections.js
index 7d1df81e4f6379f9bb4d21bc243a2ed97a9e9e2d..0fbff658ca84fc9266a31674461679e769a1ff13 100644
--- a/packages/component-fixture-manager/src/fixtures/collections.js
+++ b/packages/component-fixture-manager/src/fixtures/collections.js
@@ -17,6 +17,7 @@ const {
   collectionReviewCompletedID,
   collectionNoInvitesID,
   twoVersionsCollectionId,
+  oneReviewedFragmentCollectionID,
   noEditorRecomedationCollectionID,
 } = require('./collectionIDs')
 
@@ -30,6 +31,7 @@ const collections = {
     fragments: [fragment.id],
     owners: [user.id],
     save: jest.fn(() => collections.collection),
+    getFragments: jest.fn(() => [fragment]),
     invitations: [
       {
         id: chance.guid(),
@@ -73,6 +75,7 @@ const collections = {
     fragments: [fragment.id],
     owners: [user.id],
     save: jest.fn(() => collections.collection),
+    getFragments: jest.fn(() => [fragment]),
     invitations: [
       {
         id: chance.guid(),
@@ -115,6 +118,7 @@ const collections = {
     fragments: [fragment1.id, noInvitesFragment.id],
     owners: [user.id],
     save: jest.fn(() => collections.collection2),
+    getFragments: jest.fn(() => [fragment1, noInvitesFragment]),
     invitations: [
       {
         id: chance.guid(),
@@ -159,6 +163,7 @@ const collections = {
     created: chance.timestamp(),
     customId: '0000001',
     fragments: [reviewCompletedFragment.id],
+    getFragments: jest.fn(() => [reviewCompletedFragment]),
     invitations: [
       {
         id: chance.guid(),
@@ -189,6 +194,7 @@ const collections = {
     fragments: [fragment.id, reviewCompletedFragment.id],
     owners: [user.id],
     save: jest.fn(() => collections.collection),
+    getFragments: jest.fn(() => [fragment, reviewCompletedFragment]),
     invitations: [
       {
         id: chance.guid(),
@@ -219,6 +225,7 @@ const collections = {
     fragments: [],
     owners: [user.id],
     save: jest.fn(() => collections.collection),
+    getFragments: jest.fn(() => []),
     customId: chance.natural({ min: 999999, max: 9999999 }),
   },
   noEditorRecomedationCollection: {
@@ -228,6 +235,7 @@ const collections = {
     fragments: [noEditorRecomedationFragment.id],
     owners: [user.id],
     save: jest.fn(() => collections.noEditorRecomedationCollection),
+    getFragments: jest.fn(() => [noEditorRecomedationFragment]),
     invitations: [
       {
         id: chance.guid(),
@@ -263,6 +271,37 @@ const collections = {
     },
     status: 'reviewCompleted',
   },
+  oneReviewedFragmentCollection: {
+    id: oneReviewedFragmentCollectionID,
+    title: chance.sentence(),
+    type: 'collection',
+    fragments: [reviewCompletedFragment.id, noInvitesFragment.id],
+    owners: [user.id],
+    save: jest.fn(() => collections.collection),
+    getFragments: jest.fn(() => [reviewCompletedFragment, noInvitesFragment]),
+    invitations: [
+      {
+        id: chance.guid(),
+        role: 'handlingEditor',
+        hasAnswer: true,
+        isAccepted: false,
+        userId: handlingEditor.id,
+        invitedOn: chance.timestamp(),
+        respondedOn: null,
+      },
+    ],
+    handlingEditor: {
+      id: handlingEditor.id,
+      hasAnswer: false,
+      isAccepted: false,
+      email: handlingEditor.email,
+      invitedOn: chance.timestamp(),
+      respondedOn: null,
+      name: `${handlingEditor.firstName} ${handlingEditor.lastName}`,
+    },
+    status: 'revisionRequested',
+    customId: chance.natural({ min: 999999, max: 9999999 }),
+  },
 }
 
 module.exports = collections
diff --git a/packages/component-fixture-manager/src/fixtures/fragments.js b/packages/component-fixture-manager/src/fixtures/fragments.js
index 15e4cb3fa981f4316d1d686a6dc2414d783ed89b..337c0d943c7e6fd87e47fd3e31ff3458c0fb567d 100644
--- a/packages/component-fixture-manager/src/fixtures/fragments.js
+++ b/packages/component-fixture-manager/src/fixtures/fragments.js
@@ -340,6 +340,7 @@ const fragments = {
         invitedOn: chance.timestamp(),
         isAccepted: true,
         respondedOn: chance.timestamp(),
+        reviewerNumber: 2,
       },
       {
         id: chance.guid(),
diff --git a/packages/component-helper-service/src/services/Collection.js b/packages/component-helper-service/src/services/Collection.js
index 6e05d9a584f61eddc5a63a7ad309ac81bea1edb6..b0789f05aa93601db62053ce8f5f18382b944973 100644
--- a/packages/component-helper-service/src/services/Collection.js
+++ b/packages/component-helper-service/src/services/Collection.js
@@ -1,4 +1,4 @@
-const { findLast, get } = require('lodash')
+const { findLast, isEmpty, maxBy, get, flatMap } = require('lodash')
 
 const Fragment = require('./Fragment')
 
@@ -109,6 +109,27 @@ class Collection {
     return lastName || firstName
   }
 
+  async getReviewerNumber({ userId }) {
+    const allCollectionFragments = await this.collection.getFragments()
+    const allCollectionInvitations = flatMap(
+      allCollectionFragments,
+      fragment => fragment.invitations,
+    )
+    const allNumberedInvitationsForUser = allCollectionInvitations
+      .filter(invite => invite.userId === userId)
+      .filter(invite => invite.reviewerNumber)
+
+    if (isEmpty(allNumberedInvitationsForUser)) {
+      const maxReviewerNumber = get(
+        maxBy(allCollectionInvitations, 'reviewerNumber'),
+        'reviewerNumber',
+        0,
+      )
+      return maxReviewerNumber + 1
+    }
+    return allNumberedInvitationsForUser[0].reviewerNumber
+  }
+
   // eslint-disable-next-line class-methods-use-this
   hasAtLeastOneReviewReport(fragments) {
     return fragments.some(fragment =>
@@ -126,17 +147,19 @@ class Collection {
       [],
     )
 
-    const lastRecommendationByHE = findLast(
+    const lastEditorRecommendation = findLast(
       previousVersionRecommendations,
       recommendation =>
-        recommendation.userId === this.collection.handlingEditor.id &&
         recommendation.recommendationType === 'editorRecommendation',
     )
-    if (lastRecommendationByHE.recommendation === 'minor') {
+
+    if (lastEditorRecommendation.recommendation === 'minor') {
       return this.hasAtLeastOneReviewReport(fragments)
-    } else if (lastRecommendationByHE.recommendation === 'major') {
+    } else if (lastEditorRecommendation.recommendation === 'major') {
       return fragmentHelper.hasReviewReport()
     }
+
+    return false
   }
 
   async getAllFragments({ FragmentModel }) {
diff --git a/packages/component-helper-service/src/tests/collection.test.js b/packages/component-helper-service/src/tests/collection.test.js
index 41c9f0ed6481079f790df50fc83584af62f2d1c4..167153af8c03fc7149c36a9e8c149de351c0f7db 100644
--- a/packages/component-helper-service/src/tests/collection.test.js
+++ b/packages/component-helper-service/src/tests/collection.test.js
@@ -10,11 +10,65 @@ const { Collection, Fragment } = require('../Helper')
 describe('Collection helper', () => {
   let testFixtures = {}
   let models
+
   beforeEach(() => {
     testFixtures = cloneDeep(fixtures)
     models = Model.build(testFixtures)
   })
 
+  describe('getReviewerNumber', () => {
+    it('should assign reviewer number 1 on invitation if no other reviewer numbers exist', async () => {
+      const { collection } = testFixtures.collections
+      const { reviewer } = testFixtures.users
+      const collectionHelper = new Collection({ collection })
+
+      const reviewerNumber = await collectionHelper.getReviewerNumber({
+        userId: reviewer.id,
+      })
+
+      expect(reviewerNumber).toBe(1)
+    })
+    it('should assign next reviewer number on invitation if another reviewer numbers exist', async () => {
+      const { collectionReviewCompleted } = testFixtures.collections
+      const { reviewer } = testFixtures.users
+      const collectionHelper = new Collection({
+        collection: collectionReviewCompleted,
+      })
+
+      const reviewerNumber = await collectionHelper.getReviewerNumber({
+        userId: reviewer.id,
+      })
+
+      expect(reviewerNumber).toBe(3)
+    })
+    it('should keep reviewer number across fragment versions', async () => {
+      const { oneReviewedFragmentCollection } = testFixtures.collections
+      const { answerReviewer } = testFixtures.users
+      const collectionHelper = new Collection({
+        collection: oneReviewedFragmentCollection,
+      })
+
+      const reviewerNumber = await collectionHelper.getReviewerNumber({
+        userId: answerReviewer.id,
+      })
+
+      expect(reviewerNumber).toBe(2)
+    })
+    it('should assign next reviewer number across fragment versions', async () => {
+      const { oneReviewedFragmentCollection } = testFixtures.collections
+      const { reviewer } = testFixtures.users
+      const collectionHelper = new Collection({
+        collection: oneReviewedFragmentCollection,
+      })
+
+      const reviewerNumber = await collectionHelper.getReviewerNumber({
+        userId: reviewer.id,
+      })
+
+      expect(reviewerNumber).toBe(3)
+    })
+  })
+
   describe('hasAtLeastOneReviewReport', () => {
     it('should return true if collection has at least one report from reviewers.', async () => {
       const { collection } = testFixtures.collections
diff --git a/packages/component-invite/src/CollectionsInvitations.js b/packages/component-invite/src/CollectionsInvitations.js
index 2f80dd1b70e3089a7ab7f9068a4e12dbb84985e5..0b72a54da398154f0b1e82b5f78601d57cf86064 100644
--- a/packages/component-invite/src/CollectionsInvitations.js
+++ b/packages/component-invite/src/CollectionsInvitations.js
@@ -39,7 +39,7 @@ const CollectionsInvitations = app => {
     require(`${routePath}/post`)(app.locals.models),
   )
   /**
-   * @api {delete} /api/collections/:collectionId/invitations/:invitationId Delete invitation
+   * @api {delete} /api/collections/:collectionId/invitations/:invitationId Delete invitation (or revoke HE if invitation is accepted)
    * @apiGroup CollectionsInvitations
    * @apiParam {collectionId} collectionId Collection id
    * @apiParam {invitationId} invitationId Invitation id
diff --git a/packages/component-invite/src/routes/collectionsInvitations/delete.js b/packages/component-invite/src/routes/collectionsInvitations/delete.js
index 6b3b6764bc654b1f05ea8b4402645649abf7243a..8442dea8cc79be967061c9846127f4d2d34846d9 100644
--- a/packages/component-invite/src/routes/collectionsInvitations/delete.js
+++ b/packages/component-invite/src/routes/collectionsInvitations/delete.js
@@ -1,8 +1,17 @@
+const config = require('config')
+
 const {
   Team,
   services,
   authsome: authsomeHelper,
 } = require('pubsweet-component-helper-service')
+const {
+  deleteFilesS3,
+} = require('pubsweet-component-mts-package/src/PackageManager')
+
+const { last, get, chain, difference } = require('lodash')
+
+const s3Config = get(config, 'pubsweet-component-aws-s3', {})
 
 const notifications = require('./emails/notifications')
 
@@ -56,13 +65,88 @@ module.exports = models => async (req, res) => {
     user.teams = user.teams.filter(userTeamId => team.id !== userTeamId)
     await user.save()
 
-    notifications.sendInvitedHEEmail({
-      models,
-      collection,
-      invitedHE: user,
-      isCanceled: true,
-      baseUrl: services.getBaseUrl(req),
-    })
+    if (invitation.hasAnswer && invitation.isAccepted) {
+      const FragmentModel = models.Fragment
+      const fragment = await FragmentModel.find(
+        last(get(collection, 'fragments', [])),
+      )
+
+      const fragmentId = fragment.id
+      const teamHelperForFragment = new Team({
+        TeamModel: models.Team,
+        collectionId,
+        fragmentId,
+      })
+
+      const teams = await teamHelperForFragment.getTeams('fragment')
+      const reviewerTeam = teams.find(
+        team => team.object.id === fragmentId && team.group === 'reviewer',
+      )
+      if (reviewerTeam) {
+        reviewerTeam.delete()
+      }
+
+      const fileKeys = []
+      fragment.recommendations &&
+        fragment.recommendations.forEach(recommendation => {
+          recommendation.comments.forEach(comment => {
+            comment.files &&
+              comment.files.forEach(file => {
+                fileKeys.push(file.id)
+              })
+          })
+        })
+
+      const revision = get(fragment, 'revision', false)
+      if (revision) {
+        const fragmentFilesIds = chain(get(fragment, 'files', []))
+          .flatMap(item => item)
+          .map(item => item.id)
+          .value()
+        const revisionFilesIds = chain(get(fragment, 'revision.files', []))
+          .flatMap(item => item)
+          .map(item => item.id)
+          .value()
+        const revisionFileIds = difference(revisionFilesIds, fragmentFilesIds)
+        fileKeys.concat(revisionFileIds)
+      }
+      if (fileKeys.length > 1) {
+        await deleteFilesS3({ fileKeys, s3Config })
+      }
+
+      let shouldAuthorBeNotified
+      if (fragment.invitations.length > 0) {
+        shouldAuthorBeNotified = true
+      }
+
+      fragment.invitations = []
+      fragment.recommendations = []
+      fragment.revision && delete fragment.revision
+      await fragment.save()
+
+      notifications.notifyInvitedHEWhenRemoved({
+        models,
+        collection,
+        invitedHE: user,
+        baseUrl: services.getBaseUrl(req),
+      })
+
+      if (shouldAuthorBeNotified) {
+        notifications.notifyAuthorWhenHERemoved({
+          models,
+          collection,
+          baseUrl: services.getBaseUrl(req),
+        })
+      }
+    } else {
+      notifications.sendInvitedHEEmail({
+        models,
+        collection,
+        invitedHE: user,
+        isCanceled: true,
+        baseUrl: services.getBaseUrl(req),
+      })
+    }
 
     return res.status(200).json({})
   } catch (e) {
diff --git a/packages/component-invite/src/routes/collectionsInvitations/emails/emailCopy.js b/packages/component-invite/src/routes/collectionsInvitations/emails/emailCopy.js
index c7c665749f3f3bb53a1743c6843753186201620d..54db6a8357ffc883df3a8c9c2123bd6ab8452003 100644
--- a/packages/component-invite/src/routes/collectionsInvitations/emails/emailCopy.js
+++ b/packages/component-invite/src/routes/collectionsInvitations/emails/emailCopy.js
@@ -1,6 +1,7 @@
 const config = require('config')
 
 const staffEmail = config.get('journal.staffEmail')
+const journalName = config.get('journal.name')
 
 const getEmailCopy = ({ emailType, titleText, targetUserName, comments }) => {
   let paragraph
@@ -34,6 +35,22 @@ const getEmailCopy = ({ emailType, titleText, targetUserName, comments }) => {
       paragraph = `${targetUserName} has removed you from the role of Handling Editor for ${titleText}.<br/><br/>
         The manuscript will no longer appear in your dashboard. Please contact ${staffEmail} if you have any questions about this change.`
       break
+    case 'author-he-removed':
+      hasIntro = true
+      hasLink = false
+      hasSignature = true
+      paragraph = `The handling editor of your manuscript "${titleText}" had to be replaced. This may cause some delays in the peer review process.<br/><br/>
+        If you have questions please email them to ${staffEmail}.<br/><br/>
+        Thank you for your submission to ${journalName}.`
+      break
+    case 'he-he-removed':
+      hasIntro = true
+      hasLink = false
+      hasSignature = true
+      paragraph = `The Editor in Chief removed you from the manuscript "${titleText}".<br/><br/>
+        If you have any questions regarding this action, please let us know at ${staffEmail}.<br/><br/>
+        Thank you for reviewing ${journalName}.`
+      break
     default:
       throw new Error(`The ${emailType} email type is not defined.`)
   }
diff --git a/packages/component-invite/src/routes/collectionsInvitations/emails/notifications.js b/packages/component-invite/src/routes/collectionsInvitations/emails/notifications.js
index 2b85380e873f1a686ed362c33c0b991eabac3aef..10de02e83f68a525e6cf39f1702290dae90c316b 100644
--- a/packages/component-invite/src/routes/collectionsInvitations/emails/notifications.js
+++ b/packages/component-invite/src/routes/collectionsInvitations/emails/notifications.js
@@ -35,9 +35,7 @@ module.exports = {
     } ${submittingAuthor.lastName}`
 
     const userHelper = new User({ UserModel })
-    const eics = await userHelper.getEditorsInChief()
-    const eic = eics[0]
-    const eicName = `${eic.firstName} ${eic.lastName}`
+    const eicName = await userHelper.getEiCName()
     const { customId } = collection
 
     const { paragraph, ...bodyProps } = getEmailCopy({
@@ -73,6 +71,92 @@ module.exports = {
 
     return email.sendEmail()
   },
+  notifyAuthorWhenHERemoved: async ({
+    baseUrl,
+    collection,
+    models: { User: UserModel, Fragment: FragmentModel },
+  }) => {
+    const fragmentId = last(collection.fragments)
+    const fragment = await FragmentModel.find(fragmentId)
+    const fragmentHelper = new Fragment({ fragment })
+    const { title: titleText } = await fragmentHelper.getFragmentData()
+    const { submittingAuthor } = await fragmentHelper.getAuthorData({
+      UserModel,
+    })
+
+    const userHelper = new User({ UserModel })
+    const eicName = await userHelper.getEiCName()
+    const { customId } = collection
+
+    const { paragraph, ...bodyProps } = getEmailCopy({
+      titleText,
+      emailType: 'author-he-removed',
+    })
+
+    const email = new Email({
+      type: 'user',
+      fromEmail: `${eicName} <${staffEmail}>`,
+      toUser: {
+        email: submittingAuthor.email,
+        name: `${submittingAuthor.lastName}`,
+      },
+      content: {
+        subject: `${customId}:  Your manuscript's editor was changed`,
+        paragraph,
+        signatureName: eicName,
+        signatureJournal: journalName,
+        unsubscribeLink: services.createUrl(baseUrl, unsubscribeSlug, {
+          id: submittingAuthor.id,
+          token: submittingAuthor.accessTokens.unsubscribe,
+        }),
+      },
+      bodyProps,
+    })
+
+    return email.sendEmail()
+  },
+  notifyInvitedHEWhenRemoved: async ({
+    baseUrl,
+    invitedHE,
+    collection,
+    models: { User: UserModel, Fragment: FragmentModel },
+  }) => {
+    const fragmentId = last(collection.fragments)
+    const fragment = await FragmentModel.find(fragmentId)
+    const fragmentHelper = new Fragment({ fragment })
+    const { title: titleText } = await fragmentHelper.getFragmentData()
+
+    const userHelper = new User({ UserModel })
+    const eicName = await userHelper.getEiCName()
+    const { customId } = collection
+
+    const { paragraph, ...bodyProps } = getEmailCopy({
+      titleText,
+      emailType: 'he-he-removed',
+    })
+
+    const email = new Email({
+      type: 'user',
+      fromEmail: `${eicName} <${staffEmail}>`,
+      toUser: {
+        email: invitedHE.email,
+        name: `${invitedHE.lastName}`,
+      },
+      content: {
+        subject: `${customId}: The editor in chief removed you from ${titleText}`,
+        paragraph,
+        signatureName: eicName,
+        signatureJournal: journalName,
+        unsubscribeLink: services.createUrl(baseUrl, unsubscribeSlug, {
+          id: invitedHE.id,
+          token: invitedHE.accessTokens.unsubscribe,
+        }),
+      },
+      bodyProps,
+    })
+
+    return email.sendEmail()
+  },
   sendEiCEmail: async ({
     reason,
     baseUrl,
diff --git a/packages/component-invite/src/tests/collectionsInvitations/delete.test.js b/packages/component-invite/src/tests/collectionsInvitations/delete.test.js
index c6e6089b02c4946f6a624911036cf2736a905d77..184f8818018ca0bab8fb24db9a5e844cc1273ed3 100644
--- a/packages/component-invite/src/tests/collectionsInvitations/delete.test.js
+++ b/packages/component-invite/src/tests/collectionsInvitations/delete.test.js
@@ -9,6 +9,9 @@ const { Model, fixtures } = fixturesService
 jest.mock('@pubsweet/component-send-email', () => ({
   send: jest.fn(),
 }))
+jest.mock('pubsweet-component-mts-package/src/PackageManager', () => ({
+  deleteFilesS3: jest.fn(),
+}))
 
 const path = '../routes/collectionsInvitations/delete'
 const route = {
@@ -86,4 +89,19 @@ describe('Delete Collections Invitations route handler', () => {
     const data = JSON.parse(res._getData())
     expect(data.error).toEqual('Unauthorized.')
   })
+  it('should return success when the EiC revokes a HE', async () => {
+    const { editorInChief } = testFixtures.users
+    const { collection } = testFixtures.collections
+    const res = await requests.sendRequest({
+      userId: editorInChief.id,
+      route,
+      models,
+      path,
+      params: {
+        collectionId: collection.id,
+        invitationId: collection.invitations[1].id,
+      },
+    })
+    expect(res.statusCode).toBe(200)
+  })
 })
diff --git a/packages/component-manuscript-manager/src/routes/fragments/patch.js b/packages/component-manuscript-manager/src/routes/fragments/patch.js
index acd037254ddb9ada6417d99980a2a30588799d08..6a3e11ef06411ccd3868b8da6aca8389289f0d6a 100644
--- a/packages/component-manuscript-manager/src/routes/fragments/patch.js
+++ b/packages/component-manuscript-manager/src/routes/fragments/patch.js
@@ -24,7 +24,8 @@ module.exports = models => async (req, res) => {
     fragment = await models.Fragment.find(fragmentId)
     if (!fragment.revision) {
       return res.status(400).json({
-        error: 'No revision has been found.',
+        error:
+          'Your Handling Editor was changed. A new handling editor will be assigned to your manuscript soon. Sorry for the inconvenience.',
       })
     }
 
diff --git a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/patch.js b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/patch.js
index 7846722ed2f83db255a59ff80f95c142ccf2d3ec..7cd5b2ae49984d23fff26a53ae1bfb38a19f8244 100644
--- a/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/patch.js
+++ b/packages/component-manuscript-manager/src/routes/fragmentsRecommendations/patch.js
@@ -1,3 +1,4 @@
+const { find } = require('lodash')
 const {
   services,
   authsome: authsomeHelper,
@@ -8,6 +9,7 @@ const Notification = require('../../notifications/notification')
 
 module.exports = models => async (req, res) => {
   const { collectionId, fragmentId, recommendationId } = req.params
+  const userId = req.user
   let collection, fragment
   try {
     collection = await models.Collection.find(collectionId)
@@ -25,7 +27,7 @@ module.exports = models => async (req, res) => {
     if (!recommendation)
       return res.status(404).json({ error: 'Recommendation not found.' })
 
-    if (recommendation.userId !== req.user)
+    if (recommendation.userId !== userId)
       return res.status(403).json({
         error: 'Unauthorized.',
       })
@@ -35,14 +37,14 @@ module.exports = models => async (req, res) => {
       fragment,
       path: req.route.path,
     }
-    const canPatch = await authsome.can(req.user, 'PATCH', target)
+    const canPatch = await authsome.can(userId, 'PATCH', target)
     if (!canPatch)
       return res.status(403).json({
         error: 'Unauthorized.',
       })
 
     const UserModel = models.User
-    const reviewer = await UserModel.find(req.user)
+    const reviewer = await UserModel.find(userId)
 
     Object.assign(recommendation, req.body)
     recommendation.updatedOn = Date.now()
@@ -62,6 +64,16 @@ module.exports = models => async (req, res) => {
         const collectionHelper = new Collection({ collection })
         collectionHelper.updateStatus({ newStatus: 'reviewCompleted' })
       }
+
+      const collectionHelper = new Collection({ collection })
+      const reviewerNumber = await collectionHelper.getReviewerNumber({
+        userId,
+      })
+
+      find(fragment.invitations, [
+        'userId',
+        userId,
+      ]).reviewerNumber = reviewerNumber
     }
 
     fragment.save()
diff --git a/packages/component-manuscript-manager/src/tests/collections/get.test.js b/packages/component-manuscript-manager/src/tests/collections/get.test.js
index aa4a1cfec4a3e9de92809e07e056a81b2aaede1f..b721805c99c9b00833fcb953cc16f5a529840164 100644
--- a/packages/component-manuscript-manager/src/tests/collections/get.test.js
+++ b/packages/component-manuscript-manager/src/tests/collections/get.test.js
@@ -58,7 +58,6 @@ describe('Get collections route handler', () => {
 
     expect(res.statusCode).toBe(200)
     const data = JSON.parse(res._getData())
-
     expect(data).toHaveLength(2)
     expect(data[0].type).toEqual('collection')
     expect(data[0].currentVersion.recommendations).toHaveLength(6)
diff --git a/packages/component-manuscript-manager/src/tests/fragments/patch.test.js b/packages/component-manuscript-manager/src/tests/fragments/patch.test.js
index f4e2147a5604bf4f77e0782fdd1f33cb28ec9f58..be867cbe7df7674d91c619d7837a94ed08e808e6 100644
--- a/packages/component-manuscript-manager/src/tests/fragments/patch.test.js
+++ b/packages/component-manuscript-manager/src/tests/fragments/patch.test.js
@@ -148,7 +148,9 @@ describe('Patch fragments route handler', () => {
 
     expect(res.statusCode).toBe(400)
     const data = JSON.parse(res._getData())
-    expect(data.error).toEqual('No revision has been found.')
+    expect(data.error).toEqual(
+      'Your Handling Editor was changed. A new handling editor will be assigned to your manuscript soon. Sorry for the inconvenience.',
+    )
   })
   it('should return an error when the user is inactive', async () => {
     const { inactiveUser } = testFixtures.users
diff --git a/packages/component-manuscript/src/components/ManuscriptLayout.js b/packages/component-manuscript/src/components/ManuscriptLayout.js
index 4953fa278e884980a5bfe28168c62a6a0e97a455..5f870ecfa43fe24b4886780c6a78feaf2f0d675b 100644
--- a/packages/component-manuscript/src/components/ManuscriptLayout.js
+++ b/packages/component-manuscript/src/components/ManuscriptLayout.js
@@ -17,9 +17,9 @@ import {
   ResponseToRevisionRequest,
 } from 'pubsweet-component-faraday-ui'
 
-import ReviewerReportCard from './ReviewReportCard'
 import ReviewerReportForm from './ReviewerReportForm'
 import EditorialCommentCard from './EditorialCommentCard'
+import ReviewerReports from './ReviewerReports'
 
 const messagesLabel = {
   'return-to-handling-editor': 'Comments for Handling Editor',
@@ -122,17 +122,25 @@ const ManuscriptLayout = ({
           <AuthorReviews
             currentUser={currentUser}
             getSignedUrl={getSignedUrl}
+            invitations={invitationsWithReviewers}
             journal={journal}
-            reports={reviewerReports}
+            reviewerReports={reviewerReports}
             token={get(currentUser, 'token')}
           />
         )}
 
-        {submittedOwnRecommendation && (
-          <ReviewerReportCard
+        {get(
+          currentUser,
+          'permissions.reviewersCanViewReviewerReports',
+          false,
+        ) && (
+          <ReviewerReports
+            currentUser={currentUser}
             getSignedUrl={getSignedUrl}
+            invitations={invitationsWithReviewers}
+            isLatestVersion={isLatestVersion}
             journal={journal}
-            report={submittedOwnRecommendation}
+            reviewerReports={reviewerRecommendations}
             token={get(currentUser, 'token')}
           />
         )}
@@ -163,17 +171,18 @@ const ManuscriptLayout = ({
             />
           )}
 
-        {get(currentUser, 'isInvitedHE', false) && (
-          <ResponseToInvitation
-            commentsOn="decline"
-            expanded={heResponseExpanded}
-            formValues={formValues.responseToInvitation}
-            label="Do you agree to be the handling editor for this manuscript?"
-            onResponse={inviteHandlingEditor.onHEResponse}
-            title="Respond to Editorial Invitation"
-            toggle={toggleHEResponse}
-          />
-        )}
+        {isLatestVersion &&
+          get(currentUser, 'isInvitedHE', false) && (
+            <ResponseToInvitation
+              commentsOn="decline"
+              expanded={heResponseExpanded}
+              formValues={formValues.responseToInvitation}
+              label="Do you agree to be the handling editor for this manuscript?"
+              onResponse={inviteHandlingEditor.onHEResponse}
+              title="Respond to Editorial Invitation"
+              toggle={toggleHEResponse}
+            />
+          )}
 
         {get(currentUser, 'isInvitedToReview', false) && (
           <ResponseToInvitation
@@ -185,14 +194,16 @@ const ManuscriptLayout = ({
           />
         )}
 
-        <ManuscriptAssignHE
-          assignHE={inviteHandlingEditor.assignHE}
-          currentUser={currentUser}
-          expanded={heExpanded}
-          handlingEditors={handlingEditors}
-          isFetching={isFetchingData.editorsFetching}
-          toggle={toggleAssignHE}
-        />
+        {isLatestVersion && (
+          <ManuscriptAssignHE
+            assignHE={inviteHandlingEditor.assignHE}
+            currentUser={currentUser}
+            expanded={heExpanded}
+            handlingEditors={handlingEditors}
+            isFetching={isFetchingData.editorsFetching}
+            toggle={toggleAssignHE}
+          />
+        )}
 
         {get(currentUser, 'permissions.canViewReviewersDetails', false) && (
           <ReviewerDetails
diff --git a/packages/component-manuscript/src/components/ManuscriptPage.js b/packages/component-manuscript/src/components/ManuscriptPage.js
index 89b5dadefcc611d56684ad1b442b326f2f3870ab..9ecbb8297bdce18ebcfd1b00c0b26e2b624af545 100644
--- a/packages/component-manuscript/src/components/ManuscriptPage.js
+++ b/packages/component-manuscript/src/components/ManuscriptPage.js
@@ -57,6 +57,7 @@ import {
   getOwnPendingRecommendation,
   getOwnSubmittedRecommendation,
   canAuthorViewEditorialComments,
+  reviewersCanViewReviewerReports,
   canHEMakeRecommendationToPublish,
   getFragmentReviewerRecommendations,
   getInvitationsWithReviewersForFragment,
@@ -177,7 +178,11 @@ export default compose(
             collection,
             statuses: get(journal, 'statuses', {}),
           }),
-          canAssignHE: canAssignHE(state, collection),
+          canAssignHE: canAssignHE(
+            state,
+            collection,
+            isLatestVersion(collection, fragment),
+          ),
           canViewReports: canViewReports(state, match.params.project),
           canViewEditorialComments: canViewEditorialComments(
             state,
@@ -195,6 +200,11 @@ export default compose(
             collection,
             get(fragment, 'id', ''),
           ),
+          reviewersCanViewReviewerReports: reviewersCanViewReviewerReports(
+            state,
+            collection,
+            get(fragment, 'id', ''),
+          ),
           canOverrideTechChecks: canOverrideTechnicalChecks(state, collection),
           canAuthorViewEditorialComments: canAuthorViewEditorialComments(
             state,
diff --git a/packages/component-manuscript/src/components/ReviewerReports.js b/packages/component-manuscript/src/components/ReviewerReports.js
new file mode 100644
index 0000000000000000000000000000000000000000..9d838360390efb16be9bb8a837d299b866c55c8a
--- /dev/null
+++ b/packages/component-manuscript/src/components/ReviewerReports.js
@@ -0,0 +1,88 @@
+import React from 'react'
+import { compose, withProps } from 'recompose'
+import { get } from 'lodash'
+import {
+  ReviewerReport,
+  ContextualBox,
+  withFilePreview,
+  withFileDownload,
+  Text,
+  Row,
+  indexReviewers,
+} from 'pubsweet-component-faraday-ui'
+
+const SubmittedReports = ({ reports }) => (
+  <Row fitContent justify="flex-end">
+    <Text customId mr={1 / 2}>
+      {reports}
+    </Text>
+    <Text mr={1 / 2} pr={1 / 2} secondary>
+      {' '}
+      submitted
+    </Text>
+  </Row>
+)
+
+const ReviewerReports = ({
+  journal,
+  reports,
+  previewFile,
+  downloadFile,
+  isLatestVersion,
+  currentUser,
+  token,
+  invitations,
+  reviwerReports,
+}) => (
+  <ContextualBox
+    label={isLatestVersion ? 'Your Report' : 'Reviewer Reports'}
+    mb={2}
+    rightChildren={<SubmittedReports reports={reports.length} />}
+    startExpanded
+  >
+    {reports.map(report => (
+      <ReviewerReport
+        currentUser={currentUser}
+        journal={journal}
+        key={report.id}
+        onDownload={downloadFile}
+        onPreview={previewFile}
+        report={report}
+        reviewerNumber={report.reviewerNumber}
+        showOwner={report.userId === currentUser.id}
+      />
+    ))}
+  </ContextualBox>
+)
+
+export default compose(
+  withFileDownload,
+  withFilePreview,
+  withProps(
+    ({
+      invitations = [],
+      publonReviewers = [],
+      reviewerReports = [],
+      currentUser,
+      isLatestVersion,
+    }) => ({
+      token: get(currentUser, 'token', ''),
+      publonReviewers,
+      invitations: invitations.map(i => ({
+        ...i,
+        review: reviewerReports.find(r => r.userId === i.userId),
+      })),
+      reports: isLatestVersion
+        ? indexReviewers(
+            reviewerReports.filter(
+              r => r.submittedOn && r.userId === currentUser.id,
+            ),
+            invitations,
+          )
+        : indexReviewers(
+            reviewerReports.filter(r => r.submittedOn),
+            invitations,
+          ),
+    }),
+  ),
+)(ReviewerReports)
diff --git a/packages/component-manuscript/src/redux/editors.js b/packages/component-manuscript/src/redux/editors.js
index e28c0dd29ff392776fa2092639ec8fceda19026a..2ff500a7c82c6d94db4b74faaa837b961b6c1b04 100644
--- a/packages/component-manuscript/src/redux/editors.js
+++ b/packages/component-manuscript/src/redux/editors.js
@@ -24,13 +24,14 @@ export const selectHandlingEditors = state =>
     .value()
 
 const canAssignHEStatuses = ['submitted']
-export const canAssignHE = (state, collection = {}) => {
+export const canAssignHE = (state, collection = {}, isLatestVersion) => {
   const isEIC = currentUserIs(state, 'adminEiC')
   const hasHE = get(collection, 'handlingEditor', false)
 
   return (
     isEIC &&
     !hasHE &&
+    isLatestVersion &&
     canAssignHEStatuses.includes(get(collection, 'status', 'draft'))
   )
 }
diff --git a/packages/component-manuscript/src/submitRevision/utils.js b/packages/component-manuscript/src/submitRevision/utils.js
index bee60515f02ca64d53e90cb8478ebe32de58ea8b..970d5303370d5be965c0c4ad64bae08d7e1ec5d9 100644
--- a/packages/component-manuscript/src/submitRevision/utils.js
+++ b/packages/component-manuscript/src/submitRevision/utils.js
@@ -5,7 +5,7 @@ import { autosaveRequest } from 'pubsweet-component-wizard/src/redux/autosave'
 import { submitRevision } from 'pubsweet-component-wizard/src/redux/conversion'
 
 const parseRevision = (values, fragment) => ({
-  ...fragment,
+  ...omit(fragment, 'recommendations'),
   revision: {
     ...values,
   },
diff --git a/packages/xpub-faraday/config/authsome-helpers.js b/packages/xpub-faraday/config/authsome-helpers.js
index 08e583c721fa6103de2f4729e0f2e64a348567a7..39f753c539a754d22829a00a0397277236eb40b1 100644
--- a/packages/xpub-faraday/config/authsome-helpers.js
+++ b/packages/xpub-faraday/config/authsome-helpers.js
@@ -4,8 +4,6 @@ const { omit, get, last, chain } = require('lodash')
 
 const statuses = config.get('statuses')
 
-const keysToOmit = [`email`, `id`]
-const authorCannotViewHENameStatuses = ['heInvited']
 const authorAllowedStatuses = ['revisionRequested', 'rejected', 'accepted']
 
 const getTeamsByPermissions = async (
@@ -72,23 +70,57 @@ const filterAuthorRecommendations = (recommendations, status, isLast) => {
   return []
 }
 
+const filterRecommendationsFromLastVersion = (recommendations, user) =>
+  recommendations
+    .filter(
+      r =>
+        r.userId === user.id || r.recommendationType === 'editorRecommendation',
+    )
+    .map(r => ({
+      ...r,
+      comments: r.comments.filter(c => c.public === true),
+    }))
+
+const filterRecommendationsFromOlderVersions = (recommendations, user) => {
+  const ownRecommendation = recommendations.find(r => r.userId === user.id)
+  if (ownRecommendation) {
+    return recommendations
+      .filter(
+        r => r.submittedOn || r.recommendationType === 'editorRecommendation',
+      )
+      .map(
+        r =>
+          r.userId !== ownRecommendation.userId
+            ? { ...r, comments: r.comments.filter(c => c.public === true) }
+            : { ...r },
+      )
+  }
+  return []
+}
+
 const stripeCollectionByRole = ({ collection = {}, role = '' }) => {
   if (role === 'author') {
-    const { handlingEditor } = collection
-
-    if (authorCannotViewHENameStatuses.includes(collection.status)) {
+    if (collection.status === 'heInvited') {
       return {
         ...collection,
-        handlingEditor: handlingEditor &&
-          !handlingEditor.isAccepted && {
-            ...omit(handlingEditor, keysToOmit),
-            name: 'Assigned',
-          },
+        handlingEditor: {
+          name: 'Assigned',
+        },
+      }
+    }
+    if (collection.status === 'submitted') {
+      return {
+        ...collection,
+        handlingEditor: {
+          name: 'Unassigned',
+        },
       }
     }
   }
+
   return collection
 }
+
 const stripeFragmentByRole = ({
   fragment = {},
   role = '',
@@ -96,7 +128,8 @@ const stripeFragmentByRole = ({
   user = {},
   isLast = false,
 }) => {
-  const { recommendations, files, authors } = fragment
+  const { files, authors, recommendations = [] } = fragment
+  let recommendationsFromFragment = []
   switch (role) {
     case 'author':
       return {
@@ -106,22 +139,22 @@ const stripeFragmentByRole = ({
           : [],
       }
     case 'reviewer':
+      if (isLast) {
+        recommendationsFromFragment = filterRecommendationsFromLastVersion(
+          recommendations,
+          user,
+        )
+      } else {
+        recommendationsFromFragment = filterRecommendationsFromOlderVersions(
+          recommendations,
+          user,
+        )
+      }
       return {
         ...fragment,
         files: omit(files, ['coverLetter']),
         authors: authors.map(a => omit(a, ['email'])),
-        recommendations: recommendations
-          ? recommendations
-              .filter(
-                r =>
-                  r.userId === user.id ||
-                  r.recommendationType === 'editorRecommendation',
-              )
-              .map(r => ({
-                ...r,
-                comments: r.comments.filter(c => c.public === true),
-              }))
-          : [],
+        recommendations: recommendationsFromFragment,
       }
     case 'handlingEditor':
       return {
@@ -175,10 +208,13 @@ const getCollections = async ({ user, models }) => {
         } else {
           fragment = await models.Fragment.find(userPermission.objectId)
           collection = await models.Collection.find(fragment.collectionId)
+          const latestFragmentId =
+            collection.fragments[collection.fragments.length - 1]
           collection.currentVersion = stripeFragmentByRole({
             fragment,
             role: userPermission.role,
             user,
+            isLast: latestFragmentId === fragment.id,
           })
         }
       } catch (e) {
diff --git a/packages/xpub-faraday/config/authsome-mode.js b/packages/xpub-faraday/config/authsome-mode.js
index fe678f981257b9e3a67647f062f3f15ef0f87f31..c9df55d68c485557d2c6031a4a5a35e6f9f752a9 100644
--- a/packages/xpub-faraday/config/authsome-mode.js
+++ b/packages/xpub-faraday/config/authsome-mode.js
@@ -93,8 +93,13 @@ async function applyAuthenticatedUserPolicy(user, operation, object, context) {
             FragmentModel: context.models.Fragment,
           })
 
+          const parsedCollection = helpers.stripeCollectionByRole({
+            collection,
+            role,
+          })
+
           return {
-            ...collection,
+            ...parsedCollection,
             ...parsedStatuses,
             fragments:
               role !== 'reviewer'
diff --git a/packages/xpub-faraday/tests/config/authsome-helpers.test.js b/packages/xpub-faraday/tests/config/authsome-helpers.test.js
index c5634168fdf6ab29134874c7c3fa9ee96183b2d0..41fa760afb11a7bb0cb7896549aa19151e3ce79a 100644
--- a/packages/xpub-faraday/tests/config/authsome-helpers.test.js
+++ b/packages/xpub-faraday/tests/config/authsome-helpers.test.js
@@ -19,7 +19,7 @@ describe('Authsome Helpers', () => {
       expect(newCollection).toBeTruthy()
     })
 
-    it('Author should not see HE name on dashboard before HE accepts invitation', () => {
+    it('Author should see Assigned instead of HE name on dashboard before HE accepts invitation', () => {
       const { collection } = testFixtures.collections
       collection.handlingEditor = {
         ...collection.handlingEditor,
@@ -86,6 +86,19 @@ describe('Authsome Helpers', () => {
       const { handlingEditor = {} } = newCollection
       expect(handlingEditor.name).not.toEqual('Assigned')
     })
+
+    it('Author should see Unassigned insted of HE name before HE is invited', () => {
+      const { collection } = testFixtures.collections
+      collection.status = 'submitted'
+      const role = 'author'
+      const newCollection = ah.stripeCollectionByRole({
+        collection,
+        role,
+      })
+      const { handlingEditor = {} } = newCollection
+      expect(handlingEditor.name).toEqual('Unassigned')
+    })
+
     it('stripeCollection - returns if collection does not have HE', () => {
       const { collection } = testFixtures.collections
       delete collection.handlingEditor
@@ -116,7 +129,7 @@ describe('Authsome Helpers', () => {
       const { files = {} } = result
       expect(files.coverLetter).toBeFalsy()
     })
-    it('reviewer should not see private comments', () => {
+    it('reviewer should not see private comments on the last version of the manuscript', () => {
       const { fragment } = testFixtures.fragments
       fragment.recommendations = [
         {
@@ -132,13 +145,59 @@ describe('Authsome Helpers', () => {
           ],
         },
       ]
-      const result = ah.stripeFragmentByRole({ fragment, role: 'reviewer' })
+      const result = ah.stripeFragmentByRole({
+        fragment,
+        role: 'reviewer',
+        isLast: true,
+      })
       const { recommendations } = result
       expect(recommendations).toHaveLength(1)
       expect(recommendations[0].comments).toHaveLength(1)
       expect(recommendations[0].comments[0].public).toEqual(true)
     })
 
+    it('reviewer should see other reviewers recommendations on previous version if he submitted a review on that fragment', () => {
+      const { fragment } = testFixtures.fragments
+      const { answerReviewer } = testFixtures.users
+
+      const result = ah.stripeFragmentByRole({
+        fragment,
+        role: 'reviewer',
+        isLast: false,
+        user: answerReviewer,
+      })
+      const { recommendations } = result
+      expect(recommendations).toHaveLength(7)
+    })
+
+    it('reviewer should not see other reviewers recommendations on latest fragment', () => {
+      const { fragment } = testFixtures.fragments
+      const { answerReviewer } = testFixtures.users
+
+      const result = ah.stripeFragmentByRole({
+        fragment,
+        role: 'reviewer',
+        isLast: true,
+        user: answerReviewer,
+      })
+      const { recommendations } = result
+      expect(recommendations).toHaveLength(6)
+    })
+
+    it('reviewer should not see any reviewer recommendation on previous version if he did not submit a review on that fragment', () => {
+      const { fragment } = testFixtures.fragments
+      const { inactiveReviewer } = testFixtures.users
+
+      const result = ah.stripeFragmentByRole({
+        fragment,
+        role: 'reviewer',
+        isLast: false,
+        user: inactiveReviewer,
+      })
+      const { recommendations } = result
+      expect(recommendations).toHaveLength(0)
+    })
+
     it('author should not see recommendations if a decision has not been made', () => {
       const { fragment } = testFixtures.fragments
       fragment.recommendations = [