diff --git a/web/modules/custom/asc_courses/asc_courses.install b/web/modules/custom/asc_courses/asc_courses.install
index 917af32f97b6775fff76a886afc24e66bc6d3029..998e84da09f304a0841087cee267a848746fa067 100644
--- a/web/modules/custom/asc_courses/asc_courses.install
+++ b/web/modules/custom/asc_courses/asc_courses.install
@@ -17,7 +17,7 @@ function asc_courses_update_8001(&$sandbox) {
   $content_type = 'course';
 
   /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
-  $entity_type_manager = \Drupal::entityTypeManager(); 
+  $entity_type_manager = \Drupal::entityTypeManager();
 
   /** @var \Drupal\Core\Entity\EntityStorageInterface $node_storage */
   $node_storage = $entity_type_manager->getStorage('node');
@@ -228,7 +228,7 @@ function asc_courses_schema() {
           'type' => 'text',
           'length' => 16777215,
           'not null' => TRUE,
-        ],  
+        ],
       ],
       'primary key' => ['asc_courses_dorgs_id'],
     ];
@@ -409,7 +409,7 @@ function asc_courses_schema() {
     ],
     'primary key' => ['asc_courses_processed_id'],
   ];
-  
+
   return $schema;
 }
 
diff --git a/web/modules/custom/asc_courses/asc_courses.links.menu.yml b/web/modules/custom/asc_courses/asc_courses.links.menu.yml
index 75fbe69e735ba04738f0262c6638da0e5dfcefdc..f7b1d8a6ae558be2a834c8eaff1228b190092098 100644
--- a/web/modules/custom/asc_courses/asc_courses.links.menu.yml
+++ b/web/modules/custom/asc_courses/asc_courses.links.menu.yml
@@ -18,7 +18,7 @@ asc_courses.search:
   route_name: asc_courses.search
   parent: 'asc_courses.settings'
   weight: 5
-  
+
 asc_courses.api_settings:
   title: 'API Settings'
   description: 'Administrate API settings'
diff --git a/web/modules/custom/asc_courses/asc_courses.routing.yml b/web/modules/custom/asc_courses/asc_courses.routing.yml
index d0f21abad2de86013628fe9a82d9daef0fb24230..d18b6141ec1a470c9f81bb9cbd45b1629f92ca19 100644
--- a/web/modules/custom/asc_courses/asc_courses.routing.yml
+++ b/web/modules/custom/asc_courses/asc_courses.routing.yml
@@ -25,4 +25,4 @@ asc_courses.api_settings:
     link_id: 'asc_courses.api_settings'
   requirements:
     _permission: 'asc courses admin'
-    
\ No newline at end of file
+
diff --git a/web/modules/custom/asc_courses/config/schema/asc_courses.schema.yml b/web/modules/custom/asc_courses/config/schema/asc_courses.schema.yml
index 688d53297bba322621df4fe2f07c4b9402018559..34203bdf620d7433fb25097ebaeca48af4c86d19 100644
--- a/web/modules/custom/asc_courses/config/schema/asc_courses.schema.yml
+++ b/web/modules/custom/asc_courses/config/schema/asc_courses.schema.yml
@@ -11,4 +11,4 @@ asc_courses.settings:
         consumer_secret:
           type: text
           label: 'Consumer Secret'
