/*
 * Copyright 2010 Google Inc.
 *
 * 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Author: jmarantz@google.com (Joshua Marantz)

#ifndef NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_OPTIONS_H_
#define NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_OPTIONS_H_

#include <bitset>
#include <cstddef>
#include <map>
#include <set>
#include <utility>
#include <vector>

#include "base/logging.h"
#include "net/instaweb/rewriter/public/domain_lawyer.h"
#include "net/instaweb/rewriter/public/experiment_util.h"
#include "net/instaweb/rewriter/public/file_load_policy.h"
#include "net/instaweb/rewriter/public/javascript_library_identification.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/dense_hash_map.h"
#include "pagespeed/kernel/base/enum_set.h"
#include "pagespeed/kernel/base/fast_wildcard_group.h"
#include "pagespeed/kernel/base/gtest_prod.h"
#include "pagespeed/kernel/base/hasher.h"
#include "pagespeed/kernel/base/md5_hasher.h"
#include "pagespeed/kernel/base/proto_util.h"
#include "pagespeed/kernel/base/rde_hash_map.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/sha1_signature.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_hash.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/thread_annotations.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/base/wildcard.h"
#include "pagespeed/kernel/http/http_names.h"
#include "pagespeed/kernel/http/semantic_type.h"
#include "pagespeed/kernel/http/user_agent_matcher.h"
#include "pagespeed/kernel/util/copy_on_write.h"

namespace net_instaweb {

class MessageHandler;
class PurgeSet;
class RequestHeaders;

struct HttpOptions;

// Defines a set of customizations that can be applied to any Rewrite.  There
// are multiple categories of customizations:
//   - filter sets (controllable individually or by level)
//   - options (arbitrarily typed variables)
//   - domain customization (see DomainLawyer class).
//   - FileLoadPolicy (enables reading resources as files from the file system)
// RewriteOptions can be specified in several ways, forming a hierarchy:
//   - Globally for a process
//   - Customized per server (e.g. Apache VirtualHost)
//   - Customized at Directory level (e.g. Apache <Directory> or .htaccess)
//   - Tuned at the request-level (e.g. via request-headers or query-params).
// The hierarchy is implemented via Merging.
//
// The options are themselves a complex system.  Many Option objects are
// instantiated for each RewriteOptions instance.  RewriteOptions can be
// constructed and destroyed multiple times per request so to reduce
// this cost, the static aspects of Options are factored out into
// Properties, which are intialized once per process via
// RewriteOptions::Initialize.  Subclasses may also add new Properties
// and so property-list-merging takes place at Initialization time.
class RewriteOptions {
 protected:
  // These being protected is against the style guide but necessary to keep
  // them protected while still being used by the Option class hierarchy.
  // Note that iwyu.py incorrectly complains about the template classes but
  // scripts/iwyu manually removes the warning.
  class PropertyBase;
  template<class ValueType> class Property;
  template<class RewriteOptionsSubclass, class OptionClass> class PropertyLeaf;

 public:
  // If you add or remove anything from this list, you must also update the
  // kFilterVectorStaticInitializer array in rewrite_options.cc.  If you add
  // an image-related filter or a css-related filter, you must add it to the
  // kRelatedFilters array in image_rewrite_filter.cc and/or css_filter.cc
  //
  // Each filter added here should go into at least one of the filter-arrays
  // in rewrite_options.cc, even if it's just kDangerousFilterSet.
  //
  // Filters that can improve bandwidth but have basically zero risk
  // of breaking pages should be added to
  // kOptimizeForBandwidthFilterSet.  Filters with relatively low risk
  // should be added to kCoreFilterSet.
  enum Filter {
    kAddBaseTag,  // Update kFirstFilter if you add something before this.
    kAddHead,
    kAddIds,
    kAddInstrumentation,
    kComputeStatistics,
    kCachePartialHtml,
    kCanonicalizeJavascriptLibraries,
    kCollapseWhitespace,
    kCollectFlushEarlyContentFilter,
    kCombineCss,
    kCombineHeads,
    kCombineJavascript,
    kComputeCriticalCss,
    kComputeVisibleText,
    kConvertGifToPng,
    kConvertJpegToProgressive,
    kConvertJpegToWebp,
    kConvertMetaTags,
    kConvertPngToJpeg,
    kConvertToWebpAnimated,
    kConvertToWebpLossless,
    kDebug,
    kDecodeRewrittenUrls,
    kDedupInlinedImages,
    kDeferIframe,
    kDeferJavascript,
    kDelayImages,
    kDeterministicJs,
    kDisableJavascript,
    kDivStructure,
    kElideAttributes,
    kExperimentCollectMobImageInfo,
    kExperimentSpdy,  // Temporary and will be removed soon.
    kExplicitCloseTags,
    kExtendCacheCss,
    kExtendCacheImages,
    kExtendCachePdfs,
    kExtendCacheScripts,
    kFallbackRewriteCssUrls,
    kFixReflows,
    kFlattenCssImports,
    kFlushSubresources,
    kHandleNoscriptRedirect,
    kHtmlWriterFilter,
    kIncludeJsSourceMaps,
    kInlineCss,
    kInlineGoogleFontCss,
    kInlineImages,
    kInlineImportToLink,
    kInlineJavascript,
    kInPlaceOptimizeForBrowser,
    kInsertDnsPrefetch,
    kInsertGA,
    kInsertImageDimensions,
    kJpegSubsampling,
    kLazyloadImages,
    kLeftTrimUrls,
    kLocalStorageCache,
    kMakeGoogleAnalyticsAsync,
    kMakeShowAdsAsync,
    kMobilize,
    kMobilizePrecompute,  // TODO(jud): This is unused, remove it.
    kMoveCssAboveScripts,
    kMoveCssToHead,
    kOutlineCss,
    kOutlineJavascript,
    kPedantic,
    kPrioritizeCriticalCss,
    kRecompressJpeg,
    kRecompressPng,
    kRecompressWebp,
    kRemoveComments,
    kRemoveQuotes,
    kResizeImages,
    kResizeMobileImages,
    kResizeToRenderedImageDimensions,
    kResponsiveImages,
    kResponsiveImagesZoom,
    kRewriteCss,
    kRewriteDomains,
    kRewriteJavascriptExternal,
    kRewriteJavascriptInline,
    kRewriteStyleAttributes,
    kRewriteStyleAttributesWithUrl,
    kServeDeprecationNotice,
    kSplitHtml,
    kSplitHtmlHelper,
    kSpriteImages,
    kStripImageColorProfile,
    kStripImageMetaData,
    kStripNonCacheable,
    kStripScripts,
    kEndOfFilters
  };

  enum EnabledEnum {
    // Don't optimize HTML. Do serve .pagespeed. Can be overridden via query
    // param.
    kEnabledOff,
    // Pagespeed runs normally.  Can be overridden via query param.
    kEnabledOn,
    // Completely passive. Do not serve .pagespeed. Return from handlers
    // immediately. Cannot be overridden via query param.
    kEnabledUnplugged,
  };

  // Any new Option added should have a corresponding name here that must be
  // passed in when Add*Property is called in AddProperties(). You must also
  // update the LookupOptionByNameTest method in rewrite_options_test.cc. If
  // you add an image-related option or css-related option you must also add
  // it to the kRelatedOptions array in image_rewrite_filter.cc and/or
  // css_filter.cc.
  static const char kAcceptInvalidSignatures[];
  static const char kAccessControlAllowOrigins[];
  static const char kAddOptionsToUrls[];
  static const char kAllowLoggingUrlsInLogRecord[];
  static const char kAllowOptionsToBeSetByCookies[];
  static const char kAllowVaryOn[];
  static const char kAlwaysMobilize[];
  static const char kAlwaysRewriteCss[];
  static const char kAnalyticsID[];
  static const char kAvoidRenamingIntrospectiveJavascript[];
  static const char kAwaitPcacheLookup[];
  static const char kBeaconReinstrumentTimeSec[];
  static const char kBeaconUrl[];
  static const char kBlinkMaxHtmlSizeRewritable[];
  static const char kCacheFragment[];
  static const char kCacheSmallImagesUnrewritten[];
  static const char kClientDomainRewrite[];
  static const char kCombineAcrossPaths[];
  static const char kContentExperimentID[];
  static const char kContentExperimentVariantID[];
  static const char kCriticalImagesBeaconEnabled[];
  static const char kCriticalLineConfig[];
  static const char kCssFlattenMaxBytes[];
  static const char kCssImageInlineMaxBytes[];
  static const char kCssInlineMaxBytes[];
  static const char kCssOutlineMinBytes[];
  static const char kCssPreserveURLs[];
  static const char kDefaultCacheHtml[];
  static const char kDisableBackgroundFetchesForBots[];
  static const char kDisableRewriteOnNoTransform[];
  static const char kDistributeFetches[];
  static const char kDistributedRewriteKey[];
  static const char kDistributedRewriteServers[];
  static const char kDistributedRewriteTimeoutMs[];
  static const char kDomainRewriteCookies[];
  static const char kDomainRewriteHyperlinks[];
  static const char kDomainShardCount[];
  static const char kDownstreamCachePurgeMethod[];
  static const char kDownstreamCacheRebeaconingKey[];
  static const char kDownstreamCacheRewrittenPercentageThreshold[];
  static const char kEnableAggressiveRewritersForMobile[];
  static const char kEnableBlinkHtmlChangeDetection[];
  static const char kEnableBlinkHtmlChangeDetectionLogging[];
  static const char kEnableCachePurge[];
  static const char kEnableDeferJsExperimental[];
  static const char kEnableExtendedInstrumentation[];
  static const char kEnableFlushEarlyCriticalCss[];
  static const char kEnableLazyLoadHighResImages[];
  static const char kEnablePrioritizingScripts[];
  static const char kEnabled[];
  static const char kEnrollExperiment[];
  static const char kExperimentCookieDurationMs[];
  static const char kExperimentSlot[];
  static const char kFetcherTimeOutMs[];
  static const char kFinderPropertiesCacheExpirationTimeMs[];
  static const char kFinderPropertiesCacheRefreshTimeMs[];
  static const char kFlushBufferLimitBytes[];
  static const char kFlushHtml[];
  static const char kFlushMoreResourcesEarlyIfTimePermits[];
  static const char kGoogleFontCssInlineMaxBytes[];
  static const char kForbidAllDisabledFilters[];
  static const char kHideRefererUsingMeta[];
  static const char kHttpCacheCompressionLevel[];
  static const char kIdleFlushTimeMs[];
  static const char kImageInlineMaxBytes[];
  // TODO(huibao): Unify terminology for image rewrites. For example,
  // kImageJpeg*Quality might be renamed to kImageJpegQuality.
  static const char kImageJpegNumProgressiveScans[];
  static const char kImageJpegNumProgressiveScansForSmallScreens[];
  static const char kImageJpegQualityForSaveData[];
  static const char kImageJpegRecompressionQuality[];
  static const char kImageJpegRecompressionQualityForSmallScreens[];
  static const char kImageLimitOptimizedPercent[];
  static const char kImageLimitRenderedAreaPercent[];
  static const char kImageLimitResizeAreaPercent[];
  static const char kImageMaxRewritesAtOnce[];
  static const char kImagePreserveURLs[];
  static const char kImageRecompressionQuality[];
  static const char kImageResolutionLimitBytes[];
  static const char kImageWebpQualityForSaveData[];
  static const char kImageWebpRecompressionQuality[];
  static const char kImageWebpRecompressionQualityForSmallScreens[];
  static const char kImageWebpAnimatedRecompressionQuality[];
  static const char kImageWebpTimeoutMs[];
  static const char kImplicitCacheTtlMs[];
  static const char kIncreaseSpeedTracking[];
  static const char kInlineOnlyCriticalImages[];
  static const char kInPlacePreemptiveRewriteCss[];
  static const char kInPlacePreemptiveRewriteCssImages[];
  static const char kInPlacePreemptiveRewriteImages[];
  static const char kInPlacePreemptiveRewriteJavascript[];
  static const char kInPlaceResourceOptimization[];
  static const char kInPlaceRewriteDeadlineMs[];
  static const char kInPlaceWaitForOptimized[];
  static const char kJsInlineMaxBytes[];
  static const char kJsOutlineMinBytes[];
  static const char kJsPreserveURLs[];
  static const char kLazyloadImagesAfterOnload[];
  static const char kLazyloadImagesBlankUrl[];
  static const char kLoadFromFileCacheTtlMs[];
  static const char kLogBackgroundRewrite[];
  static const char kLogMobilizationSamples[];
  static const char kLogRewriteTiming[];
  static const char kLogUrlIndices[];
  static const char kLowercaseHtmlNames[];
  static const char kMaxCacheableResponseContentLength[];
  static const char kMaxCombinedCssBytes[];
  static const char kMaxCombinedJsBytes[];
  static const char kMaxHtmlCacheTimeMs[];
  static const char kMaxHtmlParseBytes[];
  static const char kMaxImageBytesForWebpInCss[];
  static const char kMaxImageSizeLowResolutionBytes[];
  static const char kMaxInlinedPreviewImagesIndex[];
  static const char kMaxLowResImageSizeBytes[];
  static const char kMaxLowResToHighResImageSizePercentage[];
  static const char kMaxPrefetchJsElements[];
  static const char kMaxRewriteInfoLogSize[];
  static const char kMaxUrlSegmentSize[];
  static const char kMaxUrlSize[];
  static const char kMetadataCacheStalenessThresholdMs[];
  static const char kMinCacheTtlMs[];
  static const char kMinImageSizeLowResolutionBytes[];
  static const char kMinResourceCacheTimeToRewriteMs[];
  static const char kMobBeaconCategory[];
  static const char kMobBeaconUrl[];
  static const char kMobMapLocation[];
  static const char kMobPhoneNumber[];
  static const char kMobConversionId[];
  static const char kMobMapConversionLabel[];
  static const char kMobPhoneConversionLabel[];
  static const char kMobConfig[];
  static const char kMobIframe[];
  static const char kMobIframeDisable[];
  static const char kMobIframeViewport[];
  static const char kMobLayout[];
  static const char kMobNav[];
  static const char kMobLabeledMode[];
  static const char kMobNavClasses[];
  static const char kMobStatic[];
  static const char kMobTheme[];
  static const char kModifyCachingHeaders[];
  static const char kNoop[];
  static const char kNoTransformOptimizedImages[];
  static const char kNonCacheablesForCachePartialHtml[];
  static const char kObliviousPagespeedUrls[];
  static const char kOptionCookiesDurationMs[];
  static const char kOverrideCachingTtlMs[];
  static const char kPreserveSubresourceHints[];
  static const char kPreserveUrlRelativity[];
  static const char kPrivateNotVaryForIE[];
  static const char kProactiveResourceFreshening[];
  static const char kProactivelyFreshenUserFacingRequest[];
  static const char kProgressiveJpegMinBytes[];
  static const char kPubliclyCacheMismatchedHashesExperimental[];
  static const char kRejectBlacklistedStatusCode[];
  static const char kRejectBlacklisted[];
  static const char kRemoteConfigurationTimeoutMs[];
  static const char kRemoteConfigurationUrl[];
  static const char kReportUnloadTime[];
  static const char kRequestOptionOverride[];
  static const char kRespectVary[];
  static const char kRespectXForwardedProto[];
  static const char kResponsiveImageDensities[];
  static const char kRewriteDeadlineMs[];
  static const char kRewriteLevel[];
  static const char kRewriteRandomDropPercentage[];
  static const char kRewriteUncacheableResources[];
  static const char kRunningExperiment[];
  static const char kServeGhostClickBusterWithSplitHtml[];
  static const char kServeSplitHtmlInTwoChunks[];
  static const char kServeStaleIfFetchError[];
  static const char kServeStaleWhileRevalidateThresholdSec[];
  static const char kServeXhrAccessControlHeaders[];
  static const char kStickyQueryParameters[];
  static const char kSupportNoScriptEnabled[];
  static const char kTestOnlyPrioritizeCriticalCssDontApplyOriginalCss[];
  static const char kUrlSigningKey[];
  static const char kUseAnalyticsJs[];
  static const char kUseBlankImageForInlinePreview[];
  static const char kUseExperimentalJsMinifier[];
  static const char kUseFallbackPropertyCacheValues[];
  static const char kUseImageScanlineApi[];
  static const char kUseSelectorsForCriticalCss[];
  static const char kUseSmartDiffInBlink[];
  static const char kXModPagespeedHeaderValue[];
  static const char kXPsaBlockingRewrite[];
  // Options that require special handling, e.g. non-scalar values
  static const char kAllow[];
  static const char kBlockingRewriteRefererUrls[];
  static const char kDisableFilters[];
  static const char kDisallow[];
  static const char kDistributableFilters[];  // For experimentation.
  static const char kDomain[];
  static const char kDownstreamCachePurgeLocationPrefix[];
  static const char kEnableFilters[];
  static const char kExperimentVariable[];
  static const char kExperimentSpec[];
  static const char kForbidFilters[];
  static const char kInlineResourcesWithoutExplicitAuthorization[];
  static const char kRetainComment[];
  // 2-argument ones:
  static const char kCustomFetchHeader[];
  static const char kLoadFromFile[];
  static const char kLoadFromFileMatch[];
  static const char kLoadFromFileRule[];
  static const char kLoadFromFileRuleMatch[];
  static const char kMapOriginDomain[];
  static const char kMapProxyDomain[];
  static const char kMapRewriteDomain[];
  static const char kShardDomain[];
  // 3-argument ones:
  static const char kLibrary[];
  static const char kUrlValuedAttribute[];
  // apache/ or system/ specific:
  // TODO(matterbury): move these to system_rewrite_options.cc?
  static const char kCacheFlushFilename[];
  static const char kCacheFlushPollIntervalSec[];
  static const char kCompressMetadataCache[];
  static const char kFetcherProxy[];
  static const char kFetchFromModSpdy[];
  static const char kFetchHttps[];
  static const char kFileCacheCleanInodeLimit[];
  static const char kFileCacheCleanIntervalMs[];
  static const char kFileCacheCleanSizeKb[];
  static const char kFileCachePath[];
  static const char kLogDir[];
  static const char kLruCacheByteLimit[];
  static const char kLruCacheKbPerProcess[];
  static const char kMemcachedServers[];
  static const char kMemcachedThreads[];
  static const char kMemcachedTimeoutUs[];
  static const char kProxySuffix[];
  static const char kRateLimitBackgroundFetches[];
  static const char kServeWebpToAnyAgent[];
  static const char kSlurpDirectory[];
  static const char kSlurpFlushLimit[];
  static const char kSlurpReadOnly[];
  static const char kSslCertDirectory[];
  static const char kSslCertFile[];
  static const char kStatisticsEnabled[];
  static const char kStatisticsLoggingChartsCSS[];
  static const char kStatisticsLoggingChartsJS[];
  static const char kStatisticsLoggingEnabled[];
  static const char kStatisticsLoggingIntervalMs[];
  static const char kStatisticsLoggingMaxFileSizeKb[];
  static const char kTestProxy[];
  static const char kTestProxySlurp[];
  static const char kUseSharedMemLocking[];
  // The option name you have when you don't have an option name.
  static const char kNullOption[];

  // We allow query params to be set in custom beacon URLs through the
  // ModPagespeedBeaconUrl option, but we don't use those query params for
  // validation of a beacon URL. The http and https fields should be the URLs
  // that beacon responses are to be sent to, while http_in and https_in are the
  // fields that should be validated on the server to verify if a URL is a
  // beacon request (they are just a precomputation of the corresponding
  // outbound URL with query params stripped).
  struct BeaconUrl {
    GoogleString http;
    GoogleString https;
    GoogleString http_in;
    GoogleString https_in;
  };

  struct Color {
    unsigned char r;
    unsigned char g;
    unsigned char b;
  };

  struct MobTheme {
    Color background_color;
    Color foreground_color;
    GoogleString logo_url;
  };

  struct NameValue {
    NameValue(StringPiece name_in, StringPiece value_in) {
      name_in.CopyToString(&name);
      value_in.CopyToString(&value);
    }
    GoogleString name;
    GoogleString value;
  };

  // We only create this class so that we get the correct ParseFromString()
  // version for parsing densities.
  class ResponsiveDensities : public std::vector<double> {
  };

  class AllowVaryOn {
   public:
    // Strings for display.
    static const char kNoneString[];
    static const char kAutoString[];

    AllowVaryOn() :
        allow_auto_(false),
        allow_accept_(false),
        allow_save_data_(false),
        allow_user_agent_(false) {
    }

    GoogleString ToString() const;

    bool allow_auto() const {
      return allow_auto_;
    }
    void set_allow_auto(bool v) {
      allow_auto_ = v;
    }
    bool allow_accept() const {
      return allow_accept_;
    }
    void set_allow_accept(bool v) {
      allow_accept_ = v;
    }
    bool allow_save_data() const {
      return allow_save_data_ || allow_auto_;
    }
    void set_allow_save_data(bool v) {
      allow_save_data_ = v;
    }
    bool allow_user_agent() const {
      return allow_user_agent_;
    }
    void set_allow_user_agent(bool v) {
      allow_user_agent_ = v;
    }

   private:
    // All of the properties must be included in
    // RewriteOptions::OptionSignature.
    bool allow_auto_;
    bool allow_accept_;
    bool allow_save_data_;
    bool allow_user_agent_;
  };

  bool AllowVaryOnAuto() const {
    return allow_vary_on_.value().allow_auto();
  }
  bool AllowVaryOnAccept() const {
    return allow_vary_on_.value().allow_accept();
  }
  bool AllowVaryOnSaveData() const {
    return allow_vary_on_.value().allow_save_data();
  }
  bool AllowVaryOnUserAgent() const {
    return allow_vary_on_.value().allow_user_agent();
  }
  GoogleString AllowVaryOnToString() const {
    return ToString(allow_vary_on_.value());
  }

  // Returns true if PageSpeed responds differently for image requests with
  // Save-Data header, i.e., using a unique quality and adding
  // "Vary: Save-Data" header.
  bool SupportSaveData() const {
    return (HasValidSaveDataQualities() && AllowVaryOnSaveData());
  }

  void set_allow_vary_on(const AllowVaryOn& x) {
    set_option(x, &allow_vary_on_);
  }

  // Image qualities and parameters, after applying the inheritance rules.
  int64 ImageJpegQuality() const;
  int64 ImageJpegQualityForSmallScreen() const;
  int64 ImageJpegQualityForSaveData() const;
  int64 ImageWebpQuality() const;
  int64 ImageWebpQualityForSmallScreen() const;
  int64 ImageWebpQualityForSaveData() const;
  int64 ImageWebpAnimatedQuality() const;
  int64 ImageJpegNumProgressiveScansForSmallScreen() const;
  // Returns true if any quality for small screen is valid and different from
  // the base quality.
  bool HasValidSmallScreenQualities() const;
  // Returns true if any quality for Save-Data is valid and different from the
  // base quality.
  bool HasValidSaveDataQualities() const;

  // This version index serves as global signature key.  Much of the
  // data emitted in signatures is based on the option ordering, which
  // can change as we add new options.  So every time there is a
  // binary-incompatible change to the option ordering, we bump this
  // version.
  //
  // Note: we now use a two-letter code for identifying enabled filters, so
  // there is no need bump the option version when changing the filter enum.
  //
  // Updating this value will have the indirect effect of flushing the metadata
  // cache. The HTTPCache can be flushed by updating kHttpCacheVersion in
  // http_cache.cc.
  //
  // This version number should be incremented if any default-values
  // are changed, either in an Add*Property() call or via
  // options->set_default.
  static const int kOptionsVersion = 14;

  // Number of bytes used for signature hashing.
  static const int kHashBytes = 20;

  // Number of bytes capacity in the URL invalidation set.
  static const int kCachePurgeBytes = 25000;

  // Determines the scope at which an option is evaluated.  In Apache,
  // for example, kDirectoryScope indicates it can be changed via .htaccess
  // files, which is the only way that sites using shared hosting can change
  // settings.
  //
  // The options are ordered from most permissive to least permissive.
  enum OptionScope {
    kQueryScope,      // customized at query (query-param, request headers,
                      // response headers)
    kDirectoryScope,  // customized at directory level (.htaccess, <Directory>)
    kServerScope,     // customized at server level (e.g. VirtualHost)
    kProcessScope,    // customized at process level only (command-line flags)
    kProcessScopeStrict,  // as above, but fail startup if included in vhost
  };

  static const char kCacheExtenderId[];
  static const char kCollectFlushEarlyContentFilterId[];
  static const char kCssCombinerId[];
  static const char kCssFilterId[];
  static const char kCssImportFlattenerId[];
  static const char kCssInlineId[];
  static const char kGoogleFontCssInlineId[];
  static const char kImageCombineId[];
  static const char kImageCompressionId[];
  static const char kInPlaceRewriteId[];
  static const char kJavascriptCombinerId[];
  static const char kJavascriptInlineId[];
  static const char kJavascriptMinId[];
  static const char kJavascriptMinSourceMapId[];
  static const char kLocalStorageCacheId[];
  static const char kPrioritizeCriticalCssId[];

  static const char kPanelCommentPrefix[];

  // Return the appropriate human-readable filter name for the given filter,
  // e.g. "CombineCss".
  static const char* FilterName(Filter filter);

  // Returns a two-letter id code for this filter, used for for encoding
  // URLs.
  static const char* FilterId(Filter filter);

  // Returns the number of filter ids. This is used to loop over all filter ids
  // using the FilterId() method.
  static int NumFilterIds();

  // Used for enumerating over all entries in the Filter enum.
  static const Filter kFirstFilter = kAddBaseTag;

  typedef EnumSet<Filter, kEndOfFilters> FilterSet;
  typedef std::vector<Filter> FilterVector;

  // Convenience name for a set of rewrite filter ids.
  typedef std::set<GoogleString> FilterIdSet;

  // Lookup the given name to see if it's a filter name or one of the special
  // names like "core" or "rewrite_images", and if so add the corresponding
  // filter(s) to the given set. If the given name doesn't match -and- if
  // handler is not NULL, logs a warning message to handler. Returns true if
  // the name matched and the set was updated, false otherwise.
  static bool AddByNameToFilterSet(const StringPiece& option, FilterSet* set,
                                   MessageHandler* handler);

  // Convenience name for (name,value) pairs of options (typically filter
  // parameters), as well as sets of those pairs.
  typedef std::pair<GoogleString, GoogleString> OptionStringPair;
  typedef std::set<OptionStringPair> OptionSet;

  typedef std::vector<PropertyBase*> PropertyVector;

  // Base class for Option -- the instantiation of a Property that
  // occurs in each RewriteOptions instance.
  class OptionBase {
   public:
    OptionBase() {}
    virtual ~OptionBase();

    // Returns if parsing was successful. error_detail will be appended to
    // to an error message if this returns false. Implementors are not
    // required to set *error_detail; its the callers responsibility to do so.
    virtual bool SetFromString(StringPiece value_string,
                               GoogleString* error_detail) = 0;
    virtual void Merge(const OptionBase* src) = 0;
    virtual bool was_set() const = 0;
    virtual GoogleString Signature(const Hasher* hasher) const = 0;
    virtual GoogleString ToString() const = 0;
    const char* id() const { return property()->id(); }
    const char* help_text() const { return property()->help_text(); }
    OptionScope scope() const { return property()->scope(); }
    StringPiece option_name() const { return property()->option_name(); }
    bool is_used_for_signature_computation() const {
      return property()->is_used_for_signature_computation();
    }
    virtual const PropertyBase* property() const = 0;
  };

  // Convenience name for a set of rewrite options.
  typedef std::vector<OptionBase*> OptionBaseVector;

  // TODO(huibao): Use bitmask for the values of the enums, and make combination
  // of rewrite levels possible.
  enum RewriteLevel {
    // Enable no filters. Parse HTML but do not perform any
    // transformations. This is the default value. Most users should
    // explicitly enable the kCoreFilters level by calling
    // SetRewriteLevel(kCoreFilters).
    kPassThrough,

    // Enable filters that make resources smaller, but carry no risk
    // of site breakage.  Turning this on implies inplace resource
    // optimization and preserve-URLs.
    kOptimizeForBandwidth,

    // Enable the core set of filters. These filters are considered
    // generally safe for most sites, though even safe filters can
    // break some sites. Most users should specify this option, and
    // then optionally add or remove specific filters based on
    // specific needs.
    kCoreFilters,

    // Enable the filters which are essential to make webpages designed for
    // desktop computers look good on mobile devices.
    kMobilizeFilters,

    // Enable all filters intended for core, but some of which might
    // need more testing. Good for if users are willing to test out
    // the results of the rewrite more closely.
    kTestingCoreFilters,

    // Enable all filters. This includes filters you should never turn
    // on for a real page, like StripScripts!
    kAllFilters,
  };

  // Used for return value of SetOptionFromName.
  enum OptionSettingResult {
    kOptionOk,
    kOptionNameUnknown,
    kOptionValueInvalid
  };

  static const char kDefaultAllowVaryOn[];
  static const int kDefaultBeaconReinstrumentTimeSec;
  static const int64 kDefaultBlinkMaxHtmlSizeRewritable;
  static const int64 kDefaultCssFlattenMaxBytes;
  static const int64 kDefaultCssImageInlineMaxBytes;
  static const int64 kDefaultCssInlineMaxBytes;
  static const int64 kDefaultCssOutlineMinBytes;
  static const int64 kDefaultGoogleFontCssInlineMaxBytes;
  static const int64 kDefaultImageInlineMaxBytes;
  static const int64 kDefaultJsInlineMaxBytes;
  static const int64 kDefaultJsOutlineMinBytes;
  static const int64 kDefaultProgressiveJpegMinBytes;
  static const int64 kDefaultMaxCacheableResponseContentLength;
  static const int64 kDefaultMaxHtmlCacheTimeMs;
  static const int64 kDefaultMaxHtmlParseBytes;
  static const int64 kDefaultMaxImageBytesForWebpInCss;
  static const int64 kDefaultMaxLowResImageSizeBytes;
  static const int kDefaultMaxLowResToFullResImageSizePercentage;
  static const int64 kDefaultMetadataInputErrorsCacheTtlMs;
  static const int64 kDefaultMinResourceCacheTimeToRewriteMs;
  static const char kDefaultDownstreamCachePurgeMethod[];
  static const int64 kDefaultDownstreamCacheRewrittenPercentageThreshold;
  static const int64 kDefaultIdleFlushTimeMs;
  static const int64 kDefaultFlushBufferLimitBytes;
  static const int64 kDefaultImplicitCacheTtlMs;
  static const int64 kDefaultMinCacheTtlMs;
  static const int64 kDefaultPrioritizeVisibleContentCacheTimeMs;
  static const char kDefaultBeaconUrl[];
  static const int64 kDefaultImageRecompressQuality;
  static const int64 kDefaultImageJpegQualityForSaveData;
  static const int64 kDefaultImageJpegRecompressQuality;
  static const int64 kDefaultImageJpegRecompressQualityForSmallScreens;
  static const int kDefaultImageLimitOptimizedPercent;
  static const int kDefaultImageLimitRenderedAreaPercent;
  static const int kDefaultImageLimitResizeAreaPercent;
  static const int64 kDefaultImageResolutionLimitBytes;
  static const int64 kDefaultImageJpegNumProgressiveScans;
  static const int64 kDefaultImageWebpQualityForSaveData;
  static const int64 kDefaultImageWebpRecompressQuality;
  static const int64 kDefaultImageWebpAnimatedRecompressQuality;
  static const int64 kDefaultImageWebpRecompressQualityForSmallScreens;
  static const int64 kDefaultImageWebpTimeoutMs;
  static const int kDefaultDomainShardCount;
  static const int64 kDefaultBlinkHtmlChangeDetectionTimeMs;
  static const int kDefaultMaxPrefetchJsElements;
  static const int64 kDefaultOptionCookiesDurationMs;
  static const int64 kDefaultLoadFromFileCacheTtlMs;
  static const double kDefaultResponsiveImageDensities[];

  // IE limits URL size overall to about 2k characters.  See
  // http://support.microsoft.com/kb/208427/EN-US
  static const int kDefaultMaxUrlSize;

  static const int kDefaultImageMaxRewritesAtOnce;

  // See http://code.google.com/p/modpagespeed/issues/detail?id=9
  // Apache evidently limits each URL path segment (between /) to
  // about 256 characters.  This is not fundamental URL limitation
  // but is Apache specific.
  static const int kDefaultMaxUrlSegmentSize;

  // Default time to wait for rewrite before returning original resource.
  static const int kDefaultRewriteDeadlineMs;

  // Default time to wait for a distributed rewrite to return.
  static const int64 kDefaultDistributedTimeoutMs;

  // Default number of first N images for which low res image is generated by
  // DelayImagesFilter.
  static const int kDefaultMaxInlinedPreviewImagesIndex;
  // Default minimum image size above which low res image is generated by
  // InlinePreviewImagesFilter.
  static const int64 kDefaultMinImageSizeLowResolutionBytes;
  // Default maximum image size below which low res image is generated by
  // InlinePreviewImagesFilter.
  static const int64 kDefaultMaxImageSizeLowResolutionBytes;
  // Default cache expiration value for finder properties in pcache.
  static const int64 kDefaultFinderPropertiesCacheExpirationTimeMs;
  // Default cache refresh value for finder properties in pcache.
  static const int64 kDefaultFinderPropertiesCacheRefreshTimeMs;

  // Default duration after which the experiment cookie will expire on the
  // user's browser.
  static const int64 kDefaultExperimentCookieDurationMs;

  // Default time in milliseconds for which a metadata cache entry may be used
  // after expiry.
  static const int64 kDefaultMetadataCacheStalenessThresholdMs;

  // Default maximum size of the combined CSS resource.
  static const int64 kDefaultMaxCombinedCssBytes;

  // Default maximum size of the combined js resource generated by JsCombiner.
  static const int64 kDefaultMaxCombinedJsBytes;

  static const int kDefaultExperimentTrafficPercent;
  // Default Custom Variable slot in which to put Experiment information.
  static const int kDefaultExperimentSlot;

  static const char kDefaultBlockingRewriteKey[];

  static const char kRejectedRequestUrlKeyName[];

  static const int kDefaultPropertyCacheHttpStatusStabilityThreshold;

  static const int kDefaultMaxRewriteInfoLogSize;

  // This class is a separate subset of options for running an experiment.
  // These options can be specified by a spec string that looks like:
  // "id=<number greater than 0>;level=<rewrite level>;enabled=
  // <comma-separated-list of filters to enable>;disabled=
  // <comma-separated-list of filters to disable>;options=
  // <comma-separated-list of option=value pairs to set>.
  class ExperimentSpec {
   public:
    // Creates a ExperimentSpec parsed from spec.
    // If spec doesn't have an id, then id_ will be set to
    // experiment::kExperimentNotSet.  These ExperimentSpecs will then be
    // rejected by AddExperimentSpec().
    ExperimentSpec(const StringPiece& spec, const RewriteOptions* options,
                   MessageHandler* handler);

    // Creates a ExperimentSpec with id_=id.  All other variables
    // are initialized to 0.
    // This is primarily used for setting up the control and for cloning.
    explicit ExperimentSpec(int id);

    virtual ~ExperimentSpec();

    // Return a ExperimentSpec with all the same information as this one.
    virtual ExperimentSpec* Clone();

    bool is_valid() const { return id_ >= 0; }

    // Accessors.
    int id() const { return id_; }
    int percent() const { return percent_; }
    const GoogleString& ga_id() const { return ga_id_; }
    int slot() const { return ga_variable_slot_; }
    RewriteLevel rewrite_level() const { return rewrite_level_; }
    FilterSet enabled_filters() const { return enabled_filters_; }
    FilterSet disabled_filters() const { return disabled_filters_; }
    OptionSet filter_options() const { return filter_options_; }
    bool matches_device_type(UserAgentMatcher::DeviceType type) const;
    bool use_default() const { return use_default_; }
    GoogleString ToString() const;

    // Mutate the origin domains in DomainLawyer with alternate_origin_domains_.
    void ApplyAlternateOriginsToDomainLawyer(DomainLawyer* domain_lawyer,
                                             MessageHandler* handler) const;

   protected:
    // Merges a spec into this. This follows the same semantics as
    // RewriteOptions. Specifically, filter/options list get unioned, and
    // vars get overwritten, except ID.  In the event of a conflict, e.g.
    // preserve vs extend_cache, *this will take precedence.
    void Merge(const ExperimentSpec& spec);

    typedef std::bitset<net_instaweb::UserAgentMatcher::kEndOfDeviceType>
        DeviceTypeBitSet;

    static bool ParseDeviceTypeBitSet(const StringPiece& in,
                                      DeviceTypeBitSet* out,
                                      MessageHandler* handler);

    struct AlternateOriginDomainSpec {
      StringVector serving_domains;
      GoogleString origin_domain;
      GoogleString host_header;
    };

    // Simple check that 's' is not obviously an invalid host. Used to avoid
    // problems when a port number is accidentally placed in a host field.
    static bool LooksLikeValidHost(const StringPiece& s);

    // Parses the string after an 'alternate_origin_domain' experiment
    // option, returning if it was successfull. If it returns false, the spec is
    // invalid and should be discarded.
    static bool ParseAlternateOriginDomain(const StringPiece& in,
                                           AlternateOriginDomainSpec* out,
                                           MessageHandler* handler);

    // Combine consecutive entries in a StringPieceVector such that
    // [ a, b, "host, port" ] can be turned into [ a, b, host:port ].
    // Inspects vec[first_pos] and vec[first_pos + 1]. If they appear to be a
    // quoted tuple, will replace vec[first_pos] with a combined value and
    // vec[first_pos + 1] will be removed, ie: vec will reduce in size by 1.
    // combined_container is used as the underlying storage for the combined
    // string, if necessary.
    static void CombineQuotedHostPort(StringPieceVector* vec, size_t first_pos,
                                      GoogleString* combined_container);

    // Returns a copy of the input string that will be surrounded by double
    // quotes if the input string contains a colon. This is used to turn
    // host:port into "host:port" when printing an ExperimentSpec.
    static GoogleString QuoteHostPort(const GoogleString& in);

   private:
    FRIEND_TEST(RewriteOptionsTest, ExperimentMergeTest);
    FRIEND_TEST(RewriteOptionsTest, DeviceTypeMergeTest);
    FRIEND_TEST(RewriteOptionsTest, AlternateOriginDomainMergeTest);

    // Parse 'spec' and set the FilterSets, rewrite level, inlining thresholds,
    // and OptionSets accordingly.
    void Initialize(const StringPiece& spec, MessageHandler* handler);

    //
    // If you add any members to this list, be sure to also add them to the
    // Merge method.
    //
    int id_;  // id for this experiment
    GoogleString ga_id_;  // Google Analytics ID for this experiment
    int ga_variable_slot_;
    int percent_;  // percentage of traffic to go through this experiment.
    RewriteLevel rewrite_level_;
    FilterSet enabled_filters_;
    FilterSet disabled_filters_;
    OptionSet filter_options_;
    // bitset to indicate which device types this ExperimentSpec should apply
    // to. If NULL, no device type was specified and the experiment applies
    // to all device types.
    scoped_ptr<DeviceTypeBitSet> matches_device_types_;
    // Use whatever RewriteOptions' settings are without experiments
    // for this experiment.
    bool use_default_;
    // vector of parsed alternate_origin_domain options. These mutations will
    // be applied to a DomainLawyer when passed to MutateDomainLawer.
    typedef std::vector<AlternateOriginDomainSpec> AlternateOriginDomains;
    AlternateOriginDomains alternate_origin_domains_;

    DISALLOW_COPY_AND_ASSIGN(ExperimentSpec);
  };

  // Represents the content type of user-defined url-valued attributes.
  struct ElementAttributeCategory {
    GoogleString element;
    GoogleString attribute;
    semantic_type::Category category;
  };

  // Identifies static properties of RewriteOptions that must be
  // initialized before the properties can be used.  Primarily for the
  // benefit of unit tests and valgrind sanity, Initialize/Terminate
  // is balance-checked.
  //
  // TODO(jmarantz): Add static properties -- currently there are none.
  class Properties {
   public:
    // Initializes a static Properties* object.  Pass the address of a static
    // member variable.  A count is kept of how many times Initialize is called.
    //
    // True will be returned if this was the first call to initialize
    // the properties object, and this can be used by implementations
    // to decide whether to initialize other static variables.
    //
    // Initialization is not thread-safe.
    static bool Initialize(Properties** properties);

    // Terminates a static Properties* object.  Pass the address of a static
    // member variable.
    //
    // True will be returned if Terminate has been called the same number
    // of times as Initialize is called, and this can be used to decide
    // whether to clean up other static variables.
    //
    // Termination is not thread-safe.
    static bool Terminate(Properties** properties_handle);

    // Returns the number of properties
    int size() const { return property_vector_.size(); }

    const PropertyBase* property(int index) const {
      return property_vector_[index];
    }
    PropertyBase* property(int index) { return property_vector_[index]; }

    // Merges the passed-in property-vector into this one, sorting the
    // merged properties.  Each property's needs its index into the
    // merged vector for initializing subclass-specific Options in
    // each constructor.  So this method mutates its input by setting
    // an index field in each property.
    void Merge(Properties* properties);

    void push_back(PropertyBase* p) { property_vector_.push_back(p); }

   private:
    // This object should not be constructed/destructed directly; it should be
    // created by calling Properties::Initialize and Properties::Terminate.
    Properties();
    ~Properties();

    // initialization_count_ acts as a reference count: it is incremented on
    // Initialize(), and decremented on Terminate().  At 0 the object is
    // deleted.
    int initialization_count_;

    // owns_properties_ is set to true if the PropertyBase* in the vector should
    // be deleted when Terminate is called bringing initialization_count_ to 0.
    //   RewriteOptions::properties_.owns_properties_ is true.
    //   RewriteOptions::all_properties_.owns_properties_ is false.
    bool owns_properties_;
    PropertyVector property_vector_;
  };

  // Maps a filter's enum (kAddHead) to its id ("ah") and name ("Add Head").
  struct FilterEnumToIdAndNameEntry {
    RewriteOptions::Filter filter_enum;
    const char* filter_id;
    const char* filter_name;
  };

  static bool ParseRewriteLevel(const StringPiece& in, RewriteLevel* out);

  typedef std::set<semantic_type::Category> ResourceCategorySet;

  static bool ParseInlineUnauthorizedResourceType(
      const StringPiece& in,
      ResourceCategorySet* resource_types);

  // Parse a beacon url, or a pair of beacon urls (http https) separated by a
  // space.  If only an http url is given, the https url is derived from it
  // by simply substituting the protocol.
  static bool ParseBeaconUrl(const StringPiece& in, BeaconUrl* out);

  // Checks if either of the optimizing rewrite options are ON and it includes
  // kRecompressJPeg, kRecompressPng, kRecompressWebp, kConvertGifToPng,
  // kConvertJpegToWebp, kConvertPngToJpeg, and kConvertToWebpLossless.
  bool ImageOptimizationEnabled() const;

  explicit RewriteOptions(ThreadSystem* thread_system);
  virtual ~RewriteOptions();

  // Static initialization of members.  Calls to Initialize and
  // Terminate must be matched.  Returns 'true' for the first
  // Initialize call and the last Terminate call.
  static bool Initialize();
  static bool Terminate();

#ifndef NDEBUG
  // Determines whether it's OK to modify the RewriteOptions in the
  // current thread.  Note that this is stricter than necessary, but
  // makes it easier to reason about potential thread safety issues
  // for copy-on-write sharing of substructures.
  //
  // This is exposed as an external API for ease of unit testing.
  bool ModificationOK() const;

  // Determines whether it's OK to merge from the RewriteOptions object
  // in the current thread.  Note that this is stricter than necessary, but
  // makes it easier to reason about potential thread safety issues
  // for copy-on-write sharing of substructures.
  //
  // This is exposed as an external API for ease of unit testing.
  bool MergeOK() const;
#endif

  // Initializes the Options objects in a RewriteOptions instance
  // based on the supplied Properties vector.  Note that subclasses
  // can statically define additional properties, in which case they
  // should call this method from their constructor.
  void InitializeOptions(const Properties* properties);

  bool modified() const { return modified_; }

  // Sets the default rewrite level for this RewriteOptions object only.
  // Note that the defaults for other RewriteOptions objects are unaffected.
  //
  // TODO(jmarantz): Get rid of this method.  The semantics it requires are
  // costly to implement and don't add much value.
  void SetDefaultRewriteLevel(RewriteLevel level) {
    // Do not set the modified bit -- we are only changing the default.
    level_.set_default(level);
  }
  void SetRewriteLevel(RewriteLevel level) {
    set_option(level, &level_);
  }

  // Specify a header to insert when fetching subresources.
  void AddCustomFetchHeader(const StringPiece& name, const StringPiece& value);

  const NameValue* custom_fetch_header(int i) const {
    return custom_fetch_headers_[i];
  }

  int num_custom_fetch_headers() const {
    return custom_fetch_headers_.size();
  }

  // Returns the spec with the id_ that matches id.  Returns NULL if no
  // spec matches.
  ExperimentSpec* GetExperimentSpec(int id) const;

  // Returns false if id is negative, or if the id is reserved
  // for NoExperiment or NotSet, or if we already have an experiment
  // with that id.
  bool AvailableExperimentId(int id);

  // Creates a ExperimentSpec from spec and adds it to the configuration,
  // returning it on success and NULL on failure.
  virtual ExperimentSpec* AddExperimentSpec(const StringPiece& spec,
                                            MessageHandler* handler);

  // Sets which side of the experiment these RewriteOptions are on.
  // Cookie-setting must be done separately.
  // experiment::kExperimentNotSet indicates it hasn't been set.
  // experiment::kNoExperiment indicates this request shouldn't be
  // in any experiment.
  // Then sets the rewriters to match the experiment indicated by id.
  // Returns true if succeeded in setting state.
  virtual bool SetExperimentState(int id);

  // We encode experiment information in urls as an experiment index: the first
  // ExperimentSpec is a, the next is b, and so on.  Empty string or an invalid
  // letter means kNoExperiment.
  void SetExperimentStateStr(const StringPiece& experiment_index);

  int experiment_id() const { return experiment_id_; }

  int experiment_spec_id(int i) const {
    return experiment_specs_[i]->id();
  }

  // Returns a string representation of experiment_id() suitable for consumption
  // by SetExperimentStateStr(), encoding the index of the current experiment
  // (not its id).  If we're not running an experiment, returns the empty
  // string.
  GoogleString GetExperimentStateStr() const;

  ExperimentSpec* experiment_spec(int i) const {
    return experiment_specs_[i];
  }

  int num_experiments() const { return experiment_specs_.size(); }

  bool enroll_experiment() const {
    return enroll_experiment_id() != experiment::kForceNoExperiment;
  }

  // Store that when we see <element attribute=X> we should treat X as a URL
  // pointing to a resource of the type indicated by category.  For example,
  // while by default we would treat the 'src' attribute of an a 'img' element
  // as the URL for an image and will cache-extend, inline, or otherwise
  // optimize it as appropriate, we would not do the same for the 'src'
  // atrtribute of a 'span' element (<span src=...>) because there's no "src"
  // attribute of "span" in the HTML spec.  If someone needed us to treat
  // span.src as a URL, however, they could call:
  //    AddUrlValuedAttribute("src", "span", appropriate_category)
  //
  // Makes copies of element and attribute.
  void AddUrlValuedAttribute(const StringPiece& element,
                             const StringPiece& attribute,
                             semantic_type::Category category);

  // Look up a url-valued attribute, return details via element, attribute,
  // and category.  index must be less than num_url_valued_attributes().
  void UrlValuedAttribute(int index,
                          StringPiece* element,
                          StringPiece* attribute,
                          semantic_type::Category* category) const;

  int num_url_valued_attributes() const {
    if (url_valued_attributes_ == NULL) {
      return 0;
    } else {
      return url_valued_attributes_->size();
    }
  }

  void AddInlineUnauthorizedResourceType(semantic_type::Category category);
  bool HasInlineUnauthorizedResourceType(
      semantic_type::Category category) const;
  void ClearInlineUnauthorizedResourceTypes();
  void set_inline_unauthorized_resource_types(ResourceCategorySet x);

  // Store size, md5 hash and canonical url for library recognition.
  bool RegisterLibrary(
      uint64 bytes, StringPiece md5_hash, StringPiece canonical_url) {
    return WriteableJavascriptLibraryIdentification()->RegisterLibrary(
        bytes, md5_hash, canonical_url);
  }

  // Return the javascript_library_identification_ object that applies to
  // the current configuration (NULL if identification is disabled).
  const JavascriptLibraryIdentification* javascript_library_identification()
      const {
    if (Enabled(kCanonicalizeJavascriptLibraries)) {
      return javascript_library_identification_.get();
    } else {
      return NULL;
    }
  }

  RewriteLevel level() const { return level_.value(); }

  // Enables filters specified without a prefix or with a prefix of '+' and
  // disables filters specified with a prefix of '-'. Returns false if any
  // of the filter names are invalid, but all the valid ones will be
  // added anyway.
  bool AdjustFiltersByCommaSeparatedList(const StringPiece& filters,
                                         MessageHandler* handler);

  // Adds a set of filters to the enabled set.  Returns false if any
  // of the filter names are invalid, but all the valid ones will be
  // added anyway.
  bool EnableFiltersByCommaSeparatedList(const StringPiece& filters,
                                         MessageHandler* handler);

  // Adds a set of filters to the disabled set.  Returns false if any
  // of the filter names are invalid, but all the valid ones will be
  // added anyway.
  bool DisableFiltersByCommaSeparatedList(const StringPiece& filters,
                                          MessageHandler* handler);

  // Adds a set of filters to the forbidden set.  Returns false if any
  // of the filter names are invalid, but all the valid ones will be
  // added anyway.
  bool ForbidFiltersByCommaSeparatedList(const StringPiece& filters,
                                         MessageHandler* handler);

  // Set rewrite level to kPassThrough and explicitly disable all filters.
  void DisableAllFilters();

  // Explicitly disable all filters which are not *currently* explicitly enabled
  //
  // Note: Do not call EnableFilter(...) for this options object after calling
  // DisableAllFilters..., because the Disable list will not be auto-updated.
  //
  // Used to deal with query param ?ModPagespeedFilter=foo
  // Which implies that all filters not listed should be disabled.
  void DisableAllFiltersNotExplicitlyEnabled();

  // Adds a set of filter prefixes (ids) to the set of distributable filters.
  // The names are not verified and all prefixes will be added.
  void DistributeFiltersByCommaSeparatedList(const StringPiece& filter_ids,
                                             MessageHandler* handler);
  // Adds the filter to the list of distributable filters.
  // For experimentation, may be removed later.
  void DistributeFilter(const StringPiece& filter_id);

  // Returns true if the filter is in the list of distributable filters.
  // For experimentation, may be removed later.
  bool Distributable(const StringPiece& filter_id) const;

  // Adds the filter to the list of enabled filters. However, if the filter
  // is also present in either the list of disabled or forbidden filters,
  // that takes precedence and it is not enabled.
  void EnableFilter(Filter filter);
  // Guarantees that a filter would be enabled even if it is present in the list
  // of disabled filters by removing it from disabled & forbidden filter lists.
  void ForceEnableFilter(Filter filter);
  void DisableFilter(Filter filter);
  void DisableIfNotExplictlyEnabled(Filter filter);
  void ForbidFilter(Filter filter);
  void EnableFilters(const FilterSet& filter_set);
  void DisableFilters(const FilterSet& filter_set);
  void ForbidFilters(const FilterSet& filter_set);
  // Clear all explicitly enabled and disabled filters. Some filters may still
  // be enabled by the rewrite level and HtmlWriterFilter will be enabled.
  void ClearFilters();

  // Induces a filter to be considered enabled by turning on the AllFilters
  // level and disabling the filters that are not wanted.  This is used for
  // testing the desired behavior of PreserveUrls, which is to disable inlining
  // and combining when the level is CoreFilters, but allow explictly enabled
  // combiners and inliners to work.
  //
  // Beware: this mode of enabling filters is difficult to manage
  // across multiple levels of test inheritance.  In particular, once
  // SoftEnableFilterForTesting is called, EnableFilter will no longer
  // work due to the explicit disables.  It does work to call
  // SoftEnableFilterForTesting multiple times to enable several
  // filters, and it also works to call EnableFilter first.  ForceEnable
  // also works.
  //
  // It is only necessary to call this in tests with PreserveUrls.
  //
  // Caveat emptor.
  void SoftEnableFilterForTesting(Filter filter);

  // Enables extend_cache_css, extend_cache_images, and extend_cache_scripts.
  // Does not enable extend_cache_pdfs.
  void EnableExtendCacheFilters();

  bool Enabled(Filter filter) const;
  bool Forbidden(Filter filter) const;
  bool Forbidden(StringPiece filter_id) const;

  // Returns the set of enabled filters that require JavaScript for execution.
  void GetEnabledFiltersRequiringScriptExecution(FilterVector* filters) const;

  // Disables all filters that depend on executing custom javascript.
  void DisableFiltersRequiringScriptExecution();

  // Returns true if any filter benefits from per-origin property cache
  // information.
  bool UsePerOriginPropertyCachePage() const;

  // Adds pairs of (option, value) to the option set. The option names and
  // values are not checked for validity, just stored. If the string piece
  // was parsed correctly, this returns true. If there were parsing errors this
  // returns false. The set is still populated on error.
  static bool AddCommaSeparatedListToOptionSet(
      const StringPiece& options, OptionSet* set, MessageHandler* handler);

  // Set Option 'name' to 'value'. Returns whether it succeeded or the kind of
  // failure (wrong name or value), and writes the diagnostic into 'msg'.
  // This only understands simple scalar options, and not more general things
  // like filter lists, blacklists, etc.
  OptionSettingResult SetOptionFromName(
      StringPiece name, StringPiece value, GoogleString* msg);

  // Like above, but doesn't bother formatting the error message.
  OptionSettingResult SetOptionFromName(
      StringPiece name, StringPiece value);

  // Same as SetOptionFromName, but only works with options that are valid
  // to use as query parameters, returning kOptionNameUnknown for properties
  // where the scope() is not kQueryScope.
  OptionSettingResult SetOptionFromQuery(StringPiece name, StringPiece value);

  // Same as SetOptionFromName, but only works with options that are valid
  // to use as remote config, returning kOptionNameUnknown for properties
  // where the scope() is not kQueryScope or kDirectoryScope.
  OptionSettingResult SetOptionFromRemoteConfig(StringPiece name,
                                                StringPiece value);

  GoogleString ScopeEnumToString(OptionScope scope);

  // Advanced option parsing, that can understand non-scalar values
  // (unlike SetOptionFromName), and which is extensible by platforms.
  // Returns whether succeeded or the kind of failure, and writes the
  // diagnostic into *msg.
  //
  // If you extend any of these you also need to extend Merge() and
  // SubclassSignatureLockHeld().
  virtual OptionSettingResult ParseAndSetOptionFromName1(
      StringPiece name, StringPiece arg,
      GoogleString* msg, MessageHandler* handler);
  // Parses and sets options like ParseAndSetOptionFromName1, but with a maximum
  // scope specified.  ParseAndSetOptionFromName1 will apply options from any
  // scope, whereas ParseAndSetOptionFromNameWithScope will only apply options
  // within max_scope scope.
  OptionSettingResult ParseAndSetOptionFromNameWithScope(
      StringPiece name, StringPiece arg, OptionScope max_scope,
      GoogleString* msg, MessageHandler* handler);

  virtual OptionSettingResult ParseAndSetOptionFromName2(
      StringPiece name, StringPiece arg1, StringPiece arg2,
      GoogleString* msg, MessageHandler* handler);

  virtual OptionSettingResult ParseAndSetOptionFromName3(
      StringPiece name, StringPiece arg1, StringPiece arg2, StringPiece arg3,
      GoogleString* msg, MessageHandler* handler);

  // Returns the id and value of the specified option-enum in *id and *value.
  // Sets *was_set to true if this option has been altered from the default.
  //
  // If this option was not found, false is returned, and *id, *was_set, and
  // *value will be left unassigned.
  bool OptionValue(StringPiece option_name, const char** id,
                   bool* was_set, GoogleString* value) const;

  // Set all of the options to their values specified in the option set.
  // Returns true if all options in the set were successful, false if not.
  bool SetOptionsFromName(const OptionSet& option_set, MessageHandler* handler);

  // Sets Option 'name' to 'value'. Returns whether it succeeded and logs
  // any warnings to 'handler'.
  bool SetOptionFromNameAndLog(StringPiece name,
                               StringPiece value,
                               MessageHandler* handler);

  // These static methods are used by Option<T>::SetFromString to set
  // Option<T>::value_ from a string representation of it.
  static bool ParseFromString(StringPiece value_string, bool* value);
  static bool ParseFromString(StringPiece value_string, EnabledEnum* value);
  static bool ParseFromString(StringPiece value_string, int* value) {
    return StringToInt(value_string, value);
  }
  static bool ParseFromString(StringPiece value_string, int64* value) {
    return StringToInt64(value_string, value);
  }
  static bool ParseFromString(StringPiece value_string, double* value) {
    return StringToDouble(value_string, value);
  }
  static bool ParseFromString(StringPiece value_string, GoogleString* value) {
    value_string.CopyToString(value);
    return true;
  }
  static bool ParseFromString(StringPiece value_string, RewriteLevel* value) {
    return ParseRewriteLevel(value_string, value);
  }
  static bool ParseFromString(StringPiece value_string,
                              ResourceCategorySet* value) {
    return ParseInlineUnauthorizedResourceType(value_string, value);
  }
  static bool ParseFromString(StringPiece value_string, BeaconUrl* value) {
    return ParseBeaconUrl(value_string, value);
  }
  static bool ParseFromString(StringPiece value_string, Color* color);
  static bool ParseFromString(StringPiece value_string, MobTheme* theme);
  static bool ParseFromString(StringPiece value_string,
                              ResponsiveDensities* value);
  static bool ParseFromString(StringPiece value_string,
                              protobuf::MessageLite* proto);
  static bool ParseFromString(StringPiece value_string,
                              AllowVaryOn* allow_vary_on);

  // TODO(jmarantz): consider setting flags in the set_ methods so that
  // first's explicit settings can override default values from second.
  int64 css_outline_min_bytes() const { return css_outline_min_bytes_.value(); }
  void set_css_outline_min_bytes(int64 x) {
    set_option(x, &css_outline_min_bytes_);
  }

  const GoogleString& ga_id() const { return ga_id_.value(); }
  void set_ga_id(const GoogleString& id) {
    set_option(id, &ga_id_);
  }

  void set_content_experiment_id(const GoogleString& s) {
    set_option(s, &content_experiment_id_);
  }
  const GoogleString& content_experiment_id() const {
    return content_experiment_id_.value();
  }

  void set_content_experiment_variant_id(const GoogleString& s) {
    set_option(s, &content_experiment_variant_id_);
  }
  const GoogleString& content_experiment_variant_id() const {
    return content_experiment_variant_id_.value();
  }

  bool is_content_experiment() const {
    return !content_experiment_id().empty() &&
           !content_experiment_variant_id().empty();
  }

  bool use_analytics_js() const {
    return use_analytics_js_.value();
  }
  void set_use_analytics_js(bool x) {
    set_option(x, &use_analytics_js_);
  }

  bool increase_speed_tracking() const {
    return increase_speed_tracking_.value();
  }
  void set_increase_speed_tracking(bool x) {
    set_option(x, &increase_speed_tracking_);
  }

  int64 js_outline_min_bytes() const { return js_outline_min_bytes_.value(); }
  void set_js_outline_min_bytes(int64 x) {
    set_option(x, &js_outline_min_bytes_);
  }

  int64 progressive_jpeg_min_bytes() const {
    return progressive_jpeg_min_bytes_.value();
  }
  void set_progressive_jpeg_min_bytes(int64 x) {
    set_option(x, &progressive_jpeg_min_bytes_);
  }

  int64 css_flatten_max_bytes() const { return css_flatten_max_bytes_.value(); }
  void set_css_flatten_max_bytes(int64 x) {
    set_option(x, &css_flatten_max_bytes_);
  }
  bool cache_small_images_unrewritten() const {
    return cache_small_images_unrewritten_.value();
  }
  void set_cache_small_images_unrewritten(bool x) {
    set_option(x, &cache_small_images_unrewritten_);
  }
  int64 image_resolution_limit_bytes() const {
    return image_resolution_limit_bytes_.value();
  }
  void set_image_resolution_limit_bytes(int64 x) {
    set_option(x, &image_resolution_limit_bytes_);
  }

  // Retrieve the image inlining threshold, but return 0 if it's disabled.
  int64 ImageInlineMaxBytes() const;
  void set_image_inline_max_bytes(int64 x);
  // Retrieve the css image inlining threshold, but return 0 if it's disabled.
  int64 CssImageInlineMaxBytes() const;
  void set_css_image_inline_max_bytes(int64 x) {
    set_option(x, &css_image_inline_max_bytes_);
  }
  // The larger of ImageInlineMaxBytes and CssImageInlineMaxBytes.
  int64 MaxImageInlineMaxBytes() const;
  int64 css_inline_max_bytes() const { return css_inline_max_bytes_.value(); }
  void set_css_inline_max_bytes(int64 x) {
    set_option(x, &css_inline_max_bytes_);
  }
  int64 google_font_css_inline_max_bytes() const {
    return google_font_css_inline_max_bytes_.value();
  }
  void set_google_font_css_inline_max_bytes(int64 x) {
    set_option(x, &google_font_css_inline_max_bytes_);
  }
  int64 js_inline_max_bytes() const { return js_inline_max_bytes_.value(); }
  void set_js_inline_max_bytes(int64 x) {
    set_option(x, &js_inline_max_bytes_);
  }
  int64 max_html_cache_time_ms() const {
    return max_html_cache_time_ms_.value();
  }
  void set_max_html_cache_time_ms(int64 x) {
    set_option(x, &max_html_cache_time_ms_);
  }
  int64 max_html_parse_bytes() const {
    return max_html_parse_bytes_.value();
  }
  void set_max_html_parse_bytes(int64 x) {
    set_option(x, &max_html_parse_bytes_);
  }
  int64 max_image_bytes_for_webp_in_css() const {
    return max_image_bytes_for_webp_in_css_.value();
  }
  void set_max_image_bytes_for_webp_in_css(int64 x) {
    set_option(x, &max_image_bytes_for_webp_in_css_);
  }
  int64 max_cacheable_response_content_length() const {
    return max_cacheable_response_content_length_.value();
  }
  void set_max_cacheable_response_content_length(int64 x) {
    set_option(x, &max_cacheable_response_content_length_);
  }
  int64 min_resource_cache_time_to_rewrite_ms() const {
    return min_resource_cache_time_to_rewrite_ms_.value();
  }
  void set_min_resource_cache_time_to_rewrite_ms(int64 x) {
    set_option(x, &min_resource_cache_time_to_rewrite_ms_);
  }
  bool need_to_store_experiment_data() const {
    return need_to_store_experiment_data_;
  }
  void set_need_to_store_experiment_data(bool x) {
    need_to_store_experiment_data_ = x;
  }

  int64 blocking_fetch_timeout_ms() const {
    return blocking_fetch_timeout_ms_.value();
  }
  void set_blocking_fetch_timeout_ms(int64 x) {
    set_option(x, &blocking_fetch_timeout_ms_);
  }
  bool override_ie_document_mode() const {
    return override_ie_document_mode_.value();
  }
  void set_override_ie_document_mode(bool x) {
    set_option(x, &override_ie_document_mode_);
  }

  int64 blink_blacklist_end_timestamp_ms() const {
    return blink_blacklist_end_timestamp_ms_.value();
  }
  void set_blink_blacklist_end_timestamp_ms(int64 x) {
    set_option(x, &blink_blacklist_end_timestamp_ms_);
  }

  bool preserve_subresource_hints() const {
    return preserve_subresource_hints_.value();
  }
  void set_preserve_subresource_hints(bool x) {
    set_option(x, &preserve_subresource_hints_);
  }


  bool preserve_url_relativity() const {
    return preserve_url_relativity_.value();
  }
  void set_preserve_url_relativity(bool x) {
    set_option(x, &preserve_url_relativity_);
  }

  // Returns whether the given URL is valid for use in the cache, given the
  // timestamp stored in the cache.
  //
  // It first checks time_ms against the global cache invalidation timestamp.
  //
  // It next checks if PurgeCacheUrl has been called on url with a timestamp
  // earlier than time_ms.  Note: this is not a wildcard check but an
  // exact lookup.
  //
  // Finally, if search_wildcards is true, it scans
  // url_cache_invalidation_entries_ for entries with timestamp_ms > time_ms and
  // url matching the url_pattern.
  //
  // In most contexts where you'd call this you should consider instead
  // calling OptionsAwareHTTPCacheCallback::IsCacheValid instead, which takes
  // into account request-headers.
  bool IsUrlCacheValid(StringPiece url, int64 time_ms,
                       bool search_wildcards) const;

  // If timestamp_ms greater than or equal to the last timestamp in
  // url_cache_invalidation_entries_, then appends an UrlCacheInvalidationEntry
  // with 'timestamp_ms' and 'url_pattern' to url_cache_invalidation_entries_.
  // Else does nothing.
  //
  // Also see PurgeCacheUrl.  AddUrlCacheInvalidationEntry with a non-wildcard
  // pattern and ignores_metadata_and_pcache==false is equivalent to
  // PurgeCacheUrl.
  //
  // If ignores_metadata_and_pcache is true, metadata is not
  // invalidated and property cache is invalidated of URLs matching
  // url_pattern.  If false, metadata cache and property cache entries
  // may be invalidated, depending on whether there are wildcards in
  // the pattern, and whether enable_cache_purge() is true.  Note that
  // HTTP cache invalidation is always exactly for the URLs matching
  // url_pattern.
  void AddUrlCacheInvalidationEntry(StringPiece url_pattern,
                                    int64 timestamp_ms,
                                    bool ignores_metadata_and_pcache);

  // Purge a cache entry for an exact URL, not a wildcard.
  void PurgeUrl(StringPiece url, int64 timestamp_ms);

  // Checks if url_cache_invalidation_entries_ is in increasing order of
  // timestamp.  For testing.
  bool IsUrlCacheInvalidationEntriesSorted() const;

  // Supply optional mutex for setting a global cache invalidation
  // timestamp.  Ownership of 'lock' is transfered to this.
  void set_cache_invalidation_timestamp_mutex(ThreadSystem::RWLock* lock) {
    cache_purge_mutex_.reset(lock);
  }

  // Cache invalidation timestamp is in milliseconds since 1970.  It is used
  // for invalidating everything in the cache written prior to the timestamp.
  //
  // TODO(jmarantz): rename to cache_invalidation_timestamp_ms().
  int64 cache_invalidation_timestamp() const;

  // Determines whether there is a valid cache_invalidation_timestamp.  It
  // is invalid to call cache_invalidation_timestamp() if
  // has_cache_invalidation_timestamp_ms() is false.
  bool has_cache_invalidation_timestamp_ms() const;

  // Sets the cache invalidation timestamp -- in milliseconds since
  // 1970.  This function is meant to be called on a RewriteOptions*
  // immediately after instantiation.
  //
  // It can also be used to mutate the invalidation timestamp of a
  // RewriteOptions instance that is used as a base for cloning/merging,
  // in which case you should make sure to establish a real mutex with
  // set_cache_invalidation_timestamp_mutex for such instances.
  bool UpdateCacheInvalidationTimestampMs(int64 timestamp_ms)
      LOCKS_EXCLUDED(cache_purge_mutex_.get());

  // Mutates the options PurgeSet by copying the contents from purge_set.
  // Returns true if the contents actually changed, false if the incoming
  // purge_set was identical to purge_set already in this.
  bool UpdateCachePurgeSet(const CopyOnWrite<PurgeSet>& purge_set)
      LOCKS_EXCLUDED(cache_purge_mutex_.get());

  // Generates a human-readable view of the PurgeSet, including timestamps
  // in GMT.
  GoogleString PurgeSetString() const;

  // How much inactivity of HTML input will result in PSA introducing a flush.
  // Values <= 0 disable the feature.
  int64 idle_flush_time_ms() const {
    return idle_flush_time_ms_.value();
  }
  void set_idle_flush_time_ms(int64 x) {
    set_option(x, &idle_flush_time_ms_);
  }

  // How much accumulated HTML will result in PSA introducing a flush.
  int64 flush_buffer_limit_bytes() const {
    return flush_buffer_limit_bytes_.value();
  }

  void set_flush_buffer_limit_bytes(int64 x) {
    set_option(x, &flush_buffer_limit_bytes_);
  }

  // The maximum length of a URL segment.
  // for http://a/b/c.d, this is == strlen("c.d")
  int max_url_segment_size() const { return max_url_segment_size_.value(); }
  void set_max_url_segment_size(int x) {
    set_option(x, &max_url_segment_size_);
  }

  int image_max_rewrites_at_once() const {
    return image_max_rewrites_at_once_.value();
  }
  void set_image_max_rewrites_at_once(int x) {
    set_option(x, &image_max_rewrites_at_once_);
  }

  // The maximum size of the entire URL.  If '0', this is left unlimited.
  int max_url_size() const { return max_url_size_.value(); }
  void set_max_url_size(int x) {
    set_option(x, &max_url_size_);
  }

  int rewrite_deadline_ms() const { return rewrite_deadline_ms_.value(); }
  void set_rewrite_deadline_ms(int x) {
    set_option(x, &rewrite_deadline_ms_);
  }

  bool test_instant_fetch_rewrite_deadline() const {
    return test_instant_fetch_rewrite_deadline_.value();
  }
  void set_test_instant_fetch_rewrite_deadline(bool x) {
    set_option(x, &test_instant_fetch_rewrite_deadline_);
  }

  void set_test_only_prioritize_critical_css_dont_apply_original_css(bool x) {
    set_option(x, &test_only_prioritize_critical_css_dont_apply_original_css_);
  }
  bool test_only_prioritize_critical_css_dont_apply_original_css() const {
    return test_only_prioritize_critical_css_dont_apply_original_css_.value();
  }

  int domain_shard_count() const { return domain_shard_count_.value(); }
  // The argument is int64 to allow it to be set from the http header or url
  // query param and int64_query_params_ only allows setting of 64 bit values.
  void set_domain_shard_count(int64 x) {
    int value = x;
    set_option(value, &domain_shard_count_);
  }

  void set_enabled(EnabledEnum x) {
    set_option(x, &enabled_);
  }
  bool enabled() const {
    return enabled_.value() == kEnabledOn;
  }
  bool unplugged() const {
    return enabled_.value() == kEnabledUnplugged;
  }

  void set_add_options_to_urls(bool x) {
    set_option(x, &add_options_to_urls_);
  }

  bool add_options_to_urls() const {
    return add_options_to_urls_.value();
  }

  void set_publicly_cache_mismatched_hashes_experimental(bool x) {
    set_option(x, &publicly_cache_mismatched_hashes_experimental_);
  }

  bool publicly_cache_mismatched_hashes_experimental() const {
    return publicly_cache_mismatched_hashes_experimental_.value();
  }

  void set_oblivious_pagespeed_urls(bool x) {
    set_option(x, &oblivious_pagespeed_urls_);
  }

  bool oblivious_pagespeed_urls() const {
    return oblivious_pagespeed_urls_.value();
  }

  void set_in_place_rewriting_enabled(bool x) {
    set_option(x, &in_place_rewriting_enabled_);
  }

  bool in_place_rewriting_enabled() const {
    return CheckBandwidthOption(in_place_rewriting_enabled_);
  }

  void set_in_place_wait_for_optimized(bool x) {
    set_option(x, &in_place_wait_for_optimized_);
  }

  bool in_place_wait_for_optimized() const {
    return (in_place_wait_for_optimized_.value() ||
            (in_place_rewrite_deadline_ms() < 0));
  }

  void set_in_place_rewrite_deadline_ms(int x) {
    set_option(x, &in_place_rewrite_deadline_ms_);
  }

  int in_place_rewrite_deadline_ms() const {
    return in_place_rewrite_deadline_ms_.value();
  }

  void set_in_place_preemptive_rewrite_css(bool x) {
    set_option(x, &in_place_preemptive_rewrite_css_);
  }
  bool in_place_preemptive_rewrite_css() const {
    return CheckBandwidthOption(in_place_preemptive_rewrite_css_);
  }

  void set_in_place_preemptive_rewrite_css_images(bool x) {
    set_option(x, &in_place_preemptive_rewrite_css_images_);
  }
  bool in_place_preemptive_rewrite_css_images() const {
    return CheckBandwidthOption(in_place_preemptive_rewrite_css_images_);
  }

  void set_in_place_preemptive_rewrite_images(bool x) {
    set_option(x, &in_place_preemptive_rewrite_images_);
  }
  bool in_place_preemptive_rewrite_images() const {
    return CheckBandwidthOption(in_place_preemptive_rewrite_images_);
  }

  void set_in_place_preemptive_rewrite_javascript(bool x) {
    set_option(x, &in_place_preemptive_rewrite_javascript_);
  }
  bool in_place_preemptive_rewrite_javascript() const {
    return CheckBandwidthOption(in_place_preemptive_rewrite_javascript_);
  }

  void set_private_not_vary_for_ie(bool x) {
    set_option(x, &private_not_vary_for_ie_);
  }
  bool private_not_vary_for_ie() const {
    return private_not_vary_for_ie_.value();
  }

  void set_combine_across_paths(bool x) {
    set_option(x, &combine_across_paths_);
  }
  bool combine_across_paths() const { return combine_across_paths_.value(); }

  void set_log_background_rewrites(bool x) {
    set_option(x, &log_background_rewrites_);
  }
  bool log_background_rewrites() const {
    return log_background_rewrites_.value();
  }

  void set_log_mobilization_samples(bool x) {
    set_option(x, &log_mobilization_samples_);
  }
  bool log_mobilization_samples() const {
    return log_mobilization_samples_.value();
  }

  void set_log_rewrite_timing(bool x) {
    set_option(x, &log_rewrite_timing_);
  }
  bool log_rewrite_timing() const { return log_rewrite_timing_.value(); }

  void set_log_url_indices(bool x) {
    set_option(x, &log_url_indices_);
  }
  bool log_url_indices() const { return log_url_indices_.value(); }

  void set_lowercase_html_names(bool x) {
    set_option(x, &lowercase_html_names_);
  }
  bool lowercase_html_names() const { return lowercase_html_names_.value(); }

  void set_always_rewrite_css(bool x) {
    set_option(x, &always_rewrite_css_);
  }
  bool always_rewrite_css() const { return always_rewrite_css_.value(); }

  void set_respect_vary(bool x) {
    set_option(x, &respect_vary_);
  }
  bool respect_vary() const { return respect_vary_.value(); }

  void set_respect_x_forwarded_proto(bool x) {
    set_option(x, &respect_x_forwarded_proto_);
  }
  bool respect_x_forwarded_proto() const {
    return respect_x_forwarded_proto_.value();
  }

  void set_flush_html(bool x) { set_option(x, &flush_html_); }
  bool flush_html() const { return flush_html_.value(); }

  void set_serve_split_html_in_two_chunks(bool x) {
    set_option(x, &serve_split_html_in_two_chunks_);
  }
  bool serve_split_html_in_two_chunks() const {
    return serve_split_html_in_two_chunks_.value();
  }

  void set_serve_stale_if_fetch_error(bool x) {
    set_option(x, &serve_stale_if_fetch_error_);
  }
  bool serve_stale_if_fetch_error() const {
    return serve_stale_if_fetch_error_.value();
  }

  void set_serve_ghost_click_buster_with_split_html(bool x) {
    set_option(x, &serve_ghost_click_buster_with_split_html_);
  }
  bool serve_ghost_click_buster_with_split_html() const {
    return serve_ghost_click_buster_with_split_html_.value();
  }

  void set_serve_xhr_access_control_headers(bool x) {
    set_option(x, &serve_xhr_access_control_headers_);
  }
  bool serve_xhr_access_control_headers() const {
    return serve_xhr_access_control_headers_.value();
  }

  void set_proactively_freshen_user_facing_request(bool x) {
    set_option(x, &proactively_freshen_user_facing_request_);
  }
  bool proactively_freshen_user_facing_request() const {
    return proactively_freshen_user_facing_request_.value();
  }

  void set_serve_stale_while_revalidate_threshold_sec(int64 x) {
    set_option(x, &serve_stale_while_revalidate_threshold_sec_);
  }
  int64 serve_stale_while_revalidate_threshold_sec() const {
    return serve_stale_while_revalidate_threshold_sec_.value();
  }

  void set_enable_flush_early_critical_css(bool x) {
    set_option(x, &enable_flush_early_critical_css_);
  }
  bool enable_flush_early_critical_css() const {
    return enable_flush_early_critical_css_.value();
  }

  void set_use_selectors_for_critical_css(bool x) {
    set_option(x, &use_selectors_for_critical_css_);
  }
  bool use_selectors_for_critical_css() const {
    return use_selectors_for_critical_css_.value();
  }

  void set_default_cache_html(bool x) { set_option(x, &default_cache_html_); }
  bool default_cache_html() const { return default_cache_html_.value(); }

  void set_modify_caching_headers(bool x) {
    set_option(x, &modify_caching_headers_);
  }
  bool modify_caching_headers() const {
    return modify_caching_headers_.value();
  }

  void set_inline_only_critical_images(bool x) {
    set_option(x, &inline_only_critical_images_);
  }
  bool inline_only_critical_images() const {
    return inline_only_critical_images_.value();
  }

  void set_critical_images_beacon_enabled(bool x) {
    set_option(x, &critical_images_beacon_enabled_);
  }
  bool critical_images_beacon_enabled() const {
    return critical_images_beacon_enabled_.value();
  }

  void set_beacon_reinstrument_time_sec(int x) {
    set_option(x, &beacon_reinstrument_time_sec_);
  }
  int beacon_reinstrument_time_sec() const {
    return beacon_reinstrument_time_sec_.value();
  }

  void set_accept_invalid_signatures(bool x) {
    set_option(x, &accept_invalid_signatures_);
  }
  bool accept_invalid_signatures() const {
    return accept_invalid_signatures_.value();
  }

  void set_remote_configuration_timeout_ms(int64 x) {
    set_option(x, &remote_configuration_timeout_ms_);
  }
  int64 remote_configuration_timeout_ms() const {
    return remote_configuration_timeout_ms_.value();
  }

  void set_remote_configuration_url(StringPiece p) {
    set_option(GoogleString(p.data(), p.size()), &remote_configuration_url_);
  }
  const GoogleString& remote_configuration_url() const {
    return remote_configuration_url_.value();
  }

  void set_http_cache_compression_level(int x) {
    set_option(x, &http_cache_compression_level_);
  }
  int http_cache_compression_level() const {
    return http_cache_compression_level_.value();
  }

  void set_request_option_override(StringPiece p) {
    set_option(GoogleString(p.data(), p.size()), &request_option_override_);
  }
  const GoogleString& request_option_override() const {
    return request_option_override_.value();
  }

  void set_url_signing_key(StringPiece p) {
    set_option(GoogleString(p.data(), p.size()), &url_signing_key_);
  }
  const GoogleString& url_signing_key() const {
    return url_signing_key_.value();
  }

  void set_lazyload_images_after_onload(bool x) {
    set_option(x, &lazyload_images_after_onload_);
  }
  bool lazyload_images_after_onload() const {
    return lazyload_images_after_onload_.value();
  }

  void set_lazyload_images_blank_url(StringPiece p) {
    set_option(GoogleString(p.data(), p.size()), &lazyload_images_blank_url_);
  }
  const GoogleString& lazyload_images_blank_url() const {
    return lazyload_images_blank_url_.value();
  }

  void set_max_inlined_preview_images_index(int x) {
    set_option(x, &max_inlined_preview_images_index_);
  }
  int max_inlined_preview_images_index() const {
    return max_inlined_preview_images_index_.value();
  }

  void set_use_blank_image_for_inline_preview(bool x) {
    set_option(x, &use_blank_image_for_inline_preview_);
  }
  bool use_blank_image_for_inline_preview() const {
    return use_blank_image_for_inline_preview_.value();
  }

  void set_min_image_size_low_resolution_bytes(int64 x) {
    set_option(x, &min_image_size_low_resolution_bytes_);
  }
  int64 min_image_size_low_resolution_bytes() const {
    return min_image_size_low_resolution_bytes_.value();
  }

  void set_max_image_size_low_resolution_bytes(int64 x) {
    set_option(x, &max_image_size_low_resolution_bytes_);
  }
  int64 max_image_size_low_resolution_bytes() const {
    return max_image_size_low_resolution_bytes_.value();
  }

  void set_experiment_cookie_duration_ms(int64 x) {
    set_option(x, &experiment_cookie_duration_ms_);
  }
  int64 experiment_cookie_duration_ms() const {
    return experiment_cookie_duration_ms_.value();
  }

  void set_finder_properties_cache_expiration_time_ms(int64 x) {
    set_option(x, &finder_properties_cache_expiration_time_ms_);
  }
  int64 finder_properties_cache_expiration_time_ms() const {
    return finder_properties_cache_expiration_time_ms_.value();
  }

  void set_finder_properties_cache_refresh_time_ms(int64 x) {
    set_option(x, &finder_properties_cache_refresh_time_ms_);
  }
  int64 finder_properties_cache_refresh_time_ms() const {
    return finder_properties_cache_refresh_time_ms_.value();
  }

  void set_rewrite_random_drop_percentage(int x) {
    set_option(x, &rewrite_random_drop_percentage_);
  }
  int rewrite_random_drop_percentage() const {
    return rewrite_random_drop_percentage_.value();
  }

  // css_preserve_urls() is determined by the following rules in order:
  // 1. Value set by the user, if the user has explicitly set it.
  // 2. Default value (true) for OptimizeForBandwidth, if this is the rewrite
  //    level.
  // 3. Default value (true) for MobilizeFilters, if this is the rewrite level.
  // 4. Default value (false) otherwise.
  bool css_preserve_urls() const {
    return (CheckBandwidthOption(css_preserve_urls_) ||
            CheckMobilizeFiltersOption(css_preserve_urls_));
  }
  void set_css_preserve_urls(bool x) {
    set_option(x, &css_preserve_urls_);
  }

  bool image_preserve_urls() const {
    return CheckBandwidthOption(image_preserve_urls_);
  }
  void set_image_preserve_urls(bool x) {
    set_option(x, &image_preserve_urls_);
  }

  bool js_preserve_urls() const {
    return CheckBandwidthOption(js_preserve_urls_);
  }
  void set_js_preserve_urls(bool x) {
    set_option(x, &js_preserve_urls_);
  }

  void set_metadata_cache_staleness_threshold_ms(int64 x) {
    set_option(x, &metadata_cache_staleness_threshold_ms_);
  }
  int64 metadata_cache_staleness_threshold_ms() const {
    return metadata_cache_staleness_threshold_ms_.value();
  }

  void set_metadata_input_errors_cache_ttl_ms(int64 x) {
    set_option(x, &metadata_input_errors_cache_ttl_ms_);
  }
  int64 metadata_input_errors_cache_ttl_ms() const {
    return metadata_input_errors_cache_ttl_ms_.value();
  }

  const GoogleString& downstream_cache_purge_method() const {
    return downstream_cache_purge_method_.value();
  }
  void set_downstream_cache_purge_method(StringPiece p) {
    set_option(p.as_string(), &downstream_cache_purge_method_);
  }

  const GoogleString& downstream_cache_purge_location_prefix() const {
    return downstream_cache_purge_location_prefix_.value();
  }
  void set_downstream_cache_purge_location_prefix(StringPiece p) {
    // Remove any trailing slashes. Leaving them in causes the request to have
    // multiple trailing slashes.
    while (p.ends_with("/")) {
      p.remove_suffix(1);
    }
    set_option(p.as_string(), &downstream_cache_purge_location_prefix_);
  }
  bool IsDownstreamCacheIntegrationEnabled() const {
    return !downstream_cache_purge_location_prefix().empty();
  }

  void set_downstream_cache_rebeaconing_key(StringPiece p) {
      set_option(p.as_string(), &downstream_cache_rebeaconing_key_);
  }
  const GoogleString& downstream_cache_rebeaconing_key() const {
    return downstream_cache_rebeaconing_key_.value();
  }
  bool IsDownstreamCacheRebeaconingKeyConfigured() const {
    return !downstream_cache_rebeaconing_key().empty();
  }
  // Return true only if downstream cache rebeaconing key is configured and
  // the key argument matches the configured key.
  bool MatchesDownstreamCacheRebeaconingKey(StringPiece key) const {
    if (!IsDownstreamCacheRebeaconingKeyConfigured()) {
      return false;
    }
    return StringCaseEqual(key, downstream_cache_rebeaconing_key());
  }

  void set_downstream_cache_rewritten_percentage_threshold(int64 x) {
    set_option(x, &downstream_cache_rewritten_percentage_threshold_);
  }
  int64 downstream_cache_rewritten_percentage_threshold() const {
    return downstream_cache_rewritten_percentage_threshold_.value();
  }

  const BeaconUrl& beacon_url() const { return beacon_url_.value(); }
  void set_beacon_url(const GoogleString& beacon_url) {
    GoogleString ignored_error_detail;
    beacon_url_.SetFromString(beacon_url, &ignored_error_detail);
  }

  // Return false in a subclass if you want to disallow all URL trimming in CSS.
  virtual bool trim_urls_in_css() const { return true; }

  void set_image_jpeg_recompress_quality(int64 x) {
    set_option(x, &image_jpeg_recompress_quality_);
  }

  void set_image_jpeg_recompress_quality_for_small_screens(int64 x) {
    set_option(x, &image_jpeg_recompress_quality_for_small_screens_);
  }

  void set_image_jpeg_quality_for_save_data(int64 x) {
    set_option(x, &image_jpeg_quality_for_save_data_);
  }

  int64 image_recompress_quality() const {
    return image_recompress_quality_.value();
  }
  void set_image_recompress_quality(int64 x) {
    set_option(x, &image_recompress_quality_);
  }

  int image_limit_optimized_percent() const {
    return image_limit_optimized_percent_.value();
  }
  void set_image_limit_optimized_percent(int x) {
    set_option(x, &image_limit_optimized_percent_);
  }
  int image_limit_resize_area_percent() const {
    return image_limit_resize_area_percent_.value();
  }
  void set_image_limit_resize_area_percent(int x) {
    set_option(x, &image_limit_resize_area_percent_);
  }

  int image_limit_rendered_area_percent() const {
    return image_limit_rendered_area_percent_.value();
  }
  void set_image_limit_rendered_area_percent(int x) {
    set_option(x, &image_limit_rendered_area_percent_);
  }

  int64 image_jpeg_num_progressive_scans() const {
    return image_jpeg_num_progressive_scans_.value();
  }
  void set_image_jpeg_num_progressive_scans(int64 x) {
    set_option(x, &image_jpeg_num_progressive_scans_);
  }

  void set_image_jpeg_num_progressive_scans_for_small_screens(int64 x) {
    set_option(x, &image_jpeg_num_progressive_scans_for_small_screens_);
  }

  void set_image_webp_recompress_quality(int64 x) {
    set_option(x, &image_webp_recompress_quality_);
  }

  void set_image_webp_recompress_quality_for_small_screens(int64 x) {
    set_option(x, &image_webp_recompress_quality_for_small_screens_);
  }

  void set_image_webp_animated_recompress_quality(int64 x) {
    set_option(x, &image_webp_animated_recompress_quality_);
  }

  void set_image_webp_quality_for_save_data(int64 x) {
    set_option(x, &image_webp_quality_for_save_data_);
  }

  int64 image_webp_timeout_ms() const {
    return image_webp_timeout_ms_.value();
  }
  void set_image_webp_timeout_ms(int64 x) {
    set_option(x, &image_webp_timeout_ms_);
  }

  bool domain_rewrite_hyperlinks() const {
    return CheckMobilizeFiltersOption(domain_rewrite_hyperlinks_);
  }
  void set_domain_rewrite_hyperlinks(bool x) {
    set_option(x, &domain_rewrite_hyperlinks_);
  }

  bool domain_rewrite_cookies() const {
    return CheckMobilizeFiltersOption(domain_rewrite_cookies_);
  }
  void set_domain_rewrite_cookies(bool x) {
    set_option(x, &domain_rewrite_cookies_);
  }

  bool client_domain_rewrite() const {
    return client_domain_rewrite_.value();
  }
  void set_client_domain_rewrite(bool x) {
    set_option(x, &client_domain_rewrite_);
  }

  void set_flush_more_resources_early_if_time_permits(bool x) {
    set_option(x, &flush_more_resources_early_if_time_permits_);
  }
  bool flush_more_resources_early_if_time_permits() const {
    return flush_more_resources_early_if_time_permits_.value();
  }

  void set_flush_more_resources_in_ie_and_firefox(bool x) {
    set_option(x, &flush_more_resources_in_ie_and_firefox_);
  }
  bool flush_more_resources_in_ie_and_firefox() const {
    return flush_more_resources_in_ie_and_firefox_.value();
  }

  void set_max_prefetch_js_elements(int x) {
    set_option(x, &max_prefetch_js_elements_);
  }
  int max_prefetch_js_elements() const {
    return max_prefetch_js_elements_.value();
  }

  void set_enable_defer_js_experimental(bool x) {
    set_option(x, &enable_defer_js_experimental_);
  }
  bool enable_defer_js_experimental() const {
    return enable_defer_js_experimental_.value();
  }

  void set_disable_rewrite_on_no_transform(bool x) {
    set_option(x, &disable_rewrite_on_no_transform_);
  }
  bool disable_rewrite_on_no_transform() const {
    return disable_rewrite_on_no_transform_.value();
  }

  void set_disable_background_fetches_for_bots(bool x) {
    set_option(x, &disable_background_fetches_for_bots_);
  }
  bool disable_background_fetches_for_bots() const {
    return disable_background_fetches_for_bots_.value();
  }

  void set_enable_cache_purge(bool x) {
    set_option(x, &enable_cache_purge_);
  }
  bool enable_cache_purge() const {
    return enable_cache_purge_.value();
  }

  void set_proactive_resource_freshening(bool x) {
    set_option(x, &proactive_resource_freshening_);
  }
  bool proactive_resource_freshening() const {
    return proactive_resource_freshening_.value();
  }

  void set_lazyload_highres_images(bool x) {
    set_option(x, &lazyload_highres_images_);
  }
  bool lazyload_highres_images() const {
    return lazyload_highres_images_.value();
  }

  void set_enable_blink_debug_dashboard(bool x) {
    set_option(x, &enable_blink_debug_dashboard_);
  }
  bool enable_blink_debug_dashboard() const {
    return enable_blink_debug_dashboard_.value();
  }

  void set_enable_blink_html_change_detection(bool x) {
    set_option(x, &enable_blink_html_change_detection_);
  }
  bool enable_blink_html_change_detection() const {
    return enable_blink_html_change_detection_.value();
  }

  void set_enable_blink_html_change_detection_logging(bool x) {
    set_option(x, &enable_blink_html_change_detection_logging_);
  }
  bool enable_blink_html_change_detection_logging() const {
    return enable_blink_html_change_detection_logging_.value();
  }

  void set_use_smart_diff_in_blink(bool x) {
    set_option(x, &use_smart_diff_in_blink_);
  }
  bool use_smart_diff_in_blink() const {
    return use_smart_diff_in_blink_.value();
  }

  void set_use_fallback_property_cache_values(bool x) {
    set_option(x, &use_fallback_property_cache_values_);
  }
  bool use_fallback_property_cache_values() const {
    return use_fallback_property_cache_values_.value();
  }

  void set_await_pcache_lookup(bool x) {
    set_option(x, &await_pcache_lookup_);
  }
  bool await_pcache_lookup() const {
    return await_pcache_lookup_.value();
  }

  void set_enable_prioritizing_scripts(bool x) {
    set_option(x, &enable_prioritizing_scripts_);
  }
  bool enable_prioritizing_scripts() const {
    return enable_prioritizing_scripts_.value();
  }

  void set_blink_html_change_detection_time_ms(int64 x) {
    set_option(x, &blink_html_change_detection_time_ms_);
  }
  int64 blink_html_change_detection_time_ms() const {
    return blink_html_change_detection_time_ms_.value();
  }

  const GoogleString& blocking_rewrite_key() const {
    return blocking_rewrite_key_.value();
  }
  void set_blocking_rewrite_key(StringPiece p) {
    set_option(p.as_string(), &blocking_rewrite_key_);
  }

  void EnableBlockingRewriteForRefererUrlPattern(
      StringPiece url_pattern) {
    Modify();
    blocking_rewrite_referer_urls_.MakeWriteable()->Allow(url_pattern);
  }

  bool IsBlockingRewriteEnabledForReferer(StringPiece url) const {
    return blocking_rewrite_referer_urls_->Match(url, false);
  }

  bool IsBlockingRewriteRefererUrlPatternPresent() const {
    return blocking_rewrite_referer_urls_->num_wildcards() > 0;
  }

  bool rewrite_uncacheable_resources() const {
    return rewrite_uncacheable_resources_.value();
  }

  void set_rewrite_uncacheable_resources(bool x) {
    set_option(x, &rewrite_uncacheable_resources_);
  }

  void set_running_experiment(bool x) {
    set_option(x, &running_experiment_);
  }
  bool running_experiment() const {
    return running_experiment_.value();
  }

  // x should be between 1 and 5 inclusive.
  void set_experiment_ga_slot(int x) {
    set_option(x, &experiment_ga_slot_);
  }
  int experiment_ga_slot() const { return experiment_ga_slot_.value(); }

  void set_enroll_experiment_id(int x) {
    set_option(x, &enroll_experiment_id_);
  }
  int enroll_experiment_id() const { return enroll_experiment_id_.value(); }

  void set_report_unload_time(bool x) {
    set_option(x, &report_unload_time_);
  }
  bool report_unload_time() const {
    return report_unload_time_.value();
  }

  void set_implicit_cache_ttl_ms(int64 x) {
    set_option(x, &implicit_cache_ttl_ms_);
  }
  int64 implicit_cache_ttl_ms() const {
    return implicit_cache_ttl_ms_.value();
  }

  void set_load_from_file_cache_ttl_ms(int64 x) {
    set_option(x, &load_from_file_cache_ttl_ms_);
  }
  int64 load_from_file_cache_ttl_ms() const {
    return load_from_file_cache_ttl_ms_.value();
  }
  bool load_from_file_cache_ttl_ms_was_set() const {
    return load_from_file_cache_ttl_ms_.was_set();
  }

  void set_x_header_value(StringPiece p) {
    set_option(p.as_string(), &x_header_value_);
  }
  const GoogleString& x_header_value() const {
    return x_header_value_.value();
  }

  void set_distributed_rewrite_key(StringPiece p) {
      set_option(p.as_string(), &distributed_rewrite_key_);
  }
  const GoogleString& distributed_rewrite_key() const {
    return distributed_rewrite_key_.value();
  }

  void set_distribute_fetches(bool x) {
    set_option(x, &distribute_fetches_);
  }
  bool distribute_fetches() const {
    return distribute_fetches_.value();
  }

  void set_distributed_rewrite_servers(StringPiece p) {
      set_option(p.as_string(), &distributed_rewrite_servers_);
  }
  const GoogleString& distributed_rewrite_servers() const {
    return distributed_rewrite_servers_.value();
  }

  void set_distributed_rewrite_timeout_ms(const int64 x) {
    set_option(x, &distributed_rewrite_timeout_ms_);
  }
  int64 distributed_rewrite_timeout_ms() const {
    return distributed_rewrite_timeout_ms_.value();
  }

  void set_avoid_renaming_introspective_javascript(bool x) {
    set_option(x, &avoid_renaming_introspective_javascript_);
  }
  bool avoid_renaming_introspective_javascript() const {
    return avoid_renaming_introspective_javascript_.value();
  }

  int64 blink_max_html_size_rewritable() const {
    return blink_max_html_size_rewritable_.value();
  }
  void set_blink_max_html_size_rewritable(int64 x) {
    set_option(x, &blink_max_html_size_rewritable_);
  }

  void set_critical_line_config(StringPiece p) {
      set_option(GoogleString(p.data(), p.size()), &critical_line_config_);
  }
  const GoogleString& critical_line_config() const {
    return critical_line_config_.value();
  }

  void set_forbid_all_disabled_filters(bool x) {
    set_option(x, &forbid_all_disabled_filters_);
  }
  bool forbid_all_disabled_filters() const {
    return forbid_all_disabled_filters_.value();
  }

  bool reject_blacklisted() const { return reject_blacklisted_.value(); }
  void set_reject_blacklisted(bool x) {
    set_option(x, &reject_blacklisted_);
  }

  HttpStatus::Code reject_blacklisted_status_code() const {
    return static_cast<HttpStatus::Code>(
        reject_blacklisted_status_code_.value());
  }
  void set_reject_blacklisted_status_code(HttpStatus::Code x) {
    set_option(static_cast<int>(x), &reject_blacklisted_status_code_);
  }

  bool support_noscript_enabled() const {
    return support_noscript_enabled_.value();
  }
  void set_support_noscript_enabled(bool x) {
    set_option(x, &support_noscript_enabled_);
  }

  bool enable_extended_instrumentation() const {
    return enable_extended_instrumentation_.value();
  }
  void set_enable_extended_instrumentation(bool x) {
    set_option(x, &enable_extended_instrumentation_);
  }

  bool use_experimental_js_minifier() const {
    return use_experimental_js_minifier_.value();
  }
  void set_use_experimental_js_minifier(bool x) {
    set_option(x, &use_experimental_js_minifier_);
  }

  void set_max_combined_css_bytes(int64 x) {
    set_option(x, &max_combined_css_bytes_);
  }
  int64 max_combined_css_bytes() const {
    return max_combined_css_bytes_.value();
  }

  void set_max_combined_js_bytes(int64 x) {
    set_option(x, &max_combined_js_bytes_);
  }
  int64 max_combined_js_bytes() const {
    return max_combined_js_bytes_.value();
  }

  void set_pre_connect_url(StringPiece p) {
    set_option(GoogleString(p.data(), p.size()), &pre_connect_url_);
  }
  const GoogleString& pre_connect_url() const {
    return pre_connect_url_.value();
  }
  void set_property_cache_http_status_stability_threshold(int x) {
    set_option(x, &property_cache_http_status_stability_threshold_);
  }
  int property_cache_http_status_stability_threshold() const {
    return property_cache_http_status_stability_threshold_.value();
  }

  void set_max_rewrite_info_log_size(int x) {
    set_option(x, &max_rewrite_info_log_size_);
  }
  int max_rewrite_info_log_size() const {
    return max_rewrite_info_log_size_.value();
  }

  void set_enable_aggressive_rewriters_for_mobile(bool x) {
    set_option(x, &enable_aggressive_rewriters_for_mobile_);
  }
  bool enable_aggressive_rewriters_for_mobile() const {
    return enable_aggressive_rewriters_for_mobile_.value();
  }

  void set_allow_logging_urls_in_log_record(bool x) {
    set_option(x, &allow_logging_urls_in_log_record_);
  }
  bool allow_logging_urls_in_log_record() const {
    return allow_logging_urls_in_log_record_.value();
  }

  void set_allow_options_to_be_set_by_cookies(bool x) {
    set_option(x, &allow_options_to_be_set_by_cookies_);
  }
  bool allow_options_to_be_set_by_cookies() const {
    return allow_options_to_be_set_by_cookies_.value();
  }

  void set_non_cacheables_for_cache_partial_html(StringPiece p) {
    set_option(p.as_string(), &non_cacheables_for_cache_partial_html_);
  }
  const GoogleString& non_cacheables_for_cache_partial_html() const {
    return non_cacheables_for_cache_partial_html_.value();
  }

  void set_no_transform_optimized_images(bool x) {
    set_option(x, &no_transform_optimized_images_);
  }
  bool no_transform_optimized_images() const {
    return no_transform_optimized_images_.value();
  }

  void set_access_control_allow_origins(StringPiece p) {
    set_option(p.as_string(), &access_control_allow_origins_);
  }
  const GoogleString& access_control_allow_origins() const {
    return access_control_allow_origins_.value();
  }

  void set_hide_referer_using_meta(bool x) {
    set_option(x, &hide_referer_using_meta_);
  }
  bool hide_referer_using_meta() const {
    return hide_referer_using_meta_.value();
  }

  void set_max_low_res_image_size_bytes(int64 x) {
    set_option(x, &max_low_res_image_size_bytes_);
  }
  int64 max_low_res_image_size_bytes() const {
    return max_low_res_image_size_bytes_.value();
  }

  void set_max_low_res_to_full_res_image_size_percentage(int x) {
    set_option(x, &max_low_res_to_full_res_image_size_percentage_);
  }
  int max_low_res_to_full_res_image_size_percentage() const {
    return max_low_res_to_full_res_image_size_percentage_.value();
  }

  void set_serve_rewritten_webp_urls_to_any_agent(bool x) {
    set_option(x, &serve_rewritten_webp_urls_to_any_agent_);
  }
  bool serve_rewritten_webp_urls_to_any_agent() const {
    return serve_rewritten_webp_urls_to_any_agent_.value();
  }

  void set_cache_fragment(StringPiece p) {
    set_option(p.as_string(), &cache_fragment_);
  }
  const GoogleString& cache_fragment() const {
    return cache_fragment_.value();
  }

  void set_sticky_query_parameters(StringPiece p) {
    set_option(p.as_string(), &sticky_query_parameters_);
  }
  const GoogleString& sticky_query_parameters() const {
    return sticky_query_parameters_.value();
  }

  void set_option_cookies_duration_ms(int64 x) {
    set_option(x, &option_cookies_duration_ms_);
  }
  int64 option_cookies_duration_ms() const {
    return option_cookies_duration_ms_.value();
  }

  void set_responsive_image_densities(const ResponsiveDensities& x) {
    set_option(x, &responsive_image_densities_);
  }
  const ResponsiveDensities& responsive_image_densities() const {
    return responsive_image_densities_.value();
  }

  bool mob_always() const { return mob_always_.value(); }
  void set_mob_always(bool x) { set_option(x, &mob_always_); }
  bool mob_config() const { return mob_config_.value(); }
  bool mob_iframe() const { return mob_iframe_.value(); }
  const GoogleString& mob_iframe_viewport() const {
    return mob_iframe_viewport_.value();
  }
  bool mob_iframe_disable() const { return mob_iframe_disable_.value(); }
  bool mob_layout() const { return mob_layout_.value(); }
  void set_mob_beacon_url(StringPiece x) {
    set_option(x.as_string(), &mob_beacon_url_);
  }
  const GoogleString& mob_beacon_url() const { return mob_beacon_url_.value(); }
  void set_mob_beacon_category(StringPiece x) {
    set_option(x.as_string(), &mob_beacon_category_);
  }
  const GoogleString& mob_beacon_category() const {
    return mob_beacon_category_.value();
  }
  void set_mob_phone_number(StringPiece x) {
    set_option(x.as_string(), &mob_phone_number_);
  }
  const GoogleString& mob_phone_number() const {
    return mob_phone_number_.value();
  }
  void set_mob_map_location(StringPiece x) {
    set_option(x.as_string(), &mob_map_location_);
  }
  const GoogleString& mob_map_location() const {
    return mob_map_location_.value();
  }
  void set_mob_config(bool x) { set_option(x, &mob_config_); }
  void set_mob_iframe(bool x) { set_option(x, &mob_iframe_); }
  void set_mob_iframe_disable(bool x) { set_option(x, &mob_iframe_disable_); }
  void set_mob_iframe_viewport(StringPiece x) {
    set_option(x.as_string(), &mob_iframe_viewport_);
  }
  void set_mob_layout(bool x) { set_option(x, &mob_layout_); }
  bool mob_nav() const {
    return CheckMobilizeFiltersOption(mob_nav_);
  }
  void set_mob_nav(bool x) { set_option(x, &mob_nav_); }
  bool mob_labeled_mode() const { return mob_labeled_mode_.value(); }
  void set_mob_labeled_mode(bool x) { set_option(x, &mob_labeled_mode_); }
  const GoogleString& mob_nav_classes() const {
    return mob_nav_classes_.value();
  }
  void set_mob_nav_classes(StringPiece p) {
    set_option(p.as_string(), &mob_nav_classes_);
  }
  bool has_mob_nav_classes() const { return mob_nav_classes_.was_set(); }
  // Should menu extraction be run?
  bool MobRenderServerSideMenus() const {
    return (Enabled(kMobilize) && !mob_labeled_mode());
  }
  // Should labeling be run in the request flow?
  bool MobUseLabelFilter() const {
    // We use the label filter if we're doing mobilization.  But we don't run
    // it in iframe mode, ever, because that doesn't see the page we'd be
    // extracting mobilization data from.  We used to not run it if we were
    // doing nav server side, and should consider doing that again -- but if
    // something goes wrong we can't then fall back to client-side navigation.
    return (Enabled(kMobilize) && !mob_iframe() && !mob_labeled_mode());
  }
  bool mob_static() const { return mob_static_.value(); }
  void set_mob_static(bool x) { set_option(x, &mob_static_); }
  const MobTheme& mob_theme() const { return mob_theme_.value(); }
  void set_mob_theme(const MobTheme& x) {
    set_option(x, &mob_theme_);
  }
  bool has_mob_theme() const { return mob_theme_.was_set(); }
  int64 mob_conversion_id() const { return mob_conversion_id_.value(); }
  void set_mob_conversion_id(int64 x) { set_option(x, &mob_conversion_id_); }
  const GoogleString& mob_map_conversion_label() const {
    return mob_map_conversion_label_.value();
  }
  void set_mob_map_conversion_label(StringPiece x) {
    set_option(x.as_string(), &mob_map_conversion_label_);
  }
  const GoogleString& mob_phone_conversion_label() const {
    return mob_phone_conversion_label_.value();
  }
  void set_mob_phone_conversion_label(StringPiece x) {
    set_option(x.as_string(), &mob_phone_conversion_label_);
  }

  // Merge src into 'this'.  Generally, options that are explicitly
  // set in src will override those explicitly set in 'this' (except that
  // filters forbidden in 'this' cannot be enabled by 'src'), although
  // option Merge implementations can be redefined by specific Option
  // class implementations (e.g. OptionInt64MergeWithMax).  One
  // semantic subject to interpretation is when a core-filter is
  // disabled in the first set and not in the second.  My judgement is
  // that the 'disable' from 'this' should override the core-set
  // membership in the 'src', but not an 'enable' in the 'src'.
  //
  // You can make an exact duplicate of RewriteOptions object 'src' via
  // (new 'typeof src')->Merge(src), aka Clone().
  //
  // Merge expects that 'src' and 'this' are the same type.  If that's
  // not true, this function will DCHECK.
  virtual void Merge(const RewriteOptions& src);

  // Merge the process scope options (including strict ones) from src into
  // this.
  void MergeOnlyProcessScopeOptions(const RewriteOptions& src);

  // Registers a wildcard pattern for to be allowed, potentially overriding
  // previous Disallow wildcards.
  void Allow(StringPiece wildcard_pattern) {
    Modify();
    allow_resources_.MakeWriteable()->Allow(wildcard_pattern);
  }

  // Registers a wildcard pattern for to be disallowed, potentially overriding
  // previous Allow wildcards.
  void Disallow(StringPiece wildcard_pattern) {
    Modify();
    allow_resources_.MakeWriteable()->Disallow(wildcard_pattern);
  }

  // Like Allow().  See IsAllowedWhenInlining().
  void AllowWhenInlining(StringPiece wildcard_pattern) {
    Modify();
    allow_when_inlining_resources_.MakeWriteable()->Allow(wildcard_pattern);
  }

  // Helper function to Disallow something except when inlining.  Useful for
  // resources that you expect to be on good CDNs but may still be worth
  // inlining if small enough.
  void AllowOnlyWhenInlining(StringPiece wildcard_pattern) {
    Disallow(wildcard_pattern);
    AllowWhenInlining(wildcard_pattern);
  }

  // Like Disallow().  See IsAllowedWhenInlining().
  void DisallowWhenInlining(StringPiece wildcard_pattern) {
    Modify();
    allow_when_inlining_resources_.MakeWriteable()->Disallow(wildcard_pattern);
  }

  // Blacklist of javascript files that don't like their names changed.
  // This should be called for root options to set defaults.
  // TODO(sligocki): Rename to allow for more general initialization.
  virtual void DisallowTroublesomeResources();

  // Disallows resources that are served on well-distributed CDNs
  // already, and are likely to be in browser-caches, or that are
  // troublesome resources stored on external domains.  Note: this is
  // not currently called by mod_pagespeed.
  virtual void DisallowResourcesForProxy();

  // When someone asks for a readonly lawyer, we can return a pointer to
  // the potentially shared DomainLawyer* object.  But if you want a mutable
  // one, we clone whatever Lawyer we had and detach it from the shared
  // group.  Here are several scenarios.
  //   1. We are setting up the global_options() for a ServerContext on
  //      startup.  There will be no concurrent access, and at this point
  //      there will be no sharing with other RewriteOptions.
  //   2. We are merging down global_options() based on the
  //      vhost/directory/.htaccess data and need to update (among
  //      other things) the settings.  This may happen concurrently for
  //      several different server-scoped, directory-scoped, or request-scoped
  //      RewriteOptions objects.  Those will all be attached to their
  //      parent when the options get created.  However writing to these
  //      will effectively detach them.
  // One case that would be problematic is a mutation of a parent
  // RewriteOptions->WriteableDomainLawyer() concurrent with instantiating
  // a new child RewriteOptions.  However this does not occur in our system.
  //
  // The only similar place this does occur is cache_invalidation_timestamp_
  // which can be mutated when there are active children.
  const DomainLawyer* domain_lawyer() const { return domain_lawyer_.get(); }
  DomainLawyer* WriteableDomainLawyer();

  FileLoadPolicy* file_load_policy() { return &file_load_policy_; }
  const FileLoadPolicy* file_load_policy() const { return &file_load_policy_; }

  // Determines, based on the sequence of Allow/Disallow calls above, whether
  // a url is allowed.
  bool IsAllowed(StringPiece url) const {
    return allow_resources_->Match(url, true /* default allow */);
  }

  // Call this when:
  //
  //  1. IsAllowed() returns false and
  //  2. The url is for a resource we're planning to inline if successful.
  //
  // If it returns true, it's ok to fetch, rewrite, and inline this resource as
  // if IsAllowed() had returned true.
  bool IsAllowedWhenInlining(StringPiece url) const {
    return allow_when_inlining_resources_->Match(
        url, false /* default disallow */);
  }

  // Adds a new comment wildcard pattern to be retained.
  void RetainComment(StringPiece comment) {
    Modify();
    retain_comments_.MakeWriteable()->Allow(comment);
  }

  // If enabled, the 'remove_comments' filter will remove all HTML comments.
  // As discussed in Issue 237, some comments have semantic value and must
  // be retained.
  bool IsRetainedComment(StringPiece comment) const {
    return retain_comments_->Match(comment, false);
  }

  // Adds a new class name for which lazyload should be disabled.
  void DisableLazyloadForClassName(StringPiece class_name) {
    Modify();
    lazyload_enabled_classes_.MakeWriteable()->Disallow(class_name);
  }

  // Checks if lazyload images is enabled for the specified class.
  bool IsLazyloadEnabledForClassName(StringPiece class_name) const {
    return lazyload_enabled_classes_->Match(class_name, true);
  }

  void set_override_caching_ttl_ms(int64 x) {
    set_option(x, &override_caching_ttl_ms_);
  }
  int64 override_caching_ttl_ms() const {
    return override_caching_ttl_ms_.value();
  }

  // Overrides the cache ttl for all urls matching the wildcard with
  // override_caching_ttl_ms().
  void AddOverrideCacheTtl(StringPiece wildcard) {
    Modify();
    override_caching_wildcard_.MakeWriteable()->Allow(wildcard);
  }

  // Is the cache TTL overridden for the given url?
  bool IsCacheTtlOverridden(StringPiece url) const {
    return override_caching_wildcard_->Match(url, false);
  }

  void AddRejectedUrlWildcard(const GoogleString& wildcard) {
    AddRejectedHeaderWildcard(kRejectedRequestUrlKeyName, wildcard);
  }

  void AddRejectedHeaderWildcard(StringPiece header_name,
                                 const GoogleString& wildcard) {
    Modify();
    std::pair<FastWildcardGroupMap::iterator, bool> insert_result =
        rejected_request_map_.insert(std::make_pair(
            header_name, static_cast<FastWildcardGroup*>(NULL)));

    if (insert_result.second) {
      insert_result.first->second = new FastWildcardGroup;
    }
    insert_result.first->second->Allow(wildcard);
  }

  void set_min_cache_ttl_ms(int64 x) {
    set_option(x, &min_cache_ttl_ms_);
  }
  int64 min_cache_ttl_ms() const {
    return min_cache_ttl_ms_.value();
  }

  // Determine if the request url needs to be declined based on the url,
  // request headers and rewrite options.
  bool IsRequestDeclined(const GoogleString& url,
                         const RequestHeaders* request_headers) const;

  // Make an identical copy of these options and return it.  This does
  // *not* copy the signature, and the returned options are not in
  // a frozen state.
  virtual RewriteOptions* Clone() const;

  // Make an empty options object of the same type as this.
  virtual RewriteOptions* NewOptions() const;

  // Computes a signature for the RewriteOptions object, including all
  // contained classes (DomainLawyer, FileLoadPolicy, WildCardGroups).
  //
  // Computing a signature "freezes" the class instance.  Attempting
  // to modify a RewriteOptions after freezing will DCHECK.
  void ComputeSignature() LOCKS_EXCLUDED(cache_purge_mutex_.get());
  void ComputeSignatureLockHeld() SHARED_LOCKS_REQUIRED(cache_purge_mutex_);

  // If you subclass RewriteOptions and store any configuration data that's not
  // an Option, use this hook to include the signature of your additional data.
  virtual GoogleString SubclassSignatureLockHeld() { return ""; }

  // Freeze a RewriteOptions so we can't modify it anymore and thus
  // know that it's safe to read it from multiple threads, but don't
  // bother calculating its signature since we will only be using this
  // instance for merging and cloning.
  void Freeze();

  // Clears the computed signature, unfreezing the options object.
  // Warning: Please note that using this method is extremely risky and should
  // be avoided as much as possible. If you are planning to use this, please
  // discuss this with your team-mates and ensure that you clearly understand
  // its implications. Also, please do repeat this warning at every place you
  // use this method.
  //
  // Returns true if the signature was previously computed, and thus should
  // be recomputed after modification.
  bool ClearSignatureWithCaution();

  bool frozen() const { return frozen_; }

  // Clears a computed signature, unfreezing the options object.  This
  // is intended for testing.  Returns whether the options were frozen
  // in the first place.
  bool ClearSignatureForTesting() {
    bool frozen = frozen_;
    ClearSignatureWithCaution();
    return frozen;
  }

  // Returns the computed signature.
  const GoogleString& signature() const {
    // We take a reader-lock because we may be looking at the
    // global_options signature concurrent with updating it if someone
    // flushes cache.  Note that the default mutex implementation is
    // NullRWLock, which isn't actually a mutex.  Only (currently) for the
    // Apache global_options() object do we create a real mutex.  We
    // don't expect contention here because we take a reader-lock and the
    // only time we Write is if someone flushes the cache.
    ThreadSystem::ScopedReader lock(cache_purge_mutex_.get());
    DCHECK(frozen_);
    DCHECK(!signature_.empty());
    return signature_;
  }

  virtual GoogleString OptionsToString() const;
  GoogleString FilterSetToString(const FilterSet& filter_set) const;
  GoogleString EnabledFiltersToString() const;
  // Returns a string containing the enabled options which do not leak sensitive
  // information about the server state.
  GoogleString SafeEnabledOptionsToString() const;

  // Returns a string identifying the currently running experiment to be used in
  // tagging Google Analytics data.
  virtual GoogleString ToExperimentString() const;

  // Returns a string with more information about the currently running
  // experiment. Primarily used for tagging Google Analytics data.  This format
  // is not at all specific to Google Analytics, however.
  virtual GoogleString ToExperimentDebugString() const;

  // Convert an id string like "ah" to a Filter enum like kAddHead.
  // Returns kEndOfFilters if the id isn't known.
  static Filter LookupFilterById(const StringPiece& filter_id);

  // Convert the filter name to a Filter.
  static Filter LookupFilter(const StringPiece& filter_name);

  // Looks up an option id/name and returns the corresponding PropertyBase if
  // found, or NULL if the id/name is not found.
  static const PropertyBase* LookupOptionById(StringPiece option_id);
  static const PropertyBase* LookupOptionByName(StringPiece option_name);

  // Looks up an option id and returns the corresponding name, or kNullOption
  // if the id is not found. Example: for "ii" it returns "ImageInlineMaxBytes".
  static const StringPiece LookupOptionNameById(StringPiece option_id);

  // Determine if the given option name is valid/known.
  static bool IsValidOptionName(StringPiece name);

  // Return the list of all options.  Used to initialize the configuration
  // vector to the Apache configuration system.
  const OptionBaseVector& all_options() const {
    return all_options_;
  }

  // Determines whether this and that are the same.  Uses the signature() to
  // short-cut most of the deep comparisons, but then compares directly some
  // options and other fields that are omitted from the signature.
  bool IsEqual(const RewriteOptions& that) const;

  // Returns the hasher used for signatures and URLs to purge.
  const Hasher* hasher() const { return &hasher_; }

  const SHA1Signature* sha1signature() const { return &sha1signature_; }

  ThreadSystem* thread_system() const { return thread_system_; }

  // Produces a new HttpOptions each time this is called, shouldn't be a big
  // deal since we don't call it very often and HttpOptions are pretty light,
  // but we might want to reconsider if those assumptions change.
  HttpOptions ComputeHttpOptions() const;

 protected:
  // Helper class to represent an Option, whose value is held in some class T.
  // An option is explicitly initialized with its default value, although the
  // default value can be altered later.  It keeps track of whether a
  // value has been explicitly set (independent of whether that happens to
  // coincide with the default value).
  //
  // It can use this knowledge to intelligently merge a 'base' option value
  // into a 'new' option value, allowing explicitly set values from 'base'
  // to override default values from 'new'.
  template<class T> class OptionTemplateBase : public OptionBase {
   public:
    typedef T ValueType;

    OptionTemplateBase() : was_set_(false), property_(NULL) {}

    virtual bool was_set() const { return was_set_; }

    void set(const T& val) {
      was_set_ = true;
      value_ = val;
    }

    void set_default(const T& val) {
      if (!was_set_) {
        value_ = val;
      }
    }

    const T& value() const { return value_; }
    T& mutable_value() { was_set_ = true; return value_; }

    // The signature of the Merge implementation must match the base-class.  The
    // caller is responsible for ensuring that only the same typed Options are
    // compared.  In RewriteOptions::Merge this is guaranteed because the
    // vector<OptionBase*> all_options_ is sorted on option_name().  We DCHECK
    // that the option_name of this and src are the same.
    virtual void Merge(const OptionBase* src) {
      DCHECK(option_name() == src->option_name());
      MergeHelper(static_cast<const OptionTemplateBase*>(src));
    }

    void MergeHelper(const OptionTemplateBase* src) {
      // Even if !src->was_set, the default value needs to be transferred
      // over in case it was changed with set_default or SetDefaultRewriteLevel.
      if (src->was_set_ || !was_set_) {
        value_ = src->value_;
        was_set_ = src->was_set_;
      }
    }

    // The static properties of an Option are held in a Property<T>*.
    void set_property(const Property<T>* property) {
      property_ = property;

      // Note that the copying of default values here is only required
      // to support SetDefaultRewriteLevel, which it should be
      // possible to remove.  Otherwise we could just pull the
      // default value out of properties_ when !was_set_;
      value_ = property->default_value();
    }
    virtual const PropertyBase* property() const { return property_; }

    // Sets a the option default value globally.  This is thread-unsafe,
    // and reaches into the option property_ field via a const-cast to
    // mutate it.  Note that this method does not affect the current value
    // of the instantiated option.
    //
    // TODO(jmarantz): consider an alternate structure where the
    // Property<T>* can be easily located programmatically
    // rather than going through a dummy Option object.
    void set_global_default(const T& val) {
      Property<T>* property = const_cast<Property<T>*>(property_);
      property->set_default(val);
    }

    // Sets a the option's participation in Signatures globally.  This
    // is thread-unsafe, and reaches into the option property_ field
    // via a const-cast to mutate it.  Note that this method does not
    // affect the current value of the instantiated option.
    //
    // TODO(jmarantz): consider an alternate structure where the
    // Property<T>* can be easily located programmatically
    // rather than going through a dummy Option object.
    void DoNotUseForSignatureComputation() {
      Property<T>* property = const_cast<Property<T>*>(property_);
      property->set_do_not_use_for_signature_computation(true);
    }

   private:
    bool was_set_;
    T value_;
    const Property<T>* property_;

    DISALLOW_COPY_AND_ASSIGN(OptionTemplateBase);
  };

  // Subclassing OptionTemplateBase so that the conversion functions that need
  // to invoke static overloaded functions are declared only here.  Enables
  // subclasses of RewriteOptions to override these in case they use Option
  // types not visible here.
  template<class T> class Option : public OptionTemplateBase<T> {
   public:
    Option() {}

    // Sets value_ from value_string.
    virtual bool SetFromString(StringPiece value_string,
                               GoogleString* error_detail) {
      T value;
      bool success = RewriteOptions::ParseFromString(value_string, &value);
      if (success) {
        this->set(value);
      }
      return success;
    }

    virtual GoogleString Signature(const Hasher* hasher) const {
      return RewriteOptions::OptionSignature(this->value(), hasher);
    }

    virtual GoogleString ToString() const {
      return RewriteOptions::ToString(this->value());
    }

   private:
    DISALLOW_COPY_AND_ASSIGN(Option);
  };

 protected:
  // Adds a new Property to 'properties' (the last argument).
  template<class RewriteOptionsSubclass, class OptionClass>
  static void AddProperty(
      typename OptionClass::ValueType default_value,
      OptionClass RewriteOptionsSubclass::*offset,
      const char* id,
      StringPiece option_name,
      OptionScope scope,
      const char* help_text,
      bool safe_to_print,
      Properties* properties) {
    PropertyBase* property =
        new PropertyLeaf<RewriteOptionsSubclass, OptionClass>(
            default_value, offset, id, option_name);
    property->set_scope(scope);
    property->set_help_text(help_text);
    property->set_safe_to_print(safe_to_print);
    properties->push_back(property);
  }

  // Merges properties into all_properties so that
  // RewriteOptions::Merge and SetOptionFromName can work across
  // options from RewriteOptions and all relevant subclasses.
  //
  // Each RewriteOptions subclass keeps its own property lists using
  // its own private Properties* member variables.  The private lists
  // are used for initialization of default-values during
  // construction.  We cannot initialize subclass default option
  // values during RewriteOptions construction because options with
  // non-POD ValueType (e.g. GoogleString) have not yet been
  // initialized, so we have to keep separate per-class property-lists
  // for use during construction.  However, we use a global sorted
  // list for fast merging and setting-by-option-name.
  static void MergeSubclassProperties(Properties* properties);

  // Populates all_options_, based on the passed-in index, which
  // should correspond to the property index calculated after
  // sorting all_properties_.  This enables us to sort the all_properties_
  // vector once, and use that to give us all_options_ that is sorted
  // the same way.
  void set_option_at(int index, OptionBase* option) {
    all_options_[index] = option;
  }

  // When setting an option, however, we generally are doing so
  // with a variable rather than a constant so it makes sense to pass
  // it by reference.
  template<class T>
  void set_option(const T& new_value, OptionTemplateBase<T>* option) {
    option->set(new_value);
    Modify();
  }

  // Marks the config as modified.
  void Modify();

  // Sets the global default value for 'x_header_value'.  Note that setting
  // this Option reaches through to the underlying property and sets the
  // default value there, and in fact does *not affect the value of the
  // instantiated RewriteOptions object.
  //
  // TODO(jmarantz): Remove this method and make another one that operate
  // directly on the Property.
  void set_default_x_header_value(StringPiece x_header_value) {
    x_header_value_.set_global_default(x_header_value.as_string());
  }

  // Enable/disable filters and set options according to the current
  // ExperimentSpec that experiment_id_ matches. Returns true if the state was
  // set successfully.
  bool SetupExperimentRewriters();

  // Enables filters needed by Experiment regardless of experiment.
  virtual void SetRequiredExperimentFilters();

  // Helper method to add pre-configured ExperimentSpec objects to the internal
  // vector of ExperimentSpec's. Returns true if the experiment was added
  // successfully. Takes ownership of (and may delete) spec.
  bool InsertExperimentSpecInVector(ExperimentSpec* spec);

  // Protected option values so that derived class can modify.
  Option<BeaconUrl> beacon_url_;

  // The value we put for the X-Mod-Pagespeed header. Default is our version.
  Option<GoogleString> x_header_value_;

 protected:
  // The base class for a Property.  This class contains fields of
  // Properties that are independent of type.
  class PropertyBase {
   public:
    PropertyBase(const char* id, StringPiece option_name)
        : id_(id),
          help_text_(NULL),
          option_name_(option_name),
          scope_(kDirectoryScope),
          do_not_use_for_signature_computation_(false),
          index_(-1) {
    }
    virtual ~PropertyBase();

    // Connect the specified RewriteOption to this property.
    // set_index() must previously have been called on this.
    virtual void InitializeOption(RewriteOptions* options) const = 0;

    void set_do_not_use_for_signature_computation(bool x) {
      do_not_use_for_signature_computation_ = x;
    }
    bool is_used_for_signature_computation() const {
      return !do_not_use_for_signature_computation_;
    }

    void set_scope(OptionScope x) { scope_ = x; }
    OptionScope scope() const { return scope_; }

    void set_help_text(const char* x) { help_text_ = x; }
    const char* help_text() const { return help_text_; }

    void set_index(int index) { index_ = index; }
    const char* id() const { return id_; }
    StringPiece option_name() const { return option_name_; }
    int index() const { return index_; }

    bool safe_to_print() const { return safe_to_print_; }
    void set_safe_to_print(bool safe_to_print) {
      safe_to_print_ = safe_to_print;
    }

   private:
    const char* id_;
    const char* help_text_;
    StringPiece option_name_;  // Key into all_options_.
    OptionScope scope_;
    bool do_not_use_for_signature_computation_;  // Default is false.
    bool safe_to_print_;  // Safe to print in debug filter output.
    int index_;

    DISALLOW_COPY_AND_ASSIGN(PropertyBase);
  };

  // Type-specific class of Property.  This subclass of PropertyBase
  // knows what sort of value the Option will hold, and so we can put
  // the default value here.
  template<class ValueType>
  class Property : public PropertyBase {
   public:
    // When adding a new Property, we take the default_value by value,
    // not const-reference.  This is because when calling AddProperty
    // we may want to use a compile-time constant
    // (e.g. Timer::kHourMs) which does not have a linkable address.
    Property(ValueType default_value,
             const char* id,
             StringPiece option_name)
        : PropertyBase(id, option_name),
          default_value_(default_value) {
    }

    void set_default(ValueType value) { default_value_ = value; }
    const ValueType& default_value() const { return default_value_; }

   private:
    ValueType default_value_;

    DISALLOW_COPY_AND_ASSIGN(Property);
  };

  // Leaf subclass of Property<ValueType>, which is templated on the class of
  // the corresponding Option.  The template parameters here are
  //   RewriteOptionsSubclass -- the subclass of RewriteOptions in which
  //     this option is instantiated, e.g. ApacheConfig.
  //   OptionClass -- the subclass of OptionBase that is being instantiated
  //     in each RewriteOptionsSubclass.
  // These template parameters are generally automatically discovered by
  // the compiler when AddProperty is called.
  //
  // TODO(jmarantz): It looks tempting to fold Property<T> and
  // PropertyLeaf<T> together, but this is difficult because of the
  // way that the Option class hiearchy is structured and the
  // precision of C++ pointers-to-members.  Attempting that is
  // probably a worthwhile follow-up task.
  template<class RewriteOptionsSubclass, class OptionClass>
  class PropertyLeaf : public Property<typename OptionClass::ValueType> {
   public:
    // Fancy C++ pointers to members; a typesafe version of offsetof.  See
    // http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?
    // topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr034.htm
    typedef OptionClass RewriteOptionsSubclass::*OptionOffset;
    typedef typename OptionClass::ValueType ValueType;

    PropertyLeaf(ValueType default_value,
                 OptionOffset offset,
                 const char* id,
                 StringPiece option_name)
        : Property<ValueType>(default_value, id, option_name),
          offset_(offset) {
    }

    virtual void InitializeOption(RewriteOptions* options) const {
      RewriteOptionsSubclass* options_subclass =
          static_cast<RewriteOptionsSubclass*>(options);
      OptionClass& option = options_subclass->*offset_;
      option.set_property(this);
      DCHECK_NE(-1, this->index()) << "Call Property::set_index first.";
      options->set_option_at(this->index(), &option);
    }

   private:
    OptionOffset offset_;

    DISALLOW_COPY_AND_ASSIGN(PropertyLeaf);
  };

 private:
  // We need to check for valid settings with CacheFragment.
  class CacheFragmentOption : public Option<GoogleString> {
   public:
    virtual bool SetFromString(StringPiece value_string,
                               GoogleString* error_detail);
  };

  struct OptionIdCompare;

  // Enum type used to record what action must be taken to resolve conflicts
  // between "preserve URLs" and "extend cache" directives at different levels
  // of the merge.  The lower priority wins.  These must be calculated before
  // option/filter merging, and then performed after option/filter merging.
  enum MergeOverride { kNoAction, kDisablePreserve, kDisableFilter };

  static Properties* properties_;          // from RewriteOptions only
  static Properties* all_properties_;      // includes subclass properties

  FRIEND_TEST(RewriteOptionsTest, ExperimentMergeTest);
  FRIEND_TEST(RewriteOptionsTest, LookupOptionByNameTest);
  FRIEND_TEST(RewriteOptionsTest, ColorUtilTest);
  FRIEND_TEST(RewriteOptionsTest, ParseFloats);

  // Helper functions to check if given header need to be blocked.
  bool HasRejectedHeader(const StringPiece& header_name,
                         const RequestHeaders* request_headers) const;

  bool IsRejectedUrl(const GoogleString& url) const {
    return IsRejectedRequest(kRejectedRequestUrlKeyName, url);
  }

  bool IsRejectedRequest(StringPiece header_name,
                         StringPiece value) const {
    FastWildcardGroupMap::const_iterator it = rejected_request_map_.find(
        header_name);
    if (it != rejected_request_map_.end()) {
      return it->second->Match(value, false);
    }
    return false;
  }

  // Makes sure that javascript_library_identification_ points to an object
  // owned only by us, so that we can modify it; and returns the pointer to it.
  JavascriptLibraryIdentification* WriteableJavascriptLibraryIdentification();

  // A family of urls for which prioritize_visible_content filter can be
  // applied.  url_pattern represents the actual set of urls,
  // cache_time_ms is the duration for which the cacheable portions of pages of
  // the family can be cached, and non_cacheable_elements is a comma-separated
  // list of elements (e.g., "id:foo,class:bar") that cannot be cached for the
  // family.
  struct PrioritizeVisibleContentFamily {
    PrioritizeVisibleContentFamily(StringPiece url_pattern_string,
                                   int64 cache_time_ms_in,
                                   StringPiece non_cacheable_elements_in)
        : url_pattern(url_pattern_string),
          cache_time_ms(cache_time_ms_in),
          non_cacheable_elements(non_cacheable_elements_in.data(),
                                 non_cacheable_elements_in.size()) {}

    PrioritizeVisibleContentFamily* Clone() const {
      return new PrioritizeVisibleContentFamily(
          url_pattern.spec(), cache_time_ms, non_cacheable_elements);
    }

    GoogleString ComputeSignature() const {
      return StrCat(url_pattern.spec(), ";", Integer64ToString(cache_time_ms),
                    ";", non_cacheable_elements);
    }

    GoogleString ToString() const {
      return StrCat("URL pattern: ", url_pattern.spec(), ",  Cache time (ms): ",
                    Integer64ToString(cache_time_ms), ",  Non-cacheable: ",
                    non_cacheable_elements);
    }

    Wildcard url_pattern;
    int64 cache_time_ms;
    GoogleString non_cacheable_elements;
  };

  // A URL pattern cache invalidation entry.  All values cached for an URL that
  // matches url_pattern before timestamp_ms should be evicted.
  struct UrlCacheInvalidationEntry {
    UrlCacheInvalidationEntry(StringPiece url_pattern_in,
                              int64 timestamp_ms_in,
                              bool ignores_metadata_and_pcache_in)
        : url_pattern(url_pattern_in),
          timestamp_ms(timestamp_ms_in),
          ignores_metadata_and_pcache(ignores_metadata_and_pcache_in) {}

    UrlCacheInvalidationEntry* Clone() const {
      return new UrlCacheInvalidationEntry(
          url_pattern.spec(), timestamp_ms, ignores_metadata_and_pcache);
    }

    GoogleString ComputeSignature() const {
      if (ignores_metadata_and_pcache) {
        return "";
      }
      return StrCat(url_pattern.spec(), "@", Integer64ToString(timestamp_ms));
    }

    GoogleString ToString() const {
      return StrCat(
          url_pattern.spec(), ", ",
          (ignores_metadata_and_pcache ? "STRICT" : "REFERENCE"), " @ ",
          Integer64ToString(timestamp_ms));
    }

    Wildcard url_pattern;
    int64 timestamp_ms;
    bool ignores_metadata_and_pcache;
  };

  typedef std::vector<UrlCacheInvalidationEntry*>
      UrlCacheInvalidationEntryVector;
  typedef dense_hash_map<GoogleString, int64> UrlCacheInvalidationMap;

  // Sigh. The folding Hash struct is required so that we ignore case when
  // inserting. The folding Equal struct is required for looking up. Damned
  // if I know why one needs to specify both.
  typedef rde::hash_map<StringPiece, const PropertyBase*,
                        CaseFoldStringPieceHash, /* TLoadFactor4 = */ 6,
                        CaseFoldStringPieceEqual> PropertyNameMap;

  // Private methods to help add properties to
  // RewriteOptions::properties_.  Subclasses define their own
  // versions of these to add to their own private property-lists, and
  // subsequently merge them into RewriteOptions::all_properties_ via
  // MergeSubclassProperties.
  //
  // This version is for a property without a unique option_name_ field.
  // kNullOption will be used for the name, and thus SetOptionFromName cannot
  // be used for options associated with such properties.
  //
  // TODO(jmarantz): This method should be removed and such properties
  // should be moved into RequestContext.
  template<class OptionClass>
  static void AddRequestProperty(typename OptionClass::ValueType default_value,
                                 OptionClass RewriteOptions::*offset,
                                 const char* id, bool safe_to_print) {
    AddProperty(default_value, offset, id, kNullOption, kProcessScope,
                NULL, safe_to_print, properties_);
  }

  // Adds a property with a unique option_name_ field, allowing use of
  // SetOptionFromName.
  template<class OptionClass>
  static void AddBaseProperty(typename OptionClass::ValueType default_value,
                              OptionClass RewriteOptions::*offset,
                              const char* id,
                              StringPiece option_name,
                              OptionScope scope,
                              const char* help,
                              bool safe_to_print) {
    AddProperty(default_value, offset, id, option_name, scope, help,
                safe_to_print, properties_);
  }

  static void AddProperties();
  bool AddCommaSeparatedListToFilterSetState(
      const StringPiece& filters, FilterSet* set, MessageHandler* handler);
  static bool AddCommaSeparatedListToFilterSet(
      const StringPiece& filters, FilterSet* set, MessageHandler* handler);
  // Initialize the Filter id to enum reverse array used for fast lookups.
  static void InitFilterIdToEnumArray();
  static void InitOptionIdToPropertyArray();
  static void InitOptionNameToPropertyArray();

  // Helper for converting the result of SetOptionFromNameInternal into
  // a status/message pair. The returned result may be adjusted from the passed
  // in one (in particular when option_name is kNullOption).
  OptionSettingResult FormatSetOptionMessage(
      OptionSettingResult result, StringPiece name, StringPiece value,
      StringPiece error_detail, GoogleString* msg);

  // Backend to SetOptionFromName that doesn't do full message
  // formatting. *error_detail may not be always set.
  OptionSettingResult SetOptionFromNameInternal(
      StringPiece name, StringPiece value, OptionScope max_scope,
      GoogleString* error_detail);

  // These static methods enable us to generate signatures for all
  // instantiated option-types from Option<T>::Signature().
  static GoogleString OptionSignature(bool x, const Hasher* hasher) {
    return x ? "T" : "F";
  }
  static GoogleString OptionSignature(int x, const Hasher* hasher) {
    return IntegerToString(x);
  }
  static GoogleString OptionSignature(int64 x, const Hasher* hasher) {
    return Integer64ToString(x);
  }
  static GoogleString OptionSignature(const GoogleString& x,
                                      const Hasher* hasher);
  static GoogleString OptionSignature(RewriteLevel x,
                                      const Hasher* hasher);
  static GoogleString OptionSignature(ResourceCategorySet x,
                                      const Hasher* hasher);
  static GoogleString OptionSignature(const BeaconUrl& beacon_url,
                                      const Hasher* hasher);
  static GoogleString OptionSignature(const MobTheme& mob_theme,
                                      const Hasher* hasher);
  static GoogleString OptionSignature(const ResponsiveDensities& densities,
                                      const Hasher* hasher);
  static GoogleString OptionSignature(const AllowVaryOn& allow_vary_on,
                                      const Hasher* hasher);
  static GoogleString OptionSignature(
      const protobuf::MessageLite& proto,
      const Hasher* hasher);

  // These static methods enable us to generate strings for all
  // instantiated option-types from Option<T>::Signature().
  static GoogleString ToString(bool x) {
    return x ? "True" : "False";
  }
  static GoogleString ToString(int x) {
    return IntegerToString(x);
  }
  static GoogleString ToString(int64 x) {
    return Integer64ToString(x);
  }
  static GoogleString ToString(const GoogleString& x) {
    return x;
  }
  static GoogleString ToString(RewriteLevel x);
  static GoogleString ToString(const ResourceCategorySet &x);
  static GoogleString ToString(const BeaconUrl& beacon_url);
  static GoogleString ToString(const MobTheme& mob_theme);
  static GoogleString ToString(const Color& color);
  static GoogleString ToString(const ResponsiveDensities& densities);
  static GoogleString ToString(const protobuf::MessageLite& proto);
  static GoogleString ToString(const AllowVaryOn& allow_vary_on);

  // Returns true if p1's option_name is less than p2's. Used to order
  // all_properties_ and all_options_.
  static bool PropertyLessThanByOptionName(PropertyBase* p1, PropertyBase* p2) {
    return StringCaseCompare(p1->option_name(), p2->option_name()) < 0;
  }

  // Returns true if option's name is less than arg.
  static bool OptionNameLessThanArg(OptionBase* option, StringPiece arg) {
    return StringCaseCompare(option->option_name(), arg) < 0;
  }

  // Returns true if e1's timestamp is less than e2's.
  static bool CompareUrlCacheInvalidationEntry(UrlCacheInvalidationEntry* e1,
                                               UrlCacheInvalidationEntry* e2) {
    return e1->timestamp_ms < e2->timestamp_ms;
  }

  // Returns true if the first entry's id is less than the second's id.
  static bool FilterEnumToIdAndNameEntryLessThanById(
      const FilterEnumToIdAndNameEntry* e1,
      const FilterEnumToIdAndNameEntry* e2) {
    return strcmp(e1->filter_id, e2->filter_id) < 0;
  }

  // Return the effective option name. If the name is deprecated, the new name
  // will be returned; otherwise the name will be returned as is.
  static StringPiece GetEffectiveOptionName(StringPiece name);

  // Returns value of this option if it has been set; otherwise, returns true
  // if the rewrite level matches the argument. If nothing applies, returns
  // false.
  bool CheckLevelSpecificOption(RewriteLevel rewrite_level,
                                const Option<bool>& option) const;

  // In OptimizeForBandwidth mode, this sets up certain default filters
  // and options, which take effect only if not explicitly overridden.
  bool CheckBandwidthOption(const Option<bool>& option) const {
    return CheckLevelSpecificOption(kOptimizeForBandwidth, option);
  }

  // In MobilizeFilters mode, this sets up certain default filters and options,
  // which take effect only if not explicitly overridden.
  bool CheckMobilizeFiltersOption(const Option<bool>& option) const {
    return CheckLevelSpecificOption(kMobilizeFilters, option);
  }

  // Helps resolve the conflict between explicit extend_cache filters and
  // preserve settings, but does not perform the action itself.  This is so
  // that the standard option-merging and filter-merging that works over
  // all filters can function.  This function is called prior to merging
  // options and filters.  The resulting value is then passed to
  // ApplyMergeOverride, which must be run after the filter/option merging.
  MergeOverride ComputeMergeOverride(
      Filter filter,
      const Option<bool>& src_preserve_option,
      const Option<bool>& preserve_option,
      const RewriteOptions& src);

  // Applies the results of ComputeMergeOverride.
  void ApplyMergeOverride(
      MergeOverride merge_override,
      Filter filter,
      Option<bool>* preserve_option);

  bool modified_;
  bool frozen_;
  FilterSet enabled_filters_;
  FilterSet disabled_filters_;
  FilterSet forbidden_filters_;

  // The set of filters that can be distributed to other tasks.
  // For experimentation, may be removed later.
  FilterIdSet distributable_filters_;

  // Note: using the template class Option here saves a lot of repeated
  // and error-prone merging code.  However, it is not space efficient as
  // we are alternating int64s and bools in the structure.  If we cared
  // about that, then we would keep the bools in a bitmask.  But since
  // we don't really care we'll try to keep the code structured better.
  Option<RewriteLevel> level_;

  // List of URL wildcard patterns and timestamp for which it should be
  // invalidated.  In increasing order of timestamp.
  UrlCacheInvalidationEntryVector url_cache_invalidation_entries_;

  // Map of exact URLs to be invalidated; no wildcards.  Note that the
  // cache_purge_mutex_ is, by default, a NullRWLock.  You must call
  // set_cache_invalidation_timestamp_mutex to make it be a real mutex.
  // This is generally done only for the global context for each server,
  // so that we can atomically propagate cache flush updates into it while
  // it's running.
  CopyOnWrite<PurgeSet> purge_set_ GUARDED_BY(cache_purge_mutex_);

  scoped_ptr<ThreadSystem::RWLock> cache_purge_mutex_;
  Option<int64> css_flatten_max_bytes_;
  Option<bool> cache_small_images_unrewritten_;
  Option<bool> no_transform_optimized_images_;

  // Sets limit for image optimization
  Option<int64> image_resolution_limit_bytes_;
  Option<int64> css_image_inline_max_bytes_;
  Option<int64> css_inline_max_bytes_;
  Option<int64> css_outline_min_bytes_;
  Option<int64> google_font_css_inline_max_bytes_;

  // Preserve URL options
  Option<bool> css_preserve_urls_;
  Option<bool> js_preserve_urls_;
  Option<bool> image_preserve_urls_;

  Option<int64> image_inline_max_bytes_;
  Option<int64> js_inline_max_bytes_;
  Option<int64> js_outline_min_bytes_;
  Option<int64> progressive_jpeg_min_bytes_;
  // The max Cache-Control TTL for HTML.
  Option<int64> max_html_cache_time_ms_;
  // The maximum number of bytes of HTML that we parse, before redirecting to
  // ?ModPagespeed=off.
  Option<int64> max_html_parse_bytes_;
  // The maximum size of an image in CSS, which we convert to webp.
  Option<int64> max_image_bytes_for_webp_in_css_;
  // Resources with Cache-Control TTL less than this will not be rewritten.
  Option<int64> min_resource_cache_time_to_rewrite_ms_;
  Option<int64> idle_flush_time_ms_;
  Option<int64> flush_buffer_limit_bytes_;

  // How long to wait in blocking fetches before timing out.
  // Applies to ResourceFetch::BlockingFetch() and class SyncFetcherAdapter.
  // Does not apply to async fetches.
  Option<int64> blocking_fetch_timeout_ms_;

  // Option related to generic image quality. This is overridden by
  // image(jpeg/webp) specific options.
  Option<int64> image_recompress_quality_;

  // Options related to jpeg compression.
  Option<int64> image_jpeg_recompress_quality_;
  Option<int64> image_jpeg_recompress_quality_for_small_screens_;
  Option<int64> image_jpeg_quality_for_save_data_;
  Option<int64> image_jpeg_num_progressive_scans_;
  Option<int64> image_jpeg_num_progressive_scans_for_small_screens_;

  // Options governing when to retain optimized images vs keep original
  Option<int> image_limit_optimized_percent_;
  Option<int> image_limit_resize_area_percent_;
  Option<int> image_limit_rendered_area_percent_;

  // Options related to webp compression.
  Option<int64> image_webp_recompress_quality_;
  Option<int64> image_webp_recompress_quality_for_small_screens_;
  Option<int64> image_webp_animated_recompress_quality_;
  Option<int64> image_webp_quality_for_save_data_;
  Option<int64> image_webp_timeout_ms_;

  Option<int> image_max_rewrites_at_once_;
  Option<int> max_url_segment_size_;  // For http://a/b/c.d, use strlen("c.d").
  Option<int> max_url_size_;          // This is strlen("http://a/b/c.d").
  // The interval to wait for async rewrites to complete before flushing
  // content.  This deadline is per flush.
  Option<int> rewrite_deadline_ms_;
  // Maximum number of shards for rewritten resources in a directory.
  Option<int> domain_shard_count_;

  Option<EnabledEnum> enabled_;

  Option<bool> distributable_;

  // Encode relevant rewrite options as URL query-parameters so that resources
  // can be reconstructed on servers without the same configuration file.
  Option<bool> add_options_to_urls_;

  // If this option is enabled, serves .pagespeed. resource URLs with
  // mismatching hashes with the same cache expiration as the inputs.
  // By default, we convert resources requests with the wrong hash to
  // Cache-Control:private,max-age=300 to avoid caching stale content
  // in proxies.
  Option<bool> publicly_cache_mismatched_hashes_experimental_;

  // Should in-place-resource-optimization(IPRO) be enabled?
  Option<bool> in_place_rewriting_enabled_;
  // Optimize before responding in in-place flow?
  Option<bool> in_place_wait_for_optimized_;
  // Interval to delay serving on the IPRO path while waiting for optimizations.
  // After this interval, the unoptimized resource will be served.
  Option<int> in_place_rewrite_deadline_ms_;
  // If set, preemptively rewrite images in CSS files on the HTML serving path
  // when IPRO of CSS is enabled.
  Option<bool> in_place_preemptive_rewrite_css_;
  // If set, preemptively rewrite images in CSS files on the IPRO serving path.
  Option<bool> in_place_preemptive_rewrite_css_images_;
  // If set, preemptively rewrite images in image files on the HTML serving path
  // when IPRO of images is enabled.
  Option<bool> in_place_preemptive_rewrite_images_;
  // If set, preemptively rewrite images in JS files on the HTML serving path
  // when IPRO of JS is enabled.
  Option<bool> in_place_preemptive_rewrite_javascript_;
  // Use cache-control:private rather than vary:accept when serving IPRO
  // resources to IE.  This avoids the need for an if-modified-since request
  // from IE on each cache hit.  The flip side is no proxy cache will store it
  // (though few or no proxy caches will store Vary: accept data in any case
  // unless they are specially configured to do so).
  Option<bool> private_not_vary_for_ie_;
  Option<bool> combine_across_paths_;
  Option<bool> log_background_rewrites_;
  Option<bool> log_mobilization_samples_;
  Option<bool> log_rewrite_timing_;   // Should we time HtmlParser?
  Option<bool> log_url_indices_;
  Option<bool> lowercase_html_names_;
  Option<bool> always_rewrite_css_;  // For tests/debugging.
  Option<bool> respect_vary_;
  Option<bool> respect_x_forwarded_proto_;
  Option<bool> flush_html_;
  // Should we serve the split html response in two chunks - above the fold and
  // below the fold. If set to false, we serve the above the fold and below the
  // fold in a single response.
  Option<bool> serve_split_html_in_two_chunks_;
  // Should we serve stale responses if the fetch results in a server side
  // error.
  Option<bool> serve_stale_if_fetch_error_;
  // Should we serve ghost click buster code when split html is enabled.
  Option<bool> serve_ghost_click_buster_with_split_html_;
  // Should we serve access control headers in response headers.
  Option<bool> serve_xhr_access_control_headers_;
  // Proactively freshen user facing request if it is about to expire. So, that
  // subsequent requests will experience a cache hit.
  Option<bool> proactively_freshen_user_facing_request_;
  // Threshold for serving stale responses while revalidating in background.
  // 0 means don't serve stale content.
  Option<int64> serve_stale_while_revalidate_threshold_sec_;
  // Whether to flush the inlined critical css rules early.
  Option<bool> enable_flush_early_critical_css_;
  // Whether to use CriticalSelectorFilter for prioritize_critical_css filter.
  Option<bool> use_selectors_for_critical_css_;
  // When default_cache_html_ is false (default) we do not cache
  // input HTML which lacks Cache-Control headers. But, when set true,
  // we will cache those inputs for the implicit lifetime just like we
  // do for resources.
  Option<bool> default_cache_html_;
  // In general, we rewrite Cache-Control headers for HTML. We do this
  // for several reasons, but at least one is that our rewrites are not
  // necessarily publicly cacheable.
  // Some people don't like this, so we allow them to disable it.
  Option<bool> modify_caching_headers_;
  // In general, lazyload images loads images on scroll. However, some people
  // may want to load images when the onload event is fired instead. If set to
  // true, images are loaded when onload is fired.
  Option<bool> lazyload_images_after_onload_;
  // The initial image url to load in the lazyload images filter. If this is not
  // specified, we use a 1x1 inlined image.
  Option<GoogleString> lazyload_images_blank_url_;
  // Whether inline preview should use a blank image instead of a low resolution
  // version of the original image.
  Option<bool> use_blank_image_for_inline_preview_;
  // By default, inline_images will inline only critical images. However, some
  // people may want to inline all images (both critical and non-critical). If
  // set to false, all images will be inlined within the html.
  Option<bool> inline_only_critical_images_;
  // Indicates whether image rewriting filters should insert the critical images
  // beacon code.
  Option<bool> critical_images_beacon_enabled_;
  // Indicates whether the DomainRewriteFilter should also do client side
  // rewriting.
  Option<bool> client_domain_rewrite_;
  // Indicates whether DomainRewriteFilter should rewrite domain information
  // in Set-Cookie: headers.
  Option<bool> domain_rewrite_cookies_;
  // Indicates whether the DomainRewriteFilter should rewrite all tags,
  // including <a href> and <form action>.
  Option<bool> domain_rewrite_hyperlinks_;
  // Are we running the A/B experiment framework that uses cookies and Google
  // Analytics to track page speed statistics with multiple sets of rewriters?
  Option<bool> running_experiment_;
  // The experiment framework reports to Google Analytice in a custom variable
  // slot.  Specify which one to use.
  Option<int> experiment_ga_slot_;
  // For testing purposes you can force users to be enrolled in a specific
  // experiment.  This makes most sense in a query param.
  Option<int> enroll_experiment_id_;

  // When running a content experiment, which IDs should we use when logging to
  // Google Analytics?
  Option<GoogleString> content_experiment_id_;
  Option<GoogleString> content_experiment_variant_id_;

  // Log to analytics.js instead of ga.js.
  Option<bool> use_analytics_js_;

  // Increase the percentage of hits to 10% (current max) that have
  // site speed tracking in Google Analytics.
  Option<bool> increase_speed_tracking_;

  // If enabled we will report time taken before navigating to a new page. This
  // won't have effect, if onload beacon is sent before unload event is
  // trigggered.
  Option<bool> report_unload_time_;

  Option<bool> serve_rewritten_webp_urls_to_any_agent_;

  // Flush more resources if origin is slow to respond.
  Option<bool> flush_more_resources_early_if_time_permits_;

  // Flush more resources in IE and Firefox.
  Option<bool> flush_more_resources_in_ie_and_firefox_;

  // Number of script elements to prefetch early. Applicable when defer_js
  // filter is enabled.
  Option<int> max_prefetch_js_elements_;

  // Enables experimental code in defer js.
  Option<bool> enable_defer_js_experimental_;

  // Option to disable rewrite optimizations on no-transform header.
  Option<bool> disable_rewrite_on_no_transform_;

  // Option to disable pre-emptive background fetches for bot requests.
  Option<bool> disable_background_fetches_for_bots_;

  // Enables the Cache Purge API.  This is not on by default because
  // it requires saving input URLs to each metadata cache entry to
  // facilitate fast URL cache invalidation.
  //
  // Note that in the absence of this API, purging URLs can still
  // work, but it will invalidate either the entire metadata cache
  // (ignores_metadata_and_pcache==false in the call to
  // AddUrlCacheInvalidationEntry) or will not invalidate the metadata
  // cache entries at all (ignores_metadata_and_pcache==false).
  Option<bool> enable_cache_purge_;

  // If set, the urls of the inputs to the resource are saved in the metadata
  // cache entry. This increases the size of the cache entry, but can be used in
  // freshening of the embedded resources.
  Option<bool> proactive_resource_freshening_;

  // Enables the code to lazy load high res images.
  Option<bool> lazyload_highres_images_;

  // Some introspective javascript is very brittle and may break if we
  // make any changes.  Enables code to detect such cases and avoid renaming.
  Option<bool> avoid_renaming_introspective_javascript_;

  // Overrides the IE document mode to use the highest mode available.
  Option<bool> override_ie_document_mode_;

  // Test-only flag to get fetch deadlines to trigger instantly.
  Option<bool> test_instant_fetch_rewrite_deadline_;

  // Indicates whether the prioritize_critical_css filter should invoke its
  // JavaScript function to load all the "hidden" CSS files at onload.
  // Intended for testing only.
  Option<bool> test_only_prioritize_critical_css_dont_apply_original_css_;

  // Enables blocking rewrite of html. RewriteDriver provides a flag
  // fully_rewrite_on_flush which makes sure that all rewrites are done before
  // the response is flushed to the client. If the value of the
  // X-PSA-Blocking-Rewrite header matches this key, the
  // RewriteDriver::fully_rewrite_on_flush flag will be set.
  Option<GoogleString> blocking_rewrite_key_;

  // Indicates how often we should reinstrument pages with the critical images
  // beacon, based on the time since the last write to the property cache by a
  // beacon response.
  Option<int> beacon_reinstrument_time_sec_;

  // Number of first N images for which low res image is generated. Negative
  // values will bypass image index check.
  Option<int> max_inlined_preview_images_index_;
  // Minimum image size above which low res image is generated.
  Option<int64> min_image_size_low_resolution_bytes_;
  // Maximum image size below which low res image is generated.
  Option<int64> max_image_size_low_resolution_bytes_;
  // Percentage (an integer between 0 and 100 inclusive) of images rewrites to
  // drop.
  Option<int> rewrite_random_drop_percentage_;

  // For proxies operating in in-place mode this allows fetching optimized
  // resources from sites that have MPS, etc configured.
  Option<bool> oblivious_pagespeed_urls_;

  // Cache expiration time in msec for properties of finders.
  Option<int64> finder_properties_cache_expiration_time_ms_;

  // Cache refresh time in msec for properties of finders. The properties are
  // refreshed when their age is larger than the specified value. However, the
  // property will be used until finder_properties_cache_expiration_time_ms_.
  Option<int64> finder_properties_cache_refresh_time_ms_;
  // Duration after which the experiment cookie will expire on the user's
  // browser (in msec).
  Option<int64> experiment_cookie_duration_ms_;

  // The maximum time beyond expiry for which a metadata cache entry may be
  // used.
  Option<int64> metadata_cache_staleness_threshold_ms_;

  // The metadata cache ttl for input resources which are 4xx errors.
  Option<int64> metadata_input_errors_cache_ttl_ms_;

  // The HTTP method to use ("PURGE", "GET" etc.) for purge requests sent to
  // downstream caches (e.g. proxy_cache, Varnish).
  Option<GoogleString> downstream_cache_purge_method_;

  // The host:port/path prefix to be used for purging the cached responses.
  Option<GoogleString> downstream_cache_purge_location_prefix_;

  // The webmaster-provided key used to authenticate rebeaconing requests from
  // downstream caches.
  Option<GoogleString> downstream_cache_rebeaconing_key_;

  // Threshold for amount of rewriting finished before the response was served
  // out (expressed as a percentage) and simultaneously stored in the downstream
  // cache  beyond which the response will not be purged from the cache even if
  // more rewriting is possible now. If the threshold is exceeded, this means
  // that the version in the cache is good enough and hence need not be purged.
  Option<int64> downstream_cache_rewritten_percentage_threshold_;

  // The number of milliseconds of cache TTL we assign to resources that
  // are "likely cacheable" (e.g. images, js, css, not html) and have no
  // explicit cache ttl or expiration date.
  Option<int64> implicit_cache_ttl_ms_;

  // The number of miliseconds of cache TTL we assign to resources that are
  // loaded from file and "likely cacheable" and have no explicit cache ttl or
  // expiration date. If this option is not set explicitly, fall back to using
  // implicit_cache_ttl_ms for load from file cache ttl.
  Option<int64> load_from_file_cache_ttl_ms_;

  // Maximum length (in bytes) of response content.
  Option<int64> max_cacheable_response_content_length_;

  // The timestamp when blink blacklist expires.
  Option<int64> blink_blacklist_end_timestamp_ms_;

  // Keep the original subresource hints
  Option<bool> preserve_subresource_hints_;

  // Keep rewritten URLs as relative as the original resource URL was.
  // TODO(sligocki): Remove this option once we know it's always safe.
  Option<bool> preserve_url_relativity_;

  Option<GoogleString> ga_id_;

  Option<int64> blink_max_html_size_rewritable_;
  // Time after which we should try to detect if publisher html in blink
  // has changed.
  Option<int64> blink_html_change_detection_time_ms_;
  // Show the blink debug dashboard.
  Option<bool> enable_blink_debug_dashboard_;
  // Enable automatic detection of publisher changes in html in blink.
  Option<bool> enable_blink_html_change_detection_;
  // Enable logging of publisher changes detected in html in blink flow.
  Option<bool> enable_blink_html_change_detection_logging_;
  // Use smart diff to detect publisher changes in html in blink.
  Option<bool> use_smart_diff_in_blink_;
  // Use fallback values from property cache.
  Option<bool> use_fallback_property_cache_values_;
  // Always wait for property cache lookup to finish.
  Option<bool> await_pcache_lookup_;
  // Enable Prioritizing of scripts in defer javascript.
  Option<bool> enable_prioritizing_scripts_;
  // Enables rewriting of uncacheable resources.
  Option<bool> rewrite_uncacheable_resources_;
  // Specification for critical line.
  Option<GoogleString> critical_line_config_;
  // The user-provided key used to authenticate requests from one rewrite task
  // to another.  Right now only used to validate meta-data headers.
  Option<GoogleString> distributed_rewrite_key_;
  // A comma delimited list of hosts that can be used to rewrite resources.
  Option<GoogleString> distributed_rewrite_servers_;
  // Whether or not to distribute IPRO and .pagespeed. resource fetch requests
  // from the RewriteDriver before checking the cache.  If this is false,
  // then a distribution will only occur for a fetch if a nested
  // RewriteContext is created and its id is distributable.
  Option<bool> distribute_fetches_;
  // Time to wait for a distributed rewrite to complete before giving up on the
  // request.
  Option<int64> distributed_rewrite_timeout_ms_;
  // Forbid turning on of any disabled (not enabled) filters either via query
  // parameters or request headers or .htaccess for Directory. Note that this
  // is a latch so that setting it at some directory level forces it on for
  // that and all lower levels, as otherwise someone could just create a
  // sub-directory and enable it in a .htaccess in there.
  Option<bool> forbid_all_disabled_filters_;
  // Enables aggressive rewriters for mobile user agents.
  Option<bool> enable_aggressive_rewriters_for_mobile_;

  // If this is true (it defaults to false) ProxyInterface frontend will
  // reject requests where PSA is not enabled or URL is blacklisted with
  // status code reject_blacklisted_status_code_ (default 403) rather than
  // proxy them in passthrough mode. This does not affect behavior for
  // resource rewriting.
  Option<bool> reject_blacklisted_;
  Option<int> reject_blacklisted_status_code_;

  // Support handling of clients without javascript support.  This is applicable
  // only if any filter that inserts new javascript (e.g., lazyload_images) is
  // enabled.
  Option<bool> support_noscript_enabled_;

  // If this set to true, we add additional instrumentation code to page that
  // reports more information in the beacon.
  Option<bool> enable_extended_instrumentation_;

  Option<bool> use_experimental_js_minifier_;

  // Maximum size allowed for the combined CSS resource.
  // Negative value will bypass the size check.
  Option<int64> max_combined_css_bytes_;

  // Maximum size allowed for the combined js resource.
  // Negative value will bypass the size check.
  Option<int64> max_combined_js_bytes_;

  // Url to which pre connect requests will be sent.
  Option<GoogleString> pre_connect_url_;
  // The number of requests for which the status code should remain same so that
  // we consider it to be stable.
  Option<int> property_cache_http_status_stability_threshold_;
  // The maximum number of rewrite info logs stored for a single request.
  Option<int> max_rewrite_info_log_size_;

  // The cache TTL with which to override the urls matching the
  // override_caching_ WildCardGroup. Note that we do not override the cache TTL
  // for any urls if this value is negative. The same TTL value is used for all
  // urls that match override_caching_wildcard_.
  Option<int64> override_caching_ttl_ms_;
  CopyOnWrite<FastWildcardGroup> override_caching_wildcard_;

  // The minimum milliseconds of cache TTL for all resources that are
  // explicitly cacheable. This overrides the max-age even when it is set on
  // Cache-Control headers.
  Option<int64> min_cache_ttl_ms_;

  // Whether to allow logging urls as part of LogRecord.
  Option<bool> allow_logging_urls_in_log_record_;

  // Whether to allow options to be set by cookies.
  Option<bool> allow_options_to_be_set_by_cookies_;

  // Non cacheables used when partial HTML is cached.
  Option<GoogleString> non_cacheables_for_cache_partial_html_;

  // Comma seperated list of origins that are allowed to make cross-origin
  // requests. These domain requests are served with
  // Access-Control-Allow-Origin header.
  Option<GoogleString> access_control_allow_origins_;

  // If set to true, hides the referer by adding meta tag to the HTML.
  Option<bool> hide_referer_using_meta_;

  // Options to control the edge-case behaviour of inline-previewed images. The
  // idea is to avoid inline-previewing when:
  // a. low-res image is large.
  // b. low-res image is not small enough compared to the full-res version.
  Option<int64> max_low_res_image_size_bytes_;
  Option<int> max_low_res_to_full_res_image_size_percentage_;

  // The URL from which to pull remote configurations.
  Option<GoogleString> remote_configuration_url_;
  // The timeout, in milliseconds for the remote configuration file fetch.
  Option<int64> remote_configuration_timeout_ms_;

  // The level to set the gzip compression of HTTPCache items.
  Option<int> http_cache_compression_level_;

  // Pass this string in url to allow for pagespeed options.
  Option<GoogleString> request_option_override_;

  // The key used to sign .pagespeed resources if URL signing is enabled.
  Option<GoogleString> url_signing_key_;

  // If set to true, accepts urls with invalid signatures.
  Option<bool> accept_invalid_signatures_;

  // sticky_query_parameters_ is the token specified in the configuration that
  // must be specified in a request's query parameters/headers for the other
  // options in the request to be converted to cookies.
  // option_cookies_duration_ms_ is how long the cookie will live for when set.
  Option<GoogleString> sticky_query_parameters_;
  Option<int64> option_cookies_duration_ms_;

  // Comma separated list of densities to use for responsive images.
  Option<ResponsiveDensities> responsive_image_densities_;

  // If set, how to fragment the http cache.  Otherwise the server's hostname,
  // from the Host header, is used.
  CacheFragmentOption cache_fragment_;

  // Be sure to update constructor when new fields are added so that they are
  // added to all_options_, which is used for Merge, and eventually, Compare.
  OptionBaseVector all_options_;
  size_t initialized_options_;  // Counts number of options initialized so far.

  // Reverse map from filter id string to corresponding Filter enum.  Note
  // that this is not indexed by filter enum; it's indexed alphabetically by id.
  static const FilterEnumToIdAndNameEntry* filter_id_to_enum_array_[
      kEndOfFilters];

  // Reverse map from option name string to corresponding PropertyBase.
  static PropertyNameMap* option_name_to_property_map_;

  // Reverse map from option id string to corresponding PropertyBase.
  static const PropertyBase** option_id_to_property_array_;

  // When compiled for debug, we lazily check whether the all the Option<>
  // member variables in all_options have unique IDs.
  //
  // Note that we include this member-variable in the structrue even under
  // optimization as otherwise it might be very bad news indeed if someone
  // mixed debug/opt object files in an executable.
  bool options_uniqueness_checked_;

  bool need_to_store_experiment_data_;
  int experiment_id_;  // Which experiment configuration are we in?
  int experiment_percent_;  // Total traffic going through experiments.
  std::vector<ExperimentSpec*> experiment_specs_;

  // Headers to add to subresource requests.
  std::vector<NameValue*> custom_fetch_headers_;

  // If this is non-NULL it tells us additional attributes that should be
  // interpreted as containing urls.
  scoped_ptr<std::vector<ElementAttributeCategory> > url_valued_attributes_;

  Option<ResourceCategorySet> inline_unauthorized_resource_types_;

  Option<bool> mob_always_;
  Option<bool> mob_config_;
  Option<bool> mob_iframe_;
  Option<bool> mob_iframe_disable_;
  Option<GoogleString> mob_iframe_viewport_;
  Option<bool> mob_layout_;
  Option<bool> mob_nav_;
  Option<bool> mob_labeled_mode_;
  Option<GoogleString> mob_nav_classes_;
  Option<bool> mob_static_;

  Option<GoogleString> mob_beacon_url_;
  Option<GoogleString> mob_beacon_category_;
  Option<GoogleString> mob_map_location_;
  Option<GoogleString> mob_phone_number_;
  Option<int64> mob_conversion_id_;
  Option<GoogleString> mob_map_conversion_label_;
  Option<GoogleString> mob_phone_conversion_label_;
  Option<MobTheme> mob_theme_;

  Option<int64> noop_;

  // Comma separated list of headers which we can vary-on, or "Auto", or "None".
  Option<AllowVaryOn> allow_vary_on_;

  CopyOnWrite<JavascriptLibraryIdentification>
      javascript_library_identification_;

  CopyOnWrite<DomainLawyer> domain_lawyer_;
  FileLoadPolicy file_load_policy_;

  CopyOnWrite<FastWildcardGroup> allow_resources_;
  CopyOnWrite<FastWildcardGroup> allow_when_inlining_resources_;
  CopyOnWrite<FastWildcardGroup> retain_comments_;
  CopyOnWrite<FastWildcardGroup> lazyload_enabled_classes_;

  // When certain url patterns are in the referer we want to do a blocking
  // rewrite.
  CopyOnWrite<FastWildcardGroup> blocking_rewrite_referer_urls_;

  // Using StringPiece here is safe since all entries in this map have static
  // strings as the key.
  typedef std::map<StringPiece, FastWildcardGroup*> FastWildcardGroupMap;
  FastWildcardGroupMap rejected_request_map_;

  GoogleString signature_;
  MD5Hasher hasher_;  // Used to compute named signatures.
  SHA1Signature sha1signature_;

  ThreadSystem* thread_system_;

  // When compiled for debug, keep track of the last thread to modify
  // this object.  If cloned or merged from prior to
  // ComputeSignature(), we check that the thread doing the Merge is
  // in the same thread that modified it.
  //
  // We also ensure that only one thread modifies a RewriteOptions
  // object.
  //
  // Note: we don't ifdef the member variable declaration as having the
  // structure-size dependent on debug-ifdef seems dangerous when used
  // as a library against externally compiled code.  We do ifdef its
  // usage within the class implementation, however.
  scoped_ptr<ThreadSystem::ThreadId> last_thread_id_;

  DISALLOW_COPY_AND_ASSIGN(RewriteOptions);
};

}  // namespace net_instaweb

#endif  // NET_INSTAWEB_REWRITER_PUBLIC_REWRITE_OPTIONS_H_
