diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 8730012b..81a3f58d 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -18,7 +18,10 @@
 			"extensions": [
 				"bmewburn.vscode-intelephense-client",
 				"xdebug.php-debug",
-				"DEVSENSE.composer-php-vscode"
+				"DEVSENSE.composer-php-vscode",
+				"xdebug.php-pack",
+				"recca0120.vscode-phpunit",
+				"eamodio.gitlens"
 			]
 		}
 	}
diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml
index 574c3a53..109abb8a 100644
--- a/.github/workflows/php.yml
+++ b/.github/workflows/php.yml
@@ -11,7 +11,8 @@ jobs:
     name: Linting
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3
+      - name: Checkout code
+        uses: actions/checkout@v3
       - name: Set up PHP
         uses: shivammathur/setup-php@v2
         with:
@@ -25,28 +26,24 @@ jobs:
     name: Source Clear Scan
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
+      - name: Checkout code
+        uses: actions/checkout@v3
       - name: Source clear scan
         env:
           SRCCLR_API_TOKEN: ${{ secrets.SRCCLR_API_TOKEN }}
         run: curl -sSL https://download.sourceclear.com/ci.sh | bash -s – scan
 
-  integration_tests:
-    name: Integration Tests
-    uses: optimizely/php-sdk/.github/workflows/integration_test.yml@master
-    secrets:
-      CI_USER_TOKEN: ${{ secrets.CI_USER_TOKEN }}
-      TRAVIS_COM_TOKEN: ${{ secrets.TRAVIS_COM_TOKEN }}
-
   unit_tests:
     name: Unit Tests ${{ matrix.php-versions }}
+    needs: [ linting, source_clear ]
     runs-on: ubuntu-latest
     strategy:
       fail-fast: false
       matrix:
         php-versions: [ '8.1', '8.2' ]
     steps:
-      - uses: actions/checkout@v3
+      - name: Checkout code
+        uses: actions/checkout@v3
       - name: Set up PHP v${{ matrix.php-versions }}
         uses: shivammathur/setup-php@v2
         with:
@@ -77,3 +74,11 @@ jobs:
         run: |
           composer global require php-coveralls/php-coveralls
           php-coveralls --coverage_clover=./build/logs/clover.xml -v
+
+  integration_tests:
+    name: Integration Tests
+    needs: [ unit_tests ]
+    uses: optimizely/php-sdk/.github/workflows/integration_test.yml@master
+    secrets:
+      CI_USER_TOKEN: ${{ secrets.CI_USER_TOKEN }}
+      TRAVIS_COM_TOKEN: ${{ secrets.TRAVIS_COM_TOKEN }}
diff --git a/src/Optimizely/ProjectConfigManager/HTTPProjectConfigManager.php b/src/Optimizely/ProjectConfigManager/HTTPProjectConfigManager.php
index 7b962aee..83e5f839 100644
--- a/src/Optimizely/ProjectConfigManager/HTTPProjectConfigManager.php
+++ b/src/Optimizely/ProjectConfigManager/HTTPProjectConfigManager.php
@@ -1,12 +1,12 @@
 <?php
 /**
- * Copyright 2019-2020, 2022 Optimizely Inc and Contributors
+ * Copyright 2019-2020, 2022-2023 Optimizely Inc and Contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -75,7 +75,12 @@ class HTTPProjectConfigManager implements ProjectConfigManagerInterface
     /**
     * @var String datafile access token.
     */
-    private $datafileAccessToken;
+    private $_datafileAccessToken;
+
+    /**
+     * @var boolean Flag indicates that the datafile access token is valid.
+     */
+    private $_isDatafileAccessTokenValid;
 
     public function __construct(
         $sdkKey = null,
@@ -93,8 +98,8 @@ public function __construct(
         $this->_logger = $logger ?: new NoOpLogger();
         $this->_errorHandler = $errorHandler ?: new NoOpErrorHandler();
         $this->_notificationCenter = $notificationCenter ?: new NotificationCenter($this->_logger, $this->_errorHandler);
-        $this->datafileAccessToken = $datafileAccessToken;
-        $this->isDatafileAccessTokenValid = Validator::validateNonEmptyString($this->datafileAccessToken);
+        $this->_datafileAccessToken = $datafileAccessToken;
+        $this->_isDatafileAccessTokenValid = Validator::validateNonEmptyString($this->_datafileAccessToken);
 
         $this->httpClient = new HttpClient();
         $this->_url = $this->getUrl($sdkKey, $url, $urlTemplate);
@@ -136,7 +141,7 @@ protected function getUrl($sdkKey, $url, $urlTemplate)
         }
 
         if (!Validator::validateNonEmptyString($urlTemplate)) {
-            if ($this->isDatafileAccessTokenValid) {
+            if ($this->_isDatafileAccessTokenValid) {
                 $urlTemplate = ProjectConfigManagerConstants::AUTHENTICATED_DATAFILE_URL_TEMPLATE;
             } else {
                 $urlTemplate = ProjectConfigManagerConstants::DEFAULT_DATAFILE_URL_TEMPLATE;
@@ -179,8 +184,8 @@ protected function fetchDatafile()
         }
 
         // Add Authorization header if access token available.
-        if ($this->isDatafileAccessTokenValid) {
-            $headers['Authorization'] = "Bearer {$this->datafileAccessToken}";
+        if ($this->_isDatafileAccessTokenValid) {
+            $headers['Authorization'] = "Bearer {$this->_datafileAccessToken}";
         }
 
         $options = [