 
   # @returns the clinical profile panel promise
   clinicalProfile: ->
-    # @param selector the selection criterion
-    # @param bindings the table field {property: binding} bindings
-    # @returns the target table augmented with the component table
-    #   access functions, or null if the table was not found
-    findTableWithBindings = (selector, bindings) =>
-      # Gets the given WebElement text.
-      text = (elt) -> elt.getText() if elt
-
-      # Searches for a WebElement and resolves to its text.
-      findText = (selector) => @find(selector).then(text)
-
-      # @param table the target table
-      # @param bindings the table field bindings
-      addTextFields = (table, bindings) =>
-        # @param property the field property
-        # @param _binding the subject property bound to the field
-        addTextField = (property, binding) ->
-          # Associate the field property with its text.
-          table[property] = ->
-            # Note: the assignments below must be made locally in
-            # this anonymous function rather than preceding this
-            # statement in the addTextField function in order to
-            # work around the following Javascript scope/closure
-            # interaction anomaly:
-            # * If the local variables below are bound in the
-            #   parent context, then every property finder resolves
-            #   to the last property binding.
-            sbjBinding = 'subject.' + binding
-            # Make the field element search selector.
-            selector = By.binding(sbjBinding)
-            findText(selector)
-
-        addTextField(prop, binding) for prop, binding of bindings
-
-      # Find the table.
-      #
-      # Note: A better solution is to perform the field selects below
-      # against the table rather than the page. However,
-      # panel.findElement('qi-demographics-table')
-      # results in an error, since the untyped panel object has most, but
-      # not all, of the WebElement function properties. In particular, it
-      # is missing the findElement function. The work-around is to search
-      # in the page context instead.
-      #
-      # TODO - find out why the panel is neither an ElementFinder nor a
-      # WebElement and replace the select below with panel.element or
-      # panel.findElement. Add panel to the clinicalProfile function
-      # arguments.
-      @find(selector).then (table) ->
-        # Add the fields.
-        addTextFields(table, bindings) if table
-        # Return the table, or null if the table was not found.
-        table
-
-    # Adds a function property for each component table to the given
-    # profile panel.
+    # The table specifications as described in the getTable()
+    # function below.
     #
-    # @param panel the clinical profile panel
-    addComponentTables = (panel) ->
-      componentTables =
-        demographics:
-          selector: '#demographics'
-          bindings:
-            age: 'birthDate'
-            weight: 'weight'
-            races: 'races'
-            ethnicity: 'ethnicity'
-
-      addComponentTable = (prop, selector, bindings) ->
-        panel[prop] = -> findTableWithBindings(selector, bindings)
-
-      for prop, spec of componentTables
-        addComponentTable(prop, spec.selector, spec.bindings)
-
-    # Find the clinical profile panel.
-    @find('.qi-clinical-profile').then (panel) =>
-      # Add the component table functions.
-      addComponentTables(panel) if panel?
-      panel
-
+    TABLES =
+      demographics:
+        selector: '#demographics'
+        bindings:
+          age: 'subject.birthDate'
+          weight: 'subject.weight'
+          races: 'subject.races'
+          ethnicity: 'subject.ethnicity'
+
+    @find('.qi-clinical-profile').then (profile) ->
+      if profile?
+        # The table object builder.
+        getTable = (name) ->
+          spec = TABLES[name]
+          profile.findTable(spec.selector).then (table) ->
+            table.addBindings(spec.bindings) if table?
+        
+        # The table accessor properties.
+        for name in Object.keys(TABLES)
+          profile[name] = getTable(name)
+
+        # The encounter accessor properties.
+        for enc in ['Biopsy', 'Surgery', 'Assessment']
+          profile[enc.toLowerCase()] =
+            profile.find("div[ng-switch-when='#{ enc }']")
+      
+      # Return the clinical profile.
+      profile
 
 describe 'E2E Testing Subject Detail', ->
   page = null

          it 'should not have a blank percent value in the remaining rows', ->
            modelingTables.then (tables) ->
              for table, tblNdx in tables
                table.body.then (rows) ->
                  for columns, rowNdx in _.rest(rows)
                    for colNdx in _.range(2, columns.length, 2)
                      value = columns[colNdx]

        before ->
          # The tables are only added to the DOM if the format button
          # is clicked.
          page.imageProfileFormatButton().then (button) ->
            button.click().then ->
              modelingTables = page.modelingTables()
        
        after ->
          # Restore the format to chart.
