diff --git a/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Base_getConstraintTypeListPerPortalType.py b/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Base_getConstraintTypeListPerPortalType.py
index e803cc007b353e0ed5fd1f7d3fbf0e47e58f6a95..6ee69053cacb10dac3d3d93d742e5b108cdb4936 100644
--- a/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Base_getConstraintTypeListPerPortalType.py
+++ b/bt5/erp5_upgrader/SkinTemplateItem/portal_skins/erp5_upgrader/Base_getConstraintTypeListPerPortalType.py
@@ -40,13 +40,12 @@ for property_sheet_id, category_list in constraint_type_per_id.iteritems():
     constraint_type_per_type.setdefault(portal_type, set()).update(category_list)
 
 portal_type_tool = portal.portal_types
-portal_type_list = constraint_type_per_type.keys()
 
-for portal_type in portal_type_list:
+for portal_type in list(constraint_type_per_type.keys()):
   allowed_content_type_list = \
     portal_type_tool[portal_type].getTypeAllowedContentTypeList()
   for allowed_content_type in allowed_content_type_list:
-    if allowed_content_type in portal_type_list:
+    if allowed_content_type in constraint_type_per_type:
       type_list = constraint_type_per_type.pop(allowed_content_type)
       for constraint_type in type_list:
         type_per_constraint_type[constraint_type].remove(allowed_content_type)
diff --git a/bt5/erp5_web/PortalTypePropertySheetTemplateItem/property_sheet_list.xml b/bt5/erp5_web/PortalTypePropertySheetTemplateItem/property_sheet_list.xml
index 0e5713010d2b4e292a28b1d20f0f91e2e2eb85c4..85f1c06f36c888f5e34d7f6c19578aa84d0064a7 100644
--- a/bt5/erp5_web/PortalTypePropertySheetTemplateItem/property_sheet_list.xml
+++ b/bt5/erp5_web/PortalTypePropertySheetTemplateItem/property_sheet_list.xml
@@ -1,8 +1,10 @@
 <property_sheet_list>
  <portal_type id="Static Web Section">
   <item>SortIndex</item>
+  <item>WebSectionUpgradeConstraint</item>
  </portal_type>
  <portal_type id="Static Web Site">
+  <item>WebSectionUpgradeConstraint</item>
   <item>WebSitePreference</item>
  </portal_type>
  <portal_type id="Web Page">
@@ -11,8 +13,10 @@
  </portal_type>
  <portal_type id="Web Section">
   <item>SortIndex</item>
+  <item>WebSectionUpgradeConstraint</item>
  </portal_type>
  <portal_type id="Web Site">
+  <item>WebSectionUpgradeConstraint</item>
   <item>WebSitePreference</item>
  </portal_type>
 </property_sheet_list>
