diff --git a/src/gflags.cc b/src/gflags.cc
new file mode 100644
index 0000000..285050f
--- /dev/null
+++ b/src/gflags.cc
@@ -0,0 +1,1957 @@
+// Copyright (c) 1999, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Revamped and reorganized by Craig Silverstein
+//
+// This file contains the implementation of all our command line flags
+// stuff.  Here's how everything fits together
+//
+// * FlagRegistry owns CommandLineFlags owns FlagValue.
+// * FlagSaver holds a FlagRegistry (saves it at construct time,
+//     restores it at destroy time).
+// * CommandLineFlagParser lives outside that hierarchy, but works on
+//     CommandLineFlags (modifying the FlagValues).
+// * Free functions like SetCommandLineOption() work via one of the
+//     above (such as CommandLineFlagParser).
+//
+// In more detail:
+//
+// -- The main classes that hold flag data:
+//
+// FlagValue holds the current value of a flag.  It's
+// pseudo-templatized: every operation on a FlagValue is typed.  It
+// also deals with storage-lifetime issues (so flag values don't go
+// away in a destructor), which is why we need a whole class to hold a
+// variable's value.
+//
+// CommandLineFlag is all the information about a single command-line
+// flag.  It has a FlagValue for the flag's current value, but also
+// the flag's name, type, etc.
+//
+// FlagRegistry is a collection of CommandLineFlags.  There's the
+// global registry, which is where flags defined via DEFINE_foo()
+// live.  But it's possible to define your own flag, manually, in a
+// different registry you create.  (In practice, multiple registries
+// are used only by FlagSaver).
+//
+// A given FlagValue is owned by exactly one CommandLineFlag.  A given
+// CommandLineFlag is owned by exactly one FlagRegistry.  FlagRegistry
+// has a lock; any operation that writes to a FlagValue or
+// CommandLineFlag owned by that registry must acquire the
+// FlagRegistry lock before doing so.
+//
+// --- Some other classes and free functions:
+//
+// CommandLineFlagInfo is a client-exposed version of CommandLineFlag.
+// Once it's instantiated, it has no dependencies or relationships
+// with any other part of this file.
+//
+// FlagRegisterer is the helper class used by the DEFINE_* macros to
+// allow work to be done at global initialization time.
+//
+// CommandLineFlagParser is the class that reads from the commandline
+// and instantiates flag values based on that.  It needs to poke into
+// the innards of the FlagValue->CommandLineFlag->FlagRegistry class
+// hierarchy to do that.  It's careful to acquire the FlagRegistry
+// lock before doing any writing or other non-const actions.
+//
+// GetCommandLineOption is just a hook into registry routines to
+// retrieve a flag based on its name.  SetCommandLineOption, on the
+// other hand, hooks into CommandLineFlagParser.  Other API functions
+// are, similarly, mostly hooks into the functionality described above.
+
+#include "config.h"
+#include "gflags.h"
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#if defined(HAVE_FNMATCH_H)
+#  include <fnmatch.h>
+#elif defined(HAVE_SHLWAPI_H)
+#  include <shlwapi.h>
+#endif
+#include <stdarg.h> // For va_list and related operations
+#include <stdio.h>
+#include <string.h>
+
+#include <algorithm>
+#include <map>
+#include <string>
+#include <utility>     // for pair<>
+#include <vector>
+
+#include "mutex.h"
+#include "util.h"
+
+// Special flags, type 1: the 'recursive' flags.  They set another flag's val.
+DEFINE_string(flagfile,   "", "load flags from file");
+DEFINE_string(fromenv,    "", "set flags from the environment"
+                              " [use 'export FLAGS_flag1=value']");
+DEFINE_string(tryfromenv, "", "set flags from the environment if present");
+
+// Special flags, type 2: the 'parsing' flags.  They modify how we parse.
+DEFINE_string(undefok, "", "comma-separated list of flag names that it is okay to specify "
+                           "on the command line even if the program does not define a flag "
+                           "with that name.  IMPORTANT: flags in this list that have "
+                           "arguments MUST use the flag=value format");
+
+namespace GFLAGS_NAMESPACE {
+
+using std::map;
+using std::pair;
+using std::sort;
+using std::string;
+using std::vector;
+
+// This is used by the unittest to test error-exit code
+void GFLAGS_DLL_DECL (*gflags_exitfunc)(int) = &exit;  // from stdlib.h
+
+
+// The help message indicating that the commandline flag has been
+// 'stripped'. It will not show up when doing "-help" and its
+// variants. The flag is stripped if STRIP_FLAG_HELP is set to 1
+// before including base/gflags.h
+
+// This is used by this file, and also in gflags_reporting.cc
+const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001";
+
+namespace {
+
+// There are also 'reporting' flags, in gflags_reporting.cc.
+
+static const char kError[] = "ERROR: ";
+
+// Indicates that undefined options are to be ignored.
+// Enables deferred processing of flags in dynamically loaded libraries.
+static bool allow_command_line_reparsing = false;
+
+static bool logging_is_probably_set_up = false;
+
+// This is a 'prototype' validate-function.  'Real' validate
+// functions, take a flag-value as an argument: ValidateFn(bool) or
+// ValidateFn(uint64).  However, for easier storage, we strip off this
+// argument and then restore it when actually calling the function on
+// a flag value.
+typedef bool (*ValidateFnProto)();
+
+// Whether we should die when reporting an error.
+enum DieWhenReporting { DIE, DO_NOT_DIE };
+
+// Report Error and exit if requested.
+static void ReportError(DieWhenReporting should_die, const char* format, ...) {
+  char error_message[255];
+  va_list ap;
+  va_start(ap, format);
+  vsnprintf(error_message, sizeof(error_message), format, ap);
+  va_end(ap);
+  fprintf(stderr, "%s", error_message);
+  fflush(stderr);   // should be unnecessary, but cygwin's rxvt buffers stderr
+  if (should_die == DIE) gflags_exitfunc(1);
+}
+
+
+// --------------------------------------------------------------------
+// FlagValue
+//    This represent the value a single flag might have.  The major
+//    functionality is to convert from a string to an object of a
+//    given type, and back.  Thread-compatible.
+// --------------------------------------------------------------------
+
+class CommandLineFlag;
+class FlagValue {
+ public:
+  FlagValue(void* valbuf, const char* type, bool transfer_ownership_of_value);
+  ~FlagValue();
+
+  bool ParseFrom(const char* spec);
+  string ToString() const;
+
+ private:
+  friend class CommandLineFlag;  // for many things, including Validate()
+  friend class GFLAGS_NAMESPACE::FlagSaverImpl;  // calls New()
+  friend class FlagRegistry;     // checks value_buffer_ for flags_by_ptr_ map
+  template <typename T> friend T GetFromEnv(const char*, const char*, T);
+  friend bool TryParseLocked(const CommandLineFlag*, FlagValue*,
+                             const char*, string*);  // for New(), CopyFrom()
+
+  enum ValueType {
+    FV_BOOL = 0,
+    FV_INT32 = 1,
+    FV_INT64 = 2,
+    FV_UINT64 = 3,
+    FV_DOUBLE = 4,
+    FV_STRING = 5,
+    FV_MAX_INDEX = 5,
+  };
+  const char* TypeName() const;
+  bool Equal(const FlagValue& x) const;
+  FlagValue* New() const;   // creates a new one with default value
+  void CopyFrom(const FlagValue& x);
+  int ValueSize() const;
+
+  // Calls the given validate-fn on value_buffer_, and returns
+  // whatever it returns.  But first casts validate_fn_proto to a
+  // function that takes our value as an argument (eg void
+  // (*validate_fn)(bool) for a bool flag).
+  bool Validate(const char* flagname, ValidateFnProto validate_fn_proto) const;
+
+  void* value_buffer_;          // points to the buffer holding our data
+  int8 type_;                   // how to interpret value_
+  bool owns_value_;         // whether to free value on destruct
+
+  FlagValue(const FlagValue&);   // no copying!
+  void operator=(const FlagValue&);
+};
+
+
+// This could be a templated method of FlagValue, but doing so adds to the
+// size of the .o.  Since there's no type-safety here anyway, macro is ok.
+#define VALUE_AS(type)  *reinterpret_cast<type*>(value_buffer_)
+#define OTHER_VALUE_AS(fv, type)  *reinterpret_cast<type*>(fv.value_buffer_)
+#define SET_VALUE_AS(type, value)  VALUE_AS(type) = (value)
+
+FlagValue::FlagValue(void* valbuf, const char* type,
+                     bool transfer_ownership_of_value)
+    : value_buffer_(valbuf),
+      owns_value_(transfer_ownership_of_value) {
+  for (type_ = 0; type_ <= FV_MAX_INDEX; ++type_) {
+    if (!strcmp(type, TypeName())) {
+      break;
+    }
+  }
+  assert(type_ <= FV_MAX_INDEX);  // Unknown typename
+}
+
+FlagValue::~FlagValue() {
+  if (!owns_value_) {
+    return;
+  }
+  switch (type_) {
+    case FV_BOOL: delete reinterpret_cast<bool*>(value_buffer_); break;
+    case FV_INT32: delete reinterpret_cast<int32*>(value_buffer_); break;
+    case FV_INT64: delete reinterpret_cast<int64*>(value_buffer_); break;
+    case FV_UINT64: delete reinterpret_cast<uint64*>(value_buffer_); break;
+    case FV_DOUBLE: delete reinterpret_cast<double*>(value_buffer_); break;
+    case FV_STRING: delete reinterpret_cast<string*>(value_buffer_); break;
+  }
+}
+
+bool FlagValue::ParseFrom(const char* value) {
+  if (type_ == FV_BOOL) {
+    const char* kTrue[] = { "1", "t", "true", "y", "yes" };
+    const char* kFalse[] = { "0", "f", "false", "n", "no" };
+    COMPILE_ASSERT(sizeof(kTrue) == sizeof(kFalse), true_false_equal);
+    for (size_t i = 0; i < sizeof(kTrue)/sizeof(*kTrue); ++i) {
+      if (strcasecmp(value, kTrue[i]) == 0) {
+        SET_VALUE_AS(bool, true);
+        return true;
+      } else if (strcasecmp(value, kFalse[i]) == 0) {
+        SET_VALUE_AS(bool, false);
+        return true;
+      }
+    }
+    return false;   // didn't match a legal input
+
+  } else if (type_ == FV_STRING) {
+    SET_VALUE_AS(string, value);
+    return true;
+  }
+
+  // OK, it's likely to be numeric, and we'll be using a strtoXXX method.
+  if (value[0] == '\0')   // empty-string is only allowed for string type.
+    return false;
+  char* end;
+  // Leading 0x puts us in base 16.  But leading 0 does not put us in base 8!
+  // It caused too many bugs when we had that behavior.
+  int base = 10;    // by default
+  if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X'))
+    base = 16;
+  errno = 0;
+
+  switch (type_) {
+    case FV_INT32: {
+      const int64 r = strto64(value, &end, base);
+      if (errno || end != value + strlen(value))  return false;  // bad parse
+      if (static_cast<int32>(r) != r)  // worked, but number out of range
+        return false;
+      SET_VALUE_AS(int32, static_cast<int32>(r));
+      return true;
+    }
+    case FV_INT64: {
+      const int64 r = strto64(value, &end, base);
+      if (errno || end != value + strlen(value))  return false;  // bad parse
+      SET_VALUE_AS(int64, r);
+      return true;
+    }
+    case FV_UINT64: {
+      while (*value == ' ') value++;
+      if (*value == '-') return false;  // negative number
+      const uint64 r = strtou64(value, &end, base);
+      if (errno || end != value + strlen(value))  return false;  // bad parse
+      SET_VALUE_AS(uint64, r);
+      return true;
+    }
+    case FV_DOUBLE: {
+      const double r = strtod(value, &end);
+      if (errno || end != value + strlen(value))  return false;  // bad parse
+      SET_VALUE_AS(double, r);
+      return true;
+    }
+    default: {
+      assert(false);  // unknown type
+      return false;
+    }
+  }
+}
+
+string FlagValue::ToString() const {
+  char intbuf[64];    // enough to hold even the biggest number
+  switch (type_) {
+    case FV_BOOL:
+      return VALUE_AS(bool) ? "true" : "false";
+    case FV_INT32:
+      snprintf(intbuf, sizeof(intbuf), "%" PRId32, VALUE_AS(int32));
+      return intbuf;
+    case FV_INT64:
+      snprintf(intbuf, sizeof(intbuf), "%" PRId64, VALUE_AS(int64));
+      return intbuf;
+    case FV_UINT64:
+      snprintf(intbuf, sizeof(intbuf), "%" PRIu64, VALUE_AS(uint64));
+      return intbuf;
+    case FV_DOUBLE:
+      snprintf(intbuf, sizeof(intbuf), "%.17g", VALUE_AS(double));
+      return intbuf;
+    case FV_STRING:
+      return VALUE_AS(string);
+    default:
+      assert(false);
+      return "";  // unknown type
+  }
+}
+
+bool FlagValue::Validate(const char* flagname,
+                         ValidateFnProto validate_fn_proto) const {
+  switch (type_) {
+    case FV_BOOL:
+      return reinterpret_cast<bool (*)(const char*, bool)>(
+          validate_fn_proto)(flagname, VALUE_AS(bool));
+    case FV_INT32:
+      return reinterpret_cast<bool (*)(const char*, int32)>(
+          validate_fn_proto)(flagname, VALUE_AS(int32));
+    case FV_INT64:
+      return reinterpret_cast<bool (*)(const char*, int64)>(
+          validate_fn_proto)(flagname, VALUE_AS(int64));
+    case FV_UINT64:
+      return reinterpret_cast<bool (*)(const char*, uint64)>(
+          validate_fn_proto)(flagname, VALUE_AS(uint64));
+    case FV_DOUBLE:
+      return reinterpret_cast<bool (*)(const char*, double)>(
+          validate_fn_proto)(flagname, VALUE_AS(double));
+    case FV_STRING:
+      return reinterpret_cast<bool (*)(const char*, const string&)>(
+          validate_fn_proto)(flagname, VALUE_AS(string));
+    default:
+      assert(false);  // unknown type
+      return false;
+  }
+}
+
+const char* FlagValue::TypeName() const {
+  static const char types[] =
+      "bool\0xx"
+      "int32\0x"
+      "int64\0x"
+      "uint64\0"
+      "double\0"
+      "string";
+  if (type_ > FV_MAX_INDEX) {
+    assert(false);
+    return "";
+  }
+  // Directly indexing the strings in the 'types' string, each of them is 7 bytes long.
+  return &types[type_ * 7];
+}
+
+bool FlagValue::Equal(const FlagValue& x) const {
+  if (type_ != x.type_)
+    return false;
+  switch (type_) {
+    case FV_BOOL:   return VALUE_AS(bool) == OTHER_VALUE_AS(x, bool);
+    case FV_INT32:  return VALUE_AS(int32) == OTHER_VALUE_AS(x, int32);
+    case FV_INT64:  return VALUE_AS(int64) == OTHER_VALUE_AS(x, int64);
+    case FV_UINT64: return VALUE_AS(uint64) == OTHER_VALUE_AS(x, uint64);
+    case FV_DOUBLE: return VALUE_AS(double) == OTHER_VALUE_AS(x, double);
+    case FV_STRING: return VALUE_AS(string) == OTHER_VALUE_AS(x, string);
+    default: assert(false); return false;  // unknown type
+  }
+}
+
+FlagValue* FlagValue::New() const {
+  const char *type = TypeName();
+  switch (type_) {
+    case FV_BOOL:   return new FlagValue(new bool(false), type, true);
+    case FV_INT32:  return new FlagValue(new int32(0), type, true);
+    case FV_INT64:  return new FlagValue(new int64(0), type, true);
+    case FV_UINT64: return new FlagValue(new uint64(0), type, true);
+    case FV_DOUBLE: return new FlagValue(new double(0.0), type, true);
+    case FV_STRING: return new FlagValue(new string, type, true);
+    default: assert(false); return NULL;  // unknown type
+  }
+}
+
+void FlagValue::CopyFrom(const FlagValue& x) {
+  assert(type_ == x.type_);
+  switch (type_) {
+    case FV_BOOL:   SET_VALUE_AS(bool, OTHER_VALUE_AS(x, bool));      break;
+    case FV_INT32:  SET_VALUE_AS(int32, OTHER_VALUE_AS(x, int32));    break;
+    case FV_INT64:  SET_VALUE_AS(int64, OTHER_VALUE_AS(x, int64));    break;
+    case FV_UINT64: SET_VALUE_AS(uint64, OTHER_VALUE_AS(x, uint64));  break;
+    case FV_DOUBLE: SET_VALUE_AS(double, OTHER_VALUE_AS(x, double));  break;
+    case FV_STRING: SET_VALUE_AS(string, OTHER_VALUE_AS(x, string));  break;
+    default: assert(false);  // unknown type
+  }
+}
+
+int FlagValue::ValueSize() const {
+  if (type_ > FV_MAX_INDEX) {
+    assert(false);  // unknown type
+    return 0;
+  }
+  static const uint8 valuesize[] = {
+    sizeof(bool),
+    sizeof(int32),
+    sizeof(int64),
+    sizeof(uint64),
+    sizeof(double),
+    sizeof(string),
+  };
+  return valuesize[type_];
+}
+
+// --------------------------------------------------------------------
+// CommandLineFlag
+//    This represents a single flag, including its name, description,
+//    default value, and current value.  Mostly this serves as a
+//    struct, though it also knows how to register itself.
+//       All CommandLineFlags are owned by a (exactly one)
+//    FlagRegistry.  If you wish to modify fields in this class, you
+//    should acquire the FlagRegistry lock for the registry that owns
+//    this flag.
+// --------------------------------------------------------------------
+
+class CommandLineFlag {
+ public:
+  // Note: we take over memory-ownership of current_val and default_val.
+  CommandLineFlag(const char* name, const char* help, const char* filename,
+                  FlagValue* current_val, FlagValue* default_val);
+  ~CommandLineFlag();
+
+  const char* name() const { return name_; }
+  const char* help() const { return help_; }
+  const char* filename() const { return file_; }
+  const char* CleanFileName() const;  // nixes irrelevant prefix such as homedir
+  string current_value() const { return current_->ToString(); }
+  string default_value() const { return defvalue_->ToString(); }
+  const char* type_name() const { return defvalue_->TypeName(); }
+  ValidateFnProto validate_function() const { return validate_fn_proto_; }
+  const void* flag_ptr() const { return current_->value_buffer_; }
+
+  void FillCommandLineFlagInfo(struct CommandLineFlagInfo* result);
+
+  // If validate_fn_proto_ is non-NULL, calls it on value, returns result.
+  bool Validate(const FlagValue& value) const;
+  bool ValidateCurrent() const { return Validate(*current_); }
+
+ private:
+  // for SetFlagLocked() and setting flags_by_ptr_
+  friend class FlagRegistry;
+  friend class GFLAGS_NAMESPACE::FlagSaverImpl;  // for cloning the values
+  // set validate_fn
+  friend bool AddFlagValidator(const void*, ValidateFnProto);
+
+  // This copies all the non-const members: modified, processed, defvalue, etc.
+  void CopyFrom(const CommandLineFlag& src);
+
+  void UpdateModifiedBit();
+
+  const char* const name_;     // Flag name
+  const char* const help_;     // Help message
+  const char* const file_;     // Which file did this come from?
+  bool modified_;              // Set after default assignment?
+  FlagValue* defvalue_;        // Default value for flag
+  FlagValue* current_;         // Current value for flag
+  // This is a casted, 'generic' version of validate_fn, which actually
+  // takes a flag-value as an arg (void (*validate_fn)(bool), say).
+  // When we pass this to current_->Validate(), it will cast it back to
+  // the proper type.  This may be NULL to mean we have no validate_fn.
+  ValidateFnProto validate_fn_proto_;
+
+  CommandLineFlag(const CommandLineFlag&);   // no copying!
+  void operator=(const CommandLineFlag&);
+};
+
+CommandLineFlag::CommandLineFlag(const char* name, const char* help,
+                                 const char* filename,
+                                 FlagValue* current_val, FlagValue* default_val)
+    : name_(name), help_(help), file_(filename), modified_(false),
+      defvalue_(default_val), current_(current_val), validate_fn_proto_(NULL) {
+}
+
+CommandLineFlag::~CommandLineFlag() {
+  delete current_;
+  delete defvalue_;
+}
+
+const char* CommandLineFlag::CleanFileName() const {
+  // Compute top-level directory & file that this appears in
+  // search full path backwards.
+  // Stop going backwards at kRootDir; and skip by the first slash.
+  static const char kRootDir[] = "";    // can set this to root directory,
+
+  if (sizeof(kRootDir)-1 == 0)          // no prefix to strip
+    return filename();
+
+  const char* clean_name = filename() + strlen(filename()) - 1;
+  while ( clean_name > filename() ) {
+    if (*clean_name == PATH_SEPARATOR) {
+      if (strncmp(clean_name, kRootDir, sizeof(kRootDir)-1) == 0) {
+        clean_name += sizeof(kRootDir)-1;    // past root-dir
+        break;
+      }
+    }
+    --clean_name;
+  }
+  while ( *clean_name == PATH_SEPARATOR ) ++clean_name;  // Skip any slashes
+  return clean_name;
+}
+
+void CommandLineFlag::FillCommandLineFlagInfo(
+    CommandLineFlagInfo* result) {
+  result->name = name();
+  result->type = type_name();
+  result->description = help();
+  result->current_value = current_value();
+  result->default_value = default_value();
+  result->filename = CleanFileName();
+  UpdateModifiedBit();
+  result->is_default = !modified_;
+  result->has_validator_fn = validate_function() != NULL;
+  result->flag_ptr = flag_ptr();
+}
+
+void CommandLineFlag::UpdateModifiedBit() {
+  // Update the "modified" bit in case somebody bypassed the
+  // Flags API and wrote directly through the FLAGS_name variable.
+  if (!modified_ && !current_->Equal(*defvalue_)) {
+    modified_ = true;
+  }
+}
+
+void CommandLineFlag::CopyFrom(const CommandLineFlag& src) {
+  // Note we only copy the non-const members; others are fixed at construct time
+  if (modified_ != src.modified_) modified_ = src.modified_;
+  if (!current_->Equal(*src.current_)) current_->CopyFrom(*src.current_);
+  if (!defvalue_->Equal(*src.defvalue_)) defvalue_->CopyFrom(*src.defvalue_);
+  if (validate_fn_proto_ != src.validate_fn_proto_)
+    validate_fn_proto_ = src.validate_fn_proto_;
+}
+
+bool CommandLineFlag::Validate(const FlagValue& value) const {
+
+  if (validate_function() == NULL)
+    return true;
+  else
+    return value.Validate(name(), validate_function());
+}
+
+
+// --------------------------------------------------------------------
+// FlagRegistry
+//    A FlagRegistry singleton object holds all flag objects indexed
+//    by their names so that if you know a flag's name (as a C
+//    string), you can access or set it.  If the function is named
+//    FooLocked(), you must own the registry lock before calling
+//    the function; otherwise, you should *not* hold the lock, and
+//    the function will acquire it itself if needed.
+// --------------------------------------------------------------------
+
+struct StringCmp {  // Used by the FlagRegistry map class to compare char*'s
+  bool operator() (const char* s1, const char* s2) const {
+    return (strcmp(s1, s2) < 0);
+  }
+};
+
+
+class FlagRegistry {
+ public:
+  FlagRegistry() {
+  }
+  ~FlagRegistry() {
+    // Not using STLDeleteElements as that resides in util and this
+    // class is base.
+    for (FlagMap::iterator p = flags_.begin(), e = flags_.end(); p != e; ++p) {
+      CommandLineFlag* flag = p->second;
+      delete flag;
+    }
+  }
+
+  static void DeleteGlobalRegistry() {
+    delete global_registry_;
+    global_registry_ = NULL;
+  }
+
+  // Store a flag in this registry.  Takes ownership of the given pointer.
+  void RegisterFlag(CommandLineFlag* flag);
+
+  void Lock() { lock_.Lock(); }
+  void Unlock() { lock_.Unlock(); }
+
+  // Returns the flag object for the specified name, or NULL if not found.
+  CommandLineFlag* FindFlagLocked(const char* name);
+
+  // Returns the flag object whose current-value is stored at flag_ptr.
+  // That is, for whom current_->value_buffer_ == flag_ptr
+  CommandLineFlag* FindFlagViaPtrLocked(const void* flag_ptr);
+
+  // A fancier form of FindFlag that works correctly if name is of the
+  // form flag=value.  In that case, we set key to point to flag, and
+  // modify v to point to the value (if present), and return the flag
+  // with the given name.  If the flag does not exist, returns NULL
+  // and sets error_message.
+  CommandLineFlag* SplitArgumentLocked(const char* argument,
+                                       string* key, const char** v,
+                                       string* error_message);
+
+  // Set the value of a flag.  If the flag was successfully set to
+  // value, set msg to indicate the new flag-value, and return true.
+  // Otherwise, set msg to indicate the error, leave flag unchanged,
+  // and return false.  msg can be NULL.
+  bool SetFlagLocked(CommandLineFlag* flag, const char* value,
+                     FlagSettingMode set_mode, string* msg);
+
+  static FlagRegistry* GlobalRegistry();   // returns a singleton registry
+
+ private:
+  friend class GFLAGS_NAMESPACE::FlagSaverImpl;  // reads all the flags in order to copy them
+  friend class CommandLineFlagParser;    // for ValidateAllFlags
+  friend void GFLAGS_NAMESPACE::GetAllFlags(vector<CommandLineFlagInfo>*);
+
+  // The map from name to flag, for FindFlagLocked().
+  typedef map<const char*, CommandLineFlag*, StringCmp> FlagMap;
+  typedef FlagMap::iterator FlagIterator;
+  typedef FlagMap::const_iterator FlagConstIterator;
+  FlagMap flags_;
+
+  // The map from current-value pointer to flag, fo FindFlagViaPtrLocked().
+  typedef map<const void*, CommandLineFlag*> FlagPtrMap;
+  FlagPtrMap flags_by_ptr_;
+
+  static FlagRegistry* global_registry_;   // a singleton registry
+
+  Mutex lock_;
+  static Mutex global_registry_lock_;
+
+  static void InitGlobalRegistry();
+
+  // Disallow
+  FlagRegistry(const FlagRegistry&);
+  FlagRegistry& operator=(const FlagRegistry&);
+};
+
+class FlagRegistryLock {
+ public:
+  explicit FlagRegistryLock(FlagRegistry* fr) : fr_(fr) { fr_->Lock(); }
+  ~FlagRegistryLock() { fr_->Unlock(); }
+ private:
+  FlagRegistry *const fr_;
+};
+
+
+void FlagRegistry::RegisterFlag(CommandLineFlag* flag) {
+  Lock();
+  pair<FlagIterator, bool> ins =
+    flags_.insert(pair<const char*, CommandLineFlag*>(flag->name(), flag));
+  if (ins.second == false) {   // means the name was already in the map
+    if (strcmp(ins.first->second->filename(), flag->filename()) != 0) {
+      ReportError(DIE, "ERROR: flag '%s' was defined more than once "
+                  "(in files '%s' and '%s').\n",
+                  flag->name(),
+                  ins.first->second->filename(),
+                  flag->filename());
+    } else {
+      ReportError(DIE, "ERROR: something wrong with flag '%s' in file '%s'.  "
+                  "One possibility: file '%s' is being linked both statically "
+                  "and dynamically into this executable.\n",
+                  flag->name(),
+                  flag->filename(), flag->filename());
+    }
+  }
+  // Also add to the flags_by_ptr_ map.
+  flags_by_ptr_[flag->current_->value_buffer_] = flag;
+  Unlock();
+}
+
+CommandLineFlag* FlagRegistry::FindFlagLocked(const char* name) {
+  FlagConstIterator i = flags_.find(name);
+  if (i == flags_.end()) {
+    return NULL;
+  } else {
+    return i->second;
+  }
+}
+
+CommandLineFlag* FlagRegistry::FindFlagViaPtrLocked(const void* flag_ptr) {
+  FlagPtrMap::const_iterator i = flags_by_ptr_.find(flag_ptr);
+  if (i == flags_by_ptr_.end()) {
+    return NULL;
+  } else {
+    return i->second;
+  }
+}
+
+CommandLineFlag* FlagRegistry::SplitArgumentLocked(const char* arg,
+                                                   string* key,
+                                                   const char** v,
+                                                   string* error_message) {
+  // Find the flag object for this option
+  const char* flag_name;
+  const char* value = strchr(arg, '=');
+  if (value == NULL) {
+    key->assign(arg);
+    *v = NULL;
+  } else {
+    // Strip out the "=value" portion from arg
+    key->assign(arg, value-arg);
+    *v = ++value;    // advance past the '='
+  }
+  flag_name = key->c_str();
+
+  CommandLineFlag* flag = FindFlagLocked(flag_name);
+
+  if (flag == NULL) {
+    // If we can't find the flag-name, then we should return an error.
+    // The one exception is if 1) the flag-name is 'nox', 2) there
+    // exists a flag named 'x', and 3) 'x' is a boolean flag.
+    // In that case, we want to return flag 'x'.
+    if (!(flag_name[0] == 'n' && flag_name[1] == 'o')) {
+      // flag-name is not 'nox', so we're not in the exception case.
+      *error_message = StringPrintf("%sunknown command line flag '%s'\n",
+                                    kError, key->c_str());
+      return NULL;
+    }
+    flag = FindFlagLocked(flag_name+2);
+    if (flag == NULL) {
+      // No flag named 'x' exists, so we're not in the exception case.
+      *error_message = StringPrintf("%sunknown command line flag '%s'\n",
+                                    kError, key->c_str());
+      return NULL;
+    }
+    if (strcmp(flag->type_name(), "bool") != 0) {
+      // 'x' exists but is not boolean, so we're not in the exception case.
+      *error_message = StringPrintf(
+          "%sboolean value (%s) specified for %s command line flag\n",
+          kError, key->c_str(), flag->type_name());
+      return NULL;
+    }
+    // We're in the exception case!
+    // Make up a fake value to replace the "no" we stripped out
+    key->assign(flag_name+2);   // the name without the "no"
+    *v = "0";
+  }
+
+  // Assign a value if this is a boolean flag
+  if (*v == NULL && strcmp(flag->type_name(), "bool") == 0) {
+    *v = "1";    // the --nox case was already handled, so this is the --x case
+  }
+
+  return flag;
+}
+
+bool TryParseLocked(const CommandLineFlag* flag, FlagValue* flag_value,
+                    const char* value, string* msg) {
+  // Use tenative_value, not flag_value, until we know value is valid.
+  FlagValue* tentative_value = flag_value->New();
+  if (!tentative_value->ParseFrom(value)) {
+    if (msg) {
+      StringAppendF(msg,
+                    "%sillegal value '%s' specified for %s flag '%s'\n",
+                    kError, value,
+                    flag->type_name(), flag->name());
+    }
+    delete tentative_value;
+    return false;
+  } else if (!flag->Validate(*tentative_value)) {
+    if (msg) {
+      StringAppendF(msg,
+          "%sfailed validation of new value '%s' for flag '%s'\n",
+          kError, tentative_value->ToString().c_str(),
+          flag->name());
+    }
+    delete tentative_value;
+    return false;
+  } else {
+    flag_value->CopyFrom(*tentative_value);
+    if (msg) {
+      StringAppendF(msg, "%s set to %s\n",
+                    flag->name(), flag_value->ToString().c_str());
+    }
+    delete tentative_value;
+    return true;
+  }
+}
+
+bool FlagRegistry::SetFlagLocked(CommandLineFlag* flag,
+                                 const char* value,
+                                 FlagSettingMode set_mode,
+                                 string* msg) {
+  flag->UpdateModifiedBit();
+  switch (set_mode) {
+    case SET_FLAGS_VALUE: {
+      // set or modify the flag's value
+      if (!TryParseLocked(flag, flag->current_, value, msg))
+        return false;
+      flag->modified_ = true;
+      break;
+    }
+    case SET_FLAG_IF_DEFAULT: {
+      // set the flag's value, but only if it hasn't been set by someone else
+      if (!flag->modified_) {
+        if (!TryParseLocked(flag, flag->current_, value, msg))
+          return false;
+        flag->modified_ = true;
+      } else {
+        *msg = StringPrintf("%s set to %s",
+                            flag->name(), flag->current_value().c_str());
+      }
+      break;
+    }
+    case SET_FLAGS_DEFAULT: {
+      // modify the flag's default-value
+      if (!TryParseLocked(flag, flag->defvalue_, value, msg))
+        return false;
+      if (!flag->modified_) {
+        // Need to set both defvalue *and* current, in this case
+        TryParseLocked(flag, flag->current_, value, NULL);
+      }
+      break;
+    }
+    default: {
+      // unknown set_mode
+      assert(false);
+      return false;
+    }
+  }
+
+  return true;
+}
+
+// Get the singleton FlagRegistry object
+FlagRegistry* FlagRegistry::global_registry_ = NULL;
+Mutex FlagRegistry::global_registry_lock_(Mutex::LINKER_INITIALIZED);
+
+FlagRegistry* FlagRegistry::GlobalRegistry() {
+  MutexLock acquire_lock(&global_registry_lock_);
+  if (!global_registry_) {
+    global_registry_ = new FlagRegistry;
+  }
+  return global_registry_;
+}
+
+// --------------------------------------------------------------------
+// CommandLineFlagParser
+//    Parsing is done in two stages.  In the first, we go through
+//    argv.  For every flag-like arg we can make sense of, we parse
+//    it and set the appropriate FLAGS_* variable.  For every flag-
+//    like arg we can't make sense of, we store it in a vector,
+//    along with an explanation of the trouble.  In stage 2, we
+//    handle the 'reporting' flags like --help and --mpm_version.
+//    (This is via a call to HandleCommandLineHelpFlags(), in
+//    gflags_reporting.cc.)
+//    An optional stage 3 prints out the error messages.
+//       This is a bit of a simplification.  For instance, --flagfile
+//    is handled as soon as it's seen in stage 1, not in stage 2.
+// --------------------------------------------------------------------
+
+class CommandLineFlagParser {
+ public:
+  // The argument is the flag-registry to register the parsed flags in
+  explicit CommandLineFlagParser(FlagRegistry* reg) : registry_(reg) {}
+  ~CommandLineFlagParser() {}
+
+  // Stage 1: Every time this is called, it reads all flags in argv.
+  // However, it ignores all flags that have been successfully set
+  // before.  Typically this is only called once, so this 'reparsing'
+  // behavior isn't important.  It can be useful when trying to
+  // reparse after loading a dll, though.
+  uint32 ParseNewCommandLineFlags(int* argc, char*** argv, bool remove_flags);
+
+  // Stage 2: print reporting info and exit, if requested.
+  // In gflags_reporting.cc:HandleCommandLineHelpFlags().
+
+  // Stage 3: validate all the commandline flags that have validators
+  // registered.
+  void ValidateAllFlags();
+
+  // Stage 4: report any errors and return true if any were found.
+  bool ReportErrors();
+
+  // Set a particular command line option.  "newval" is a string
+  // describing the new value that the option has been set to.  If
+  // option_name does not specify a valid option name, or value is not
+  // a valid value for option_name, newval is empty.  Does recursive
+  // processing for --flagfile and --fromenv.  Returns the new value
+  // if everything went ok, or empty-string if not.  (Actually, the
+  // return-string could hold many flag/value pairs due to --flagfile.)
+  // NB: Must have called registry_->Lock() before calling this function.
+  string ProcessSingleOptionLocked(CommandLineFlag* flag,
+                                   const char* value,
+                                   FlagSettingMode set_mode);
+
+  // Set a whole batch of command line options as specified by contentdata,
+  // which is in flagfile format (and probably has been read from a flagfile).
+  // Returns the new value if everything went ok, or empty-string if
+  // not.  (Actually, the return-string could hold many flag/value
+  // pairs due to --flagfile.)
+  // NB: Must have called registry_->Lock() before calling this function.
+  string ProcessOptionsFromStringLocked(const string& contentdata,
+                                        FlagSettingMode set_mode);
+
+  // These are the 'recursive' flags, defined at the top of this file.
+  // Whenever we see these flags on the commandline, we must take action.
+  // These are called by ProcessSingleOptionLocked and, similarly, return
+  // new values if everything went ok, or the empty-string if not.
+  string ProcessFlagfileLocked(const string& flagval, FlagSettingMode set_mode);
+  // diff fromenv/tryfromenv
+  string ProcessFromenvLocked(const string& flagval, FlagSettingMode set_mode,
+                              bool errors_are_fatal);
+
+ private:
+  FlagRegistry* const registry_;
+  map<string, string> error_flags_;      // map from name to error message
+  // This could be a set<string>, but we reuse the map to minimize the .o size
+  map<string, string> undefined_names_;  // --[flag] name was not registered
+};
+
+
+// Parse a list of (comma-separated) flags.
+static void ParseFlagList(const char* value, vector<string>* flags) {
+  for (const char *p = value; p && *p; value = p) {
+    p = strchr(value, ',');
+    size_t len;
+    if (p) {
+      len = p - value;
+      p++;
+    } else {
+      len = strlen(value);
+    }
+
+    if (len == 0)
+      ReportError(DIE, "ERROR: empty flaglist entry\n");
+    if (value[0] == '-')
+      ReportError(DIE, "ERROR: flag \"%*s\" begins with '-'\n", len, value);
+
+    flags->push_back(string(value, len));
+  }
+}
+
+// Snarf an entire file into a C++ string.  This is just so that we
+// can do all the I/O in one place and not worry about it everywhere.
+// Plus, it's convenient to have the whole file contents at hand.
+// Adds a newline at the end of the file.
+#define PFATAL(s)  do { perror(s); gflags_exitfunc(1); } while (0)
+
+static string ReadFileIntoString(const char* filename) {
+  const int kBufSize = 8092;
+  char buffer[kBufSize];
+  string s;
+  FILE* fp;
+  if ((errno = SafeFOpen(&fp, filename, "r")) != 0) PFATAL(filename);
+  size_t n;
+  while ( (n=fread(buffer, 1, kBufSize, fp)) > 0 ) {
+    if (ferror(fp))  PFATAL(filename);
+    s.append(buffer, n);
+  }
+  fclose(fp);
+  return s;
+}
+
+uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv,
+                                                       bool remove_flags) {
+  const char *program_name = strrchr((*argv)[0], PATH_SEPARATOR);   // nix path
+  program_name = (program_name == NULL ? (*argv)[0] : program_name+1);
+
+  int first_nonopt = *argc;        // for non-options moved to the end
+
+  registry_->Lock();
+  for (int i = 1; i < first_nonopt; i++) {
+    char* arg = (*argv)[i];
+
+    // Like getopt(), we permute non-option flags to be at the end.
+    if (arg[0] != '-' ||           // must be a program argument
+        (arg[0] == '-' && arg[1] == '\0')) {  // "-" is an argument, not a flag
+      memmove((*argv) + i, (*argv) + i+1, (*argc - (i+1)) * sizeof((*argv)[i]));
+      (*argv)[*argc-1] = arg;      // we go last
+      first_nonopt--;              // we've been pushed onto the stack
+      i--;                         // to undo the i++ in the loop
+      continue;
+    }
+
+    if (arg[0] == '-') arg++;      // allow leading '-'
+    if (arg[0] == '-') arg++;      // or leading '--'
+
+    // -- alone means what it does for GNU: stop options parsing
+    if (*arg == '\0') {
+      first_nonopt = i+1;
+      break;
+    }
+
+    // Find the flag object for this option
+    string key;
+    const char* value;
+    string error_message;
+    CommandLineFlag* flag = registry_->SplitArgumentLocked(arg, &key, &value,
+                                                           &error_message);
+    if (flag == NULL) {
+      undefined_names_[key] = "";    // value isn't actually used
+      error_flags_[key] = error_message;
+      continue;
+    }
+
+    if (value == NULL) {
+      // Boolean options are always assigned a value by SplitArgumentLocked()
+      assert(strcmp(flag->type_name(), "bool") != 0);
+      if (i+1 >= first_nonopt) {
+        // This flag needs a value, but there is nothing available
+        error_flags_[key] = (string(kError) + "flag '" + (*argv)[i] + "'"
+                             + " is missing its argument");
+        if (flag->help() && flag->help()[0] > '\001') {
+          // Be useful in case we have a non-stripped description.
+          error_flags_[key] += string("; flag description: ") + flag->help();
+        }
+        error_flags_[key] += "\n";
+        break;    // we treat this as an unrecoverable error
+      } else {
+        value = (*argv)[++i];                   // read next arg for value
+
+        // Heuristic to detect the case where someone treats a string arg
+        // like a bool:
+        // --my_string_var --foo=bar
+        // We look for a flag of string type, whose value begins with a
+        // dash, and where the flag-name and value are separated by a
+        // space rather than an '='.
+        // To avoid false positives, we also require the word "true"
+        // or "false" in the help string.  Without this, a valid usage
+        // "-lat -30.5" would trigger the warning.  The common cases we
+        // want to solve talk about true and false as values.
+        if (value[0] == '-'
+            && strcmp(flag->type_name(), "string") == 0
+            && (strstr(flag->help(), "true")
+                || strstr(flag->help(), "false"))) {
+          LOG(WARNING) << "Did you really mean to set flag '"
+                       << flag->name() << "' to the value '"
+                       << value << "'?";
+        }
+      }
+    }
+
+    // TODO(csilvers): only set a flag if we hadn't set it before here
+    ProcessSingleOptionLocked(flag, value, SET_FLAGS_VALUE);
+  }
+  registry_->Unlock();
+
+  if (remove_flags) {   // Fix up argc and argv by removing command line flags
+    (*argv)[first_nonopt-1] = (*argv)[0];
+    (*argv) += (first_nonopt-1);
+    (*argc) -= (first_nonopt-1);
+    first_nonopt = 1;   // because we still don't count argv[0]
+  }
+
+  logging_is_probably_set_up = true;   // because we've parsed --logdir, etc.
+
+  return first_nonopt;
+}
+
+string CommandLineFlagParser::ProcessFlagfileLocked(const string& flagval,
+                                                    FlagSettingMode set_mode) {
+  if (flagval.empty())
+    return "";
+
+  string msg;
+  vector<string> filename_list;
+  ParseFlagList(flagval.c_str(), &filename_list);  // take a list of filenames
+  for (size_t i = 0; i < filename_list.size(); ++i) {
+    const char* file = filename_list[i].c_str();
+    msg += ProcessOptionsFromStringLocked(ReadFileIntoString(file), set_mode);
+  }
+  return msg;
+}
+
+string CommandLineFlagParser::ProcessFromenvLocked(const string& flagval,
+                                                   FlagSettingMode set_mode,
+                                                   bool errors_are_fatal) {
+  if (flagval.empty())
+    return "";
+
+  string msg;
+  vector<string> flaglist;
+  ParseFlagList(flagval.c_str(), &flaglist);
+
+  for (size_t i = 0; i < flaglist.size(); ++i) {
+    const char* flagname = flaglist[i].c_str();
+    CommandLineFlag* flag = registry_->FindFlagLocked(flagname);
+    if (flag == NULL) {
+      error_flags_[flagname] =
+          StringPrintf("%sunknown command line flag '%s' "
+                       "(via --fromenv or --tryfromenv)\n",
+                       kError, flagname);
+      undefined_names_[flagname] = "";
+      continue;
+    }
+
+    const string envname = string("FLAGS_") + string(flagname);
+	string envval;
+	if (!SafeGetEnv(envname.c_str(), envval)) {
+      if (errors_are_fatal) {
+        error_flags_[flagname] = (string(kError) + envname +
+                                  " not found in environment\n");
+      }
+      continue;
+    }
+
+    // Avoid infinite recursion.
+    if (envval == "fromenv" || envval == "tryfromenv") {
+      error_flags_[flagname] =
+          StringPrintf("%sinfinite recursion on environment flag '%s'\n",
+                       kError, envval.c_str());
+      continue;
+    }
+
+    msg += ProcessSingleOptionLocked(flag, envval.c_str(), set_mode);
+  }
+  return msg;
+}
+
+string CommandLineFlagParser::ProcessSingleOptionLocked(
+    CommandLineFlag* flag, const char* value, FlagSettingMode set_mode) {
+  string msg;
+  if (value && !registry_->SetFlagLocked(flag, value, set_mode, &msg)) {
+    error_flags_[flag->name()] = msg;
+    return "";
+  }
+
+  // The recursive flags, --flagfile and --fromenv and --tryfromenv,
+  // must be dealt with as soon as they're seen.  They will emit
+  // messages of their own.
+  if (strcmp(flag->name(), "flagfile") == 0) {
+    msg += ProcessFlagfileLocked(FLAGS_flagfile, set_mode);
+
+  } else if (strcmp(flag->name(), "fromenv") == 0) {
+    // last arg indicates envval-not-found is fatal (unlike in --tryfromenv)
+    msg += ProcessFromenvLocked(FLAGS_fromenv, set_mode, true);
+
+  } else if (strcmp(flag->name(), "tryfromenv") == 0) {
+    msg += ProcessFromenvLocked(FLAGS_tryfromenv, set_mode, false);
+  }
+
+  return msg;
+}
+
+void CommandLineFlagParser::ValidateAllFlags() {
+  FlagRegistryLock frl(registry_);
+  for (FlagRegistry::FlagConstIterator i = registry_->flags_.begin();
+       i != registry_->flags_.end(); ++i) {
+    if (!i->second->ValidateCurrent()) {
+      // only set a message if one isn't already there.  (If there's
+      // an error message, our job is done, even if it's not exactly
+      // the same error.)
+      if (error_flags_[i->second->name()].empty())
+        error_flags_[i->second->name()] =
+            string(kError) + "--" + i->second->name() +
+            " must be set on the commandline"
+            " (default value fails validation)\n";
+    }
+  }
+}
+
+bool CommandLineFlagParser::ReportErrors() {
+  // error_flags_ indicates errors we saw while parsing.
+  // But we ignore undefined-names if ok'ed by --undef_ok
+  if (!FLAGS_undefok.empty()) {
+    vector<string> flaglist;
+    ParseFlagList(FLAGS_undefok.c_str(), &flaglist);
+    for (size_t i = 0; i < flaglist.size(); ++i) {
+      // We also deal with --no<flag>, in case the flagname was boolean
+      const string no_version = string("no") + flaglist[i];
+      if (undefined_names_.find(flaglist[i]) != undefined_names_.end()) {
+        error_flags_[flaglist[i]] = "";    // clear the error message
+      } else if (undefined_names_.find(no_version) != undefined_names_.end()) {
+        error_flags_[no_version] = "";
+      }
+    }
+  }
+  // Likewise, if they decided to allow reparsing, all undefined-names
+  // are ok; we just silently ignore them now, and hope that a future
+  // parse will pick them up somehow.
+  if (allow_command_line_reparsing) {
+    for (map<string, string>::const_iterator it = undefined_names_.begin();
+         it != undefined_names_.end();  ++it)
+      error_flags_[it->first] = "";      // clear the error message
+  }
+
+  bool found_error = false;
+  string error_message;
+  for (map<string, string>::const_iterator it = error_flags_.begin();
+       it != error_flags_.end(); ++it) {
+    if (!it->second.empty()) {
+      error_message.append(it->second.data(), it->second.size());
+      found_error = true;
+    }
+  }
+  if (found_error)
+    ReportError(DO_NOT_DIE, "%s", error_message.c_str());
+  return found_error;
+}
+
+string CommandLineFlagParser::ProcessOptionsFromStringLocked(
+    const string& contentdata, FlagSettingMode set_mode) {
+  string retval;
+  const char* flagfile_contents = contentdata.c_str();
+  bool flags_are_relevant = true;   // set to false when filenames don't match
+  bool in_filename_section = false;
+
+  const char* line_end = flagfile_contents;
+  // We read this file a line at a time.
+  for (; line_end; flagfile_contents = line_end + 1) {
+    while (*flagfile_contents && isspace(*flagfile_contents))
+      ++flagfile_contents;
+    line_end = strchr(flagfile_contents, '\n');
+    size_t len = line_end ? line_end - flagfile_contents
+                          : strlen(flagfile_contents);
+    string line(flagfile_contents, len);
+
+    // Each line can be one of four things:
+    // 1) A comment line -- we skip it
+    // 2) An empty line -- we skip it
+    // 3) A list of filenames -- starts a new filenames+flags section
+    // 4) A --flag=value line -- apply if previous filenames match
+    if (line.empty() || line[0] == '#') {
+      // comment or empty line; just ignore
+
+    } else if (line[0] == '-') {    // flag
+      in_filename_section = false;  // instead, it was a flag-line
+      if (!flags_are_relevant)      // skip this flag; applies to someone else
+        continue;
+
+      const char* name_and_val = line.c_str() + 1;    // skip the leading -
+      if (*name_and_val == '-')
+        name_and_val++;                               // skip second - too
+      string key;
+      const char* value;
+      string error_message;
+      CommandLineFlag* flag = registry_->SplitArgumentLocked(name_and_val,
+                                                             &key, &value,
+                                                             &error_message);
+      // By API, errors parsing flagfile lines are silently ignored.
+      if (flag == NULL) {
+        // "WARNING: flagname '" + key + "' not found\n"
+      } else if (value == NULL) {
+        // "WARNING: flagname '" + key + "' missing a value\n"
+      } else {
+        retval += ProcessSingleOptionLocked(flag, value, set_mode);
+      }
+
+    } else {                        // a filename!
+      if (!in_filename_section) {   // start over: assume filenames don't match
+        in_filename_section = true;
+        flags_are_relevant = false;
+      }
+
+      // Split the line up at spaces into glob-patterns
+      const char* space = line.c_str();   // just has to be non-NULL
+      for (const char* word = line.c_str(); *space; word = space+1) {
+        if (flags_are_relevant)     // we can stop as soon as we match
+          break;
+        space = strchr(word, ' ');
+        if (space == NULL)
+          space = word + strlen(word);
+        const string glob(word, space - word);
+        // We try matching both against the full argv0 and basename(argv0)
+        if (glob == ProgramInvocationName()       // small optimization
+            || glob == ProgramInvocationShortName()
+#if defined(HAVE_FNMATCH_H)
+            || fnmatch(glob.c_str(), ProgramInvocationName(),      FNM_PATHNAME) == 0
+            || fnmatch(glob.c_str(), ProgramInvocationShortName(), FNM_PATHNAME) == 0
+#elif defined(HAVE_SHLWAPI_H)
+            || PathMatchSpec(glob.c_str(), ProgramInvocationName())
+            || PathMatchSpec(glob.c_str(), ProgramInvocationShortName())
+#endif
+            ) {
+          flags_are_relevant = true;
+        }
+      }
+    }
+  }
+  return retval;
+}
+
+// --------------------------------------------------------------------
+// GetFromEnv()
+// AddFlagValidator()
+//    These are helper functions for routines like BoolFromEnv() and
+//    RegisterFlagValidator, defined below.  They're defined here so
+//    they can live in the unnamed namespace (which makes friendship
+//    declarations for these classes possible).
+// --------------------------------------------------------------------
+
+template<typename T>
+T GetFromEnv(const char *varname, const char* type, T dflt) {
+  std::string valstr;
+  if (SafeGetEnv(varname, valstr)) {
+    FlagValue ifv(new T, type, true);
+    if (!ifv.ParseFrom(valstr.c_str())) {
+      ReportError(DIE, "ERROR: error parsing env variable '%s' with value '%s'\n",
+                  varname, valstr.c_str());
+	}
+    return OTHER_VALUE_AS(ifv, T);
+  } else return dflt;
+}
+
+bool AddFlagValidator(const void* flag_ptr, ValidateFnProto validate_fn_proto) {
+  // We want a lock around this routine, in case two threads try to
+  // add a validator (hopefully the same one!) at once.  We could use
+  // our own thread, but we need to loook at the registry anyway, so
+  // we just steal that one.
+  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+  FlagRegistryLock frl(registry);
+  // First, find the flag whose current-flag storage is 'flag'.
+  // This is the CommandLineFlag whose current_->value_buffer_ == flag
+  CommandLineFlag* flag = registry->FindFlagViaPtrLocked(flag_ptr);
+  if (!flag) {
+    LOG(WARNING) << "Ignoring RegisterValidateFunction() for flag pointer "
+                 << flag_ptr << ": no flag found at that address";
+    return false;
+  } else if (validate_fn_proto == flag->validate_function()) {
+    return true;    // ok to register the same function over and over again
+  } else if (validate_fn_proto != NULL && flag->validate_function() != NULL) {
+    LOG(WARNING) << "Ignoring RegisterValidateFunction() for flag '"
+                 << flag->name() << "': validate-fn already registered";
+    return false;
+  } else {
+    flag->validate_fn_proto_ = validate_fn_proto;
+    return true;
+  }
+}
+
+}  // end unnamed namespaces
+
+
+// Now define the functions that are exported via the .h file
+
+// --------------------------------------------------------------------
+// FlagRegisterer
+//    This class exists merely to have a global constructor (the
+//    kind that runs before main(), that goes an initializes each
+//    flag that's been declared.  Note that it's very important we
+//    don't have a destructor that deletes flag_, because that would
+//    cause us to delete current_storage/defvalue_storage as well,
+//    which can cause a crash if anything tries to access the flag
+//    values in a global destructor.
+// --------------------------------------------------------------------
+
+FlagRegisterer::FlagRegisterer(const char* name, const char* type,
+                               const char* help, const char* filename,
+                               void* current_storage, void* defvalue_storage) {
+  if (help == NULL)
+    help = "";
+  // FlagValue expects the type-name to not include any namespace
+  // components, so we get rid of those, if any.
+  if (strchr(type, ':'))
+    type = strrchr(type, ':') + 1;
+  FlagValue* current = new FlagValue(current_storage, type, false);
+  FlagValue* defvalue = new FlagValue(defvalue_storage, type, false);
+  // Importantly, flag_ will never be deleted, so storage is always good.
+  CommandLineFlag* flag = new CommandLineFlag(name, help, filename,
+                                              current, defvalue);
+  FlagRegistry::GlobalRegistry()->RegisterFlag(flag);   // default registry
+}
+
+// --------------------------------------------------------------------
+// GetAllFlags()
+//    The main way the FlagRegistry class exposes its data.  This
+//    returns, as strings, all the info about all the flags in
+//    the main registry, sorted first by filename they are defined
+//    in, and then by flagname.
+// --------------------------------------------------------------------
+
+struct FilenameFlagnameCmp {
+  bool operator()(const CommandLineFlagInfo& a,
+                  const CommandLineFlagInfo& b) const {
+    int cmp = strcmp(a.filename.c_str(), b.filename.c_str());
+    if (cmp == 0)
+      cmp = strcmp(a.name.c_str(), b.name.c_str());  // secondary sort key
+    return cmp < 0;
+  }
+};
+
+void GetAllFlags(vector<CommandLineFlagInfo>* OUTPUT) {
+  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+  registry->Lock();
+  for (FlagRegistry::FlagConstIterator i = registry->flags_.begin();
+       i != registry->flags_.end(); ++i) {
+    CommandLineFlagInfo fi;
+    i->second->FillCommandLineFlagInfo(&fi);
+    OUTPUT->push_back(fi);
+  }
+  registry->Unlock();
+  // Now sort the flags, first by filename they occur in, then alphabetically
+  sort(OUTPUT->begin(), OUTPUT->end(), FilenameFlagnameCmp());
+}
+
+// --------------------------------------------------------------------
+// SetArgv()
+// GetArgvs()
+// GetArgv()
+// GetArgv0()
+// ProgramInvocationName()
+// ProgramInvocationShortName()
+// SetUsageMessage()
+// ProgramUsage()
+//    Functions to set and get argv.  Typically the setter is called
+//    by ParseCommandLineFlags.  Also can get the ProgramUsage string,
+//    set by SetUsageMessage.
+// --------------------------------------------------------------------
+
+// These values are not protected by a Mutex because they are normally
+// set only once during program startup.
+static const char* argv0 = "UNKNOWN";      // just the program name
+static const char* cmdline = "";           // the entire command-line
+static vector<string> argvs;
+static uint32 argv_sum = 0;
+static const char* program_usage = NULL;
+
+void SetArgv(int argc, const char** argv) {
+  static bool called_set_argv = false;
+  if (called_set_argv)         // we already have an argv for you
+    return;
+
+  called_set_argv = true;
+
+  assert(argc > 0);            // every program has at least a progname
+  argv0 = strdup(argv[0]);     // small memory leak, but fn only called once
+  assert(argv0);
+
+  string cmdline_string;       // easier than doing strcats
+  for (int i = 0; i < argc; i++) {
+    if (i != 0) {
+      cmdline_string += " ";
+    }
+    cmdline_string += argv[i];
+    argvs.push_back(argv[i]);
+  }
+  cmdline = strdup(cmdline_string.c_str());  // another small memory leak
+  assert(cmdline);
+
+  // Compute a simple sum of all the chars in argv
+  for (const char* c = cmdline; *c; c++)
+    argv_sum += *c;
+}
+
+const vector<string>& GetArgvs() { return argvs; }
+const char* GetArgv()            { return cmdline; }
+const char* GetArgv0()           { return argv0; }
+uint32 GetArgvSum()              { return argv_sum; }
+const char* ProgramInvocationName() {             // like the GNU libc fn
+  return GetArgv0();
+}
+const char* ProgramInvocationShortName() {        // like the GNU libc fn
+  const char* slash = strrchr(argv0, '/');
+#ifdef OS_WINDOWS
+  if (!slash)  slash = strrchr(argv0, '\\');
+#endif
+  return slash ? slash + 1 : argv0;
+}
+
+void SetUsageMessage(const string& usage) {
+  if (program_usage != NULL)
+    ReportError(DIE, "ERROR: SetUsageMessage() called twice\n");
+  program_usage = strdup(usage.c_str());      // small memory leak
+}
+
+const char* ProgramUsage() {
+  if (program_usage) {
+    return program_usage;
+  }
+  return "Warning: SetUsageMessage() never called";
+}
+
+// --------------------------------------------------------------------
+// SetVersionString()
+// VersionString()
+// --------------------------------------------------------------------
+
+static const char* version_string = NULL;
+
+void SetVersionString(const string& version) {
+  if (version_string != NULL)
+    ReportError(DIE, "ERROR: SetVersionString() called twice\n");
+  version_string = strdup(version.c_str());   // small memory leak
+}
+
+const char* VersionString() {
+  return version_string ? version_string : "";
+}
+
+
+// --------------------------------------------------------------------
+// GetCommandLineOption()
+// GetCommandLineFlagInfo()
+// GetCommandLineFlagInfoOrDie()
+// SetCommandLineOption()
+// SetCommandLineOptionWithMode()
+//    The programmatic way to set a flag's value, using a string
+//    for its name rather than the variable itself (that is,
+//    SetCommandLineOption("foo", x) rather than FLAGS_foo = x).
+//    There's also a bit more flexibility here due to the various
+//    set-modes, but typically these are used when you only have
+//    that flag's name as a string, perhaps at runtime.
+//    All of these work on the default, global registry.
+//       For GetCommandLineOption, return false if no such flag
+//    is known, true otherwise.  We clear "value" if a suitable
+//    flag is found.
+// --------------------------------------------------------------------
+
+
+bool GetCommandLineOption(const char* name, string* value) {
+  if (NULL == name)
+    return false;
+  assert(value);
+
+  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+  FlagRegistryLock frl(registry);
+  CommandLineFlag* flag = registry->FindFlagLocked(name);
+  if (flag == NULL) {
+    return false;
+  } else {
+    *value = flag->current_value();
+    return true;
+  }
+}
+
+bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT) {
+  if (NULL == name) return false;
+  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+  FlagRegistryLock frl(registry);
+  CommandLineFlag* flag = registry->FindFlagLocked(name);
+  if (flag == NULL) {
+    return false;
+  } else {
+    assert(OUTPUT);
+    flag->FillCommandLineFlagInfo(OUTPUT);
+    return true;
+  }
+}
+
+CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name) {
+  CommandLineFlagInfo info;
+  if (!GetCommandLineFlagInfo(name, &info)) {
+    fprintf(stderr, "FATAL ERROR: flag name '%s' doesn't exist\n", name);
+    gflags_exitfunc(1);    // almost certainly gflags_exitfunc()
+  }
+  return info;
+}
+
+string SetCommandLineOptionWithMode(const char* name, const char* value,
+                                    FlagSettingMode set_mode) {
+  string result;
+  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+  FlagRegistryLock frl(registry);
+  CommandLineFlag* flag = registry->FindFlagLocked(name);
+  if (flag) {
+    CommandLineFlagParser parser(registry);
+    result = parser.ProcessSingleOptionLocked(flag, value, set_mode);
+    if (!result.empty()) {   // in the error case, we've already logged
+      // Could consider logging this change
+    }
+  }
+  // The API of this function is that we return empty string on error
+  return result;
+}
+
+string SetCommandLineOption(const char* name, const char* value) {
+  return SetCommandLineOptionWithMode(name, value, SET_FLAGS_VALUE);
+}
+
+// --------------------------------------------------------------------
+// FlagSaver
+// FlagSaverImpl
+//    This class stores the states of all flags at construct time,
+//    and restores all flags to that state at destruct time.
+//    Its major implementation challenge is that it never modifies
+//    pointers in the 'main' registry, so global FLAG_* vars always
+//    point to the right place.
+// --------------------------------------------------------------------
+
+class FlagSaverImpl {
+ public:
+  // Constructs an empty FlagSaverImpl object.
+  explicit FlagSaverImpl(FlagRegistry* main_registry)
+      : main_registry_(main_registry) { }
+  ~FlagSaverImpl() {
+    // reclaim memory from each of our CommandLineFlags
+    vector<CommandLineFlag*>::const_iterator it;
+    for (it = backup_registry_.begin(); it != backup_registry_.end(); ++it)
+      delete *it;
+  }
+
+  // Saves the flag states from the flag registry into this object.
+  // It's an error to call this more than once.
+  // Must be called when the registry mutex is not held.
+  void SaveFromRegistry() {
+    FlagRegistryLock frl(main_registry_);
+    assert(backup_registry_.empty());   // call only once!
+    for (FlagRegistry::FlagConstIterator it = main_registry_->flags_.begin();
+         it != main_registry_->flags_.end();
+         ++it) {
+      const CommandLineFlag* main = it->second;
+      // Sets up all the const variables in backup correctly
+      CommandLineFlag* backup = new CommandLineFlag(
+          main->name(), main->help(), main->filename(),
+          main->current_->New(), main->defvalue_->New());
+      // Sets up all the non-const variables in backup correctly
+      backup->CopyFrom(*main);
+      backup_registry_.push_back(backup);   // add it to a convenient list
+    }
+  }
+
+  // Restores the saved flag states into the flag registry.  We
+  // assume no flags were added or deleted from the registry since
+  // the SaveFromRegistry; if they were, that's trouble!  Must be
+  // called when the registry mutex is not held.
+  void RestoreToRegistry() {
+    FlagRegistryLock frl(main_registry_);
+    vector<CommandLineFlag*>::const_iterator it;
+    for (it = backup_registry_.begin(); it != backup_registry_.end(); ++it) {
+      CommandLineFlag* main = main_registry_->FindFlagLocked((*it)->name());
+      if (main != NULL) {       // if NULL, flag got deleted from registry(!)
+        main->CopyFrom(**it);
+      }
+    }
+  }
+
+ private:
+  FlagRegistry* const main_registry_;
+  vector<CommandLineFlag*> backup_registry_;
+
+  FlagSaverImpl(const FlagSaverImpl&);  // no copying!
+  void operator=(const FlagSaverImpl&);
+};
+
+FlagSaver::FlagSaver()
+    : impl_(new FlagSaverImpl(FlagRegistry::GlobalRegistry())) {
+  impl_->SaveFromRegistry();
+}
+
+FlagSaver::~FlagSaver() {
+  impl_->RestoreToRegistry();
+  delete impl_;
+}
+
+
+// --------------------------------------------------------------------
+// CommandlineFlagsIntoString()
+// ReadFlagsFromString()
+// AppendFlagsIntoFile()
+// ReadFromFlagsFile()
+//    These are mostly-deprecated routines that stick the
+//    commandline flags into a file/string and read them back
+//    out again.  I can see a use for CommandlineFlagsIntoString,
+//    for creating a flagfile, but the rest don't seem that useful
+//    -- some, I think, are a poor-man's attempt at FlagSaver --
+//    and are included only until we can delete them from callers.
+//    Note they don't save --flagfile flags (though they do save
+//    the result of having called the flagfile, of course).
+// --------------------------------------------------------------------
+
+static string TheseCommandlineFlagsIntoString(
+    const vector<CommandLineFlagInfo>& flags) {
+  vector<CommandLineFlagInfo>::const_iterator i;
+
+  size_t retval_space = 0;
+  for (i = flags.begin(); i != flags.end(); ++i) {
+    // An (over)estimate of how much space it will take to print this flag
+    retval_space += i->name.length() + i->current_value.length() + 5;
+  }
+
+  string retval;
+  retval.reserve(retval_space);
+  for (i = flags.begin(); i != flags.end(); ++i) {
+    retval += "--";
+    retval += i->name;
+    retval += "=";
+    retval += i->current_value;
+    retval += "\n";
+  }
+  return retval;
+}
+
+string CommandlineFlagsIntoString() {
+  vector<CommandLineFlagInfo> sorted_flags;
+  GetAllFlags(&sorted_flags);
+  return TheseCommandlineFlagsIntoString(sorted_flags);
+}
+
+bool ReadFlagsFromString(const string& flagfilecontents,
+                         const char* /*prog_name*/,  // TODO(csilvers): nix this
+                         bool errors_are_fatal) {
+  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+  FlagSaverImpl saved_states(registry);
+  saved_states.SaveFromRegistry();
+
+  CommandLineFlagParser parser(registry);
+  registry->Lock();
+  parser.ProcessOptionsFromStringLocked(flagfilecontents, SET_FLAGS_VALUE);
+  registry->Unlock();
+  // Should we handle --help and such when reading flags from a string?  Sure.
+  HandleCommandLineHelpFlags();
+  if (parser.ReportErrors()) {
+    // Error.  Restore all global flags to their previous values.
+    if (errors_are_fatal)
+      gflags_exitfunc(1);
+    saved_states.RestoreToRegistry();
+    return false;
+  }
+  return true;
+}
+
+// TODO(csilvers): nix prog_name in favor of ProgramInvocationShortName()
+bool AppendFlagsIntoFile(const string& filename, const char *prog_name) {
+  FILE *fp;
+  if (SafeFOpen(&fp, filename.c_str(), "a") != 0) {
+    return false;
+  }
+
+  if (prog_name)
+    fprintf(fp, "%s\n", prog_name);
+
+  vector<CommandLineFlagInfo> flags;
+  GetAllFlags(&flags);
+  // But we don't want --flagfile, which leads to weird recursion issues
+  vector<CommandLineFlagInfo>::iterator i;
+  for (i = flags.begin(); i != flags.end(); ++i) {
+    if (strcmp(i->name.c_str(), "flagfile") == 0) {
+      flags.erase(i);
+      break;
+    }
+  }
+  fprintf(fp, "%s", TheseCommandlineFlagsIntoString(flags).c_str());
+
+  fclose(fp);
+  return true;
+}
+
+bool ReadFromFlagsFile(const string& filename, const char* prog_name,
+                       bool errors_are_fatal) {
+  return ReadFlagsFromString(ReadFileIntoString(filename.c_str()),
+                             prog_name, errors_are_fatal);
+}
+
+
+// --------------------------------------------------------------------
+// BoolFromEnv()
+// Int32FromEnv()
+// Int64FromEnv()
+// Uint64FromEnv()
+// DoubleFromEnv()
+// StringFromEnv()
+//    Reads the value from the environment and returns it.
+//    We use an FlagValue to make the parsing easy.
+//    Example usage:
+//       DEFINE_bool(myflag, BoolFromEnv("MYFLAG_DEFAULT", false), "whatever");
+// --------------------------------------------------------------------
+
+bool BoolFromEnv(const char *v, bool dflt) {
+  return GetFromEnv(v, "bool", dflt);
+}
+int32 Int32FromEnv(const char *v, int32 dflt) {
+  return GetFromEnv(v, "int32", dflt);
+}
+int64 Int64FromEnv(const char *v, int64 dflt)    {
+  return GetFromEnv(v, "int64", dflt);
+}
+uint64 Uint64FromEnv(const char *v, uint64 dflt) {
+  return GetFromEnv(v, "uint64", dflt);
+}
+double DoubleFromEnv(const char *v, double dflt) {
+  return GetFromEnv(v, "double", dflt);
+}
+
+#ifdef _MSC_VER
+#  pragma warning(push)
+#  pragma warning(disable: 4996) // ignore getenv security warning
+#endif
+const char *StringFromEnv(const char *varname, const char *dflt) {
+  const char* const val = getenv(varname);
+  return val ? val : dflt;
+}
+#ifdef _MSC_VER
+#  pragma warning(pop)
+#endif
+
+
+// --------------------------------------------------------------------
+// RegisterFlagValidator()
+//    RegisterFlagValidator() is the function that clients use to
+//    'decorate' a flag with a validation function.  Once this is
+//    done, every time the flag is set (including when the flag
+//    is parsed from argv), the validator-function is called.
+//       These functions return true if the validator was added
+//    successfully, or false if not: the flag already has a validator,
+//    (only one allowed per flag), the 1st arg isn't a flag, etc.
+//       This function is not thread-safe.
+// --------------------------------------------------------------------
+
+bool RegisterFlagValidator(const bool* flag,
+                           bool (*validate_fn)(const char*, bool)) {
+  return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const int32* flag,
+                           bool (*validate_fn)(const char*, int32)) {
+  return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const int64* flag,
+                           bool (*validate_fn)(const char*, int64)) {
+  return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const uint64* flag,
+                           bool (*validate_fn)(const char*, uint64)) {
+  return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const double* flag,
+                           bool (*validate_fn)(const char*, double)) {
+  return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+bool RegisterFlagValidator(const string* flag,
+                           bool (*validate_fn)(const char*, const string&)) {
+  return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
+}
+
+
+// --------------------------------------------------------------------
+// ParseCommandLineFlags()
+// ParseCommandLineNonHelpFlags()
+// HandleCommandLineHelpFlags()
+//    This is the main function called from main(), to actually
+//    parse the commandline.  It modifies argc and argv as described
+//    at the top of gflags.h.  You can also divide this
+//    function into two parts, if you want to do work between
+//    the parsing of the flags and the printing of any help output.
+// --------------------------------------------------------------------
+
+static uint32 ParseCommandLineFlagsInternal(int* argc, char*** argv,
+                                            bool remove_flags, bool do_report) {
+  SetArgv(*argc, const_cast<const char**>(*argv));    // save it for later
+
+  FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
+  CommandLineFlagParser parser(registry);
+
+  // When we parse the commandline flags, we'll handle --flagfile,
+  // --tryfromenv, etc. as we see them (since flag-evaluation order
+  // may be important).  But sometimes apps set FLAGS_tryfromenv/etc.
+  // manually before calling ParseCommandLineFlags.  We want to evaluate
+  // those too, as if they were the first flags on the commandline.
+  registry->Lock();
+  parser.ProcessFlagfileLocked(FLAGS_flagfile, SET_FLAGS_VALUE);
+  // Last arg here indicates whether flag-not-found is a fatal error or not
+  parser.ProcessFromenvLocked(FLAGS_fromenv, SET_FLAGS_VALUE, true);
+  parser.ProcessFromenvLocked(FLAGS_tryfromenv, SET_FLAGS_VALUE, false);
+  registry->Unlock();
+
+  // Now get the flags specified on the commandline
+  const int r = parser.ParseNewCommandLineFlags(argc, argv, remove_flags);
+
+  if (do_report)
+    HandleCommandLineHelpFlags();   // may cause us to exit on --help, etc.
+
+  // See if any of the unset flags fail their validation checks
+  parser.ValidateAllFlags();
+
+  if (parser.ReportErrors())        // may cause us to exit on illegal flags
+    gflags_exitfunc(1);
+  return r;
+}
+
+uint32 ParseCommandLineFlags(int* argc, char*** argv, bool remove_flags) {
+  return ParseCommandLineFlagsInternal(argc, argv, remove_flags, true);
+}
+
+uint32 ParseCommandLineNonHelpFlags(int* argc, char*** argv,
+                                    bool remove_flags) {
+  return ParseCommandLineFlagsInternal(argc, argv, remove_flags, false);
+}
+
+// --------------------------------------------------------------------
+// AllowCommandLineReparsing()
+// ReparseCommandLineNonHelpFlags()
+//    This is most useful for shared libraries.  The idea is if
+//    a flag is defined in a shared library that is dlopen'ed
+//    sometime after main(), you can ParseCommandLineFlags before
+//    the dlopen, then ReparseCommandLineNonHelpFlags() after the
+//    dlopen, to get the new flags.  But you have to explicitly
+//    Allow() it; otherwise, you get the normal default behavior
+//    of unrecognized flags calling a fatal error.
+// TODO(csilvers): this isn't used.  Just delete it?
+// --------------------------------------------------------------------
+
+void AllowCommandLineReparsing() {
+  allow_command_line_reparsing = true;
+}
+
+void ReparseCommandLineNonHelpFlags() {
+  // We make a copy of argc and argv to pass in
+  const vector<string>& argvs = GetArgvs();
+  int tmp_argc = static_cast<int>(argvs.size());
+  char** tmp_argv = new char* [tmp_argc + 1];
+  for (int i = 0; i < tmp_argc; ++i)
+    tmp_argv[i] = strdup(argvs[i].c_str());   // TODO(csilvers): don't dup
+
+  ParseCommandLineNonHelpFlags(&tmp_argc, &tmp_argv, false);
+
+  for (int i = 0; i < tmp_argc; ++i)
+    free(tmp_argv[i]);
+  delete[] tmp_argv;
+}
+
+void ShutDownCommandLineFlags() {
+  FlagRegistry::DeleteGlobalRegistry();
+}
+
+
+} // namespace GFLAGS_NAMESPACE
