rename rebaseline_server JSON constants to be more consistent
(no behavioral change, no change to JSON file format)

(SkipBuildbotRuns)
NOTREECHECKS=True
NOTRY=True
R=rmistry@google.com

Author: epoger@google.com

Review URL: https://codereview.chromium.org/287473002

git-svn-id: http://skia.googlecode.com/svn/trunk@14701 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/rebaseline_server/column.py b/gm/rebaseline_server/column.py
index 26597c3..07b075c 100644
--- a/gm/rebaseline_server/column.py
+++ b/gm/rebaseline_server/column.py
@@ -11,7 +11,6 @@
 
 # Keys used within dictionary representation of each column header.
 # NOTE: Keep these in sync with static/constants.js
-KEY__EXTRACOLUMNHEADERS = 'extraColumnHeaders'
 KEY__EXTRACOLUMNHEADERS__HEADER_TEXT = 'headerText'
 KEY__EXTRACOLUMNHEADERS__HEADER_URL = 'headerUrl'
 KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE = 'isFilterable'
diff --git a/gm/rebaseline_server/compare_configs.py b/gm/rebaseline_server/compare_configs.py
index e84de9a..aa26ba6 100755
--- a/gm/rebaseline_server/compare_configs.py
+++ b/gm/rebaseline_server/compare_configs.py
@@ -101,13 +101,13 @@
         diff_base_url=self._diff_base_url)
 
     all_image_pairs.ensure_extra_column_values_in_summary(
-        column_id=results.KEY__EXTRACOLUMN__RESULT_TYPE, values=[
+        column_id=results.KEY__EXTRACOLUMNS__RESULT_TYPE, values=[
             results.KEY__RESULT_TYPE__FAILED,
             results.KEY__RESULT_TYPE__NOCOMPARISON,
             results.KEY__RESULT_TYPE__SUCCEEDED,
         ])
     failing_image_pairs.ensure_extra_column_values_in_summary(
-        column_id=results.KEY__EXTRACOLUMN__RESULT_TYPE, values=[
+        column_id=results.KEY__EXTRACOLUMNS__RESULT_TYPE, values=[
             results.KEY__RESULT_TYPE__FAILED,
             results.KEY__RESULT_TYPE__NOCOMPARISON,
         ])
@@ -155,13 +155,13 @@
               result_type = results.KEY__RESULT_TYPE__FAILED
 
             extra_columns_dict = {
-                results.KEY__EXTRACOLUMN__RESULT_TYPE: result_type,
-                results.KEY__EXTRACOLUMN__BUILDER: builder,
-                results.KEY__EXTRACOLUMN__TEST: test,
+                results.KEY__EXTRACOLUMNS__RESULT_TYPE: result_type,
+                results.KEY__EXTRACOLUMNS__BUILDER: builder,
+                results.KEY__EXTRACOLUMNS__TEST: test,
                 # TODO(epoger): Right now, the client UI crashes if it receives
                 # results that do not include a 'config' column.
                 # Until we fix that, keep the client happy.
-                results.KEY__EXTRACOLUMN__CONFIG: 'TODO',
+                results.KEY__EXTRACOLUMNS__CONFIG: 'TODO',
             }
 
             try:
diff --git a/gm/rebaseline_server/compare_rendered_pictures.py b/gm/rebaseline_server/compare_rendered_pictures.py
index ba621c3..75a80d4 100755
--- a/gm/rebaseline_server/compare_rendered_pictures.py
+++ b/gm/rebaseline_server/compare_rendered_pictures.py
@@ -108,13 +108,13 @@
         diff_base_url=self._diff_base_url)
 
     all_image_pairs.ensure_extra_column_values_in_summary(
-        column_id=results.KEY__EXTRACOLUMN__RESULT_TYPE, values=[
+        column_id=results.KEY__EXTRACOLUMNS__RESULT_TYPE, values=[
             results.KEY__RESULT_TYPE__FAILED,
             results.KEY__RESULT_TYPE__NOCOMPARISON,
             results.KEY__RESULT_TYPE__SUCCEEDED,
         ])
     failing_image_pairs.ensure_extra_column_values_in_summary(
-        column_id=results.KEY__EXTRACOLUMN__RESULT_TYPE, values=[
+        column_id=results.KEY__EXTRACOLUMNS__RESULT_TYPE, values=[
             results.KEY__RESULT_TYPE__FAILED,
             results.KEY__RESULT_TYPE__NOCOMPARISON,
         ])
@@ -164,7 +164,7 @@
           if imagepair:
             all_image_pairs.add_image_pair(imagepair)
             result_type = imagepair.extra_columns_dict\
-                [results.KEY__EXTRACOLUMN__RESULT_TYPE]
+                [results.KEY__EXTRACOLUMNS__RESULT_TYPE]
             if result_type != results.KEY__RESULT_TYPE__SUCCEEDED:
               failing_image_pairs.add_image_pair(imagepair)
 
@@ -231,13 +231,13 @@
       result_type = results.KEY__RESULT_TYPE__FAILED
 
     extra_columns_dict = {
-        results.KEY__EXTRACOLUMN__CONFIG: config,
-        results.KEY__EXTRACOLUMN__RESULT_TYPE: result_type,
-        results.KEY__EXTRACOLUMN__TEST: test,
+        results.KEY__EXTRACOLUMNS__CONFIG: config,
+        results.KEY__EXTRACOLUMNS__RESULT_TYPE: result_type,
+        results.KEY__EXTRACOLUMNS__TEST: test,
         # TODO(epoger): Right now, the client UI crashes if it receives
         # results that do not include this column.
         # Until we fix that, keep the client happy.
-        results.KEY__EXTRACOLUMN__BUILDER: 'TODO',
+        results.KEY__EXTRACOLUMNS__BUILDER: 'TODO',
     }
 
     try:
diff --git a/gm/rebaseline_server/compare_to_expectations.py b/gm/rebaseline_server/compare_to_expectations.py
index cddca55..0f3c352 100755
--- a/gm/rebaseline_server/compare_to_expectations.py
+++ b/gm/rebaseline_server/compare_to_expectations.py
@@ -105,17 +105,17 @@
 
          [
            {
-             imagepair.KEY__EXPECTATIONS_DATA: {
+             imagepair.KEY__IMAGEPAIRS__EXPECTATIONS: {
                results.KEY__EXPECTATIONS__BUGS: [123, 456],
                results.KEY__EXPECTATIONS__IGNOREFAILURE: false,
                results.KEY__EXPECTATIONS__REVIEWED: true,
              },
-             imagepair.KEY__EXTRA_COLUMN_VALUES: {
-               results.KEY__EXTRACOLUMN__BUILDER: 'Test-Mac10.6-MacMini4.1-GeForce320M-x86-Debug',
-               results.KEY__EXTRACOLUMN__CONFIG: '8888',
-               results.KEY__EXTRACOLUMN__TEST: 'bigmatrix',
+             imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS: {
+               results.KEY__EXTRACOLUMNS__BUILDER: 'Test-Mac10.6-MacMini4.1-GeForce320M-x86-Debug',
+               results.KEY__EXTRACOLUMNS__CONFIG: '8888',
+               results.KEY__EXTRACOLUMNS__TEST: 'bigmatrix',
              },
-             results.KEY__NEW_IMAGE_URL: 'bitmap-64bitMD5/bigmatrix/10894408024079689926.png',
+             results.KEY__IMAGEPAIRS__IMAGE_B_URL: 'bitmap-64bitMD5/bigmatrix/10894408024079689926.png',
            },
            ...
          ]
@@ -125,23 +125,23 @@
         self._expected_root)
     for mod in modifications:
       image_name = results.IMAGE_FILENAME_FORMATTER % (
-          mod[imagepair.KEY__EXTRA_COLUMN_VALUES]
-             [results.KEY__EXTRACOLUMN__TEST],
-          mod[imagepair.KEY__EXTRA_COLUMN_VALUES]
-             [results.KEY__EXTRACOLUMN__CONFIG])
+          mod[imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS]
+             [results.KEY__EXTRACOLUMNS__TEST],
+          mod[imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS]
+             [results.KEY__EXTRACOLUMNS__CONFIG])
       _, hash_type, hash_digest = gm_json.SplitGmRelativeUrl(
-          mod[results.KEY__NEW_IMAGE_URL])
+          mod[imagepair.KEY__IMAGEPAIRS__IMAGE_B_URL])
       allowed_digests = [[hash_type, int(hash_digest)]]
       new_expectations = {
           gm_json.JSONKEY_EXPECTEDRESULTS_ALLOWEDDIGESTS: allowed_digests,
       }
       for field in EXPECTATION_FIELDS_PASSED_THRU_VERBATIM:
-        value = mod[imagepair.KEY__EXPECTATIONS_DATA].get(field)
+        value = mod[imagepair.KEY__IMAGEPAIRS__EXPECTATIONS].get(field)
         if value is not None:
           new_expectations[field] = value
       builder_dict = expected_builder_dicts[
-          mod[imagepair.KEY__EXTRA_COLUMN_VALUES]
-             [results.KEY__EXTRACOLUMN__BUILDER]]
+          mod[imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS]
+             [results.KEY__EXTRACOLUMNS__BUILDER]]
       builder_expectations = builder_dict.get(gm_json.JSONKEY_EXPECTEDRESULTS)
       if not builder_expectations:
         builder_expectations = {}
@@ -216,14 +216,14 @@
         diff_base_url=self._diff_base_url)
 
     all_image_pairs.ensure_extra_column_values_in_summary(
-        column_id=results.KEY__EXTRACOLUMN__RESULT_TYPE, values=[
+        column_id=results.KEY__EXTRACOLUMNS__RESULT_TYPE, values=[
             results.KEY__RESULT_TYPE__FAILED,
             results.KEY__RESULT_TYPE__FAILUREIGNORED,
             results.KEY__RESULT_TYPE__NOCOMPARISON,
             results.KEY__RESULT_TYPE__SUCCEEDED,
         ])
     failing_image_pairs.ensure_extra_column_values_in_summary(
-        column_id=results.KEY__EXTRACOLUMN__RESULT_TYPE, values=[
+        column_id=results.KEY__EXTRACOLUMNS__RESULT_TYPE, values=[
             results.KEY__RESULT_TYPE__FAILED,
             results.KEY__RESULT_TYPE__FAILUREIGNORED,
             results.KEY__RESULT_TYPE__NOCOMPARISON,
@@ -298,8 +298,8 @@
             # tools working in the meanwhile!
             if result_type != results.KEY__RESULT_TYPE__NOCOMPARISON:
               logging.warning('No expectations found for test: %s' % {
-                  results.KEY__EXTRACOLUMN__BUILDER: builder,
-                  results.KEY__EXTRACOLUMN__RESULT_TYPE: result_type,
+                  results.KEY__EXTRACOLUMNS__BUILDER: builder,
+                  results.KEY__EXTRACOLUMNS__RESULT_TYPE: result_type,
                   'image_name': image_name,
                   })
 
@@ -323,10 +323,10 @@
           else:
             updated_result_type = result_type
           extra_columns_dict = {
-              results.KEY__EXTRACOLUMN__RESULT_TYPE: updated_result_type,
-              results.KEY__EXTRACOLUMN__BUILDER: builder,
-              results.KEY__EXTRACOLUMN__TEST: test,
-              results.KEY__EXTRACOLUMN__CONFIG: config,
+              results.KEY__EXTRACOLUMNS__RESULT_TYPE: updated_result_type,
+              results.KEY__EXTRACOLUMNS__BUILDER: builder,
+              results.KEY__EXTRACOLUMNS__TEST: test,
+              results.KEY__EXTRACOLUMNS__CONFIG: config,
           }
           try:
             image_pair = imagepair.ImagePair(
diff --git a/gm/rebaseline_server/imagediffdb.py b/gm/rebaseline_server/imagediffdb.py
index 3b1eb3e..a37e8ce 100644
--- a/gm/rebaseline_server/imagediffdb.py
+++ b/gm/rebaseline_server/imagediffdb.py
@@ -45,11 +45,11 @@
 
 # Keys used within DiffRecord dictionary representations.
 # NOTE: Keep these in sync with static/constants.js
-KEY__DIFFERENCE_DATA__MAX_DIFF_PER_CHANNEL = 'maxDiffPerChannel'
-KEY__DIFFERENCE_DATA__NUM_DIFF_PIXELS = 'numDifferingPixels'
-KEY__DIFFERENCE_DATA__PERCENT_DIFF_PIXELS = 'percentDifferingPixels'
-KEY__DIFFERENCE_DATA__PERCEPTUAL_DIFF = 'perceptualDifference'
-KEY__DIFFERENCE_DATA__WEIGHTED_DIFF = 'weightedDiffMeasure'
+KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL = 'maxDiffPerChannel'
+KEY__DIFFERENCES__NUM_DIFF_PIXELS = 'numDifferingPixels'
+KEY__DIFFERENCES__PERCENT_DIFF_PIXELS = 'percentDifferingPixels'
+KEY__DIFFERENCES__PERCEPTUAL_DIFF = 'perceptualDifference'
+KEY__DIFFERENCES__WEIGHTED_DIFF = 'weightedDiffMeasure'
 
 
 class DiffRecord(object):
@@ -206,12 +206,12 @@
     """Returns a dictionary representation of this DiffRecord, as needed when
     constructing the JSON representation."""
     return {
-        KEY__DIFFERENCE_DATA__NUM_DIFF_PIXELS: self._num_pixels_differing,
-        KEY__DIFFERENCE_DATA__PERCENT_DIFF_PIXELS:
+        KEY__DIFFERENCES__NUM_DIFF_PIXELS: self._num_pixels_differing,
+        KEY__DIFFERENCES__PERCENT_DIFF_PIXELS:
             self.get_percent_pixels_differing(),
-        KEY__DIFFERENCE_DATA__WEIGHTED_DIFF: self.get_weighted_diff_measure(),
-        KEY__DIFFERENCE_DATA__MAX_DIFF_PER_CHANNEL: self._max_diff_per_channel,
-        KEY__DIFFERENCE_DATA__PERCEPTUAL_DIFF: self._perceptual_difference,
+        KEY__DIFFERENCES__WEIGHTED_DIFF: self.get_weighted_diff_measure(),
+        KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL: self._max_diff_per_channel,
+        KEY__DIFFERENCES__PERCEPTUAL_DIFF: self._perceptual_difference,
     }
 
 
diff --git a/gm/rebaseline_server/imagepair.py b/gm/rebaseline_server/imagepair.py
index 33385ab..446858d 100644
--- a/gm/rebaseline_server/imagepair.py
+++ b/gm/rebaseline_server/imagepair.py
@@ -11,14 +11,15 @@
 
 import posixpath
 
+
 # Keys used within ImagePair dictionary representations.
 # NOTE: Keep these in sync with static/constants.js
-KEY__DIFFERENCE_DATA = 'differenceData'
-KEY__EXPECTATIONS_DATA = 'expectations'
-KEY__EXTRA_COLUMN_VALUES = 'extraColumns'
-KEY__IMAGE_A_URL = 'imageAUrl'
-KEY__IMAGE_B_URL = 'imageBUrl'
-KEY__IS_DIFFERENT = 'isDifferent'
+KEY__IMAGEPAIRS__DIFFERENCES = 'differenceData'
+KEY__IMAGEPAIRS__EXPECTATIONS = 'expectations'
+KEY__IMAGEPAIRS__EXTRACOLUMNS = 'extraColumns'
+KEY__IMAGEPAIRS__IMAGE_A_URL = 'imageAUrl'
+KEY__IMAGEPAIRS__IMAGE_B_URL = 'imageBUrl'
+KEY__IMAGEPAIRS__IS_DIFFERENT = 'isDifferent'
 
 
 class ImagePair(object):
@@ -73,17 +74,17 @@
   def as_dict(self):
     """Returns a dictionary describing this ImagePair.
 
-    Uses the KEY__* constants as keys.
+    Uses the KEY__IMAGEPAIRS__* constants as keys.
     """
     asdict = {
-        KEY__IMAGE_A_URL: self.imageA_relative_url,
-        KEY__IMAGE_B_URL: self.imageB_relative_url,
+        KEY__IMAGEPAIRS__IMAGE_A_URL: self.imageA_relative_url,
+        KEY__IMAGEPAIRS__IMAGE_B_URL: self.imageB_relative_url,
     }
-    asdict[KEY__IS_DIFFERENT] = self._is_different
+    asdict[KEY__IMAGEPAIRS__IS_DIFFERENT] = self._is_different
     if self.expectations_dict:
-      asdict[KEY__EXPECTATIONS_DATA] = self.expectations_dict
+      asdict[KEY__IMAGEPAIRS__EXPECTATIONS] = self.expectations_dict
     if self.extra_columns_dict:
-      asdict[KEY__EXTRA_COLUMN_VALUES] = self.extra_columns_dict
+      asdict[KEY__IMAGEPAIRS__EXTRACOLUMNS] = self.extra_columns_dict
     if self.diff_record and (self.diff_record.get_num_pixels_differing() > 0):
-      asdict[KEY__DIFFERENCE_DATA] = self.diff_record.as_dict()
+      asdict[KEY__IMAGEPAIRS__DIFFERENCES] = self.diff_record.as_dict()
     return asdict
diff --git a/gm/rebaseline_server/imagepairset.py b/gm/rebaseline_server/imagepairset.py
index 8809877..25d46a9 100644
--- a/gm/rebaseline_server/imagepairset.py
+++ b/gm/rebaseline_server/imagepairset.py
@@ -14,11 +14,14 @@
 
 # Local imports
 import column
+import imagepair
 
 # Keys used within dictionary representation of ImagePairSet.
 # NOTE: Keep these in sync with static/constants.js
-KEY__IMAGEPAIRS = 'imagePairs'
-KEY__IMAGESETS = 'imageSets'
+KEY__ROOT__EXTRACOLUMNHEADERS = 'extraColumnHeaders'
+KEY__ROOT__HEADER = 'header'
+KEY__ROOT__IMAGEPAIRS = 'imagePairs'
+KEY__ROOT__IMAGESETS = 'imageSets'
 KEY__IMAGESETS__FIELD__BASE_URL = 'baseUrl'
 KEY__IMAGESETS__FIELD__DESCRIPTION = 'description'
 KEY__IMAGESETS__SET__DIFFS = 'diffs'
@@ -140,9 +143,9 @@
     key_description = KEY__IMAGESETS__FIELD__DESCRIPTION
     key_base_url = KEY__IMAGESETS__FIELD__BASE_URL
     return {
-        column.KEY__EXTRACOLUMNHEADERS: self._column_headers_as_dict(),
-        KEY__IMAGEPAIRS: self._image_pair_dicts,
-        KEY__IMAGESETS: {
+        KEY__ROOT__EXTRACOLUMNHEADERS: self._column_headers_as_dict(),
+        KEY__ROOT__IMAGEPAIRS: self._image_pair_dicts,
+        KEY__ROOT__IMAGESETS: {
             KEY__IMAGESETS__SET__IMAGE_A: {
                 key_description: self._descriptions[0],
                 key_base_url: self._image_base_url,
diff --git a/gm/rebaseline_server/imagepairset_test.py b/gm/rebaseline_server/imagepairset_test.py
index d7aeb64..b5d6206 100755
--- a/gm/rebaseline_server/imagepairset_test.py
+++ b/gm/rebaseline_server/imagepairset_test.py
@@ -22,47 +22,47 @@
 BASE_URL_2 = 'http://base/url/2'
 DIFF_BASE_URL = 'http://diff/base/url'
 IMAGEPAIR_1_AS_DICT = {
-    imagepair.KEY__EXTRA_COLUMN_VALUES: {
+    imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS: {
         'builder': 'MyBuilder',
         'test': 'test1',
     },
-    imagepair.KEY__IMAGE_A_URL: 'test1/1111.png',
-    imagepair.KEY__IMAGE_B_URL: 'test1/1111.png',
-    imagepair.KEY__IS_DIFFERENT: False,
+    imagepair.KEY__IMAGEPAIRS__IMAGE_A_URL: 'test1/1111.png',
+    imagepair.KEY__IMAGEPAIRS__IMAGE_B_URL: 'test1/1111.png',
+    imagepair.KEY__IMAGEPAIRS__IS_DIFFERENT: False,
 }
 IMAGEPAIR_2_AS_DICT = {
-    imagepair.KEY__DIFFERENCE_DATA: {
+    imagepair.KEY__IMAGEPAIRS__DIFFERENCES: {
         'maxDiffPerChannel': [1, 2, 3],
         'numDifferingPixels': 111,
         'percentDifferingPixels': 22.222,
         'weightedDiffMeasure': 33.333,
     },
-    imagepair.KEY__EXTRA_COLUMN_VALUES: {
+    imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS: {
         'builder': 'MyBuilder',
         'test': 'test2',
     },
-    imagepair.KEY__IMAGE_A_URL: 'test2/2222.png',
-    imagepair.KEY__IMAGE_B_URL: 'test2/22223.png',
-    imagepair.KEY__IS_DIFFERENT: True,
+    imagepair.KEY__IMAGEPAIRS__IMAGE_A_URL: 'test2/2222.png',
+    imagepair.KEY__IMAGEPAIRS__IMAGE_B_URL: 'test2/22223.png',
+    imagepair.KEY__IMAGEPAIRS__IS_DIFFERENT: True,
 }
 IMAGEPAIR_3_AS_DICT = {
-    imagepair.KEY__DIFFERENCE_DATA: {
+    imagepair.KEY__IMAGEPAIRS__DIFFERENCES: {
         'maxDiffPerChannel': [4, 5, 6],
         'numDifferingPixels': 111,
         'percentDifferingPixels': 44.444,
         'weightedDiffMeasure': 33.333,
     },
-    imagepair.KEY__EXPECTATIONS_DATA: {
+    imagepair.KEY__IMAGEPAIRS__EXPECTATIONS: {
         'bugs': [1001, 1002],
         'ignoreFailure': True,
     },
-    imagepair.KEY__EXTRA_COLUMN_VALUES: {
+    imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS: {
         'builder': 'MyBuilder',
         'test': 'test3',
     },
-    imagepair.KEY__IMAGE_A_URL: 'test3/3333.png',
-    imagepair.KEY__IMAGE_B_URL: 'test3/33334.png',
-    imagepair.KEY__IS_DIFFERENT: True,
+    imagepair.KEY__IMAGEPAIRS__IMAGE_A_URL: 'test3/3333.png',
+    imagepair.KEY__IMAGEPAIRS__IMAGE_B_URL: 'test3/33334.png',
+    imagepair.KEY__IMAGEPAIRS__IS_DIFFERENT: True,
 }
 SET_A_DESCRIPTION = 'expectations'
 SET_B_DESCRIPTION = 'actuals'
@@ -166,7 +166,7 @@
     """
     self.base_url = base_url
     self.extra_columns_dict = dict_to_return.get(
-        imagepair.KEY__EXTRA_COLUMN_VALUES, None)
+        imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS, None)
     self._dict_to_return = dict_to_return
 
   def as_dict(self):
diff --git a/gm/rebaseline_server/results.py b/gm/rebaseline_server/results.py
index 254b0a3..45ab133 100755
--- a/gm/rebaseline_server/results.py
+++ b/gm/rebaseline_server/results.py
@@ -31,15 +31,14 @@
 
 # Keys used to link an image to a particular GM test.
 # NOTE: Keep these in sync with static/constants.js
-REBASELINE_SERVER_SCHEMA_VERSION_NUMBER = 3
+VALUE__HEADER__SCHEMA_VERSION = 3
 KEY__EXPECTATIONS__BUGS = gm_json.JSONKEY_EXPECTEDRESULTS_BUGS
 KEY__EXPECTATIONS__IGNOREFAILURE = gm_json.JSONKEY_EXPECTEDRESULTS_IGNOREFAILURE
 KEY__EXPECTATIONS__REVIEWED = gm_json.JSONKEY_EXPECTEDRESULTS_REVIEWED
-KEY__EXTRACOLUMN__BUILDER = 'builder'
-KEY__EXTRACOLUMN__CONFIG = 'config'
-KEY__EXTRACOLUMN__RESULT_TYPE = 'resultType'
-KEY__EXTRACOLUMN__TEST = 'test'
-KEY__HEADER = 'header'
+KEY__EXTRACOLUMNS__BUILDER = 'builder'
+KEY__EXTRACOLUMNS__CONFIG = 'config'
+KEY__EXTRACOLUMNS__RESULT_TYPE = 'resultType'
+KEY__EXTRACOLUMNS__TEST = 'test'
 KEY__HEADER__DATAHASH = 'dataHash'
 KEY__HEADER__IS_EDITABLE = 'isEditable'
 KEY__HEADER__IS_EXPORTED = 'isExported'
@@ -50,7 +49,6 @@
 KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE = 'timeNextUpdateAvailable'
 KEY__HEADER__TIME_UPDATED = 'timeUpdated'
 KEY__HEADER__TYPE = 'type'
-KEY__NEW_IMAGE_URL = 'newImageUrl'
 KEY__RESULT_TYPE__FAILED = gm_json.JSONKEY_ACTUALRESULTS_FAILED
 KEY__RESULT_TYPE__FAILUREIGNORED = gm_json.JSONKEY_ACTUALRESULTS_FAILUREIGNORED
 KEY__RESULT_TYPE__NOCOMPARISON = gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON
@@ -103,9 +101,9 @@
     """
     response_dict = self._results[results_type]
     time_updated = self.get_timestamp()
-    response_dict[KEY__HEADER] = {
+    response_dict[imagepairset.KEY__ROOT__HEADER] = {
         KEY__HEADER__SCHEMA_VERSION: (
-            REBASELINE_SERVER_SCHEMA_VERSION_NUMBER),
+            VALUE__HEADER__SCHEMA_VERSION),
 
         # Timestamps:
         # 1. when this data was last updated
@@ -120,7 +118,7 @@
         # Hash of dataset, which the client must return with any edits--
         # this ensures that the edits were made to a particular dataset.
         KEY__HEADER__DATAHASH: str(hash(repr(
-            response_dict[imagepairset.KEY__IMAGEPAIRS]))),
+            response_dict[imagepairset.KEY__ROOT__IMAGEPAIRS]))),
 
         # Whether the server will accept edits back.
         KEY__HEADER__IS_EDITABLE: is_editable,
diff --git a/gm/rebaseline_server/server.py b/gm/rebaseline_server/server.py
index 73cfbef..40874d6 100755
--- a/gm/rebaseline_server/server.py
+++ b/gm/rebaseline_server/server.py
@@ -454,9 +454,9 @@
     else:
       now = int(time.time())
       response_dict = {
-          results_mod.KEY__HEADER: {
+          imagepairset.KEY__ROOT__HEADER: {
               results_mod.KEY__HEADER__SCHEMA_VERSION: (
-                  results_mod.REBASELINE_SERVER_SCHEMA_VERSION_NUMBER),
+                  results_mod.VALUE__HEADER__SCHEMA_VERSION),
               results_mod.KEY__HEADER__IS_STILL_LOADING: True,
               results_mod.KEY__HEADER__TIME_UPDATED: now,
               results_mod.KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE: (
@@ -549,7 +549,8 @@
     with _SERVER.results_rlock:
       oldResultsType = data[KEY__EDITS__OLD_RESULTS_TYPE]
       oldResults = _SERVER.results.get_results_of_type(oldResultsType)
-      oldResultsHash = str(hash(repr(oldResults[imagepairset.KEY__IMAGEPAIRS])))
+      oldResultsHash = str(hash(repr(
+          oldResults[imagepairset.KEY__ROOT__IMAGEPAIRS])))
       if oldResultsHash != data[KEY__EDITS__OLD_RESULTS_HASH]:
         raise Exception('results of type "%s" changed while the client was '
                         'making modifications. The client should reload the '
diff --git a/gm/rebaseline_server/static/constants.js b/gm/rebaseline_server/static/constants.js
index 55dddbf..ecca98e 100644
--- a/gm/rebaseline_server/static/constants.js
+++ b/gm/rebaseline_server/static/constants.js
@@ -9,7 +9,6 @@
 module.constant('constants', (function() {
   return {
     // NOTE: Keep these in sync with ../column.py
-    KEY__EXTRACOLUMNHEADERS: 'extraColumnHeaders',
     KEY__EXTRACOLUMNHEADERS__HEADER_TEXT: 'headerText',
     KEY__EXTRACOLUMNHEADERS__HEADER_URL: 'headerUrl',
     KEY__EXTRACOLUMNHEADERS__IS_FILTERABLE: 'isFilterable',
@@ -17,23 +16,26 @@
     KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS: 'valuesAndCounts',
 
     // NOTE: Keep these in sync with ../imagediffdb.py
-    KEY__DIFFERENCE_DATA__MAX_DIFF_PER_CHANNEL: 'maxDiffPerChannel',
-    KEY__DIFFERENCE_DATA__NUM_DIFF_PIXELS: 'numDifferingPixels',
-    KEY__DIFFERENCE_DATA__PERCENT_DIFF_PIXELS: 'percentDifferingPixels',
-    KEY__DIFFERENCE_DATA__PERCEPTUAL_DIFF: 'perceptualDifference',
-    KEY__DIFFERENCE_DATA__WEIGHTED_DIFF: 'weightedDiffMeasure',
+    KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL: 'maxDiffPerChannel',
+    KEY__DIFFERENCES__NUM_DIFF_PIXELS: 'numDifferingPixels',
+    KEY__DIFFERENCES__PERCENT_DIFF_PIXELS: 'percentDifferingPixels',
+    KEY__DIFFERENCES__PERCEPTUAL_DIFF: 'perceptualDifference',
+    KEY__DIFFERENCES__WEIGHTED_DIFF: 'weightedDiffMeasure',
 
     // NOTE: Keep these in sync with ../imagepair.py
-    KEY__DIFFERENCE_DATA: 'differenceData',
-    KEY__EXPECTATIONS_DATA: 'expectations',
-    KEY__EXTRA_COLUMN_VALUES: 'extraColumns',
-    KEY__IMAGE_A_URL: 'imageAUrl',
-    KEY__IMAGE_B_URL: 'imageBUrl',
-    KEY__IS_DIFFERENT: 'isDifferent',
+    KEY__IMAGEPAIRS__DIFFERENCES: 'differenceData',
+    KEY__IMAGEPAIRS__EXPECTATIONS: 'expectations',
+    KEY__IMAGEPAIRS__EXTRACOLUMNS: 'extraColumns',
+    KEY__IMAGEPAIRS__IMAGE_A_URL: 'imageAUrl',
+    KEY__IMAGEPAIRS__IMAGE_B_URL: 'imageBUrl',
+    KEY__IMAGEPAIRS__IS_DIFFERENT: 'isDifferent',
 
     // NOTE: Keep these in sync with ../imagepairset.py
-    KEY__IMAGEPAIRS: 'imagePairs',
-    KEY__IMAGESETS: 'imageSets',
+    KEY__ROOT__EXTRACOLUMNHEADERS: 'extraColumnHeaders',
+    KEY__ROOT__HEADER: 'header',
+    KEY__ROOT__IMAGEPAIRS: 'imagePairs',
+    KEY__ROOT__IMAGESETS: 'imageSets',
+    //
     KEY__IMAGESETS__FIELD__BASE_URL: 'baseUrl',
     KEY__IMAGESETS__FIELD__DESCRIPTION: 'description',
     KEY__IMAGESETS__SET__DIFFS: 'diffs',
@@ -42,15 +44,15 @@
     KEY__IMAGESETS__SET__WHITEDIFFS: 'whiteDiffs',
 
     // NOTE: Keep these in sync with ../results.py
-    REBASELINE_SERVER_SCHEMA_VERSION_NUMBER: 3,
     KEY__EXPECTATIONS__BUGS: 'bugs',
     KEY__EXPECTATIONS__IGNOREFAILURE: 'ignore-failure',
     KEY__EXPECTATIONS__REVIEWED: 'reviewed-by-human',
-    KEY__EXTRACOLUMN__BUILDER: 'builder',
-    KEY__EXTRACOLUMN__CONFIG: 'config',
-    KEY__EXTRACOLUMN__RESULT_TYPE: 'resultType',
-    KEY__EXTRACOLUMN__TEST: 'test',
-    KEY__HEADER: 'header',
+    //
+    KEY__EXTRACOLUMNS__BUILDER: 'builder',
+    KEY__EXTRACOLUMNS__CONFIG: 'config',
+    KEY__EXTRACOLUMNS__RESULT_TYPE: 'resultType',
+    KEY__EXTRACOLUMNS__TEST: 'test',
+    //
     KEY__HEADER__DATAHASH: 'dataHash',
     KEY__HEADER__IS_EDITABLE: 'isEditable',
     KEY__HEADER__IS_EXPORTED: 'isExported',
@@ -61,7 +63,8 @@
     KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE: 'timeNextUpdateAvailable',
     KEY__HEADER__TIME_UPDATED: 'timeUpdated',
     KEY__HEADER__TYPE: 'type',
-    KEY__NEW_IMAGE_URL: 'newImageUrl',
+    VALUE__HEADER__SCHEMA_VERSION: 3,
+    //
     KEY__RESULT_TYPE__FAILED: 'failed',
     KEY__RESULT_TYPE__FAILUREIGNORED: 'failure-ignored',
     KEY__RESULT_TYPE__NOCOMPARISON: 'no-comparison',
diff --git a/gm/rebaseline_server/static/loader.js b/gm/rebaseline_server/static/loader.js
index f5a4f7b..e05f1c8 100644
--- a/gm/rebaseline_server/static/loader.js
+++ b/gm/rebaseline_server/static/loader.js
@@ -35,17 +35,17 @@
       var filteredImagePairs = [];
       for (var i = 0; i < unfilteredImagePairs.length; i++) {
         var imagePair = unfilteredImagePairs[i];
-        var extraColumnValues = imagePair[constants.KEY__EXTRA_COLUMN_VALUES];
+        var extraColumnValues = imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS];
         // For performance, we examine the "set" objects directly rather
         // than calling $scope.isValueInSet().
         // Besides, I don't think we have access to $scope in here...
         if (!(true == hiddenResultTypes[extraColumnValues[
-                  constants.KEY__EXTRACOLUMN__RESULT_TYPE]]) &&
+                  constants.KEY__EXTRACOLUMNS__RESULT_TYPE]]) &&
             !(true == hiddenConfigs[extraColumnValues[
-                  constants.KEY__EXTRACOLUMN__CONFIG]]) &&
-            !(-1 == extraColumnValues[constants.KEY__EXTRACOLUMN__BUILDER]
+                  constants.KEY__EXTRACOLUMNS__CONFIG]]) &&
+            !(-1 == extraColumnValues[constants.KEY__EXTRACOLUMNS__BUILDER]
                     .indexOf(builderSubstring)) &&
-            !(-1 == extraColumnValues[constants.KEY__EXTRACOLUMN__TEST]
+            !(-1 == extraColumnValues[constants.KEY__EXTRACOLUMNS__TEST]
                     .indexOf(testSubstring)) &&
             (viewingTab == imagePair.tab)) {
           filteredImagePairs.push(imagePair);
@@ -72,13 +72,13 @@
      */
     $http.get($scope.resultsToLoad).success(
       function(data, status, header, config) {
-        var dataHeader = data[constants.KEY__HEADER];
+        var dataHeader = data[constants.KEY__ROOT__HEADER];
         if (dataHeader[constants.KEY__HEADER__SCHEMA_VERSION] !=
-            constants.REBASELINE_SERVER_SCHEMA_VERSION_NUMBER) {
+            constants.VALUE__HEADER__SCHEMA_VERSION) {
           $scope.loadingMessage = "ERROR: Got JSON file with schema version "
               + dataHeader[constants.KEY__HEADER__SCHEMA_VERSION]
               + " but expected schema version "
-              + constants.REBASELINE_SERVER_SCHEMA_VERSION_NUMBER;
+              + constants.VALUE__HEADER__SCHEMA_VERSION;
         } else if (dataHeader[constants.KEY__HEADER__IS_STILL_LOADING]) {
           // Apply the server's requested reload delay to local time,
           // so we will wait the right number of seconds regardless of clock
@@ -98,11 +98,11 @@
           $scope.loadingMessage = "processing data, please wait...";
 
           $scope.header = dataHeader;
-          $scope.extraColumnHeaders = data[constants.KEY__EXTRACOLUMNHEADERS];
-          $scope.imagePairs = data[constants.KEY__IMAGEPAIRS];
-          $scope.imageSets = data[constants.KEY__IMAGESETS];
-          $scope.sortColumnSubdict = constants.KEY__DIFFERENCE_DATA;
-          $scope.sortColumnKey = constants.KEY__DIFFERENCE_DATA__PERCEPTUAL_DIFF;
+          $scope.extraColumnHeaders = data[constants.KEY__ROOT__EXTRACOLUMNHEADERS];
+          $scope.imagePairs = data[constants.KEY__ROOT__IMAGEPAIRS];
+          $scope.imageSets = data[constants.KEY__ROOT__IMAGESETS];
+          $scope.sortColumnSubdict = constants.KEY__IMAGEPAIRS__DIFFERENCES;
+          $scope.sortColumnKey = constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF;
 
           $scope.showSubmitAdvancedSettings = false;
           $scope.submitAdvancedSettings = {};
@@ -149,12 +149,12 @@
           $scope.hiddenResultTypes[
               constants.KEY__RESULT_TYPE__SUCCEEDED] = true;
           $scope.allResultTypes = $scope.columnSliceOf2DArray(
-              $scope.extraColumnHeaders[constants.KEY__EXTRACOLUMN__RESULT_TYPE]
+              $scope.extraColumnHeaders[constants.KEY__EXTRACOLUMNS__RESULT_TYPE]
                                        [constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS],
               0);
           $scope.hiddenConfigs = {};
           $scope.allConfigs = $scope.columnSliceOf2DArray(
-              $scope.extraColumnHeaders[constants.KEY__EXTRACOLUMN__CONFIG]
+              $scope.extraColumnHeaders[constants.KEY__EXTRACOLUMNS__CONFIG]
                                        [constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS],
               0);
 
@@ -342,9 +342,9 @@
       'hiddenResultTypes': $scope.queryParameters.copiers.set,
       'hiddenConfigs':     $scope.queryParameters.copiers.set,
     };
-    $scope.queryParameters.map[constants.KEY__EXTRACOLUMN__BUILDER] =
+    $scope.queryParameters.map[constants.KEY__EXTRACOLUMNS__BUILDER] =
         $scope.queryParameters.copiers.categoryValueMatch;
-    $scope.queryParameters.map[constants.KEY__EXTRACOLUMN__TEST] =
+    $scope.queryParameters.map[constants.KEY__EXTRACOLUMNS__TEST] =
         $scope.queryParameters.copiers.categoryValueMatch;
 
     // Loads all parameters into $scope from the URL query string;
@@ -411,9 +411,9 @@
         // there are certain columns we want to sort in a different order.
         var doReverse = (
             ($scope.sortColumnKey ==
-             constants.KEY__DIFFERENCE_DATA__PERCENT_DIFF_PIXELS) ||
+             constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS) ||
             ($scope.sortColumnKey ==
-             constants.KEY__DIFFERENCE_DATA__PERCEPTUAL_DIFF));
+             constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF));
 
         $scope.filteredImagePairs =
             $filter("orderBy")(
@@ -457,9 +457,8 @@
     /**
      * Re-sort the displayed results.
      *
-     * @param subdict (string): which subdictionary
-     *     (constants.KEY__DIFFERENCE_DATA, constants.KEY__EXPECTATIONS_DATA,
-     *      constants.KEY__EXTRA_COLUMN_VALUES) the sort column key is within
+     * @param subdict (string): which KEY__IMAGEPAIRS__* subdictionary
+     *     the sort column key is within
      * @param key (string): sort by value associated with this key in subdict
      */
     $scope.sortResultsBy = function(subdict, key) {
@@ -577,33 +576,34 @@
       for (var i = 0; i < imagePairsSubset.length; i++) {
         var imagePair = imagePairsSubset[i];
         var updatedExpectation = {};
-        updatedExpectation[constants.KEY__EXPECTATIONS_DATA] =
-            imagePair[constants.KEY__EXPECTATIONS_DATA];
-        updatedExpectation[constants.KEY__EXTRA_COLUMN_VALUES] =
-            imagePair[constants.KEY__EXTRA_COLUMN_VALUES];
-        updatedExpectation[constants.KEY__NEW_IMAGE_URL] =
-            imagePair[constants.KEY__IMAGE_B_URL];
-        if (0 == updatedExpectation[constants.KEY__EXTRA_COLUMN_VALUES]
-                                   [constants.KEY__EXTRACOLUMN__CONFIG]
+        updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS] =
+            imagePair[constants.KEY__IMAGEPAIRS__EXPECTATIONS];
+        updatedExpectation[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS] =
+            imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS];
+        // IMAGE_B_URL contains the actual image (which is now the expectation)
+        updatedExpectation[constants.KEY__IMAGEPAIRS__IMAGE_B_URL] =
+            imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
+        if (0 == updatedExpectation[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS]
+                                   [constants.KEY__EXTRACOLUMNS__CONFIG]
                                    .indexOf('comparison-')) {
           encounteredComparisonConfig = true;
         }
 
         // Advanced settings...
-        if (null == updatedExpectation[constants.KEY__EXPECTATIONS_DATA]) {
-          updatedExpectation[constants.KEY__EXPECTATIONS_DATA] = {};
+        if (null == updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS]) {
+          updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS] = {};
         }
-        updatedExpectation[constants.KEY__EXPECTATIONS_DATA]
+        updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS]
                           [constants.KEY__EXPECTATIONS__REVIEWED] =
             $scope.submitAdvancedSettings[
                 constants.KEY__EXPECTATIONS__REVIEWED];
         if (true == $scope.submitAdvancedSettings[
             constants.KEY__EXPECTATIONS__IGNOREFAILURE]) {
           // if it's false, don't send it at all (just keep the default)
-          updatedExpectation[constants.KEY__EXPECTATIONS_DATA]
+          updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS]
                             [constants.KEY__EXPECTATIONS__IGNOREFAILURE] = true;
         }
-        updatedExpectation[constants.KEY__EXPECTATIONS_DATA]
+        updatedExpectation[constants.KEY__IMAGEPAIRS__EXPECTATIONS]
                           [constants.KEY__EXPECTATIONS__BUGS] = bugs;
 
         updatedExpectations.push(updatedExpectation);
@@ -827,8 +827,8 @@
      */
     $scope.getImageDiffRelativeUrl = function(imagePair) {
       var before =
-          imagePair[constants.KEY__IMAGE_A_URL] + "-vs-" +
-          imagePair[constants.KEY__IMAGE_B_URL];
+          imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" +
+          imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
       return before.replace(/[^\w\-]/g, "_") + ".png";
     }
 
diff --git a/gm/rebaseline_server/static/view.html b/gm/rebaseline_server/static/view.html
index b2f3fba..5ded697 100644
--- a/gm/rebaseline_server/static/view.html
+++ b/gm/rebaseline_server/static/view.html
@@ -68,7 +68,7 @@
     <tr valign="top">
       <td>
         resultType<br>
-        <label ng-repeat="valueAndCount in extraColumnHeaders[constants.KEY__EXTRACOLUMN__RESULT_TYPE][constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS]">
+        <label ng-repeat="valueAndCount in extraColumnHeaders[constants.KEY__EXTRACOLUMNS__RESULT_TYPE][constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS]">
           <input type="checkbox"
                  name="resultTypes"
                  value="{{valueAndCount[0]}}"
@@ -86,7 +86,7 @@
           toggle
         </button>
       </td>
-      <td ng-repeat="category in [constants.KEY__EXTRACOLUMN__BUILDER, constants.KEY__EXTRACOLUMN__TEST]">
+      <td ng-repeat="category in [constants.KEY__EXTRACOLUMNS__BUILDER, constants.KEY__EXTRACOLUMNS__TEST]">
         {{category}}
         <br>
         <input type="text"
@@ -100,7 +100,7 @@
       </td>
       <td>
         config<br>
-        <label ng-repeat="valueAndCount in extraColumnHeaders[constants.KEY__EXTRACOLUMN__CONFIG][constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS]">
+        <label ng-repeat="valueAndCount in extraColumnHeaders[constants.KEY__EXTRACOLUMNS__CONFIG][constants.KEY__EXTRACOLUMNHEADERS__VALUES_AND_COUNTS]">
           <input type="checkbox"
                  name="configs"
                  value="{{valueAndCount[0]}}"
@@ -230,12 +230,12 @@
       <table border="1" ng-app="diff_viewer"> <!-- results -->
         <tr>
           <!-- Most column headers are displayed in a common fashion... -->
-          <th ng-repeat="categoryName in [constants.KEY__EXTRACOLUMN__RESULT_TYPE, constants.KEY__EXTRACOLUMN__BUILDER, constants.KEY__EXTRACOLUMN__TEST, constants.KEY__EXTRACOLUMN__CONFIG]">
+          <th ng-repeat="categoryName in [constants.KEY__EXTRACOLUMNS__RESULT_TYPE, constants.KEY__EXTRACOLUMNS__BUILDER, constants.KEY__EXTRACOLUMNS__TEST, constants.KEY__EXTRACOLUMNS__CONFIG]">
             <input type="radio"
                    name="sortColumnRadio"
                    value="{{categoryName}}"
                    ng-checked="(sortColumnKey == categoryName)"
-                   ng-click="sortResultsBy(constants.KEY__EXTRA_COLUMN_VALUES, categoryName)">
+                   ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXTRACOLUMNS, categoryName)">
             {{categoryName}}
           </th>
           <!-- ... but there are a few columns where we display things differently. -->
@@ -244,7 +244,7 @@
                    name="sortColumnRadio"
                    value="bugs"
                    ng-checked="(sortColumnKey == constants.KEY__EXPECTATIONS__BUGS)"
-                   ng-click="sortResultsBy(constants.KEY__EXPECTATIONS_DATA, constants.KEY__EXPECTATIONS__BUGS)">
+                   ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXPECTATIONS, constants.KEY__EXPECTATIONS__BUGS)">
             bugs
           </th>
           <th width="{{imageSize}}">
@@ -257,16 +257,16 @@
             <input type="radio"
                    name="sortColumnRadio"
                    value="percentDifferingPixels"
-                   ng-checked="(sortColumnKey == constants.KEY__DIFFERENCE_DATA__PERCENT_DIFF_PIXELS)"
-                   ng-click="sortResultsBy(constants.KEY__DIFFERENCE_DATA, constants.KEY__DIFFERENCE_DATA__PERCENT_DIFF_PIXELS)">
+                   ng-checked="(sortColumnKey == constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)"
+                   ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)">
             differing pixels in white
           </th>
           <th width="{{imageSize}}">
             <input type="radio"
                    name="sortColumnRadio"
                    value="weightedDiffMeasure"
-                   ng-checked="(sortColumnKey == constants.KEY__DIFFERENCE_DATA__PERCEPTUAL_DIFF)"
-                   ng-click="sortResultsBy(constants.KEY__DIFFERENCE_DATA, constants.KEY__DIFFERENCE_DATA__PERCEPTUAL_DIFF)">
+                   ng-checked="(sortColumnKey == constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)"
+                   ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)">
             perceptual difference
             <br>
             <input type="range" ng-model="pixelDiffBgColorBrightness"
@@ -282,12 +282,12 @@
 
         <tr ng-repeat="imagePair in limitedImagePairs" results-updated-callback-directive>
           <td>
-            {{imagePair[constants.KEY__EXTRA_COLUMN_VALUES][constants.KEY__EXTRACOLUMN__RESULT_TYPE]}}
+            {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][constants.KEY__EXTRACOLUMNS__RESULT_TYPE]}}
             <br>
             <button class="show-only-button"
                     ng-show="viewingTab == defaultTab"
-                    ng-click="showOnlyResultType(imagePair[constants.KEY__EXTRA_COLUMN_VALUES][constants.KEY__EXTRACOLUMN__RESULT_TYPE])"
-                    title="show only results of type {{imagePair[constants.KEY__EXTRA_COLUMN_VALUES][constants.KEY__EXTRACOLUMN__RESULT_TYPE]}}">
+                    ng-click="showOnlyResultType(imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][constants.KEY__EXTRACOLUMNS__RESULT_TYPE])"
+                    title="show only results of type {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][constants.KEY__EXTRACOLUMNS__RESULT_TYPE]}}">
               show only
             </button>
             <br>
@@ -299,14 +299,14 @@
               show all
             </button>
           </td>
-          <td ng-repeat="categoryName in [constants.KEY__EXTRACOLUMN__BUILDER, constants.KEY__EXTRACOLUMN__TEST]">
-            {{imagePair[constants.KEY__EXTRA_COLUMN_VALUES][categoryName]}}
+          <td ng-repeat="categoryName in [constants.KEY__EXTRACOLUMNS__BUILDER, constants.KEY__EXTRACOLUMNS__TEST]">
+            {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][categoryName]}}
             <br>
             <button class="show-only-button"
                     ng-show="viewingTab == defaultTab"
-                    ng-disabled="imagePair[constants.KEY__EXTRA_COLUMN_VALUES][categoryName] == categoryValueMatch[categoryName]"
-                    ng-click="setCategoryValueMatch(categoryName, imagePair[constants.KEY__EXTRA_COLUMN_VALUES][categoryName])"
-                    title="show only results of {{categoryName}} {{imagePair[constants.KEY__EXTRA_COLUMN_VALUES][categoryName]}}">
+                    ng-disabled="imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][categoryName] == categoryValueMatch[categoryName]"
+                    ng-click="setCategoryValueMatch(categoryName, imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][categoryName])"
+                    title="show only results of {{categoryName}} {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][categoryName]}}">
               show only
             </button>
             <br>
@@ -319,12 +319,12 @@
             </button>
           </td>
           <td>
-            {{imagePair[constants.KEY__EXTRA_COLUMN_VALUES][constants.KEY__EXTRACOLUMN__CONFIG]}}
+            {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][constants.KEY__EXTRACOLUMNS__CONFIG]}}
             <br>
             <button class="show-only-button"
                     ng-show="viewingTab == defaultTab"
-                    ng-click="showOnlyConfig(imagePair[constants.KEY__EXTRA_COLUMN_VALUES][constants.KEY__EXTRACOLUMN__CONFIG])"
-                    title="show only results of config {{imagePair[constants.KEY__EXTRA_COLUMN_VALUES][constants.KEY__EXTRACOLUMN__CONFIG]}}">
+                    ng-click="showOnlyConfig(imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][constants.KEY__EXTRACOLUMNS__CONFIG])"
+                    title="show only results of config {{imagePair[constants.KEY__IMAGEPAIRS__EXTRACOLUMNS][constants.KEY__EXTRACOLUMNS__CONFIG]}}">
               show only
             </button>
             <br>
@@ -337,7 +337,7 @@
             </button>
           </td>
           <td>
-            <a ng-repeat="bug in imagePair[constants.KEY__EXPECTATIONS_DATA][constants.KEY__EXPECTATIONS__BUGS]"
+            <a ng-repeat="bug in imagePair[constants.KEY__IMAGEPAIRS__EXPECTATIONS][constants.KEY__EXPECTATIONS__BUGS]"
                href="https://code.google.com/p/skia/issues/detail?id={{bug}}"
                target="_blank">
               {{bug}}
@@ -346,13 +346,13 @@
 
           <!-- image A -->
           <td valign="bottom" width="{{imageSize}}">
-            <div ng-if="imagePair[constants.KEY__IMAGE_A_URL] != null">
-              <a href="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGE_A_URL]}}" target="_blank">View Image</a><br/>
+            <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] != null">
+              <a href="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL]}}" target="_blank">View Image</a><br/>
               <img ng-if="showThumbnails"
                    width="{{imageSize}}"
-                   ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGE_A_URL]}}" />
+                   ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL]}}" />
             </div>