\ No newline at end of file
diff --git a/bt5/erp5_web/PropertySheetTemplateItem/portal_property_sheets/WebSectionUpgradeConstraint.xml b/bt5/erp5_web/PropertySheetTemplateItem/portal_property_sheets/WebSectionUpgradeConstraint.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f3bf6aa9d09986f66a9733c517010fcd1058002c
--- /dev/null
+++ b/bt5/erp5_web/PropertySheetTemplateItem/portal_property_sheets/WebSectionUpgradeConstraint.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Property Sheet" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_count</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>_mt_index</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>_tree</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>WebSectionUpgradeConstraint</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Property Sheet</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="Length" module="BTrees.Length"/>
+    </pickle>
+    <pickle> <int>0</int> </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <global name="OOBTree" module="BTrees.OOBTree"/>
+    </pickle>
+    <pickle>
+      <none/>
+    </pickle>
+  </record>
+  <record id="4" aka="AAAAAAAAAAQ=">
+    <pickle>
+      <global name="OOBTree" module="BTrees.OOBTree"/>
+    </pickle>
+    <pickle>
+      <none/>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web/PropertySheetTemplateItem/portal_property_sheets/WebSectionUpgradeConstraint/default_page_modification_date_constraint.xml b/bt5/erp5_web/PropertySheetTemplateItem/portal_property_sheets/WebSectionUpgradeConstraint/default_page_modification_date_constraint.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1aae27d7b0ba83f7793657705c4469eaaa00743b
--- /dev/null
+++ b/bt5/erp5_web/PropertySheetTemplateItem/portal_property_sheets/WebSectionUpgradeConstraint/default_page_modification_date_constraint.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Script Constraint" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_identity_criterion</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>_range_criterion</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>constraint_type/post_upgrade</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>default_page_modification_date_constraint</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Script Constraint</string> </value>
+        </item>
+        <item>
+            <key> <string>script_id</string> </key>
+            <value> <string>WebSection_checkDefaultPageModificationDateConsistency</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web/SkinTemplateItem/portal_skins/erp5_web/WebSection_checkDefaultPageModificationDateConsistency.py b/bt5/erp5_web/SkinTemplateItem/portal_skins/erp5_web/WebSection_checkDefaultPageModificationDateConsistency.py
new file mode 100644
index 0000000000000000000000000000000000000000..7f2bcce4d4258b34b118d8450bf9e3fb1c1b1126
--- /dev/null
+++ b/bt5/erp5_web/SkinTemplateItem/portal_skins/erp5_web/WebSection_checkDefaultPageModificationDateConsistency.py
@@ -0,0 +1,31 @@
+from Products.ERP5Type.Message import translateString
+portal = context.getPortalObject()
+getDocumentValue = context.getDocumentValue
+error_list = []
+
+# Check that the web section is more recent that the default pages.
+if context.getAggregate():
+  max_content_modification_date = context.getModificationDate()
+  for default_page_reference in context.getAggregateReferenceList():
+    if default_page_reference:
+      for language in (None,) + context.getAvailableLanguageList():
+        default_page = getDocumentValue(
+            default_page_reference,
+            language=language,
+        )
+        if default_page is not None:
+          max_content_modification_date = max(
+              default_page.getModificationDate(),
+              max_content_modification_date,
+          )
+  if context.getModificationDate() < max_content_modification_date:
+    error_list.append(
+        "Web Section {} is older than default page".format(
+            context.getRelativeUrl()))
+    if fixit:
+      portal.portal_workflow.doActionFor(
+          context,
+          'edit_action',
+          comment=translateString('Edited Web Section, it was older than default page'))
+
+return error_list
diff --git a/bt5/erp5_web/SkinTemplateItem/portal_skins/erp5_web/WebSection_checkDefaultPageModificationDateConsistency.xml b/bt5/erp5_web/SkinTemplateItem/portal_skins/erp5_web/WebSection_checkDefaultPageModificationDateConsistency.xml
new file mode 100644
index 0000000000000000000000000000000000000000..acdb16633393682772a2111fae87bf5ac3dd2d04
--- /dev/null
+++ b/bt5/erp5_web/SkinTemplateItem/portal_skins/erp5_web/WebSection_checkDefaultPageModificationDateConsistency.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>fixit=False</string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>WebSection_checkDefaultPageModificationDateConsistency</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web/bt/template_portal_type_property_sheet_list b/bt5/erp5_web/bt/template_portal_type_property_sheet_list
index 0bb6c5f8a76ebffc810ce31a4156e2f80b514305..e18acb68e8dbb0c4c3e19fd39dcf4032db881bab 100644
--- a/bt5/erp5_web/bt/template_portal_type_property_sheet_list
+++ b/bt5/erp5_web/bt/template_portal_type_property_sheet_list
@@ -1,6 +1,10 @@
 Static Web Section | SortIndex
+Static Web Section | WebSectionUpgradeConstraint
+Static Web Site | WebSectionUpgradeConstraint
 Static Web Site | WebSitePreference
 Web Page | Reference
 Web Page | SortIndex
 Web Section | SortIndex
+Web Section | WebSectionUpgradeConstraint
+Web Site | WebSectionUpgradeConstraint
 Web Site | WebSitePreference
\ No newline at end of file
diff --git a/bt5/erp5_web/bt/template_property_sheet_id_list b/bt5/erp5_web/bt/template_property_sheet_id_list
new file mode 100644
index 0000000000000000000000000000000000000000..64294fe7870b62207e814b4d5c9af8996b3b9b4a
--- /dev/null
+++ b/bt5/erp5_web/bt/template_property_sheet_id_list
@@ -0,0 +1 @@
+WebSectionUpgradeConstraint
\ No newline at end of file
diff --git a/product/ERP5/tests/testERP5Web.py b/product/ERP5/tests/testERP5Web.py
index fd474eece4c54f7bd67a41a87a2628732747630a..746e9c73fa3fb8728f0443fd18eab6549ad33db1 100644
--- a/product/ERP5/tests/testERP5Web.py
+++ b/product/ERP5/tests/testERP5Web.py
@@ -29,7 +29,7 @@
 ##############################################################################
 
 import re
