MINIFICPP-1203 - Remove --headers option when running "make linter"

MINIFICPP-1203 - Upgrade linter version to 1.4.4

Originally the linter was sourced from the google style-guide fork which is not very well maintained, this is now replaced with the script shipped by the cpplint/cpplint repository maintainers

MINIFICPP-1203 - Remove build/include suppression from linter checks and fix related errors

MINIFICPP-1203 - Remove build/include suppression from linter, reorder corresponding .cpp files

MINIFICPP-1203 - Remove build/include_what_you_use supression from linter, add missing includes

Signed-off-by: Arpad Boda <aboda@apache.org>
diff --git a/extensions/librdkafka/KafkaConnection.cpp b/extensions/librdkafka/KafkaConnection.cpp
index 449a801..d5342d9 100644
--- a/extensions/librdkafka/KafkaConnection.cpp
+++ b/extensions/librdkafka/KafkaConnection.cpp
@@ -17,6 +17,8 @@
 
 #include "KafkaConnection.h"
 
+#include <memory>
+
 namespace org {
 namespace apache {
 namespace nifi {
diff --git a/extensions/librdkafka/PublishKafka.cpp b/extensions/librdkafka/PublishKafka.cpp
index 66a0937..74eb375 100644
--- a/extensions/librdkafka/PublishKafka.cpp
+++ b/extensions/librdkafka/PublishKafka.cpp
@@ -18,12 +18,15 @@
  * limitations under the License.
  */
 #include "PublishKafka.h"
+
 #include <cstdio>
 #include <algorithm>
 #include <memory>
 #include <string>
 #include <map>
 #include <set>
+#include <vector>
+
 #include "utils/TimeUtil.h"
 #include "utils/StringUtils.h"
 #include "utils/ScopeGuard.h"
diff --git a/extensions/standard-processors/CPPLINT.cfg b/extensions/standard-processors/CPPLINT.cfg
new file mode 100644
index 0000000..0304e10
--- /dev/null
+++ b/extensions/standard-processors/CPPLINT.cfg
@@ -0,0 +1,2 @@
+filter=-build/include_alpha
+
diff --git a/extensions/standard-processors/controllers/UnorderedMapPersistableKeyValueStoreService.cpp b/extensions/standard-processors/controllers/UnorderedMapPersistableKeyValueStoreService.cpp
index b41baf1..fd04d32 100644
--- a/extensions/standard-processors/controllers/UnorderedMapPersistableKeyValueStoreService.cpp
+++ b/extensions/standard-processors/controllers/UnorderedMapPersistableKeyValueStoreService.cpp
@@ -18,6 +18,7 @@
 #include "UnorderedMapPersistableKeyValueStoreService.h"
 
 #include <fstream>
+#include <set>
 
 #include "utils/file/FileUtils.h"
 #include "utils/StringUtils.h"
diff --git a/extensions/standard-processors/processors/ExtractText.cpp b/extensions/standard-processors/processors/ExtractText.cpp
index 669e2ab..439b25d 100644
--- a/extensions/standard-processors/processors/ExtractText.cpp
+++ b/extensions/standard-processors/processors/ExtractText.cpp
@@ -17,9 +17,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <algorithm>
 #include <iterator>
 #include <string>
 #include <memory>
+#include <map>
 #include <set>
 #include <regex>
 
diff --git a/extensions/standard-processors/processors/GenerateFlowFile.cpp b/extensions/standard-processors/processors/GenerateFlowFile.cpp
index 447f4dd..5f53464 100644
--- a/extensions/standard-processors/processors/GenerateFlowFile.cpp
+++ b/extensions/standard-processors/processors/GenerateFlowFile.cpp
@@ -17,17 +17,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include "GenerateFlowFile.h"
+
 #include <time.h>
+
 #include <chrono>
-#include <thread>
-#include <vector>
-#include <queue>
+#include <limits>
 #include <map>
 #include <memory>
-#include <string>
-#include <set>
+#include <queue>
 #include <random>
+#include <set>
+#include <string>
+#include <thread>
+#include <utility>
+#include <vector>
 
 #include "utils/StringUtils.h"
 #include "core/ProcessContext.h"
diff --git a/extensions/standard-processors/processors/HashContent.cpp b/extensions/standard-processors/processors/HashContent.cpp
index 5f85e5c..868ee49 100644
--- a/extensions/standard-processors/processors/HashContent.cpp
+++ b/extensions/standard-processors/processors/HashContent.cpp
@@ -23,7 +23,9 @@
 #include <algorithm>
 #include <iostream>
 #include <memory>
+#include <set>
 #include <string>
+
 #include "HashContent.h"
 #include "core/ProcessContext.h"
 #include "core/ProcessSession.h"
diff --git a/extensions/standard-processors/processors/TailFile.cpp b/extensions/standard-processors/processors/TailFile.cpp
index 84fc92a..6b95867 100644
--- a/extensions/standard-processors/processors/TailFile.cpp
+++ b/extensions/standard-processors/processors/TailFile.cpp
@@ -27,15 +27,19 @@
 #include <dirent.h>
 #include <unistd.h>
 #endif
-#include <vector>
+
+#include <algorithm>
+#include <iostream>
 #include <queue>
 #include <map>
-#include <set>
+#include <unordered_map>
 #include <memory>
-#include <algorithm>
+#include <set>
 #include <sstream>
 #include <string>
-#include <iostream>
+#include <utility>
+#include <vector>
+
 #include "utils/file/FileUtils.h"
 #include "utils/file/PathUtils.h"
 #include "utils/TimeUtil.h"
diff --git a/libminifi/src/CPPLINT.cfg b/libminifi/src/CPPLINT.cfg
index bba5060..edaf4aa 100644
--- a/libminifi/src/CPPLINT.cfg
+++ b/libminifi/src/CPPLINT.cfg
@@ -1,2 +1,2 @@
-filter=-build/include_order,-build/include_alpha
+filter=-build/include_alpha
 exclude_files=ResourceClaim.cpp
diff --git a/libminifi/src/Connection.cpp b/libminifi/src/Connection.cpp
index be0d564..b619bf2 100644
--- a/libminifi/src/Connection.cpp
+++ b/libminifi/src/Connection.cpp
@@ -30,7 +30,6 @@
 #include <iostream>
 #include <list>
 #include "core/FlowFile.h"
-#include "Connection.h"
 #include "core/Processor.h"
 #include "core/logging/LoggerConfiguration.h"
 
diff --git a/libminifi/src/c2/ControllerSocketProtocol.cpp b/libminifi/src/c2/ControllerSocketProtocol.cpp
index f36782f..84d3710 100644
--- a/libminifi/src/c2/ControllerSocketProtocol.cpp
+++ b/libminifi/src/c2/ControllerSocketProtocol.cpp
@@ -17,12 +17,14 @@
  */
 
 #include "c2/ControllerSocketProtocol.h"
-#include "utils/StringUtils.h"
-#include <utility>
-#include <memory>
-#include <vector>
-#include <string>
+
 #include <fstream>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "utils/StringUtils.h"
 
 namespace org {
 namespace apache {
diff --git a/libminifi/src/c2/protocols/RESTProtocol.cpp b/libminifi/src/c2/protocols/RESTProtocol.cpp
index 1cdec27..f08ada2 100644
--- a/libminifi/src/c2/protocols/RESTProtocol.cpp
+++ b/libminifi/src/c2/protocols/RESTProtocol.cpp
@@ -18,14 +18,15 @@
 
 #include "c2/protocols/RESTProtocol.h"
 
-#include "core/TypedValues.h"
 #include <algorithm>
-#include <memory>
-#include <utility>
-#include <map>
-#include <string>
-#include <vector>
 #include <list>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "core/TypedValues.h"
 
 namespace org {
 namespace apache {
diff --git a/libminifi/src/controllers/LinuxPowerManagementService.cpp b/libminifi/src/controllers/LinuxPowerManagementService.cpp
index a42ad41..e8613ef 100644
--- a/libminifi/src/controllers/LinuxPowerManagementService.cpp
+++ b/libminifi/src/controllers/LinuxPowerManagementService.cpp
@@ -16,14 +16,15 @@
  * limitations under the License.
  */
 #include "controllers/LinuxPowerManagementService.h"
-#include "utils/StringUtils.h"
 
 #include <fstream>
-#include <utility>
 #include <limits>
-#include <string>
-#include <vector>
 #include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "utils/StringUtils.h"
 
 namespace org {
 namespace apache {
diff --git a/libminifi/src/controllers/UpdatePolicyControllerService.cpp b/libminifi/src/controllers/UpdatePolicyControllerService.cpp
index fa485b7..01a079e 100644
--- a/libminifi/src/controllers/UpdatePolicyControllerService.cpp
+++ b/libminifi/src/controllers/UpdatePolicyControllerService.cpp
@@ -16,14 +16,17 @@
  * limitations under the License.
  */
 #include "controllers/UpdatePolicyControllerService.h"
-#include <cstdio>
-#include <utility>
-#include <limits>
-#include <string>
-#include <vector>
-#include <string.h>
+
 #include <stdlib.h>
+#include <string.h>
+
+#include <cstdio>
+#include <limits>
 #include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
 #include "utils/StringUtils.h"
 #if ( defined(__APPLE__) || defined(__MACH__) || defined(BSD))
 #include <net/if_dl.h>
diff --git a/libminifi/src/controllers/keyvalue/AbstractCoreComponentStateManagerProvider.cpp b/libminifi/src/controllers/keyvalue/AbstractCoreComponentStateManagerProvider.cpp
index 8d817d5..3a79a44 100644
--- a/libminifi/src/controllers/keyvalue/AbstractCoreComponentStateManagerProvider.cpp
+++ b/libminifi/src/controllers/keyvalue/AbstractCoreComponentStateManagerProvider.cpp
@@ -17,13 +17,13 @@
 
 #include "controllers/keyvalue/AbstractCoreComponentStateManagerProvider.h"
 
+#include <memory>
+
 #include "rapidjson/rapidjson.h"
 #include "rapidjson/document.h"
 #include "rapidjson/stringbuffer.h"
 #include "rapidjson/writer.h"
 
-#include <memory>
-
 namespace org {
 namespace apache {
 namespace nifi {
diff --git a/libminifi/src/core/ProcessSession.cpp b/libminifi/src/core/ProcessSession.cpp
index ca55ce1..a005ec3 100644
--- a/libminifi/src/core/ProcessSession.cpp
+++ b/libminifi/src/core/ProcessSession.cpp
@@ -18,17 +18,20 @@
  * limitations under the License.
  */
 #include "core/ProcessSession.h"
-#include "core/ProcessSessionReadCallback.h"
+
+#include <algorithm>
+#include <chrono>
+#include <cinttypes>
 #include <ctime>
-#include <vector>
+#include <iostream>
 #include <map>
 #include <memory>
-#include <string>
 #include <set>
-#include <chrono>
-#include <iostream>
-#include <cinttypes>
-#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "core/ProcessSessionReadCallback.h"
+
 /* This implementation is only for native Windows systems.  */
 #if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
 #define _WINSOCKAPI_
diff --git a/libminifi/src/core/ProcessSessionReadCallback.cpp b/libminifi/src/core/ProcessSessionReadCallback.cpp
index 65fd26a..32425ae 100644
--- a/libminifi/src/core/ProcessSessionReadCallback.cpp
+++ b/libminifi/src/core/ProcessSessionReadCallback.cpp
@@ -18,11 +18,12 @@
  * limitations under the License.
  */
 #include "core/ProcessSessionReadCallback.h"
-#include "core/logging/LoggerConfiguration.h"
-#include "io/BaseStream.h"
 #include <memory>
 #include <string>
 
+#include "core/logging/LoggerConfiguration.h"
+#include "io/BaseStream.h"
+
 namespace org {
 namespace apache {
 namespace nifi {
diff --git a/libminifi/src/core/Processor.cpp b/libminifi/src/core/Processor.cpp
index 357ca97..eb4b6a7 100644
--- a/libminifi/src/core/Processor.cpp
+++ b/libminifi/src/core/Processor.cpp
@@ -18,25 +18,28 @@
  * limitations under the License.
  */
 #include "core/Processor.h"
+
 #include <time.h>
-#include <vector>
-#include <queue>
-#include <map>
-#include <set>
+
 #include <chrono>
+#include <functional>
+#include <map>
+#include <memory>
+#include <queue>
+#include <set>
 #include <string>
 #include <thread>
-#include <memory>
-#include <functional>
 #include <utility>
+#include <vector>
+
 #include "Connection.h"
-#include "core/ProcessorConfig.h"
 #include "core/Connectable.h"
+#include "core/logging/LoggerConfiguration.h"
+#include "core/ProcessorConfig.h"
 #include "core/ProcessContext.h"
 #include "core/ProcessSession.h"
 #include "core/ProcessSessionFactory.h"
 #include "io/StreamFactory.h"
-#include "core/logging/LoggerConfiguration.h"
 
 namespace org {
 namespace apache {
diff --git a/libminifi/src/core/logging/WindowsEventLogSink.cpp b/libminifi/src/core/logging/WindowsEventLogSink.cpp
index d2a0058..76391e6 100644
--- a/libminifi/src/core/logging/WindowsEventLogSink.cpp
+++ b/libminifi/src/core/logging/WindowsEventLogSink.cpp
@@ -18,17 +18,15 @@
 
 #ifdef WIN32
 
-#include "core/logging/WindowsEventLogsink.h"
-
-#include "core/logging/WindowsMessageTextFile.h"
-#include "Exception.h"
-
-#include "spdlog/common.h"
-#include "spdlog/sinks/sink.h"
-#include "spdlog/details/log_msg.h"
+#include "core/logging/WindowsEventLogSink.h"
 
 #include <string>
 
+#include "core/logging/WindowsMessageTextFile.h"
+#include "Exception.h"
+#include "spdlog/common.h"
+#include "spdlog/sinks/sink.h"
+#include "spdlog/details/log_msg.h"
 
 namespace org {
 namespace apache {
diff --git a/libminifi/src/core/repository/VolatileContentRepository.cpp b/libminifi/src/core/repository/VolatileContentRepository.cpp
index 9b5f9be..5ceb139 100644
--- a/libminifi/src/core/repository/VolatileContentRepository.cpp
+++ b/libminifi/src/core/repository/VolatileContentRepository.cpp
@@ -17,13 +17,15 @@
  */
 
 #include "core/repository/VolatileContentRepository.h"
-#include "core/expect.h"
+
 #include <cstdio>
-#include <string>
 #include <memory>
+#include <string>
 #include <thread>
-#include "utils/StringUtils.h"
+
+#include "core/expect.h"
 #include "io/FileStream.h"
+#include "utils/StringUtils.h"
 
 namespace org {
 namespace apache {
diff --git a/libminifi/src/io/CPPLINT.cfg b/libminifi/src/io/CPPLINT.cfg
index 48cd471..fb51e29 100644
--- a/libminifi/src/io/CPPLINT.cfg
+++ b/libminifi/src/io/CPPLINT.cfg
@@ -1,3 +1,3 @@
 set noparent
-filter=-build/include_order,-build/include_alpha
+filter=-build/include_alpha,-build/c++11
 exclude_files=ClientSocket\.cpp
diff --git a/libminifi/src/io/StreamFactory.cpp b/libminifi/src/io/StreamFactory.cpp
index 457c6d3..35f400e 100644
--- a/libminifi/src/io/StreamFactory.cpp
+++ b/libminifi/src/io/StreamFactory.cpp
@@ -16,12 +16,13 @@
  * limitations under the License.
  */
 #include "io/StreamFactory.h"
+
 #include <atomic>
 #include <memory>
 #include <mutex>
 #include <string>
-#include <utils/GeneralUtils.h>
 
+#include <utils/GeneralUtils.h> // NOLINT
 #ifdef OPENSSL_SUPPORT
 #include "io/tls/TLSSocket.h"
 #endif
diff --git a/libminifi/src/io/tls/TLSServerSocket.cpp b/libminifi/src/io/tls/TLSServerSocket.cpp
index 891d1b2..6b83d4e 100644
--- a/libminifi/src/io/tls/TLSServerSocket.cpp
+++ b/libminifi/src/io/tls/TLSServerSocket.cpp
@@ -15,16 +15,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "io/tls/SecureDescriptorStream.h"
 #include "io/tls/TLSServerSocket.h"
 
 #include <sys/types.h>
+
 #ifndef WIN32
-#include <netinet/tcp.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
 #include <arpa/inet.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/socket.h>
 #include <unistd.h>
 #else
 #pragma comment(lib, "Ws2_32.lib")
@@ -40,8 +40,10 @@
 #include <iostream>
 #include <algorithm>
 #include <string>
-#include "io/validation.h"
+
 #include "core/logging/LoggerConfiguration.h"
+#include "io/tls/SecureDescriptorStream.h"
+#include "io/validation.h"
 
 namespace org {
 namespace apache {
diff --git a/libminifi/src/io/tls/TLSUtils.cpp b/libminifi/src/io/tls/TLSUtils.cpp
index b709d2c..f4677b3 100644
--- a/libminifi/src/io/tls/TLSUtils.cpp
+++ b/libminifi/src/io/tls/TLSUtils.cpp
@@ -16,9 +16,11 @@
  * limitations under the License.
  */
 #include "io/tls/TLSUtils.h"
-#include "utils/StringUtils.h"
-#include <string>
+
 #include <cstring>
+#include <string>
+
+#include "utils/StringUtils.h"
 
 namespace org {
 namespace apache {
diff --git a/libminifi/src/utils/BackTrace.cpp b/libminifi/src/utils/BackTrace.cpp
index fba8d9a..8fa8415 100644
--- a/libminifi/src/utils/BackTrace.cpp
+++ b/libminifi/src/utils/BackTrace.cpp
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 #include "utils/BackTrace.h"
+
 #ifdef HAS_EXECINFO
+#include <cxxabi.h>
 #include <execinfo.h>
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
@@ -23,10 +25,9 @@
 #ifdef __linux__
 #include <link.h>
 #endif
+#include <cstring>
 #include <iostream>
 #include <utility>
-#include <cstring>
-#include <cxxabi.h>
 #endif
 
 #ifdef HAS_EXECINFO
diff --git a/libminifi/src/utils/ClassUtils.cpp b/libminifi/src/utils/ClassUtils.cpp
index 9ef2c0d..21ba0b2 100644
--- a/libminifi/src/utils/ClassUtils.cpp
+++ b/libminifi/src/utils/ClassUtils.cpp
@@ -17,9 +17,12 @@
  */
 
 #include "utils/ClassUtils.h"
-#include "utils/StringUtils.h"
+
 #include <iostream>
 #include <string>
+
+#include "utils/StringUtils.h"
+
 namespace org {
 namespace apache {
 namespace nifi {
diff --git a/libminifi/src/utils/Environment.cpp b/libminifi/src/utils/Environment.cpp
index de72dea..284f016 100644
--- a/libminifi/src/utils/Environment.cpp
+++ b/libminifi/src/utils/Environment.cpp
@@ -20,9 +20,9 @@
 #ifdef WIN32
 #include <Windows.h>
 #else
+#include <unistd.h>
 #include <cstdlib>
 #include <cerrno>
-#include <unistd.h>
 #endif
 #include <mutex>
 #include <vector>
diff --git a/libminifi/src/utils/OsUtils.cpp b/libminifi/src/utils/OsUtils.cpp
index f1cc21e..40652e1 100644
--- a/libminifi/src/utils/OsUtils.cpp
+++ b/libminifi/src/utils/OsUtils.cpp
@@ -28,12 +28,14 @@
 #include <sddl.h>
 #pragma comment(lib, "Ws2_32.lib")
 #else
-#include <mutex>
-#include <pwd.h>
-#include <netdb.h>
 #include <arpa/inet.h>
+#include <netdb.h>
+#include <pwd.h>
 #include <sys/types.h>
+
+#include <mutex>
 #endif
+
 namespace org {
 namespace apache {
 namespace nifi {
diff --git a/libminifi/src/utils/file/PathUtils.cpp b/libminifi/src/utils/file/PathUtils.cpp
index 6fa95be..a960a3a 100644
--- a/libminifi/src/utils/file/PathUtils.cpp
+++ b/libminifi/src/utils/file/PathUtils.cpp
@@ -17,9 +17,7 @@
  */
 
 #include "utils/file/PathUtils.h"
-#include "utils/file/FileUtils.h"
 
-#include <iostream>
 #ifdef WIN32
 #include <Windows.h>
 #else
@@ -27,6 +25,9 @@
 #include <stdlib.h>
 #endif
 
+#include <iostream>
+#include "utils/file/FileUtils.h"
+
 namespace org {
 namespace apache {
 namespace nifi {
diff --git a/libminifi/test/CPPLINT.cfg b/libminifi/test/CPPLINT.cfg
index 3455f0f..683d094 100644
--- a/libminifi/test/CPPLINT.cfg
+++ b/libminifi/test/CPPLINT.cfg
@@ -1,4 +1,4 @@
-filter=-build/include_order,-build/include_alpha,-build/namespaces
+filter=-build/include_alpha,-build/namespaces
 exclude_files=Server.cpp
 exclude_files=TestBase.cpp
 exclude_files=RandomServerSocket.cpp
diff --git a/libminifi/test/KamikazeProcessor.cpp b/libminifi/test/KamikazeProcessor.cpp
index f4db90e..98c7ea2 100644
--- a/libminifi/test/KamikazeProcessor.cpp
+++ b/libminifi/test/KamikazeProcessor.cpp
@@ -18,6 +18,8 @@
  * limitations under the License.
  */
 
+#include <string>
+
 #include "KamikazeProcessor.h"
 #include "Exception.h"
 
diff --git a/libminifi/test/archive-tests/FocusArchiveTests.cpp b/libminifi/test/archive-tests/FocusArchiveTests.cpp
index 4e4e045..e30d2b9 100644
--- a/libminifi/test/archive-tests/FocusArchiveTests.cpp
+++ b/libminifi/test/archive-tests/FocusArchiveTests.cpp
@@ -16,24 +16,23 @@
  * limitations under the License.
  */
 
+#include <algorithm>
 #include <iostream>
 #include <map>
+#include <memory>
 #include <set>
 #include <string>
-#include <algorithm>
-#include <memory>
 #include <utility>
 
-#include "../TestBase.h"
+#include <archive.h> // NOLINT
+#include <archive_entry.h> // NOLINT
 #include "ArchiveTests.h"
-#include "processors/GetFile.h"
-#include "processors/PutFile.h"
-#include "processors/LogAttribute.h"
 #include "FocusArchiveEntry.h"
+#include "processors/GetFile.h"
+#include "processors/LogAttribute.h"
+#include "processors/PutFile.h"
 #include "UnfocusArchiveEntry.h"
-
-#include <archive.h>
-#include <archive_entry.h>
+#include "../TestBase.h"
 
 const char TEST_ARCHIVE_NAME[] = "focus_test_archive.tar";
 const int NUM_FILES = 2;
diff --git a/libminifi/test/archive-tests/MergeFileTests.cpp b/libminifi/test/archive-tests/MergeFileTests.cpp
index b3f672a..cced217 100644
--- a/libminifi/test/archive-tests/MergeFileTests.cpp
+++ b/libminifi/test/archive-tests/MergeFileTests.cpp
@@ -17,24 +17,25 @@
  */
 
 #include <fstream>
+#include <iostream>
 #include <map>
 #include <memory>
 #include <utility>
-#include <string>
 #include <set>
-#include "FlowController.h"
-#include "../TestBase.h"
+#include <sstream>
+#include <string>
+
 #include "core/Core.h"
-#include "../../include/core/FlowFile.h"
-#include "../unit/ProvenanceTestHelper.h"
 #include "core/Processor.h"
 #include "core/ProcessContext.h"
-#include "core/ProcessSession.h"
 #include "core/ProcessorNode.h"
+#include "core/ProcessSession.h"
+#include "FlowController.h"
+#include "../../include/core/FlowFile.h"
 #include "MergeContent.h"
-#include <sstream>
-#include <iostream>
 #include "processors/LogAttribute.h"
+#include "../TestBase.h"
+#include "../unit/ProvenanceTestHelper.h"
 
 static const char* FLOW_FILE = "/tmp/minifi-mergecontent";
 static const char* EXPECT_MERGE_CONTENT_FIRST = "/tmp/minifi-expect-mergecontent1.txt";
diff --git a/libminifi/test/archive-tests/util/ArchiveTests.cpp b/libminifi/test/archive-tests/util/ArchiveTests.cpp
index 6a5d475..d3080c8 100644
--- a/libminifi/test/archive-tests/util/ArchiveTests.cpp
+++ b/libminifi/test/archive-tests/util/ArchiveTests.cpp
@@ -18,13 +18,15 @@
  * limitations under the License.
  */
 #include "ArchiveTests.h"
-#include <set>
+
 #include <algorithm>
+#include <set>
 #include <string>
 #include <utility>
 
-#include <archive.h>
-#include <archive_entry.h>
+#include <archive.h> // NOLINT
+#include <archive_entry.h> // NOLINT
+
 #include "../../TestBase.h"
 
 TAE_MAP_T build_test_archive_map(int NUM_FILES, const char** FILE_NAMES, const char** FILE_CONTENT) {
diff --git a/libminifi/test/gps-tests/GPSTests.cpp b/libminifi/test/gps-tests/GPSTests.cpp
index e308f83..c067134 100644
--- a/libminifi/test/gps-tests/GPSTests.cpp
+++ b/libminifi/test/gps-tests/GPSTests.cpp
@@ -17,24 +17,26 @@
  */
 
 #define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
+
 #include <fstream>
+#include <iostream>
 #include <map>
 #include <memory>
-#include <utility>
-#include <string>
 #include <set>
-#include "FlowController.h"
-#include "../TestBase.h"
+#include <string>
+#include <utility>
+
 #include "core/Core.h"
 #include "core/FlowFile.h"
-#include "processors/GetFile.h"
-#include "../unit/ProvenanceTestHelper.h"
 #include "core/Processor.h"
 #include "core/ProcessContext.h"
-#include "core/ProcessSession.h"
 #include "core/ProcessorNode.h"
-#include <iostream>
+#include "core/ProcessSession.h"
+#include "FlowController.h"
 #include "GetGPS.h"
+#include "processors/GetFile.h"
+#include "../TestBase.h"
+#include "../unit/ProvenanceTestHelper.h"
 
 
 TEST_CASE("GPSD Create", "[gpsdtest1]") {
diff --git a/libminifi/test/keyvalue-tests/PersistableKeyValueStoreServiceTest.cpp b/libminifi/test/keyvalue-tests/PersistableKeyValueStoreServiceTest.cpp
index a30de53..6f8cd7b 100644
--- a/libminifi/test/keyvalue-tests/PersistableKeyValueStoreServiceTest.cpp
+++ b/libminifi/test/keyvalue-tests/PersistableKeyValueStoreServiceTest.cpp
@@ -17,13 +17,14 @@
  */
 
 #define CATCH_CONFIG_RUNNER
-#include "catch.hpp"
-
 #include <vector>
 #include <memory>
 #include <utility>
 #include <string>
 #include <array>
+
+#include "catch.hpp"
+
 #include "../TestBase.h"
 #include "../../controller/Controller.h"
 #include "core/controller/ControllerService.h"
diff --git a/libminifi/test/nodefs/NoRocksDB.cpp b/libminifi/test/nodefs/NoRocksDB.cpp
index 472334f..7990ce0 100644
--- a/libminifi/test/nodefs/NoRocksDB.cpp
+++ b/libminifi/test/nodefs/NoRocksDB.cpp
@@ -16,10 +16,11 @@
  * limitations under the License.
  */
 
-#include "../TestBase.h"
 #include <memory>
+
 #include "core/Core.h"
 #include "core/RepositoryFactory.h"
+#include "../TestBase.h"
 
 TEST_CASE("NoRocksDBTest1", "[NoRocksDBTest]") {
   std::shared_ptr<core::Repository> prov_repo = core::createRepository("provenancerepository", true);
diff --git a/libminifi/test/nodefs/NoYamlConfiguration.cpp b/libminifi/test/nodefs/NoYamlConfiguration.cpp
index 9a979a3..a7cabc2 100644
--- a/libminifi/test/nodefs/NoYamlConfiguration.cpp
+++ b/libminifi/test/nodefs/NoYamlConfiguration.cpp
@@ -16,11 +16,11 @@
  * limitations under the License.
  */
 
-#include "core/Core.h"
 #include <memory>
-#include "core/RepositoryFactory.h"
 
 #include "core/ConfigurationFactory.h"
+#include "core/Core.h"
+#include "core/RepositoryFactory.h"
 
 TEST_CASE("NoYamlSupport1", "[NoYamlSupport1]") {
   std::shared_ptr<core::Repository> prov_repo = core::createRepository(
diff --git a/libminifi/test/rocksdb-tests/DBContentRepositoryTests.cpp b/libminifi/test/rocksdb-tests/DBContentRepositoryTests.cpp
index 32d4f09..89d9bca 100644
--- a/libminifi/test/rocksdb-tests/DBContentRepositoryTests.cpp
+++ b/libminifi/test/rocksdb-tests/DBContentRepositoryTests.cpp
@@ -15,15 +15,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "../TestBase.h"
+
 #include <memory>
 #include <string>
-#include "../unit/ProvenanceTestHelper.h"
-#include "provenance/Provenance.h"
-#include "FlowFileRecord.h"
+
 #include "core/Core.h"
 #include "DatabaseContentRepository.h"
+#include "FlowFileRecord.h"
 #include "properties/Configure.h"
+#include "provenance/Provenance.h"
+#include "../TestBase.h"
+#include "../unit/ProvenanceTestHelper.h"
 
 TEST_CASE("Write Claim", "[TestDBCR1]") {
   TestController testController;
diff --git a/libminifi/test/rocksdb-tests/DBProvenanceRepositoryTests.cpp b/libminifi/test/rocksdb-tests/DBProvenanceRepositoryTests.cpp
index 35a4834..66b1604 100644
--- a/libminifi/test/rocksdb-tests/DBProvenanceRepositoryTests.cpp
+++ b/libminifi/test/rocksdb-tests/DBProvenanceRepositoryTests.cpp
@@ -16,12 +16,13 @@
  * limitations under the License.
  */
 
-#include "ProvenanceRepository.h"
-#include "../TestBase.h"
 #include <array>
 #include <chrono>
-#include <vector>
 #include <random>
+#include <vector>
+
+#include "ProvenanceRepository.h"
+#include "../TestBase.h"
 
 #define TEST_PROVENANCE_STORAGE_SIZE (1024*100)  // 100 KB
 #define TEST_MAX_PROVENANCE_STORAGE_SIZE (100*1024*1024)  // 100 MB
diff --git a/libminifi/test/rocksdb-tests/ProvenanceTests.cpp b/libminifi/test/rocksdb-tests/ProvenanceTests.cpp
index a40c6ca..b92d983 100644
--- a/libminifi/test/rocksdb-tests/ProvenanceTests.cpp
+++ b/libminifi/test/rocksdb-tests/ProvenanceTests.cpp
@@ -16,18 +16,19 @@
  * limitations under the License.
  */
 
-#include "../TestBase.h"
-#include <utility>
-#include <memory>
-#include <string>
 #include <map>
-#include "../unit/ProvenanceTestHelper.h"
-#include "provenance/Provenance.h"
-#include "FlowFileRecord.h"
+#include <memory>
+#include <utility>
+#include <string>
+
 #include "core/Core.h"
 #include "core/repository/AtomicRepoEntries.h"
-#include "FlowFileRepository.h"
 #include "core/repository/VolatileProvenanceRepository.h"
+#include "FlowFileRecord.h"
+#include "FlowFileRepository.h"
+#include "provenance/Provenance.h"
+#include "../unit/ProvenanceTestHelper.h"
+#include "../TestBase.h"
 
 TEST_CASE("Test Provenance record create", "[Testprovenance::ProvenanceEventRecord]") {
   provenance::ProvenanceEventRecord record1(provenance::ProvenanceEventRecord::ProvenanceEventType::CREATE, "blah", "blahblah");
diff --git a/libminifi/test/rocksdb-tests/RepoTests.cpp b/libminifi/test/rocksdb-tests/RepoTests.cpp
index a3cb3ee..34e0a39 100644
--- a/libminifi/test/rocksdb-tests/RepoTests.cpp
+++ b/libminifi/test/rocksdb-tests/RepoTests.cpp
@@ -15,20 +15,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "../TestBase.h"
+
+#include <chrono>
+#include <map>
 #include <memory>
 #include <string>
-#include <chrono>
 #include <thread>
-#include <map>
-#include "../unit/ProvenanceTestHelper.h"
-#include "provenance/Provenance.h"
-#include "FlowFileRecord.h"
+
 #include "core/Core.h"
-#include "FlowFileRepository.h"
 #include "core/repository/AtomicRepoEntries.h"
 #include "core/RepositoryFactory.h"
+#include "FlowFileRecord.h"
+#include "FlowFileRepository.h"
+#include "provenance/Provenance.h"
 #include "properties/Configure.h"
+#include "../unit/ProvenanceTestHelper.h"
+#include "../TestBase.h"
 
 TEST_CASE("Test Repo Names", "[TestFFR1]") {
   auto repoA = minifi::core::createRepository("FlowFileRepository", false, "flowfile");
diff --git a/libminifi/test/tensorflow-tests/TensorFlowTests.cpp b/libminifi/test/tensorflow-tests/TensorFlowTests.cpp
index 4bca07a..0d0b6a3 100644
--- a/libminifi/test/tensorflow-tests/TensorFlowTests.cpp
+++ b/libminifi/test/tensorflow-tests/TensorFlowTests.cpp
@@ -19,14 +19,14 @@
 #include <memory>
 #include <string>
 
-#include <tensorflow/cc/framework/scope.h>
-#include <tensorflow/cc/ops/standard_ops.h>
-#include <processors/PutFile.h>
-#include <processors/GetFile.h>
-#include <processors/LogAttribute.h>
+#include <processors/GetFile.h> // NOLINT
+#include <processors/LogAttribute.h> // NOLINT
+#include <processors/PutFile.h> // NOLINT
+#include <tensorflow/cc/framework/scope.h> // NOLINT
+#include <tensorflow/cc/ops/standard_ops.h> // NOLINT
+#include "TFApplyGraph.h"
 #include <TFConvertImageToTensor.h>
 #include <TFExtractTopLabels.h>
-#include "TFApplyGraph.h"
 
 #define CATCH_CONFIG_MAIN
 
diff --git a/libminifi/test/unit/EnvironmentUtilsTests.cpp b/libminifi/test/unit/EnvironmentUtilsTests.cpp
index fda9a90..5700a8e 100644
--- a/libminifi/test/unit/EnvironmentUtilsTests.cpp
+++ b/libminifi/test/unit/EnvironmentUtilsTests.cpp
@@ -16,16 +16,16 @@
  * limitations under the License.
  */
 
-#include "../TestBase.h"
-#include "utils/Environment.h"
-#include "utils/file/PathUtils.h"
-
-#include <thread>
+#include <cstdint>
 #include <random>
 #include <string>
-#include <cstdint>
+#include <thread>
 #include <vector>
 
+#include "utils/Environment.h"
+#include "utils/file/PathUtils.h"
+#include "../TestBase.h"
+
 TEST_CASE("getenv already existing", "[getenv]") {
   auto res = utils::Environment::getEnvironmentVariable("PATH");
   REQUIRE(true == res.first);
diff --git a/libminifi/test/unit/FileStreamTests.cpp b/libminifi/test/unit/FileStreamTests.cpp
index 86be792..5c1c2dc 100644
--- a/libminifi/test/unit/FileStreamTests.cpp
+++ b/libminifi/test/unit/FileStreamTests.cpp
@@ -15,10 +15,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "io/FileStream.h"
+#include <iostream>
 #include <string>
 #include <vector>
-#include <iostream>
+
+#include "io/FileStream.h"
 #include "../TestBase.h"
 
 TEST_CASE("TestFileOverWrite", "[TestFiles]") {
diff --git a/libminifi/test/unit/PropertyTests.cpp b/libminifi/test/unit/PropertyTests.cpp
index dfdd071..7a22fd7 100644
--- a/libminifi/test/unit/PropertyTests.cpp
+++ b/libminifi/test/unit/PropertyTests.cpp
@@ -15,10 +15,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include "../../include/core/Property.h"
+
 #include <string>
-#include "utils/StringUtils.h"
+
 #include "core/Property.h"
+#include "../../include/core/Property.h"
+#include "utils/StringUtils.h"
 #include "../TestBase.h"
 
 TEST_CASE("Test Boolean Conversion", "[testboolConversion]") {
diff --git a/libminifi/test/unit/RegexUtilsTests.cpp b/libminifi/test/unit/RegexUtilsTests.cpp
index fff615b..c0d8cfc 100644
--- a/libminifi/test/unit/RegexUtilsTests.cpp
+++ b/libminifi/test/unit/RegexUtilsTests.cpp
@@ -16,12 +16,13 @@
  * limitations under the License.
  */
 
-#include "../TestBase.h"
-#include "utils/RegexUtils.h"
-#include "Exception.h"
 #include <string>
 #include <vector>
 
+#include "Exception.h"
+#include "utils/RegexUtils.h"
+#include "../TestBase.h"
+
 using org::apache::nifi::minifi::utils::Regex;
 using org::apache::nifi::minifi::Exception;
 
diff --git a/libminifi/test/unit/SerializationTests.cpp b/libminifi/test/unit/SerializationTests.cpp
index 50831ae..7749087 100644
--- a/libminifi/test/unit/SerializationTests.cpp
+++ b/libminifi/test/unit/SerializationTests.cpp
@@ -15,14 +15,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <algorithm>
+#include <memory>
+#include <string>
+
 #include "io/BaseStream.h"
 #include "SiteToSiteHelper.h"
-#include <algorithm>
-#include <string>
-#include <memory>
-
 #include "../TestBase.h"
 #include "../unit/SiteToSiteHelper.h"
+
 #define FMT_DEFAULT fmt_lower
 
 TEST_CASE("TestWriteUTF", "[MINIFI193]") {
diff --git a/libminifi/test/unit/Site2SiteTests.cpp b/libminifi/test/unit/Site2SiteTests.cpp
index 6e8d6ae..4862b33 100644
--- a/libminifi/test/unit/Site2SiteTests.cpp
+++ b/libminifi/test/unit/Site2SiteTests.cpp
@@ -16,14 +16,15 @@
  * limitations under the License.
  */
 
-#include <string>
-#include <memory>
-#include <utility>
+#include <algorithm>
 #include <map>
+#include <memory>
+#include <string>
+#include <utility>
+
 #include "io/BaseStream.h"
 #include "sitetosite/Peer.h"
 #include "sitetosite/RawSocketProtocol.h"
-#include <algorithm>
 #include "../TestBase.h"
 #include "../unit/SiteToSiteHelper.h"
 
diff --git a/thirdparty/google-styleguide/cpplint.py b/thirdparty/google-styleguide/cpplint.py
index c9215a7..25ca8e5 100644
--- a/thirdparty/google-styleguide/cpplint.py
+++ b/thirdparty/google-styleguide/cpplint.py
@@ -52,46 +52,38 @@
 import sre_compile
 import string
 import sys
+import sysconfig
 import unicodedata
 import xml.etree.ElementTree
 
 # if empty, use defaults
-_header_extensions = set([])
-
-# if empty, use defaults
 _valid_extensions = set([])
 
+__VERSION__ = '1.4.4'
 
-# Files with any of these extensions are considered to be
-# header files (and will undergo different style checks).
-# This set can be extended by using the --headers
-# option (also supported in CPPLINT.cfg)
-def GetHeaderExtensions():
-  if not _header_extensions:
-    return set(['h', 'hpp', 'hxx', 'h++', 'cuh'])
-  return _header_extensions
-
-# The allowed extensions for file names
-# This is set by --extensions flag
-def GetAllExtensions():
-  if not _valid_extensions:
-    return GetHeaderExtensions().union(set(['c', 'cc', 'cpp', 'cxx', 'c++', 'cu']))
-  return _valid_extensions
-
-def GetNonHeaderExtensions():
-  return GetAllExtensions().difference(GetHeaderExtensions())
+try:
+  xrange          # Python 2
+except NameError:
+  #  -- pylint: disable=redefined-builtin
+  xrange = range  # Python 3
 
 
 _USAGE = """
 Syntax: cpplint.py [--verbose=#] [--output=emacs|eclipse|vs7|junit]
                    [--filter=-x,+y,...]
-                   [--counting=total|toplevel|detailed] [--repository=path]
-                   [--root=subdir] [--linelength=digits] [--recursive]
+                   [--counting=total|toplevel|detailed] [--root=subdir]
+                   [--repository=path]
+                   [--linelength=digits] [--headers=x,y,...]
+                   [--recursive]
                    [--exclude=path]
-                   [--headers=ext1,ext2]
                    [--extensions=hpp,cpp,...]
+                   [--quiet]
+                   [--version]
         <file> [file] ...
 
+  Style checker for C/C++ source files.
+  This is a fork of the Google style checker with minor extensions.
+
   The style guidelines this tries to follow are those in
     https://google.github.io/styleguide/cppguide.html
 
@@ -111,10 +103,10 @@
   Flags:
 
     output=emacs|eclipse|vs7|junit
-      By default, the output is formatted to ease emacs parsing.  Output
-      compatible with eclipse (eclipse), Visual Studio (vs7), and JUnit
-      XML parsers such as those used in Jenkins and Bamboo may also be
-      used.  Other formats are unsupported.
+      By default, the output is formatted to ease emacs parsing.  Visual Studio
+      compatible output (vs7) may also be used.  Further support exists for
+      eclipse (eclipse), and JUnit (junit). XML parsers such as those used
+      in Jenkins and Bamboo may also be used.  Other formats are unsupported.
 
     verbose=#
       Specify a number 0-5 to restrict errors to certain verbosity levels.
@@ -122,8 +114,7 @@
       likely to be false positives.
 
     quiet
-      Supress output other than linting errors, such as information about
-      which files have been processed and excluded.
+      Don't print anything if no errors are found.
 
     filter=-x,+y,...
       Specify a comma-separated list of category-filters to apply: only
@@ -172,19 +163,21 @@
         Bob   => SRC_CHROME_BROWSER_UI_BROWSER_H_
 
     root=subdir
-      The root directory used for deriving header guard CPP variables. This
-      directory is relative to the top level directory of the repository which
-      by default is determined by searching for a directory that contains .git,
-      .hg, or .svn but can also be controlled with the --repository flag. If
-      the specified directory does not exist, this flag is ignored.
+      The root directory used for deriving header guard CPP variable.
+      This directory is relative to the top level directory of the repository
+      which by default is determined by searching for a directory that contains
+      .git, .hg, or .svn but can also be controlled with the --repository flag.
+      If the specified directory does not exist, this flag is ignored.
 
       Examples:
-        Assuming that src is the top level directory of the repository, the
-        header guard CPP variables for src/chrome/browser/ui/browser.h are:
+        Assuming that src is the top level directory of the repository (and
+        cwd=top/src), the header guard CPP variables for
+        src/chrome/browser/ui/browser.h are:
 
         No flag => CHROME_BROWSER_UI_BROWSER_H_
         --root=chrome => BROWSER_UI_BROWSER_H_
         --root=chrome/browser => UI_BROWSER_H_
+        --root=.. => SRC_CHROME_BROWSER_UI_BROWSER_H_
 
     linelength=digits
       This is the allowed line length for the project. The default value is
@@ -216,13 +209,15 @@
       Examples:
         --extensions=%s
 
-    headers=extension,extension,...
-      The allowed header extensions that cpplint will consider to be header files
-      (by default, only files with extensions %s
-      will be assumed to be headers)
+    headers=x,y,...
+      The header extensions that cpplint will treat as .h in checks. Values are
+      automatically added to --extensions list.
+     (by default, only files with extensions %s will be assumed to be headers)
 
       Examples:
         --headers=%s
+        --headers=hpp,hxx
+        --headers=hpp
 
     cpplint.py supports per-directory configurations specified in CPPLINT.cfg
     files. CPPLINT.cfg file can contain a number of key=value pairs.
@@ -233,6 +228,7 @@
       exclude_files=regex
       linelength=80
       root=subdir
+      headers=x,y,...
 
     "set noparent" option prevents cpplint from traversing directory tree
     upwards looking for more .cfg files in parent directories. This option
@@ -246,13 +242,16 @@
     a file name. If the expression matches, the file is skipped and not run
     through the linter.
 
-    "linelength" specifies the allowed line length for the project.
+    "linelength" allows to specify the allowed line length for the project.
 
     The "root" option is similar in function to the --root flag (see example
-    above).
+    above). Paths are relative to the directory of the CPPLINT.cfg.
+
+    The "headers" option is similar in function to the --headers flag
+    (see example above).
 
     CPPLINT.cfg has an effect on files in the same directory and all
-    subdirectories, unless overridden by a nested configuration file.
+    sub-directories, unless overridden by a nested configuration file.
 
       Example file:
         filter=-build/include_order,+build/include_alpha
@@ -261,11 +260,8 @@
     The above example disables build/include_order warning and enables
     build/include_alpha as well as excludes all .cc from being
     processed by linter, in the current directory (where the .cfg
-    file is located) and all subdirectories.
-""" % (list(GetAllExtensions()),
-       ','.join(list(GetAllExtensions())),
-       GetHeaderExtensions(),
-       ','.join(GetHeaderExtensions()))
+    file is located) and all sub-directories.
+"""
 
 # We categorize each error message we print.  Here are the categories.
 # We want an explicit list so we can list them all in cpplint --filter=.
@@ -428,6 +424,7 @@
     'array',
     'atomic',
     'bitset',
+    'chrono',
     'codecvt',
     'complex',
     'condition_variable',
@@ -466,6 +463,7 @@
     'string',
     'strstream',
     'system_error',
+    'thread',
     'tuple',
     'typeindex',
     'typeinfo',
@@ -475,6 +473,18 @@
     'utility',
     'valarray',
     'vector',
+    # 17.6.1.2 C++14 headers
+    'shared_mutex',
+    # 17.6.1.2 C++17 headers
+    'any',
+    'charconv',
+    'codecvt',
+    'execution',
+    'filesystem',
+    'memory_resource',
+    'optional',
+    'string_view',
+    'variant',
     # 17.6.1.2 C++ headers for C library facilities
     'cassert',
     'ccomplex',
@@ -621,6 +631,7 @@
 # The root directory used for deriving header guard CPP variable.
 # This is set by --root flag.
 _root = None
+_root_debug = False
 
 # The top level repository directory. If set, _root is calculated relative to
 # this directory instead of the directory containing version control artifacts.
@@ -638,19 +649,13 @@
 _line_length = 80
 
 try:
-  xrange(1, 0)
-except NameError:
-  #  -- pylint: disable=redefined-builtin
-  xrange = range
-
-try:
   unicode
 except NameError:
   #  -- pylint: disable=redefined-builtin
   basestring = unicode = str
 
 try:
-  long(2)
+  long
 except NameError:
   #  -- pylint: disable=redefined-builtin
   long = int
@@ -671,12 +676,49 @@
   else:
     return x
 
+# Treat all headers starting with 'h' equally: .h, .hpp, .hxx etc.
+# This is set by --headers flag.
+_hpp_headers = set([])
+
 # {str, bool}: a map from error categories to booleans which indicate if the
 # category should be suppressed for every line.
 _global_error_suppressions = {}
 
+def ProcessHppHeadersOption(val):
+  global _hpp_headers
+  try:
+    _hpp_headers = {ext.strip() for ext in val.split(',')}
+  except ValueError:
+    PrintUsage('Header extensions must be comma separated list.')
 
+def IsHeaderExtension(file_extension):
+  return file_extension in GetHeaderExtensions()
 
+def GetHeaderExtensions():
+  if _hpp_headers:
+    return _hpp_headers
+  if _valid_extensions:
+    return {h for h in _valid_extensions if 'h' in h}
+  return set(['h', 'hh', 'hpp', 'hxx', 'h++', 'cuh'])
+
+# The allowed extensions for file names
+# This is set by --extensions flag
+def GetAllExtensions():
+  return GetHeaderExtensions().union(_valid_extensions or set(
+    ['c', 'cc', 'cpp', 'cxx', 'c++', 'cu']))
+
+def ProcessExtensionsOption(val):
+  global _valid_extensions
+  try:
+    extensions = [ext.strip() for ext in val.split(',')]
+    _valid_extensions = set(extensions)
+  except ValueError:
+    PrintUsage('Extensions should be a comma-separated list of values;'
+               'for example: extensions=hpp,cpp\n'
+               'This could not be parsed: "%s"' % (val,))
+
+def GetNonHeaderExtensions():
+  return GetAllExtensions().difference(GetHeaderExtensions())
 
 def ParseNolintSuppressions(filename, raw_line, linenum, error):
   """Updates the global list of line error-suppressions.
@@ -971,6 +1013,7 @@
     self._filters_backup = self.filters[:]
     self.counting = 'total'  # In what way are we counting errors?
     self.errors_by_category = {}  # string to int dict storing error counts
+    self.quiet = False  # Suppress non-error messagess?
 
     # output format:
     # "emacs" - format that emacs can parse (default)
@@ -988,6 +1031,12 @@
     """Sets the output format for errors."""
     self.output_format = output_format
 
+  def SetQuiet(self, quiet):
+    """Sets the module's quiet settings, and returns the previous setting."""
+    last_quiet = self.quiet
+    self.quiet = quiet
+    return last_quiet
+
   def SetVerboseLevel(self, level):
     """Sets the module's verbosity, and returns the previous setting."""
     last_verbose_level = self.verbose_level
@@ -1060,7 +1109,7 @@
 
   def PrintInfo(self, message):
     if not _quiet and self.output_format != 'junit':
-      sys.stderr.write(message)
+      sys.stdout.write(message)
 
   def PrintError(self, message):
     if self.output_format == 'junit':
@@ -1077,9 +1126,9 @@
     num_failures = len(self._junit_failures)
 
     testsuite = xml.etree.ElementTree.Element('testsuite')
-    testsuite.attrib['name'] = 'cpplint'
     testsuite.attrib['errors'] = str(num_errors)
     testsuite.attrib['failures'] = str(num_failures)
+    testsuite.attrib['name'] = 'cpplint'
 
     if num_errors == 0 and num_failures == 0:
       testsuite.attrib['tests'] = str(1)
@@ -1128,6 +1177,14 @@
   """Sets the module's output format."""
   _cpplint_state.SetOutputFormat(output_format)
 
+def _Quiet():
+  """Return's the module's quiet setting."""
+  return _cpplint_state.quiet
+
+def _SetQuiet(quiet):
+  """Set the module's quiet status, and return previous setting."""
+  return _cpplint_state.SetQuiet(quiet)
+
 
 def _VerboseLevel():
   """Returns the module's verbosity setting."""
@@ -1265,7 +1322,7 @@
     If we have a real absolute path name here we can try to do something smart:
     detecting the root of the checkout and truncating /path/to/checkout from
     the name so that we get header guards that don't include things like
-    "C:\Documents and Settings\..." or "/home/username/..." in them and thus
+    "C:\\Documents and Settings\\..." or "/home/username/..." in them and thus
     people on different computers who have checked the source out to different
     locations won't see bogus errors.
     """
@@ -1403,14 +1460,14 @@
   if _ShouldPrintError(category, confidence, linenum):
     _cpplint_state.IncrementErrorCount(category)
     if _cpplint_state.output_format == 'vs7':
-      _cpplint_state.PrintError('%s(%s): warning: %s  [%s] [%d]\n' % (
-          filename, linenum, message, category, confidence))
+      _cpplint_state.PrintError('%s(%s): error cpplint: [%s] %s [%d]\n' % (
+          filename, linenum, category, message, confidence))
     elif _cpplint_state.output_format == 'eclipse':
       sys.stderr.write('%s:%s: warning: %s  [%s] [%d]\n' % (
           filename, linenum, message, category, confidence))
     elif _cpplint_state.output_format == 'junit':
-        _cpplint_state.AddJUnitFailure(filename, linenum, message, category,
-            confidence)
+      _cpplint_state.AddJUnitFailure(filename, linenum, message, category,
+          confidence)
     else:
       final_message = '%s:%s:  %s  [%s] [%d]\n' % (
           filename, linenum, message, category, confidence)
@@ -1926,7 +1983,7 @@
 
   # We'll say it should occur by line 10. Don't forget there's a
   # dummy line at the front.
-  for line in range(1, min(len(lines), 11)):
+  for line in xrange(1, min(len(lines), 11)):
     if re.search(r'Copyright', lines[line], re.I): break
   else:                       # means no copyright line was found
     error(filename, 0, 'legal/copyright', 5,
@@ -1949,6 +2006,30 @@
   else:
     return 0
 
+def PathSplitToList(path):
+  """Returns the path split into a list by the separator.
+
+  Args:
+    path: An absolute or relative path (e.g. '/a/b/c/' or '../a')
+
+  Returns:
+    A list of path components (e.g. ['a', 'b', 'c]).
+  """
+  lst = []
+  while True:
+    (head, tail) = os.path.split(path)
+    if head == path:  # absolute paths end
+      lst.append(head)
+      break
+    if tail == path:  # relative paths end
+      lst.append(tail)
+      break
+
+    path = head
+    lst.append(tail)
+
+  lst.reverse()
+  return lst
 
 def GetHeaderGuardCPPVariable(filename):
   """Returns the CPP variable that should be used as a header guard.
@@ -1971,13 +2052,58 @@
 
   fileinfo = FileInfo(filename)
   file_path_from_root = fileinfo.RepositoryName()
-  if _root:
-    suffix = os.sep
-    # On Windows using directory separator will leave us with
-    # "bogus escape error" unless we properly escape regex.
-    if suffix == '\\':
-      suffix += '\\'
-    file_path_from_root = re.sub('^' + _root + suffix, '', file_path_from_root)
+
+  def FixupPathFromRoot():
+    if _root_debug:
+      sys.stderr.write("\n_root fixup, _root = '%s', repository name = '%s'\n"
+          % (_root, fileinfo.RepositoryName()))
+
+    # Process the file path with the --root flag if it was set.
+    if not _root:
+      if _root_debug:
+        sys.stderr.write("_root unspecified\n")
+      return file_path_from_root
+
+    def StripListPrefix(lst, prefix):
+      # f(['x', 'y'], ['w, z']) -> None  (not a valid prefix)
+      if lst[:len(prefix)] != prefix:
+        return None
+      # f(['a, 'b', 'c', 'd'], ['a', 'b']) -> ['c', 'd']
+      return lst[(len(prefix)):]
+
+    # root behavior:
+    #   --root=subdir , lstrips subdir from the header guard
+    maybe_path = StripListPrefix(PathSplitToList(file_path_from_root),
+                                 PathSplitToList(_root))
+
+    if _root_debug:
+      sys.stderr.write(("_root lstrip (maybe_path=%s, file_path_from_root=%s," +
+          " _root=%s)\n") % (maybe_path, file_path_from_root, _root))
+
+    if maybe_path:
+      return os.path.join(*maybe_path)
+
+    #   --root=.. , will prepend the outer directory to the header guard
+    full_path = fileinfo.FullName()
+    root_abspath = os.path.abspath(_root)
+
+    maybe_path = StripListPrefix(PathSplitToList(full_path),
+                                 PathSplitToList(root_abspath))
+
+    if _root_debug:
+      sys.stderr.write(("_root prepend (maybe_path=%s, full_path=%s, " +
+          "root_abspath=%s)\n") % (maybe_path, full_path, root_abspath))
+
+    if maybe_path:
+      return os.path.join(*maybe_path)
+
+    if _root_debug:
+      sys.stderr.write("_root ignore, returning %s\n" % (file_path_from_root))
+
+    #   --root=FAKE_DIR is ignored
+    return file_path_from_root
+
+  file_path_from_root = FixupPathFromRoot()
   return re.sub(r'[^a-zA-Z0-9]', '_', file_path_from_root).upper() + '_'
 
 
@@ -2093,22 +2219,22 @@
     return
 
   for ext in GetHeaderExtensions():
-      basefilename = filename[0:len(filename) - len(fileinfo.Extension())]
-      headerfile = basefilename + '.' + ext
-      if not os.path.exists(headerfile):
-        continue
-      headername = FileInfo(headerfile).RepositoryName()
-      first_include = None
-      for section_list in include_state.include_list:
-        for f in section_list:
-          if headername in f[0] or f[0] in headername:
-            return
-          if not first_include:
-            first_include = f[1]
+    basefilename = filename[0:len(filename) - len(fileinfo.Extension())]
+    headerfile = basefilename + '.' + ext
+    if not os.path.exists(headerfile):
+      continue
+    headername = FileInfo(headerfile).RepositoryName()
+    first_include = None
+    for section_list in include_state.include_list:
+      for f in section_list:
+        if headername in f[0] or f[0] in headername:
+          return
+        if not first_include:
+          first_include = f[1]
 
-      error(filename, first_include, 'build/include', 5,
-            '%s should include its header file %s' % (fileinfo.RepositoryName(),
-                                                      headername))
+    error(filename, first_include, 'build/include', 5,
+          '%s should include its header file %s' % (fileinfo.RepositoryName(),
+                                                    headername))
 
 
 def CheckForBadCharacters(filename, lines, error):
@@ -2981,7 +3107,8 @@
   # Look for single-argument constructors that aren't marked explicit.
   # Technically a valid construct, but against style.
   explicit_constructor_match = Match(
-      r'\s+(?:inline\s+)?(explicit\s+)?(?:inline\s+)?%s\s*'
+      r'\s+(?:(?:inline|constexpr)\s+)*(explicit\s+)?'
+      r'(?:(?:inline|constexpr)\s+)*%s\s*'
       r'\(((?:[^()]|\([^()]*\))*)\)'
       % re.escape(base_classname),
       line)
@@ -3026,7 +3153,8 @@
         Search(r'\bstd\s*::\s*initializer_list\b', constructor_args[0]))
     copy_constructor = bool(
         onearg_constructor and
-        Match(r'(const\s+)?%s(\s*<[^>]*>)?(\s+const)?\s*(?:<\w+>\s*)?&'
+        Match(r'((const\s+(volatile\s+)?)?|(volatile\s+(const\s+)?))?'
+              r'%s(\s*<[^>]*>)?(\s+const)?\s*(?:<\w+>\s*)?&'
               % re.escape(base_classname), constructor_args[0].strip()))
 
     if (not is_marked_explicit and
@@ -3192,13 +3320,13 @@
 
   if starting_func:
     body_found = False
-    for start_linenum in range(linenum, clean_lines.NumLines()):
+    for start_linenum in xrange(linenum, clean_lines.NumLines()):
       start_line = lines[start_linenum]
       joined_line += ' ' + start_line.lstrip()
       if Search(r'(;|})', start_line):  # Declarations and trivial functions
         body_found = True
         break                              # ... ignore
-      elif Search(r'{', start_line):
+      if Search(r'{', start_line):
         body_found = True
         function = Search(r'((\w|:)*)\(', line).group(1)
         if Match(r'TEST', function):    # Handle TEST... macros
@@ -3277,36 +3405,6 @@
               'Should have a space between // and comment')
 
 
-def CheckAccess(filename, clean_lines, linenum, nesting_state, error):
-  """Checks for improper use of DISALLOW* macros.
-
-  Args:
-    filename: The name of the current file.
-    clean_lines: A CleansedLines instance containing the file.
-    linenum: The number of the line to check.
-    nesting_state: A NestingState instance which maintains information about
-                   the current stack of nested blocks being parsed.
-    error: The function to call with any errors found.
-  """
-  line = clean_lines.elided[linenum]  # get rid of comments and strings
-
-  matched = Match((r'\s*(DISALLOW_COPY_AND_ASSIGN|'
-                   r'DISALLOW_IMPLICIT_CONSTRUCTORS)'), line)
-  if not matched:
-    return
-  if nesting_state.stack and isinstance(nesting_state.stack[-1], _ClassInfo):
-    if nesting_state.stack[-1].access != 'private':
-      error(filename, linenum, 'readability/constructors', 3,
-            '%s must be in the private: section' % matched.group(1))
-
-  else:
-    # Found DISALLOW* macro outside a class declaration, or perhaps it
-    # was used inside a function when it should have been part of the
-    # class declaration.  We could issue a warning here, but it
-    # probably resulted in a compiler error already.
-    pass
-
-
 def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
   """Checks for the correctness of various spacing issues in the code.
 
@@ -3422,8 +3520,8 @@
   line = clean_lines.elided[linenum]
 
   # You shouldn't have spaces before your brackets, except maybe after
-  # 'delete []' or 'return []() {};'
-  if Search(r'\w\s+\[', line) and not Search(r'(?:delete|return)\s+\[', line):
+  # 'delete []', 'return []() {};', or 'auto [abc, ...] = ...;'.
+  if Search(r'\w\s+\[', line) and not Search(r'(?:auto&?|delete|return)\s+\[', line):
     error(filename, linenum, 'whitespace/braces', 5,
           'Extra space before [')
 
@@ -4430,6 +4528,16 @@
       if unicodedata.east_asian_width(uc) in ('W', 'F'):
         width += 2
       elif not unicodedata.combining(uc):
+        # Issue 337
+        # https://mail.python.org/pipermail/python-list/2012-August/628809.html
+        if (sys.version_info.major, sys.version_info.minor) <= (3, 2):
+          # https://github.com/python/cpython/blob/2.7/Include/unicodeobject.h#L81
+          is_wide_build = sysconfig.get_config_var("Py_UNICODE_SIZE") >= 4
+          # https://github.com/python/cpython/blob/2.7/Objects/unicodeobject.c#L564
+          is_low_surrogate = 0xDC00 <= ord(uc) <= 0xDFFF
+          if not is_wide_build and is_low_surrogate:
+            width -= 1
+
         width += 1
     return width
   else:
@@ -4503,7 +4611,7 @@
 
   # Check if the line is a header guard.
   is_header_guard = False
-  if file_extension in GetHeaderExtensions():
+  if IsHeaderExtension(file_extension):
     cppvar = GetHeaderGuardCPPVariable(filename)
     if (line.startswith('#ifndef %s' % cppvar) or
         line.startswith('#define %s' % cppvar) or
@@ -4549,7 +4657,6 @@
   CheckBraces(filename, clean_lines, linenum, error)
   CheckTrailingSemicolon(filename, clean_lines, linenum, error)
   CheckEmptyBlockBody(filename, clean_lines, linenum, error)
-  CheckAccess(filename, clean_lines, linenum, nesting_state, error)
   CheckSpacing(filename, clean_lines, linenum, nesting_state, error)
   CheckOperatorSpacing(filename, clean_lines, linenum, error)
   CheckParenthesisSpacing(filename, clean_lines, linenum, error)
@@ -4632,7 +4739,7 @@
 
   # Headers with C++ extensions shouldn't be considered C system headers
   if is_system and os.path.splitext(include)[1] in ['.hpp', '.hxx', '.h++']:
-      is_system = False
+    is_system = False
 
   if is_system:
     if is_cpp_h:
@@ -4718,7 +4825,19 @@
               'Do not include .' + extension + ' files from other packages')
         return
 
-    if not _THIRD_PARTY_HEADERS_PATTERN.match(include):
+    # We DO want to include a 3rd party looking header if it matches the
+    # filename. Otherwise we get an erroneous error "...should include its
+    # header" error later.
+    third_src_header = False
+    for ext in GetHeaderExtensions():
+      basefilename = filename[0:len(filename) - len(fileinfo.Extension())]
+      headerfile = basefilename + '.' + ext
+      headername = FileInfo(headerfile).RepositoryName()
+      if headername in include or include in headername:
+        third_src_header = True
+        break
+
+    if third_src_header or not _THIRD_PARTY_HEADERS_PATTERN.match(include):
       include_state.include_list[-1].append((include, linenum))
 
       # We want to ensure that headers appear in the right order:
@@ -4872,7 +4991,7 @@
   CheckGlobalStatic(filename, clean_lines, linenum, error)
   CheckPrintf(filename, clean_lines, linenum, error)
 
-  if file_extension in GetHeaderExtensions():
+  if IsHeaderExtension(file_extension):
     # TODO(unknown): check that 1-arg constructors are explicit.
     #                How to tell it's a constructor?
     #                (handled in CheckForNonStandardConstructs for now)
@@ -4984,7 +5103,7 @@
   # Check for use of unnamed namespaces in header files.  Registration
   # macros are typically OK, so we allow use of "namespace {" on lines
   # that end with backslashes.
-  if (file_extension in GetHeaderExtensions()
+  if (IsHeaderExtension(file_extension)
       and Search(r'\bnamespace\s*{', line)
       and line[-1] != '\\'):
     error(filename, linenum, 'build/namespaces', 4,
@@ -5517,11 +5636,11 @@
                      )),
     ('<limits>', ('numeric_limits',)),
     ('<list>', ('list',)),
-    ('<map>', ('map', 'multimap',)),
+    ('<map>', ('multimap',)),
     ('<memory>', ('allocator', 'make_shared', 'make_unique', 'shared_ptr',
                   'unique_ptr', 'weak_ptr')),
     ('<queue>', ('queue', 'priority_queue',)),
-    ('<set>', ('set', 'multiset',)),
+    ('<set>', ('multiset',)),
     ('<stack>', ('stack',)),
     ('<string>', ('char_traits', 'basic_string',)),
     ('<tuple>', ('tuple',)),
@@ -5550,11 +5669,21 @@
 for _header, _templates in _HEADERS_MAYBE_TEMPLATES:
   for _template in _templates:
     # Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or
-    # type::max().
+    # 'type::max()'.
     _re_pattern_headers_maybe_templates.append(
         (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'),
             _template,
             _header))
+# Match set<type>, but not foo->set<type>, foo.set<type>
+_re_pattern_headers_maybe_templates.append(
+    (re.compile(r'[^>.]\bset\s*\<'),
+        'set<>',
+        '<set>'))
+# Match 'map<type> var' and 'std::map<type>(...)', but not 'map<type>(...)''
+_re_pattern_headers_maybe_templates.append(
+    (re.compile(r'(std\b::\bmap\s*\<)|(^(std\b::\b)map\b\(\s*\<)'),
+        'map<>',
+        '<map>'))
 
 # Other scripts may reach in and modify this pattern.
 _re_pattern_templates = []
@@ -5600,7 +5729,7 @@
     return (False, '')
 
   fileinfo_h = FileInfo(filename_h)
-  if not fileinfo_h.Extension().lstrip('.') in GetHeaderExtensions():
+  if not IsHeaderExtension(fileinfo_h.Extension().lstrip('.')):
     return (False, '')
 
   filename_cc = filename_cc[:-(len(fileinfo_cc.Extension()))]
@@ -5672,7 +5801,7 @@
   required = {}  # A map of header name to linenumber and the template entity.
                  # Example of required: { '<functional>': (1219, 'less<>') }
 
-  for linenum in range(clean_lines.NumLines()):
+  for linenum in xrange(clean_lines.NumLines()):
     line = clean_lines.elided[linenum]
     if not line or line[0] == '#':
       continue
@@ -5998,8 +6127,14 @@
 
   # Flag unapproved C++11 headers.
   if include and include.group(1) in ('cfenv',
+                                      'condition_variable',
                                       'fenv.h',
+                                      'future',
+                                      'mutex',
+                                      'thread',
+                                      'chrono',
                                       'ratio',
+                                      'regex',
                                       'system_error',
                                      ):
     error(filename, linenum, 'build/c++11', 5,
@@ -6072,10 +6207,10 @@
   RemoveMultiLineComments(filename, lines, error)
   clean_lines = CleansedLines(lines)
 
-  if file_extension in GetHeaderExtensions():
+  if IsHeaderExtension(file_extension):
     CheckForHeaderGuard(filename, clean_lines, error)
 
-  for line in range(clean_lines.NumLines()):
+  for line in xrange(clean_lines.NumLines()):
     ProcessLine(filename, file_extension, clean_lines, line,
                 include_state, function_state, nesting_state, error,
                 extra_check_functions)
@@ -6141,37 +6276,28 @@
             if base_name:
               pattern = re.compile(val)
               if pattern.match(base_name):
-                _cpplint_state.PrintInfo('Ignoring "%s": file excluded by '
-                    '"%s". File path component "%s" matches pattern "%s"\n' %
-                    (filename, cfg_file, base_name, val))
+                if _cpplint_state.quiet:
+                  # Suppress "Ignoring file" warning when using --quiet.
+                  return False
+                _cpplint_state.PrintInfo('Ignoring "%s": file excluded by "%s". '
+                                 'File path component "%s" matches '
+                                 'pattern "%s"\n' %
+                                 (filename, cfg_file, base_name, val))
                 return False
           elif name == 'linelength':
             global _line_length
             try:
-                _line_length = int(val)
+              _line_length = int(val)
             except ValueError:
-                _cpplint_state.PrintError('Line length must be numeric.')
+              _cpplint_state.PrintError('Line length must be numeric.')
           elif name == 'extensions':
-              global _valid_extensions
-              try:
-                  extensions = [ext.strip() for ext in val.split(',')]
-                  _valid_extensions = set(extensions)
-              except ValueError:
-                  sys.stderr.write('Extensions should be a comma-separated list of values;'
-                                   'for example: extensions=hpp,cpp\n'
-                                   'This could not be parsed: "%s"' % (val,))
-          elif name == 'headers':
-              global _header_extensions
-              try:
-                  extensions = [ext.strip() for ext in val.split(',')]
-                  _header_extensions = set(extensions)
-              except ValueError:
-                  sys.stderr.write('Extensions should be a comma-separated list of values;'
-                                   'for example: extensions=hpp,cpp\n'
-                                   'This could not be parsed: "%s"' % (val,))
+            ProcessExtensionsOption(val)
           elif name == 'root':
             global _root
-            _root = val
+            # root directories are specified relative to CPPLINT.cfg dir.
+            _root = os.path.join(os.path.dirname(cfg_file), val)
+          elif name == 'headers':
+            ProcessHppHeadersOption(val)
           else:
             _cpplint_state.PrintError(
                 'Invalid configuration option (%s) in file %s\n' %
@@ -6185,7 +6311,7 @@
   # Apply all the accumulated filters in reverse order (top-level directory
   # config options having the least priority).
   for cfg_filter in reversed(cfg_filters):
-     _AddFilters(cfg_filter)
+    _AddFilters(cfg_filter)
 
   return True
 
@@ -6206,6 +6332,7 @@
 
   _SetVerboseLevel(vlevel)
   _BackupFilters()
+  old_errors = _cpplint_state.error_count
 
   if not ProcessConfigOverrides(filename):
     _RestoreFilters()
@@ -6274,7 +6401,10 @@
         Error(filename, linenum, 'whitespace/newline', 1,
               'Unexpected \\r (^M) found; better to use only \\n')
 
-  _cpplint_state.PrintInfo('Done processing %s\n' % filename)
+  # Suppress printing anything if --quiet was passed unless the error
+  # count has increased after processing this file.
+  if not _cpplint_state.quiet or old_errors != _cpplint_state.error_count:
+    _cpplint_state.PrintInfo('Done processing %s\n' % filename)
   _RestoreFilters()
 
 
@@ -6284,13 +6414,21 @@
   Args:
     message: The optional error message.
   """
-  sys.stderr.write(_USAGE)
+  sys.stderr.write(_USAGE  % (list(GetAllExtensions()),
+       ','.join(list(GetAllExtensions())),
+       GetHeaderExtensions(),
+       ','.join(GetHeaderExtensions())))
 
   if message:
     sys.exit('\nFATAL ERROR: ' + message)
   else:
     sys.exit(0)
 
+def PrintVersion():
+  sys.stdout.write('Cpplint fork (https://github.com/cpplint/cpplint)\n')
+  sys.stdout.write('cpplint ' + __VERSION__ + '\n')
+  sys.stdout.write('Python ' + sys.version + '\n')
+  sys.exit(0)
 
 def PrintCategories():
   """Prints a list of all the error-categories used by error messages.
@@ -6314,6 +6452,8 @@
   """
   try:
     (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=',
+                                                 'v=',
+                                                 'version',
                                                  'counting=',
                                                  'filter=',
                                                  'root=',
@@ -6321,27 +6461,32 @@
                                                  'linelength=',
                                                  'extensions=',
                                                  'exclude=',
+                                                 'recursive',
                                                  'headers=',
-                                                 'quiet',
-                                                 'recursive'])
+                                                 'quiet'])
   except getopt.GetoptError:
     PrintUsage('Invalid arguments.')
 
   verbosity = _VerboseLevel()
   output_format = _OutputFormat()
   filters = ''
+  quiet = _Quiet()
   counting_style = ''
   recursive = False
 
   for (opt, val) in opts:
     if opt == '--help':
       PrintUsage(None)
+    if opt == '--version':
+      PrintVersion()
     elif opt == '--output':
       if val not in ('emacs', 'vs7', 'eclipse', 'junit'):
         PrintUsage('The only allowed output formats are emacs, vs7, eclipse '
                    'and junit.')
       output_format = val
-    elif opt == '--verbose':
+    elif opt == '--quiet':
+      quiet = True
+    elif opt == '--verbose' or opt == '--v':
       verbosity = int(val)
     elif opt == '--filter':
       filters = val
@@ -6369,22 +6514,11 @@
         _excludes = set()
       _excludes.update(glob.glob(val))
     elif opt == '--extensions':
-      global _valid_extensions
-      try:
-        _valid_extensions = set(val.split(','))
-      except ValueError:
-          PrintUsage('Extensions must be comma seperated list.')
+      ProcessExtensionsOption(val)
     elif opt == '--headers':
-      global _header_extensions
-      try:
-          _header_extensions = set(val.split(','))
-      except ValueError:
-        PrintUsage('Extensions must be comma seperated list.')
+      ProcessHppHeadersOption(val)
     elif opt == '--recursive':
       recursive = True
-    elif opt == '--quiet':
-      global _quiet
-      _quiet = True
 
   if not filenames:
     PrintUsage('No files were specified.')
@@ -6396,6 +6530,7 @@
     filenames = _FilterExcludedFiles(filenames)
 
   _SetOutputFormat(output_format)
+  _SetQuiet(quiet)
   _SetVerboseLevel(verbosity)
   _SetFilters(filters)
   _SetCountingStyle(counting_style)
@@ -6416,30 +6551,50 @@
   """
   expanded = set()
   for filename in filenames:
-      if not os.path.isdir(filename):
-        expanded.add(filename)
-        continue
+    if not os.path.isdir(filename):
+      expanded.add(filename)
+      continue
 
-      for root, _, files in os.walk(filename):
-        for loopfile in files:
-          fullname = os.path.join(root, loopfile)
-          if fullname.startswith('.' + os.path.sep):
-            fullname = fullname[len('.' + os.path.sep):]
-          expanded.add(fullname)
+    for root, _, files in os.walk(filename):
+      for loopfile in files:
+        fullname = os.path.join(root, loopfile)
+        if fullname.startswith('.' + os.path.sep):
+          fullname = fullname[len('.' + os.path.sep):]
+        expanded.add(fullname)
 
   filtered = []
   for filename in expanded:
-      if os.path.splitext(filename)[1][1:] in GetAllExtensions():
-          filtered.append(filename)
-
+    if os.path.splitext(filename)[1][1:] in GetAllExtensions():
+      filtered.append(filename)
   return filtered
 
-def _FilterExcludedFiles(filenames):
+def _FilterExcludedFiles(fnames):
   """Filters out files listed in the --exclude command line switch. File paths
   in the switch are evaluated relative to the current working directory
   """
   exclude_paths = [os.path.abspath(f) for f in _excludes]
-  return [f for f in filenames if os.path.abspath(f) not in exclude_paths]
+  # because globbing does not work recursively, exclude all subpath of all excluded entries
+  return [f for f in fnames
+          if not any(e for e in exclude_paths
+                  if _IsParentOrSame(e, os.path.abspath(f)))]
+
+def _IsParentOrSame(parent, child):
+  """Return true if child is subdirectory of parent.
+  Assumes both paths are absolute and don't contain symlinks.
+  """
+  parent = os.path.normpath(parent)
+  child = os.path.normpath(child)
+  if parent == child:
+    return True
+
+  prefix = os.path.commonprefix([parent, child])
+  if prefix != parent:
+    return False
+  # Note: os.path.commonprefix operates on character basis, so
+  # take extra care of situations like '/foo/ba' and '/foo/bar/baz'
+  child_suffix = child[len(prefix):]
+  child_suffix = child_suffix.lstrip(os.sep)
+  return child == os.path.join(prefix, child_suffix)
 
 def main():
   filenames = ParseArguments(sys.argv[1:])
@@ -6452,7 +6607,9 @@
     _cpplint_state.ResetErrorCounts()
     for filename in filenames:
       ProcessFile(filename, _cpplint_state.verbose_level)
-    _cpplint_state.PrintErrorCounts()
+    # If --quiet is passed, suppress printing error count unless there are errors.
+    if not _cpplint_state.quiet or _cpplint_state.error_count > 0:
+      _cpplint_state.PrintErrorCounts()
 
     if _cpplint_state.output_format == 'junit':
       sys.stderr.write(_cpplint_state.FormatJUnitXML())
diff --git a/thirdparty/google-styleguide/run_linter.sh b/thirdparty/google-styleguide/run_linter.sh
index de4de2a..c901984 100755
--- a/thirdparty/google-styleguide/run_linter.sh
+++ b/thirdparty/google-styleguide/run_linter.sh
@@ -40,4 +40,4 @@
 
 HEADERS=`find $INCLUDE_DIRS -name '*.h' | sort | uniq | tr '\n' ','`
 SOURCES=`find $SOURCE_DIRS -name  '*.cpp' | sort | uniq | tr '\n' ' '`
-python ${SCRIPT_DIR}/cpplint.py --linelength=200 --headers=${HEADERS} ${SOURCES}
+python ${SCRIPT_DIR}/cpplint.py --linelength=200 ${SOURCES}