code: @FFDCIgnore(IOException.class)
      // The feature manager and kernel only do provisioning from a single thread, so this is paranoia, but should
      // never be contended.
      private synchronized void readCache() {
          if (!!!_cacheRead) {
              BufferedReader reader = null;
              try {
                  if (_cacheFile != null && _cacheFile.exists() && _cacheFile.isFile()) {
                      reader = new BufferedReader(new FileReader(_cacheFile));
                      String line;
                      while ((line = reader.readLine()) != null) {
                          try {
                              BundleInfo bInfo = new BundleInfo(line);
                              if (bInfo.file.exists() && bInfo.symbolicName != null) {
                                  addToCache(bInfo);
                              }
                          } catch (IOException e) {
                              // IOException creating BundleInfo.
                          }
                      }
                  }
              } catch (IOException e) {
                  // If we can't load the cache then we just throw everything 
                  // away and do the more expensive read from original data.
                  _bundleLocations.clear();
                  _cacheBySymbolicName.clear();
              } finally {
                  Utils.tryToClose(reader);
              }
              _cacheRead = true;
              // now we have read the cache we want to insure all base locations are processed.
              for (String loc : new HashSet<String>(_locations)) {
                  includeBaseLocation(loc);
              }
          }
      }
docs: This method reads the cache. Each line in the file represents a different bundle. The BundleInfo
  constructor reads the cache line and validates the data re-reading from the bundle manifest if required.
  
  @param cache