-import unittest
+import time
 from unittest import expectedFailure, skip
 from StringIO import StringIO
 from urllib import urlencode
@@ -2114,11 +2114,81 @@ class TestERP5WebCategoryPublicationWorkflow(ERP5TypeTestCase):
     self.assertEqual([], self.category.getParentValue().contentValues())
 
 
-def test_suite():
-  suite = unittest.TestSuite()
-  suite.addTest(unittest.makeSuite(TestERP5Web))
-  suite.addTest(unittest.makeSuite(TestERP5WebWithSimpleSecurity))
-  suite.addTest(unittest.makeSuite(TestERP5WebCategoryPublicationWorkflow))
-  suite.addTest(unittest.makeSuite(TestWebSiteTraversalHook))
-  suite.addTest(unittest.makeSuite(TestWebSectionTraversalHook))
-  return suite
+class ERP5WebUpgraderMixin(object):
+  """Test mixin that checks that web site or web sections are upgraded.
+
+  Subclasses must set `upgraded` attribute.
+  """
+  upgraded = None # type: erp5.portal_type.WebSection
+  def getBusinessTemplateList(self):
+    return ('erp5_base', 'erp5_web', )
+
+  def test_empty_constraint(self):
+    self.assertEqual(
+        [], [str(m.getMessage()) for m in self.upgraded.checkConsistency()])
+
+  def test_upgrader_fix_modification_date(self):
+    # Upgrader sets the modification date on the web section if
+    # it's older than its default page.
+    html_page = self.portal.web_page_module.newContent(
+        portal_type='Web Page',
+        reference=self.id(),
+    )
+    html_page.publish()
+    self.tic()
+
+    self.upgraded.edit(aggregate_value=html_page)
+    self.tic()
+    time.sleep(1)
+    html_page.edit(text_content="<p>Hello again</p>")
+    self.tic()
+    self.assertLess(
+        self.upgraded.getModificationDate(),
+        html_page.getModificationDate()
+        )
+    self.assertEqual(
+        ['Web Section {} is older than default page'.format(self.upgraded.getRelativeUrl())],
+        [str(m.getMessage()) for m in self.upgraded.checkConsistency()])
+    self.upgraded.fixConsistency()
+    self.tic()
+
+    self.assertEqual(
+        [], [str(m.getMessage()) for m in self.upgraded.checkConsistency()])
+    self.assertGreater(
+        self.upgraded.getModificationDate(),
+        html_page.getModificationDate())
+
+
+class TestERP5WebSiteUpgrader(ERP5WebUpgraderMixin, ERP5TypeTestCase):
+  def afterSetUp(self):
+    super(ERP5WebUpgraderMixin, self).afterSetUp()
+    self.upgraded = self.portal.web_site_module.newContent(
+        portal_type='Web Site',
+    )
+
+
+class TestERP5WebSectionUpgrader(ERP5WebUpgraderMixin, ERP5TypeTestCase):
+  def afterSetUp(self):
+    super(ERP5WebUpgraderMixin, self).afterSetUp()
+    self.upgraded = self.portal.web_site_module.newContent(
+        portal_type='Web Site',
+    ).newContent(
+        portal_type='Web Section',
+    )
+
+class TestERP5StaticWebSiteUpgrader(ERP5WebUpgraderMixin, ERP5TypeTestCase):
+  def afterSetUp(self):
+    super(ERP5WebUpgraderMixin, self).afterSetUp()
+    self.upgraded = self.portal.web_site_module.newContent(
+        portal_type='Static Web Site',
+    )
+
+
+class TestERP5StaticWebSectionUpgrader(ERP5WebUpgraderMixin, ERP5TypeTestCase):
+  def afterSetUp(self):
+    super(ERP5WebUpgraderMixin, self).afterSetUp()
+    self.upgraded = self.portal.web_site_module.newContent(
+        portal_type='Web Site',
+    ).newContent(
+        portal_type='Static Web Section',
+    )