function Config(config) {
  EventEmitter.call(this)

  // 1. start by cloning the defaults
  Object.assign(this, defaultConfig())

  // 2. initialize undocumented, internal-only default values

  // feature flags are mostly private settings for gating unreleased features
  // flags are set in the feature_flags.js file
  this.feature_flag = copy.shallow(featureFlag.prerelease)

  // set by environment
  this.newrelic_home = null
  // set by configuration file loader
  this.config_file_path = null

  // set by collector on handshake
  this.run_id = null
  this.account_id = null
  this.application_id = null
  this.web_transactions_apdex = Object.create(null)
  this.cross_process_id = null
  this.encoding_key = null
  this.obfuscatedId = null
  this.primary_application_id = null
  this.trusted_account_ids = null
  this.trusted_account_key = null
  this.sampling_target = 10
  this.sampling_target_period_in_seconds = 60
  this.max_payload_size_in_bytes = DEFAULT_MAX_PAYLOAD_SIZE_IN_BYTES

  // this value is arbitrary
  this.max_trace_segments = 900

  this.entity_guid = null

  // feature level of this account
  this.product_level = 0
  // product-level related
  this.collect_traces = true
  this.collect_errors = true
  this.collect_span_events = true

  this.browser_monitoring.loader = 'rum'
  this.browser_monitoring.loader_version = ''

  // Settings to play nice with DLPs (see NODE-1044).
  this.simple_compression = false // Disables subcomponent compression
  this.put_for_data_send = false // Changes http verb for harvest

  // 3. override defaults with values from the loaded / passed configuration
  this._fromPassed(config)

  // 3.5. special values (only Azure environment APP_POOL_ID for now)
  this._fromSpecial()

  // 4. override config with environment variables
  this._featureFlagsFromEnv()
  this._fromEnvironment()

  // 5. clean up anything that requires postprocessing
  this._canonicalize()

  // 6. put the version in the config
  this.version = require('../../package.json').version

  // TODO: this may belong in canonicalize.
  if (!this.event_harvest_config) {
    this.event_harvest_config = {
      report_period_ms: 60000,
      harvest_limits: {
        analytic_event_data: this.transaction_events.max_samples_stored,
        custom_event_data: this.custom_insights_events.max_samples_stored,
        error_event_data: this.error_collector.max_event_samples_stored,
        span_event_data: this.span_events.max_samples_stored,
        log_event_data: this.application_logging.forwarding.max_samples_stored
      }
    }
  }

  // 7. serverless_mode specific settings
  this._enforceServerless(config)

  // 8. apply high security overrides
  if (this.high_security) {
    if (this.security_policies_token) {
      throw new Error(
        'Security Policies and High Security Mode cannot both be present ' +
          'in the agent configuration. If Security Policies have been set ' +
          'for your account, please ensure the security_policies_token is ' +
          'set but high_security is disabled (default).'
      )
    }
    this._applyHighSecurity()
  }

  // 9. Set instance attribute filter using updated context
  this.attributeFilter = new AttributeFilter(this)

  // 10. Setup labels for both `collector/facts` and application logging
  this.parsedLabels = parseLabels(this.labels, logger)
  this.loggingLabels = this._setApplicationLoggingLabels()
}
Parses and manages the agent configuration.

@param {object} config Configuration object as read from a `newrelic.js`
file. This is used as the baseline, which is the overridden by environment
variables and feature flags.

@class