-            <div ng-show="imagePair[constants.KEY__IMAGE_A_URL] == null"
+            <div ng-show="imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] == null"
                  style="text-align:center">
               &ndash;none&ndash;
             </div>
@@ -360,13 +360,13 @@
 
           <!-- image B -->
           <td valign="bottom" width="{{imageSize}}">
-            <div ng-if="imagePair[constants.KEY__IMAGE_B_URL] != null">
-              <a href="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGE_B_URL]}}" target="_blank">View Image</a><br/>
+            <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL] != null">
+              <a href="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL]}}" target="_blank">View Image</a><br/>
               <img ng-if="showThumbnails"
                    width="{{imageSize}}"
-                   ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGE_B_URL]}}" />
+                   ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL]}}" />
             </div>
-            <div ng-show="imagePair[constants.KEY__IMAGE_B_URL] == null"
+            <div ng-show="imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL] == null"
                  style="text-align:center">
               &ndash;none&ndash;
             </div>
@@ -374,18 +374,18 @@
 
           <!-- whitediffs: every differing pixel shown in white -->
           <td valign="bottom" width="{{imageSize}}">
-            <div ng-if="imagePair[constants.KEY__IS_DIFFERENT]"
-                 title="{{imagePair[constants.KEY__DIFFERENCE_DATA][constants.KEY__DIFFERENCE_DATA__NUM_DIFF_PIXELS] | number:0}} of {{(100 * imagePair[constants.KEY__DIFFERENCE_DATA][constants.KEY__DIFFERENCE_DATA__NUM_DIFF_PIXELS] / imagePair[constants.KEY__DIFFERENCE_DATA][constants.KEY__DIFFERENCE_DATA__PERCENT_DIFF_PIXELS]) | number:0}} pixels ({{imagePair[constants.KEY__DIFFERENCE_DATA][constants.KEY__DIFFERENCE_DATA__PERCENT_DIFF_PIXELS].toFixed(4)}}%) differ from expectation.">
+            <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]"
+                 title="{{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__NUM_DIFF_PIXELS] | number:0}} of {{(100 * imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__NUM_DIFF_PIXELS] / imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS]) | number:0}} pixels ({{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS].toFixed(4)}}%) differ from expectation.">
 