-          
+
diff --git a/web/modules/custom/asc_courses/src/AscCoursesApi.php b/web/modules/custom/asc_courses/src/AscCoursesApi.php
index 9f91258f660d44f9a04647122e4e4df8a42e5ece..32026d874d47d8d16f01a13641206a3e106b613b 100644
--- a/web/modules/custom/asc_courses/src/AscCoursesApi.php
+++ b/web/modules/custom/asc_courses/src/AscCoursesApi.php
@@ -28,7 +28,7 @@ class AscCoursesApi {
    */
   public function __construct($config = null, $db = null, $environment = '') {
     if ($this->debug) echo "\n============ AscCoursesApi::__construct() ============\n";
-    
+
     // Get config if not passed
     if (!empty($config)) {
       $this->config = $config;
@@ -65,7 +65,7 @@ public function __construct($config = null, $db = null, $environment = '') {
       $this->base_url = "https://apig-qa.eip.osu.edu/";
       $this->consumer_key = $config->get('asc_courses.qa_consumer_key');
       $this->consumer_secret = $config->get('asc_courses.qa_consumer_secret');
-      $this->soip_constant_name = "PANTHEON_SOIP_EIP";  
+      $this->soip_constant_name = "PANTHEON_SOIP_EIP";
     }
 
     // (Legacy) Pantheon "Secure Integration" support - establish "resolve host"
@@ -91,14 +91,14 @@ public function getAccessToken() {
     if($this->debug) echo "============ AscCoursesApi::getAccessToken() =============\n";
     if($this->debug) echo "Current time: " . date("Y-m-d h:i:s", $now) . "\n";
 
-    
+
     // Treat access tokens that are almost expired as expired
-    if(!empty($this->access_token_data) 
-       && (($this->access_token_data->expiration - $now) > 30)) 
+    if(!empty($this->access_token_data)
+       && (($this->access_token_data->expiration - $now) > 30))
     {
       // First check object variables
       if($this->debug) echo "Object variables were set and not stale\n";
-      $this->access_token = $this->access_token_data->access_token;        
+      $this->access_token = $this->access_token_data->access_token;
     }
     else {
       // Object variables stale or missing, fall back on stored config
@@ -108,7 +108,7 @@ public function getAccessToken() {
       if($this->debug) echo "Config access token: " . print_r($access_token_data, true) . "\n";
 
       if(!empty($access_token_data)
-         && (($access_token_data->expiration - $now) > 30)) 
+         && (($access_token_data->expiration - $now) > 30))
       {
         if($this->debug) echo "Config token was available and not stale.\n";
         $this->access_token_data = $access_token_data;
@@ -116,7 +116,7 @@ public function getAccessToken() {
       }
       else {
         if($this->debug) echo "Config token was unset or stale.\n";
-        
+
         // Fetch new access token from EIP
         $access_token_data = $this->fetchAccessToken();
 
@@ -132,9 +132,9 @@ public function getAccessToken() {
         $expirey = $this->access_token_data->expiration;
         echo "Token expiration: " . date("Y-m-d h:i:s", $expirey) . "\n";
         echo "Expires in " . ($expirey - $now) . " seconds..\n";
-        echo "\n\n";  
+        echo "\n\n";
       }
-      return $this->access_token;    
+      return $this->access_token;
     }
     else {
       die("\nAscCoursesApi::getAccessToken() - failed to retrieve access token! X_X\n\n");
@@ -159,7 +159,7 @@ protected function fetchAccessToken() {
     /*
       // get access token -- old drupal-ish way
       $token_response = \Drupal::httpClient()
-        ->post($access_token_url, 
+        ->post($access_token_url,
             [
               'headers' => [
                 'Accept' => 'application/json',
@@ -197,7 +197,7 @@ protected function fetchAccessToken() {
     if(isset($this->resolve_host)) {
       if ($this->debug) echo "AscCoursesApi::fetchAccessToken() - Resolve host set: " . print_r($this->resolve_host, true) . "\n";
       curl_setopt($ch, CURLOPT_RESOLVE, $this->resolve_host);
-      curl_setopt($ch, CURLOPT_PORT, constant($this->soip_constant_name));  
+      curl_setopt($ch, CURLOPT_PORT, constant($this->soip_constant_name));
     }
 
     if($this->debug > 1) {
@@ -221,23 +221,23 @@ protected function fetchAccessToken() {
       $access_token_data = json_decode($access_token_result);
       $access_token_data->expiration = (time() + $access_token_data->expires_in);
       $access_token_data->fetched = $now;
-  
+
       if ($this->debug) {
         echo "fetchAccessToken() - Access token result: \n";
         print_r($access_token_result);
         echo "\n";
-        echo "fetchAccessToken() - Access token in $access_token_seconds seconds\n";  
+        echo "fetchAccessToken() - Access token in $access_token_seconds seconds\n";
         echo "fetchAccessToken() - Now: " . $now . " - " . date("Y-m-d h:i:s", $now) . "\n";
         print_r($access_token_data);
       }
-  
+
       // Save access token data to config
       $env_access_token_setting = 'asc_courses.' . $this->environment . '_access_token';
       if($this->debug) echo "fetchAccessToken() - env_access_token_setting: $env_access_token_setting\n";
       $config = \Drupal::service('config.factory')->getEditable('asc_courses.settings');
       $config->set("asc_courses." . $this->environment . "_access_token", serialize($access_token_data));
       $config->save();
-  
+
       return $access_token_data;
     }
   }
@@ -288,7 +288,7 @@ public function fetchDorgCourses($dorg, $force = false) {
       if ($this->debug) echo "fetchDorgCourses() - Resolve host set: " . $this->resolve_host . "\n";
       // error_log("fetchDorgCourses() - Resolve host set: " . $this->resolve_host);
       curl_setopt($ch, CURLOPT_RESOLVE, $this->resolve_host);
-      curl_setopt($ch, CURLOPT_PORT, constant($this->soip_constant_name));  
+      curl_setopt($ch, CURLOPT_PORT, constant($this->soip_constant_name));
     }
 
     if($this->debug > 1) {
@@ -311,8 +311,8 @@ public function fetchDorgCourses($dorg, $force = false) {
     else {
       if ($this->debug) echo "Course data length:" . strlen($course_data_result) . "\n";
       if ($this->debug) echo "Course data in $curl_seconds seconds\n\n";
-  
-  
+
+
       // $connection = \Drupal::database();
       $row = [
         'date' => time(),
@@ -323,8 +323,8 @@ public function fetchDorgCourses($dorg, $force = false) {
         'processed' => 0,
       ];
       $this->db->insert('asc_courses_api_data')->fields($row)->execute();
-  
-      $course_data = json_decode($course_data_result);      
+
+      $course_data = json_decode($course_data_result);
       return $course_data;
     }
 
@@ -336,7 +336,7 @@ public function fetchDorgCourses($dorg, $force = false) {
    */
   public function processDorgCourses($dorg) {
     if($this->debug) echo "============ AscCoursesApi::processDorgCourses() =============\n";
-    
+
     $dorg_query = $this->db->select("asc_courses_api_data", "acad")
         ->fields("acad")
         ->condition("acad.dept_org", $dorg, "=")
@@ -363,7 +363,7 @@ public function processPendingApiData($environment = null, $count = null) {
         ->fields("acad")
         ->condition("processed", "0", "=")
         ->orderBy('date', 'ASC');
-    
+
     if(!empty($environment)) {
       $query->condition("environment", $environment, "=");
     }
@@ -372,7 +372,7 @@ public function processPendingApiData($environment = null, $count = null) {
       if ($this->debug) echo "processPendingApiData(): Count argument specified: $count";
       $query->range(0, $count);
     }
-        
+
     $api_data_result = $query->execute();
     while($row = $api_data_result->fetchAssoc()) {
       if($row['request_type'] == 'crseinfo') {
@@ -395,7 +395,7 @@ public function processApiDorgCoursesRecord($row) {
       echo "date: " . $row["date"] . "\n";
       echo "environment: " . $row["environment"] . "\n";
       echo "request_type: " . $row["request_type"] . "\n";
-      echo "processed: " . $row["processed"] . "\n"; 
+      echo "processed: " . $row["processed"] . "\n";
       echo "json data length: " . strlen($row['raw_json']) . "\n";
     }
 
@@ -417,7 +417,7 @@ public function processApiDorgCoursesRecord($row) {
             ->condition("crse_id", $course_data->{'crse-id'})
             ->execute()
             ->fetchAssoc();
-  
+
         if(!empty($existing_row)) {
           $this->updateProcessedCourse($existing_row, $course_data);
         }
@@ -448,12 +448,12 @@ public function insertProcessedCourse($course_data) {
       echo " - " . $course_data->{'descr'};
       echo "\n";
       // echo "course data: " . print_r($course_data, true) . "\n";
-      // echo "course_title_long length: " . strlen($course_data->{'course-title-long'}) . "\n";  
+      // echo "course_title_long length: " . strlen($course_data->{'course-title-long'}) . "\n";
     }
 
     $row = [
       "updated" => time(),
-      "asc_courses_api_data_id"   => $course_data->{'asc_courses_api_data_id'},      
+      "asc_courses_api_data_id"   => $course_data->{'asc_courses_api_data_id'},
       "dept_org"                  => $course_data->{'dept_org'},
       "crse_id"                   => $course_data->{'crse-id'},
       "strm"                      => $course_data->{'strm'},
@@ -502,15 +502,15 @@ public function updateProcessedCourse($existing_row, $new_course_data) {
       echo " - " . $new_course_data->{'catalog-nbr'};
       echo " - " . $new_course_data->{'descr'};
       echo "\n";
-  
+
       // echo "existing_row: " . print_r($existing_row, true) . "\n";
-      // echo "course data: " . print_r($new_course_data, true) . "\n";  
+      // echo "course data: " . print_r($new_course_data, true) . "\n";
     }
 
     $row_fields = array_keys($existing_row);
 
     // echo "row fields: " . print_r($row_fields, true) . "\n";
-    
+
     $new_course_data->{"crse-attribute"} = serialize($new_course_data->{"crse-attribute"});
 
     $update_fields = [];
@@ -527,7 +527,7 @@ public function updateProcessedCourse($existing_row, $new_course_data) {
           if ($this->debug) {
             echo $existing_row[$field_name];
             echo " != ";
-            echo $new_course_data->{$obj_field_name} . "\n";  
+            echo $new_course_data->{$obj_field_name} . "\n";
           }
           $update_fields[$field_name] = $new_course_data->{$obj_field_name};
         }
@@ -539,7 +539,7 @@ public function updateProcessedCourse($existing_row, $new_course_data) {
     unset($update_fields["asc_courses_api_data_id"]);  // doesn't come from API
     unset($update_fields["dept_org"]);  // doesn't come from API
     unset($update_fields["strm"]);  // we do not care about duplicates with different 'strm' values
-    
+
     if(empty($update_fields) && $this->debug) {
       echo "updateProcessedCourse(): There is no information to update\n";
     }
@@ -606,7 +606,7 @@ public function fetchDorgList() {
         "EFFDT_YYYYMMDD" => ""
       ];
       if($this->debug) echo "D-org POST data: " . print_r($dorg_post_data, true) . "\n";
-    */    
+    */
 
     $ch = curl_init();
     curl_setopt($ch, CURLOPT_URL, $dorg_data_url);
@@ -623,7 +623,7 @@ public function fetchDorgList() {
       if ($this->debug) echo "fetchDorgList() - Resolve host set: " . $this->resolve_host . "\n";
       // error_log("fetchDorgList() - Resolve host set: " . $this->resolve_host);
       curl_setopt($ch, CURLOPT_RESOLVE, $this->resolve_host);
-      curl_setopt($ch, CURLOPT_PORT, constant($this->soip_constant_name));  
+      curl_setopt($ch, CURLOPT_PORT, constant($this->soip_constant_name));
     }
 
     if($this->debug > 1) {
@@ -645,8 +645,8 @@ public function fetchDorgList() {
     else {
       if ($this->debug) echo "D-org data length:" . strlen($dorg_data_result) . "\n";
       if ($this->debug) echo "D-org data in $curl_seconds seconds\n\n";
-  
-      
+
+
       /*
         $dorgs = $dorgs->getDeptOrgInfoResponse->OUT_VP_CATEGORY->OUT_VP_AREA;
 
@@ -700,7 +700,7 @@ public function fetchDorgList() {
           // echo "vars: " . print_r(array_keys($out_vp_college_vars), true) . "\n";
           echo "==================\n\n";
         }
-      */ 
+      */
 
       // $connection = \Drupal::database();
       $row = [
@@ -708,11 +708,11 @@ public function fetchDorgList() {
         // 'dept_org' => $dorg,
         'raw_json' => $dorg_data_result
       ];
-      
+
       // this db table doesn't even exist
       // $this->db->insert('asc_course_dorgs')->fields($row)->execute();
-  
-      $dorg_data = json_decode($dorg_data_result);      
+
+      $dorg_data = json_decode($dorg_data_result);
       return $dorg_data;
     }
   }
@@ -758,7 +758,7 @@ public function getApiDorgList() {
 
   /**
    * Return hard-coded/statically-defined list of D-Org numbers
-   * 
+   *
    * @return array
    *   The D-Org list
    */
@@ -982,7 +982,7 @@ public static function getDorgList() {
         'name' => "Speech and Hearing",
       ],
     ];
-    
+
     return $dorgs;
   }
 }
diff --git a/web/modules/custom/asc_courses/src/AscCoursesImporter.php b/web/modules/custom/asc_courses/src/AscCoursesImporter.php
index d2211610392d38e94de4409725e31c47fd891537..27b64528b7e4b80d82b613a5b65bee64510e01b7 100644
--- a/web/modules/custom/asc_courses/src/AscCoursesImporter.php
+++ b/web/modules/custom/asc_courses/src/AscCoursesImporter.php
@@ -38,7 +38,7 @@ public function __construct($config = null, $db = null) {
     else {
       $this->db = $db;
     }
-    
+
   }
 
   public function importCourseNodes($courses_data) {
@@ -80,10 +80,10 @@ public function createCourseNode($node_storage, $course_data) {
       'field_eip_id'                => [$course_data['crse_id']],
     ));
     $course_node->save();
-    // $new_course_nid = $course_node->get('nid')->getValue()[0]['value'];
+
     $new_course_nid = $course_node->id();
-    $this->created_nodes[$new_course_nid] = 1;
-    // if($this->debug) echo "createCourseNode() - $new_course_nid\n";
+    $this->created_nodes[$new_course_nid] = 1;  // track this change
+
     if($this->debug) echo "createCourseNode() - New course nid[$new_course_nid] catalog[" . $course_data['catalog-nbr'] . "]\n";
   }
 
@@ -102,7 +102,7 @@ public function updateCourseNode($node_storage, $nid, $course_data) {
       if($this->debug) {
         echo "### Title changed..\n";
         echo "Node title: $title\n";
-        echo "API title: " . $course_data['course_title_long'] . "\n";  
+        echo "API title: " . $course_data['course_title_long'] . "\n";
       }
       $content_changed = true;
       // $course_node->setTitle($course_data['course_title_long']);
@@ -115,7 +115,7 @@ public function updateCourseNode($node_storage, $nid, $course_data) {
       if($this->debug) {
         echo "### description changed..\n";
         echo "Node description: $description\n";
-        echo "API description: " . $course_data['descrlong'] . "\n";  
+        echo "API description: " . $course_data['descrlong'] . "\n";
       }
       $content_changed = true;
       $course_node->field_course_description->value = $course_data['descrlong'];
@@ -128,7 +128,7 @@ public function updateCourseNode($node_storage, $nid, $course_data) {
       if($this->debug) {
         echo "### course_number changed..\n";
         echo "Node course_number: $course_number\n";
-        echo "API course_number: " . $course_data['catalog_nbr'] . "\n";  
+        echo "API course_number: " . $course_data['catalog_nbr'] . "\n";
       }
       $content_changed = true;
       // $course_node->set('field_course_number', $course_data['catalog_nbr']);
@@ -140,7 +140,7 @@ public function updateCourseNode($node_storage, $nid, $course_data) {
       if($this->debug) {
         echo "### credit_hours changed..\n";
         echo "Node credit_hours: $credit_hours\n";
-        echo "API credit_hours: " . $course_data['acad_prog'] . "\n";  
+        echo "API credit_hours: " . $course_data['acad_prog'] . "\n";
       }
       $content_changed = true;
       $course_node->field_credit_hours->value = $course_data['acad_prog'];
@@ -151,7 +151,7 @@ public function updateCourseNode($node_storage, $nid, $course_data) {
       if($this->debug) {
         echo "### subj_abbrev changed..\n";
         echo "Node subj_abbrev: $subj_abbrev\n";
-        echo "API subj_abbrev: " . $course_data['subject'] . "\n";  
+        echo "API subj_abbrev: " . $course_data['subject'] . "\n";
       }
       $content_changed = true;
       $course_node->field_subject_abbreviation->value = $course_data['subject'];
@@ -161,7 +161,7 @@ public function updateCourseNode($node_storage, $nid, $course_data) {
       if($this->debug) echo "\nContent has changed.. save updated node.\n\n";
       $course_node->save();
       if(!array_key_exists($nid, $this->created_nodes)) {
-        $this->updated_nodes[$nid] = 1;
+        $this->updated_nodes[$nid] = 1;   // track this change
       }
     }
   }
@@ -180,7 +180,7 @@ public function fetchAndImportAll() {
       if ($this->debug) echo "D-org: $dorg\n";
 
       $courses_data = $this->loadSubjectDataFromDatabase($dorg);
-      
+
       $this->importCourseNodes($courses_data);
     }
 
@@ -201,12 +201,12 @@ public function fetchAndImportAll() {
     }
 
     $this->importCourseNodes($alacarte_rows);
-    
+
   }
 
   public function loadSubjectDataFromDatabase($dorg) {
     if ($this->debug) echo "loadSubjectDataFromDatabase(): dorg[$dorg]\n";
-    
+
     $course_info_query = $this->db->select('asc_courses_processed', 'acp')
       ->fields('acp')
       ->condition('dept_org', $dorg, '=');
@@ -442,7 +442,7 @@ public function getDorgToSubject() {
         'name' => "Speech and Hearing",
       ],
     ];
-    
+
     return $dorg_to_name;
   }
 
@@ -480,7 +480,7 @@ public function getAllCoursesBySubject() {
       }
 
       $all_courses_by_subject[$course_subj][$course_cat_nbr][] = $row;
-      
+
       /*
         $json_length = strlen($row['raw_json']);
         $json_data = json_decode($row['raw_json'])->getCourseCatalogResponse;
@@ -488,15 +488,15 @@ public function getAllCoursesBySubject() {
         $message = $json_data->message;
 
         // if ($this->debug) echo  "$dorg_num - $json_length bytes - $dorg_subject - ";
-        
+
         if(is_array($json_data->catalog->course)) {
-          // if ($this->debug) echo count($json_data->catalog->course) . " courses\n";  
+          // if ($this->debug) echo count($json_data->catalog->course) . " courses\n";
 
           foreach($json_data->catalog->course as $course_data) {
             $course_subj = (string)$course_data->{'subject'};
             $course_cat_nbr = (string)$course_data->{'catalog-nbr'};
             $course_title = (string)$course_data->{'course-title-long'};
-            
+
 
             // if ($this->debug) echo "$course_subj - $course_cat_nbr - $course_title\n";
 
@@ -533,7 +533,7 @@ public function establishApiReferences() {
     // }
     // $config_dorgs = $this->config->get('asc_courses.dept_org');
     // $dorgs = explode(',', trim($config_dorgs));
-    
+
     $all_courses = $this->getAllCoursesBySubject();
     // print_r($all_courses);
     // print_r($all_courses['GEOG']);
@@ -582,7 +582,7 @@ public function establishApiReferences() {
         }
         if($crse_id) {
           $node->field_eip_id->value = $crse_id;
-          $node->save();  
+          $node->save();
         }
       }
       // print_r($all_courses[$subj_abbrev][$cat_num]);
@@ -592,5 +592,5 @@ public function establishApiReferences() {
     if ($this->debug) echo "===============\n";
     if ($this->debug) print_r($lookup_failed);
   }
-  
+
 }
diff --git a/web/modules/custom/asc_courses/src/Commands/AscCoursesCommands.php b/web/modules/custom/asc_courses/src/Commands/AscCoursesCommands.php
index cccffe31b289d4ff890e42ad8fa99c7a265c8f27..73d24484096a221db2c869f38436520982cb11ce 100644
--- a/web/modules/custom/asc_courses/src/Commands/AscCoursesCommands.php
+++ b/web/modules/custom/asc_courses/src/Commands/AscCoursesCommands.php
@@ -27,7 +27,7 @@ class AscCoursesCommands extends DrushCommands {
 
   // public $soip_constant_name = "PANTHEON_SOIP_EIP";
   // public $soip_constant_name = "PANTHEON_SOIP_EIP_PROD";
-  
+
   /**
    * Dummy command for running whatever arbitrary code I want
    *
@@ -53,7 +53,7 @@ public function commandName($arg1, $options = ['option-name' => 'default']) {
     // $dorg = $api->config->get('asc_courses.dept_org');
     // echo "D-org: $dorg\n";
     // $courses = $api->fetchDorgCourses($dorg);
-    
+
     // module_load_install('asc_courses');
     // $schema = Database::getConnection()->schema();
     // $tables = asc_courses_schema();
@@ -71,10 +71,10 @@ public function commandName($arg1, $options = ['option-name' => 'default']) {
     //   $subj_abbrev = $course->{'subject'};
     //   $cat_num = $course->{'catalog-nbr'};
     //   $title = $course->{'course-title-long'};
-    //   echo "$eip_id - $subj_abbrev - $cat_num - $title\n";      
+    //   echo "$eip_id - $subj_abbrev - $cat_num - $title\n";
     // }
     // $importer->fetchAndImportAll();
-    
+
     // $importer->establishApiReferences();
   }
 
@@ -102,13 +102,13 @@ public function pullAllDorgs($options = ['option-name' => 'default']) {
     echo "Dorg count: " . count($dorg_numbers) . "\n";
 
     foreach($dorg_numbers as $dorg_number) {
-      
+
         echo "=== $dorg_number - " . $dorgs[$dorg_number]["name"] . " ===\n";
         $courses = $api->fetchDorgCourses($dorg_number);
         // echo "courses type: " . gettype($courses) . "\n";
         // $courses_vars = get_object_vars($courses);
         // echo "vars: " . print_r(array_keys($courses_vars), true) . "\n";
-      
+
         echo "===================================\n";
     }
 
@@ -140,7 +140,7 @@ public function processApiData($count = null, $options = ['option-name' => 'defa
       // echo "Count is NOT numeric: $count\n";
       $api->processPendingApiData();
     }
-    
+
   }
 
 
diff --git a/web/modules/custom/asc_courses/src/Controller/CoursesController.php b/web/modules/custom/asc_courses/src/Controller/CoursesController.php
deleted file mode 100644
index c92ae255168de33c127b7a436a7759d57ed1689e..0000000000000000000000000000000000000000
--- a/web/modules/custom/asc_courses/src/Controller/CoursesController.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-namespace Drupal\asc_courses\Controller;
-
-use Drupal\Core\Controller\ControllerBase;
-
-/**
- * Defines CoursesController class.
- */
-class CoursesController extends ControllerBase {
-
-  /**
-   * Display the markup.
-   *
-   * @return array
-   *   Return markup array.
-   */
-  public function content() {
-    return [
-      '#type' => 'markup',
-      '#markup' => $this->t('Hello, World!'),
-    ];
-  }
-  
-}
\ No newline at end of file
diff --git a/web/modules/custom/asc_courses/src/Form/ApiSettingsForm.php b/web/modules/custom/asc_courses/src/Form/ApiSettingsForm.php
index 9842581db5ba5ae47daf6a75b73fc6308371a87f..9b27278aabc8540586fb6c5d9f3ce77392684f7e 100644
--- a/web/modules/custom/asc_courses/src/Form/ApiSettingsForm.php
+++ b/web/modules/custom/asc_courses/src/Form/ApiSettingsForm.php
@@ -45,7 +45,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     // Prod Consumer key field
     $form['prod_consumer_key'] = array(
       '#type' => 'textfield',
-      '#title' => $this->t('Production Consumer Key'), 
+      '#title' => $this->t('Production Consumer Key'),
       '#default_value' => $config->get('asc_courses.prod_consumer_key'),
       '#description' => $this->t('Consumer key from Production EIP API dashboard'),
     );
@@ -57,7 +57,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#default_value' => $config->get('asc_courses.prod_consumer_secret'),
       '#description' => $this->t('Consumer secret from Production EIP API dashboard.'),
     );
-    
+
     // EIP environment
     $form['eip_environment'] = array(
       '#type' => 'radios',
@@ -89,7 +89,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $config->set('asc_courses.prod_consumer_secret', $form_state->getValue('prod_consumer_secret'));
     $config->set('asc_courses.eip_environment', $form_state->getValue('eip_environment'));
     $config->save();
-    
+
     return parent::submitForm($form, $form_state);
   }
 
diff --git a/web/modules/custom/asc_courses/src/Form/CourseSearchForm.php b/web/modules/custom/asc_courses/src/Form/CourseSearchForm.php
index 1d858b1f986ea92a65c841b056ab0fa10270bde4..edd2132af175bdf4c21e4fbbd10ebd1469fa6831 100644
--- a/web/modules/custom/asc_courses/src/Form/CourseSearchForm.php
+++ b/web/modules/custom/asc_courses/src/Form/CourseSearchForm.php
@@ -55,11 +55,11 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $title = $store->get('search_title');
 
 
+    // main search form
     $form['subject'] = array(
       '#type' => 'textfield',
       '#title' => $this->t('Subject Abbreviation'),
       '#default_value' => $subject,
-      // '#description' => $this->t('desc'),
       '#weight' => 1,
     );
 
@@ -67,7 +67,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#type' => 'textfield',
       '#title' => $this->t('Catalog Number'),
       '#default_value' => $catalog_nbr,
-      // '#description' => $this->t('desc'),
       '#weight' => 20,
     );
 
@@ -75,26 +74,36 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#type' => 'textfield',
       '#title' => $this->t('Title'),
       '#default_value' => $title,
-      // '#description' => $this->t('desc'),
       '#weight' => 30,
     );
 
+
     // Table of search results, if search terms were provided
     if(!empty($subject) || !empty($catalog_nbr) || !empty($title)) {
+
+      // get individual course selections, for checkboxes
+      $config = $this->config('asc_courses.settings');
+      $individual_courses = $config->get('asc_courses.individual_courses');
+
+      $selected_courses = [];
+      // strip extra spaces
+      foreach(explode(',', trim($individual_courses)) as $selected_course) {
+        $selected_courses[trim($selected_course)] = 1;
+      }
+      // dsm($selected_courses);
+
       // table header
       $header_table = array(
         'crse_id'           => t('Course ID'),
         'subject'           => t('Subject Abbreviation'),
         'catalog_nbr'       => t('Catalog Number'),
         'course_title_long' => t('Course Title'),
-        // 'opt' => t('operations'),
-        // 'opt1' => t('operations'),
       );
-  
+
       // select records from db
       $query = \Drupal::database()->select('asc_courses_processed', 'acp');
       $query->fields('acp', ['crse_id','subject','catalog_nbr','course_title_long']);
-      
+
       if(!empty($subject)) {
         $query->condition('subject', '%'.$subject.'%', 'LIKE');
       }
@@ -111,32 +120,37 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       $query->orderBy('acp.catalog_nbr');
 
       $results = $query->execute()->fetchAll();
-        
-      // build table rows with results
+
+      // build table rows with search results
       $rows=array();
+
       foreach($results as $data) {
-        // $delete = Url::fromUserInput('/admin/config/content/asc-courses/alacarte/delete/'.$data->id);
-        // $edit   = Url::fromUserInput('/admin/config/content/asc-courses/alacarte?num='.$data->id);
-  
-        $rows[] = array(
-          'crse_id' =>$data->crse_id,
+
+        $rows[$data->crse_id] = array(
+          'crse_id' => $data->crse_id,
           'subject' => $data->subject,
           'catalog_nbr' => $data->catalog_nbr,
           'course_title_long' => $data->course_title_long,
-  
-          // \Drupal::l('Delete', $delete),
-          // \Drupal::l('Edit', $edit),
         );
       }
 
       // add table to form
       $form['table'] = [
-        '#type' => 'table',
+        '#type' => 'tableselect',
         '#header' => $header_table,
-        '#rows' => $rows,
+        '#options' => $rows,
         '#weight' => 100,
         '#empty' => t('No courses found'),
-      ]; 
+        '#default_value' => $selected_courses,
+      ];
+
+      $form['save_selections'] = [
+        '#type' => 'submit',
+        '#value' => "Save selections",
+        '#name' => 'save_selections',
+        '#weight' => 101,
+        '#button_type' => "primary",
+      ];
     }
     else { // List of subject abbreviations
       $table_header = array(
@@ -147,23 +161,23 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       $query->fields('acp', ['dept_org','subject']);
       $query->orderBy('acp.subject');
       $query->distinct();
-  
+
       $subject_results = $query->execute()->fetchAll();
       foreach ($subject_results as $subject_result) {
         $subject_table_rows[] = [
           "subject_abbrev" => $subject_result->subject,
         ];
       }
-  
+
       // add table to form
       $form['table'] = [
         '#type' => 'table',
         '#header' => $table_header,
         '#rows' => $subject_table_rows,
         '#weight' => 100,
-      ];       
+      ];
     }
-    
+
     return $form;
   }
 
@@ -178,18 +192,65 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $tempstore = \Drupal::service('tempstore.private');
-    $store = $tempstore->get('asc_courses_collection');
-
+    // Which submit button was clicked?
     $trigger = $form_state->getTriggeringElement();
 
-    if($trigger['#name'] == 'clear_button') {
+    if($trigger['#name'] == 'save_selections') {
+      $config = \Drupal::service('config.factory')->getEditable('asc_courses.settings');
+      $selections_comma_delimited = $config->get('asc_courses.individual_courses');
+      // dsm($selections_comma_delimited);
+
+      $selected_courses = [];
+      // strip extra spaces
+      foreach(explode(',', trim($selections_comma_delimited)) as $selected_course) {
+        $selected_courses[trim($selected_course)] = 1;
+      }
+      // dsm($selected_courses);
+
+      $results = $form_state->getValue('table');
+      // dsm($results);
+
+      $selections_changed = false;
+
+      foreach($results as $eip_id => $selected) {
+        if(array_key_exists($eip_id, $selected_courses) && $selected == 0) {
+          // something was removed
+          // dsm("$eip_id was removed");
+
+          unset($selected_courses[$eip_id]);
+          $selections_changed = true;
+        }
+        else if ($selected != 0 && !array_key_exists($eip_id, $selected_courses)) {
+          // something was added
+          // dsm("$eip_id was added");
+          $selected_courses[$eip_id] = 1;
+          $selections_changed = true;
+        }
+      }
+
+      if($selections_changed) {
+        $selections_comma_delimited = implode(', ', array_keys($selected_courses));
+        // dsm("Selections were changed, new value: " . $selections_comma_delimited);
+
+        $config->set('asc_courses.individual_courses', $selections_comma_delimited);
+        $config->save();
+      }
+
+    }
+
+    else if($trigger['#name'] == 'clear_button') {
+      $tempstore = \Drupal::service('tempstore.private');
+      $store = $tempstore->get('asc_courses_collection');
+
       // Clear the search fields
       $store->delete('search_subject');
       $store->delete('search_catalog_nbr');
       $store->delete('search_title');
     }
     else {
+      $tempstore = \Drupal::service('tempstore.private');
+      $store = $tempstore->get('asc_courses_collection');
+
       // Save form inputs, for reuse when rebuilding the form
       $store->set('search_subject', $form_state->getValue('subject'));
       $store->set('search_catalog_nbr', $form_state->getValue('catalog_nbr'));
diff --git a/web/modules/custom/asc_courses/src/Form/SettingsForm.php b/web/modules/custom/asc_courses/src/Form/SettingsForm.php
index 92ed21ae40086e0630664a97e4caaa3ea3c38993..3858151ca027bd1021140364b3fd898f3e267ea8 100644
--- a/web/modules/custom/asc_courses/src/Form/SettingsForm.php
+++ b/web/modules/custom/asc_courses/src/Form/SettingsForm.php
@@ -26,7 +26,44 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
     $config = $this->config('asc_courses.settings');
 
-    // D-Org number 
+    $selected_courses_delimited = $config->get('asc_courses.individual_courses');
+    if(!empty($selected_courses_delimited)) {
+      $selected_courses = [];
+      // strip extra spaces
+      foreach(explode(',', trim($selected_courses_delimited)) as $selected_course) {
+        $selected_courses[trim($selected_course)] = 1;
+      }
+      // dsm($selected_courses);
+
+      // selected courses table header
+      $selected_courses_table_header = array(
+        'crse_id'           => t('Course ID'),
+        'subject'           => t('Subject Abbreviation'),
+        'catalog_nbr'       => t('Catalog Number'),
+        'course_title_long' => t('Course Title'),
+      );
+
+      // get selected courses data from db
+      $selected_courses_query = \Drupal::database()->select('asc_courses_processed', 'acp');
+      $selected_courses_query->fields('acp', ['crse_id','subject','catalog_nbr','course_title_long']);
+      $selected_courses_query->condition('crse_id', array_keys($selected_courses), 'IN');
+
+      $selected_courses_results = $selected_courses_query->execute()->fetchAll();
+
+      // build table rows with search results
+      $selected_courses_table_rows=array();
+
+      foreach($selected_courses_results as $data) {
+        $selected_courses_table_rows[$data->crse_id] = array(
+          'crse_id' => $data->crse_id,
+          'subject' => $data->subject,
+          'catalog_nbr' => $data->catalog_nbr,
+          'course_title_long' => $data->course_title_long,
+        );
+      }
+    }
+
+    // D-Org number
     $form['dept_org'] = array(
       '#type' => 'textfield',
       '#title' => $this->t('D-Org number(s)'),
@@ -38,10 +75,26 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $form['individual_courses'] = array(
       '#type' => 'textfield',
       '#title' => $this->t('Course IDs'),
-      '#default_value' => $config->get('asc_courses.individual_courses'),
+      '#default_value' => $selected_courses_delimited,
       '#description' => $this->t('Individual course IDs, separated by commas'),
     );
-    
+
+    if(!empty($selected_courses_table_rows)) {
+      $form['selected_courses_details'] = [
+        '#type' => 'details',
+        '#title' => 'Selected Course IDs',
+        '#open' => FALSE,
+      ];
+
+      // add table to form
+      $form['selected_courses_details']['selected_courses_table'] = [
+        '#type' => 'table',
+        '#header' => $selected_courses_table_header,
+        '#rows' => $selected_courses_table_rows,
+        // '#weight' => 100,
+      ];
+    }
+
     // Import now?
     $form['import_now'] = array(
       '#type' => 'checkbox',
@@ -52,7 +105,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
 
     ////////// Table of D-orgs //////////
-    
+
     // table header
     $table_header = array(
       'dept_org'        => t('D-ORG'),
@@ -61,8 +114,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       // 'subject_name'    => t('Subject Title'),
       // 'catalog_nbr' => t('catalog_nbr'),
       // 'course_title_long' => t('course_title_long'),
-      // 'opt' => t('operations'),
-      // 'opt1' => t('operations'),
     );
 
     $static_dorglist = AscCoursesApi::getDorgList();
@@ -85,6 +136,13 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       ];
     }
 
+    // $form['dorg_list'] = [
+    //   '#type' => 'details',
+    //   '#title' => 'D-Org List',
+    //   '#open' => TRUE,
+    //   '#weight' => 100,
+    // ];
+
     // add table to form
     $form['table'] = [
       '#type' => 'table',
@@ -92,9 +150,9 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#rows' => $dorg_table_rows,
       '#weight' => 100,
       '#empty' => t('No courses found'),
-    ]; 
-    
-    
+    ];
+
+
     return $form;
   }
 
@@ -115,7 +173,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $config->save();
 
     $import = $form_state->getValue('import_now');
-    
+
     // Run courses import if requested
     if($import) {
       \Drupal::logger('asc_courses')->notice("Running courses import.");
@@ -128,7 +186,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $import_message .= count($importer->created_nodes) . " courses created. ";
       $import_message .= count($importer->updated_nodes) . " courses updated.";
     }
-    
+
     // do anyone else's form stuff
     $return = parent::submitForm($form, $form_state);
 
@@ -136,7 +194,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     if(!empty($import_message)) {
       \Drupal::messenger()->addStatus(t($import_message));
     }
-    
+
     return $return;
   }
 
diff --git a/web/modules/custom/asc_courses/src/Plugin/migrate/CourseDataCached.php b/web/modules/custom/asc_courses/src/Plugin/migrate/CourseDataCached.php
deleted file mode 100644
index 620ac3c70ce38bc4c937fdc7ee223982ac1c04d2..0000000000000000000000000000000000000000
--- a/web/modules/custom/asc_courses/src/Plugin/migrate/CourseDataCached.php
+++ /dev/null
@@ -1,205 +0,0 @@
-<?php
-namespace Drupal\asc_courses\Plugin\migrate\source;
-
-use Drupal\Core\Database\Query\Condition;
-use Drupal\migrate\Row;
-// use Drupal\migrate\MigrateSkipRowException;
-// use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
-use Drupal\migrate\Plugin\migrate\source\SqlBase;
-
-/**
- * Drupal 7 file_entity source from database.
- *
- * @MigrateSource(
- *   id = "asc_person",
- *   source_provider = "user"
- * )
- */
-class CourseDataCached extends SqlBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function query() {
-    //echo "AscPerson::query()\n";
-
-    /*
-      -- Users who also have people nodes (where clearly identifiable)
-      select
-        u.uid,
-        u.mail,
-        substring(u.mail, 1, locate('@osu.edu', u.mail)-1) as umail,
-        u.name,
-        substring(u.name, 1, locate('@osu.edu', u.name)-1) as uname,
-        fdfape.entity_id,
-        fdfapp.entity_id,
-        fdfape.field_asc_people_email_email,
-        fdfapp.field_asc_people_picture_opic
-      from
-        users u
-          left outer join field_data_field_asc_people_email fdfape
-            on u.mail = fdfape.field_asc_people_email_email
-          left outer join field_data_field_asc_people_picture fdfapp
-            on fdfape.entity_id = fdfapp.entity_id
-      ;
-
-
-      select
-        substring(u.mail, 1, locate('@osu.edu', u.mail)-1) as umail
-      from users u
-      union
-      select field_asc_people_picture_opic
-      from field_data_field_asc_people_picture fdfapp
-      ;
-
-      select
-        u.mail as umail
-      from users u
-      union
-      select field_asc_people_picture_opic
-      from field_data_field_asc_people_picture;
-
-      select uid, name, mail, created, access, login, status from users limit 20;
-
-        select
-
-        from
-          users u
-    */
-
-    $course_data_query = $this->select('asc_course_data', 'acd');
-    $course_data_query->fields('acd', ['id', 'date', 'dept_org', 'raw_json']);
-    // $course_data_query->
-
-
-
-    $people_query = $this->select('node', 'n');
-    $people_query->addExpression('n.nid', 'asc_people_id');
-    $people_query->fields('n', array('title', 'created', 'changed', 'status'));
-    $people_query->leftJoin('field_data_field_asc_people_picture', 'fdfapp', 'n.nid = fdfapp.entity_id');
-    $people_query->leftJoin('field_data_field_asc_people_email', 'fdfape', 'n.nid = fdfape.entity_id');
-    $people_query->addExpression('fdfapp.field_asc_people_picture_opic', 'osu_name_num');
-    $people_query->addExpression('fdfape.field_asc_people_email_email', 'name');
-    $people_query->addExpression('fdfape.field_asc_people_email_email', 'mail');
-    $people_query->addExpression('0', 'login');
-    $people_query->addExpression('0', 'access');
-    $people_query->condition('n.status', 0, '>');
-    $people_query->condition('n.type', 'asc_people', '=');
-    // echo "people query: $people_query\n";
-
-    // $pictures_query = $this->select('field_data_field_asc_people_picture', 'fdfapp');
-    // $pictures_query->addExpression("fdfapp.entity_id", 'asc_people_id');
-    // $pictures_query->addExpression("'node'", "entity_type");
-    // $pictures_query->addExpression("fdfapp.entity_id", "entity_id");
-    // $pictures_query->addExpression("concat(fdfapp.field_asc_people_picture_opic, '@osu.edu')", "name");
-    // $pictures_query->addExpression("concat(fdfapp.field_asc_people_picture_opic, '@osu.edu')", "mail");
-    // $pictures_query->addExpression("fdfapp.field_asc_people_picture_opic", "osu_name_num");
-
-    // $pictures_query->addExpression("1", "status");
-    // $pictures_query->addExpression("unix_timestamp()", "created");
-    // $pictures_query->range(1,1);
-    // echo "pictures query: $pictures_query\n";
-
-    return $people_query;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function count($refresh = false) {
-    //echo "AscPerson::count()\n";
-
-    $peoplecount_query = $this->select('node');
-    $peoplecount_query->condition('type', 'asc_people', '=');
-    $peoplecount_query->condition('status', 0, '>');
-    $peoplecount_query->addExpression('count(*)', 'count');
-    $peoplecount = $peoplecount_query->execute()->fetchField(0);
-
-    return $peoplecount;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function prepareRow(Row $row) {
-    // print_r($row);
-    $mail = $row->getSourceProperty('mail');
-    if(empty($mail)) {
-      $osu_name_num = $row->getSourceProperty('osu_name_num');
-      $mail = $osu_name_num . "@osu.edu";
-      $row->setSourceProperty('mail', $mail);
-      echo "Update email using OSU name.#: $mail\n";
-    }
-
-    foreach (array_keys($this->getFields('node', 'asc_people')) as $field) {
-      $nid = $row->getSourceProperty('asc_people_id');
-      $row->setSourceProperty($field, $this->getFieldValues('node', $field, $nid));
-    }
-
-    $row->setSourceProperty('roles', ['department_faculty_staff']);
-
-    // $node_query = $this->select('node', 'n')
-    //   ->fields('n', array('created', 'changed'))
-    //   ->condition('n.nid', $nid);
-    // $node_query->addExpression('0', 'login');
-    // $node_query->addExpression('0', 'access');
-    // $node_row = $node_query->execute()->fetch();
-
-    // foreach($node_row as $field_name => $field_value) {
-    //   $row->setSourceProperty($field_name, $field_value);
-    // }
-
-    return parent::prepareRow($row);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function fields() {
-    $fields = [
-      'uid' => $this->t('User ID'),
-      'name' => $this->t('Username'),
-      //'pass' => $this->t('Password'),
-      'mail' => $this->t('Email address'),
-      //'signature' => $this->t('Signature'),
-      //'signature_format' => $this->t('Signature format'),
-      'created' => $this->t('Registered timestamp'),
-      'access' => $this->t('Last access timestamp'),
-      'login' => $this->t('Last login timestamp'),
-      'changed' => $this->t('Last time user was updated'),
-      'status' => $this->t('Status'),
-      'timezone' => $this->t('Timezone'),
-      'language' => $this->t('Language'),
-      'picture' => $this->t('Picture'),
-      'init' => $this->t('Init'),
-      'data' => $this->t('User data'),
-      'roles' => $this->t('Roles'),
-    ];
-
-    return $fields;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getIds() {
-    /*
-    $ids['fid']['type'] = 'integer';
-    return $ids;
-    return [
-      'uid' => [
-        'type' => 'integer',
-        'alias' => 'u',
-      ],
-    ];
-    */
-    $ids = [
-      'asc_people_id' => [
-        'type' => 'string'
-      ]
-    ];
-
-    return $ids;
-  }
-}
-