docs: function readApicConfig(dir) {
    var cfg = {};
  
    var filename;
    var parsed;
    //read the apic.json
    try {
      filename = path.join(dir, 'apic.json');
      if (fs.existsSync(filename)) {
        parsed = JSON.parse(fs.readFileSync(filename));
        cfg.applications = parsed.applications || {};
        cfg.plans = parsed.plans || {};
  
        //post-process: caculate the hash value of the client secret in apic.json
        for (var a in cfg.applications) {
          var app = cfg.applications[a];
          if (typeof app === 'object') {
            var plain_secret = app['client-secret'];
            if (typeof plain_secret === 'string') {
              var hash = Crypto.createHash('sha256').update(plain_secret).digest('base64');
              app['client-secret'] = hash;
            }
          }
        }
      }
    } catch (e1) {
      logger.warn('Failed to read/parse apic.json:', e1);
    }
  
    //read the apic-tls-profiles.json
    try {
      filename = path.join(dir, 'apic-tls-profiles.json');
      if (fs.existsSync(filename)) {
        parsed = JSON.parse(fs.readFileSync(filename));
        cfg['tls-profiles'] = parsed || {};
  
        //post-process: read the key and cert file contents
        for (var p in cfg['tls-profiles']) {
          var profile = cfg['tls-profiles'][p];
          if (typeof profile === 'object') {
            if (profile.key && typeof profile.key === 'string') {
              try {
                profile.key = path.resolve(dir, profile.key);
                profile.key = {
                  name: profile.key,
                  content: fs.readFileSync(profile.key) };
              } catch (e) {
                logger.warn('Failed to read the key file "%s":', profile.key, e);
              }
            }
            if (profile.cert && typeof profile.cert === 'string') {
              try {
                profile.cert = path.resolve(dir, profile.cert);
                profile.cert = {
                  name: profile.cert,
                  content: fs.readFileSync(profile.cert) };
              } catch (e) {
                logger.warn('Failed to read the cert file "%s":', profile.cert, e);
              }
            }
            if (Array.isArray(profile.ca)) { //ca is an array
              for (var q in profile.ca) {
                try {
                  var ca = profile.ca[q];
                  ca = path.resolve(dir, ca);
                  ca = fs.readFileSync(ca);
                  profile.ca[q] = {
                    name: profile.ca[q],
                    content: ca };
                } catch (e) {
                  logger.warn('Failed to read the ca file "%s":', ca, e);
                }
              }
            } else {
              profile.ca = [];
            }
          }
        }
      }
    } catch (e2) {
      logger.warn('Failed to read/parse apic-tls-profiles.json:', e2);
    }
  
    return cfg;
  }