-              {{imagePair[constants.KEY__DIFFERENCE_DATA][constants.KEY__DIFFERENCE_DATA__PERCENT_DIFF_PIXELS].toFixed(4)}}%
-              ({{imagePair[constants.KEY__DIFFERENCE_DATA][constants.KEY__DIFFERENCE_DATA__NUM_DIFF_PIXELS]}})
+              {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS].toFixed(4)}}%
+              ({{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__NUM_DIFF_PIXELS]}})
               <br/>
               <a href="{{imageSets[constants.KEY__IMAGESETS__SET__WHITEDIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{getImageDiffRelativeUrl(imagePair)}}" target="_blank">View Image</a><br/>
               <img ng-if="showThumbnails"
                    width="{{imageSize}}"
                    ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__WHITEDIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{getImageDiffRelativeUrl(imagePair)}}" />
             </div>
-            <div ng-show="!imagePair[constants.KEY__IS_DIFFERENT]"
+            <div ng-show="!imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]"
                  style="text-align:center">
               &ndash;none&ndash;
             </div>
@@ -393,11 +393,11 @@
 
           <!-- diffs: per-channel RGB deltas -->
           <td valign="bottom" width="{{imageSize}}">
-            <div ng-if="imagePair[constants.KEY__IS_DIFFERENT]"
-                 title="Perceptual difference measure is {{imagePair[constants.KEY__DIFFERENCE_DATA][constants.KEY__DIFFERENCE_DATA__PERCEPTUAL_DIFF].toFixed(4)}}%.  Maximum difference per channel: R={{imagePair[constants.KEY__DIFFERENCE_DATA][constants.KEY__DIFFERENCE_DATA__MAX_DIFF_PER_CHANNEL][0]}}, G={{imagePair[constants.KEY__DIFFERENCE_DATA][constants.KEY__DIFFERENCE_DATA__MAX_DIFF_PER_CHANNEL][1]}}, B={{imagePair[constants.KEY__DIFFERENCE_DATA][constants.KEY__DIFFERENCE_DATA__MAX_DIFF_PER_CHANNEL][2]}}">
+            <div ng-if="imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]"
+                 title="Perceptual difference measure is {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF].toFixed(4)}}%.  Maximum difference per channel: R={{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL][0]}}, G={{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL][1]}}, B={{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL][2]}}">
 
-              {{imagePair[constants.KEY__DIFFERENCE_DATA][constants.KEY__DIFFERENCE_DATA__PERCEPTUAL_DIFF].toFixed(4)}}%
-              {{imagePair[constants.KEY__DIFFERENCE_DATA][constants.KEY__DIFFERENCE_DATA__MAX_DIFF_PER_CHANNEL]}}
+              {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF].toFixed(4)}}%
+              {{imagePair[constants.KEY__IMAGEPAIRS__DIFFERENCES][constants.KEY__DIFFERENCES__MAX_DIFF_PER_CHANNEL]}}
               <br/>
               <a href="{{imageSets[constants.KEY__IMAGESETS__SET__DIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{getImageDiffRelativeUrl(imagePair)}}" target="_blank">View Image</a><br/>
               <img ng-if="showThumbnails"
@@ -405,7 +405,7 @@
                    width="{{imageSize}}"
                    ng-src="{{imageSets[constants.KEY__IMAGESETS__SET__DIFFS][constants.KEY__IMAGESETS__FIELD__BASE_URL]}}/{{getImageDiffRelativeUrl(imagePair)}}" />
             </div>
-            <div ng-show="!imagePair[constants.KEY__IS_DIFFERENT]"
+            <div ng-show="!imagePair[constants.KEY__IMAGEPAIRS__IS_DIFFERENT]"
                  style="text-align:center">
               &ndash;none&ndash;
             </div>