You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by fg...@apache.org on 2021/08/04 16:29:29 UTC

[nifi-minifi-cpp] branch main updated (5c417ca -> a604977)

This is an automated email from the ASF dual-hosted git repository.

fgerlits pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git.


    from 5c417ca  MINIFICPP-1611 Add #include <string> in the patch
     new e1433c1  MINIFICPP-1522 Log invalid attribute in case of YAML parse failure
     new 0fc7ac3  MINIFICPP-1429 clean up pre-c++17 workarounds
     new a604977  MINIFICPP-1617 Update CONTRIB.md with actual practice

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 CMakeLists.txt                                     |    4 -
 CONTRIB.md                                         |   68 +-
 LICENSE                                            |   29 -
 NOTICE                                             |    1 -
 README.md                                          |   18 +-
 encrypt-config/ArgParser.cpp                       |   10 +-
 encrypt-config/ArgParser.h                         |   12 +-
 encrypt-config/ConfigFile.cpp                      |    3 +-
 encrypt-config/ConfigFile.h                        |    3 +-
 encrypt-config/ConfigFileEncryptor.cpp             |    7 +-
 encrypt-config/EncryptConfig.cpp                   |    8 +-
 encrypt-config/Utils.h                             |    5 +-
 encrypt-config/tests/ConfigFileEncryptorTests.cpp  |    7 +-
 encrypt-config/tests/ConfigFileTests.cpp           |   16 +-
 extensions/aws/AWSCredentialsProvider.cpp          |    4 +-
 extensions/aws/AWSCredentialsProvider.h            |    6 +-
 .../controllerservices/AWSCredentialsService.cpp   |    2 +-
 .../aws/controllerservices/AWSCredentialsService.h |    8 +-
 extensions/aws/processors/DeleteS3Object.cpp       |    4 +-
 extensions/aws/processors/DeleteS3Object.h         |    7 +-
 extensions/aws/processors/FetchS3Object.cpp        |    4 +-
 extensions/aws/processors/FetchS3Object.h          |    9 +-
 extensions/aws/processors/ListS3.cpp               |    2 +-
 extensions/aws/processors/PutS3Object.cpp          |    8 +-
 extensions/aws/processors/PutS3Object.h            |   17 +-
 extensions/aws/processors/S3Processor.cpp          |   22 +-
 extensions/aws/processors/S3Processor.h            |   13 +-
 extensions/aws/s3/S3ClientRequestSender.cpp        |   24 +-
 extensions/aws/s3/S3ClientRequestSender.h          |   14 +-
 extensions/aws/s3/S3RequestSender.h                |   16 +-
 extensions/aws/s3/S3Wrapper.cpp                    |   35 +-
 extensions/aws/s3/S3Wrapper.h                      |   19 +-
 extensions/azure/AzureLoader.h                     |    3 +-
 .../azure/processors/PutAzureBlobStorage.cpp       |    4 +-
 extensions/azure/processors/PutAzureBlobStorage.h  |   10 +-
 extensions/azure/storage/AzureBlobStorage.cpp      |   13 +-
 extensions/azure/storage/AzureBlobStorage.h        |    5 +-
 extensions/azure/storage/BlobStorage.h             |    7 +-
 extensions/civetweb/processors/ListenHTTP.cpp      |    7 +-
 extensions/coap/tests/CoapIntegrationBase.h        |   16 +-
 extensions/http-curl/sitetosite/HTTPProtocol.cpp   |    2 +-
 extensions/http-curl/sitetosite/HTTPProtocol.h     |    7 +-
 extensions/http-curl/tests/C2PauseResumeTest.cpp   |    8 +-
 extensions/http-curl/tests/C2RequestClassTest.cpp  |   10 +-
 extensions/http-curl/tests/HTTPHandlers.h          |    7 +-
 extensions/http-curl/tests/HTTPIntegrationBase.h   |    4 +-
 extensions/http-curl/tests/TestServer.h            |    4 +-
 extensions/http-curl/tests/VerifyInvokeHTTP.h      |   11 +-
 .../http-curl/tests/VerifyInvokeHTTPPostTest.cpp   |    4 +-
 extensions/libarchive/MergeContent.cpp             |   13 +-
 extensions/librdkafka/ConsumeKafka.cpp             |    6 +-
 extensions/librdkafka/ConsumeKafka.h               |    3 +-
 extensions/librdkafka/PublishKafka.cpp             |    8 +-
 extensions/librdkafka/rdkafka_utils.cpp            |    2 +-
 extensions/librdkafka/rdkafka_utils.h              |    4 +-
 extensions/librdkafka/tests/ConsumeKafkaTests.cpp  |   61 +-
 .../mqtt/processors/AbstractMQTTProcessor.cpp      |    4 +-
 extensions/mqtt/processors/PublishMQTT.cpp         |   13 +-
 extensions/opc/src/putopc.cpp                      |    9 +-
 extensions/pdh/PerformanceDataMonitor.cpp          |    2 +-
 extensions/pdh/PerformanceDataMonitor.h            |    9 +-
 extensions/rocksdb-repos/FlowFileRepository.cpp    |    5 +-
 .../rocksdb-repos/database/RocksDatabase.cpp       |    6 +-
 extensions/rocksdb-repos/database/RocksDatabase.h  |    4 +-
 .../rocksdb-repos/database/RocksDbInstance.cpp     |   12 +-
 .../rocksdb-repos/database/RocksDbInstance.h       |    6 +-
 extensions/sql/SQLLoader.h                         |    6 +-
 extensions/sql/data/SociConnectors.cpp             |    8 +-
 extensions/sql/data/SociConnectors.h               |    1 -
 extensions/sql/services/ODBCConnector.h            |    1 +
 .../processors/RetryFlowFile.cpp                   |   10 +-
 .../standard-processors/processors/RetryFlowFile.h |    4 +-
 .../TLSClientSocketSupportedProtocolsTest.cpp      |    2 +-
 .../TLSServerSocketSupportedProtocolsTest.cpp      |    2 +-
 .../tests/unit/ProcessGroupTestUtils.h             |    2 +-
 .../tests/unit/RetryFlowFileTests.cpp              |    4 +-
 .../tests/unit/YamlConfigurationTests.cpp          |  327 ++--
 extensions/systemd/ConsumeJournald.cpp             |   19 +-
 extensions/systemd/ConsumeJournald.h               |    6 +-
 extensions/systemd/libwrapper/DlopenWrapper.cpp    |    2 +-
 extensions/systemd/libwrapper/LibWrapper.cpp       |    3 +-
 extensions/systemd/tests/ConsumeJournaldTest.cpp   |    5 +-
 .../windows-event-log/tests/BookmarkTests.cpp      |    3 +-
 extensions/windows-event-log/tests/CWELTestUtils.h |   12 +-
 libminifi/CMakeLists.txt                           |    2 +-
 libminifi/include/FlowController.h                 |    2 +-
 libminifi/include/c2/C2Agent.h                     |   11 +-
 libminifi/include/c2/C2Client.h                    |   10 +-
 libminifi/include/c2/C2Payload.h                   |    2 +-
 .../include/core/AgentIdentificationProvider.h     |    6 +-
 libminifi/include/core/ConfigurationFactory.h      |    9 +-
 libminifi/include/core/CoreComponentState.h        |   11 +-
 libminifi/include/core/FlowConfiguration.h         |   10 +-
 libminifi/include/core/FlowFile.h                  |    4 +-
 libminifi/include/core/ProcessContext.h            |   23 +-
 libminifi/include/core/TypedValues.h               |   10 +-
 libminifi/include/core/logging/Logger.h            |    5 +-
 .../include/core/logging/internal/LogBuffer.h      |    2 +-
 .../include/core/state/nodes/AgentInformation.h    |    3 +-
 libminifi/include/core/yaml/YamlConfiguration.h    |    6 +-
 libminifi/include/core/yaml/YamlConnectionParser.h |   12 +-
 libminifi/include/io/CRCStream.h                   |    4 +-
 libminifi/include/properties/Configure.h           |   10 +-
 libminifi/include/properties/Decryptor.h           |    8 +-
 libminifi/include/properties/Properties.h          |    8 +-
 libminifi/include/properties/PropertiesFile.h      |   20 +-
 libminifi/include/utils/ChecksumCalculator.h       |    9 +-
 libminifi/include/utils/Enum.h                     |    6 +-
 libminifi/include/utils/GeneralUtils.h             |   96 --
 libminifi/include/utils/HTTPClient.h               |    6 +-
 libminifi/include/utils/Id.h                       |    9 +-
 libminifi/include/utils/JsonCallback.h             |   11 +-
 libminifi/include/utils/OptionalUtils.h            |   68 +-
 libminifi/include/utils/ProcessorConfigUtils.h     |    7 +-
 libminifi/include/utils/StringUtils.h              |   71 +-
 libminifi/include/utils/TryMoveCall.h              |    5 +-
 libminifi/include/utils/crypto/EncryptionManager.h |   14 +-
 .../include/utils/crypto/EncryptionProvider.h      |   13 +-
 libminifi/include/utils/file/FileSystem.h          |   10 +-
 libminifi/include/utils/file/PathUtils.h           |    6 +-
 .../include/utils/requirements/LegacyIterator.h    |    2 +-
 libminifi/include/utils/requirements/Swappable.h   |    2 +-
 libminifi/include/utils/tls/DistinguishedName.h    |    7 +-
 libminifi/src/Configure.cpp                        |    8 +-
 libminifi/src/DiskSpaceWatchdog.cpp                |   14 +-
 libminifi/src/FlowController.cpp                   |    9 +-
 libminifi/src/SchedulingAgent.cpp                  |    5 +-
 libminifi/src/ThreadedSchedulingAgent.cpp          |   20 +-
 libminifi/src/c2/C2Agent.cpp                       |   22 +-
 libminifi/src/c2/C2Client.cpp                      |    2 +-
 libminifi/src/controllers/SSLContextService.cpp    |    3 +-
 .../keyvalue/PersistableKeyValueStoreService.cpp   |    2 +-
 libminifi/src/core/ConfigurationFactory.cpp        |   25 +-
 libminifi/src/core/FlowConfiguration.cpp           |    6 +-
 libminifi/src/core/FlowFile.cpp                    |    4 +-
 libminifi/src/core/logging/LoggerConfiguration.cpp |   15 +-
 .../core/logging/internal/CompressionManager.cpp   |    5 +-
 libminifi/src/core/yaml/YamlConfiguration.cpp      |   14 +-
 libminifi/src/core/yaml/YamlConnectionParser.cpp   |   10 +-
 libminifi/src/io/ClientSocket.cpp                  |   17 +-
 libminifi/src/io/StreamFactory.cpp                 |    4 +-
 libminifi/src/io/tls/TLSSocket.cpp                 |   13 +-
 libminifi/src/properties/Properties.cpp            |    4 +-
 libminifi/src/properties/PropertiesFile.cpp        |    4 +-
 libminifi/src/utils/BackTrace.cpp                  |    4 +-
 libminifi/src/utils/HTTPClient.cpp                 |    8 +-
 libminifi/src/utils/Id.cpp                         |    4 +-
 libminifi/src/utils/OsUtils.cpp                    |   12 +-
 libminifi/src/utils/ProcessorConfigUtils.cpp       |    6 +-
 libminifi/src/utils/StringUtils.cpp                |    6 +-
 libminifi/src/utils/crypto/EncryptionManager.cpp   |   18 +-
 libminifi/src/utils/crypto/EncryptionProvider.cpp  |    2 +-
 libminifi/src/utils/file/FileSystem.cpp            |    9 +-
 libminifi/src/utils/tls/DistinguishedName.cpp      |    4 +-
 libminifi/test/aws-tests/MockS3RequestSender.h     |   21 +-
 .../test/azure-tests/PutAzureBlobStorageTests.cpp  |    7 +-
 libminifi/test/flow-tests/TestControllerWithFlow.h |    2 +-
 libminifi/test/integration/IntegrationBase.h       |    8 +-
 .../UnorderedMapKeyValueStoreServiceTest.cpp       |    3 +-
 libminifi/test/sql-tests/ExecuteSQLTests.cpp       |    4 +-
 libminifi/test/sql-tests/FlowFileMatcher.h         |   11 +-
 .../test/sql-tests/QueryDatabaseTableTests.cpp     |    2 +-
 libminifi/test/sql-tests/SQLTestPlan.h             |   11 +-
 libminifi/test/sql-tests/mocks/MockConnectors.cpp  |   10 +-
 libminifi/test/sql-tests/mocks/MockODBCService.h   |    3 +-
 libminifi/test/unit/DecryptorTests.cpp             |   23 +-
 libminifi/test/unit/FileSystemTests.cpp            |    9 +-
 libminifi/test/unit/GeneralUtilsTest.cpp           |   78 -
 libminifi/test/unit/LoggerTests.cpp                |    2 +-
 libminifi/test/unit/OptionalTest.cpp               |   24 +-
 libminifi/test/unit/ProcessSessionTests.cpp        |   18 +-
 libminifi/test/unit/StringUtilsTests.cpp           |   13 +-
 main/MiNiFiMain.cpp                                |    9 +-
 thirdparty/optional-lite-3.2.0/LICENSE.txt         |   23 -
 .../include/nonstd/optional.hpp                    | 1698 --------------------
 175 files changed, 996 insertions(+), 2893 deletions(-)
 delete mode 100644 thirdparty/optional-lite-3.2.0/LICENSE.txt
 delete mode 100644 thirdparty/optional-lite-3.2.0/include/nonstd/optional.hpp

[nifi-minifi-cpp] 02/03: MINIFICPP-1429 clean up pre-c++17 workarounds

Posted by fg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

fgerlits pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git

commit 0fc7ac3098457a5944205290c9323b2561cf23ac
Author: Marton Szasz <sz...@apache.org>
AuthorDate: Tue Jul 27 16:50:32 2021 +0200

    MINIFICPP-1429 clean up pre-c++17 workarounds
    
    due to previously missing language and stdlib features
    
    Signed-off-by: Ferenc Gerlits <fg...@gmail.com>
    
    This closes #1144
---
 CMakeLists.txt                                     |    4 -
 LICENSE                                            |   29 -
 NOTICE                                             |    1 -
 encrypt-config/ArgParser.cpp                       |   10 +-
 encrypt-config/ArgParser.h                         |   12 +-
 encrypt-config/ConfigFile.cpp                      |    3 +-
 encrypt-config/ConfigFile.h                        |    3 +-
 encrypt-config/ConfigFileEncryptor.cpp             |    7 +-
 encrypt-config/EncryptConfig.cpp                   |    8 +-
 encrypt-config/Utils.h                             |    5 +-
 encrypt-config/tests/ConfigFileEncryptorTests.cpp  |    7 +-
 encrypt-config/tests/ConfigFileTests.cpp           |   16 +-
 extensions/aws/AWSCredentialsProvider.cpp          |    4 +-
 extensions/aws/AWSCredentialsProvider.h            |    6 +-
 .../controllerservices/AWSCredentialsService.cpp   |    2 +-
 .../aws/controllerservices/AWSCredentialsService.h |    8 +-
 extensions/aws/processors/DeleteS3Object.cpp       |    4 +-
 extensions/aws/processors/DeleteS3Object.h         |    7 +-
 extensions/aws/processors/FetchS3Object.cpp        |    4 +-
 extensions/aws/processors/FetchS3Object.h          |    9 +-
 extensions/aws/processors/ListS3.cpp               |    2 +-
 extensions/aws/processors/PutS3Object.cpp          |    8 +-
 extensions/aws/processors/PutS3Object.h            |   17 +-
 extensions/aws/processors/S3Processor.cpp          |   22 +-
 extensions/aws/processors/S3Processor.h            |   13 +-
 extensions/aws/s3/S3ClientRequestSender.cpp        |   24 +-
 extensions/aws/s3/S3ClientRequestSender.h          |   14 +-
 extensions/aws/s3/S3RequestSender.h                |   16 +-
 extensions/aws/s3/S3Wrapper.cpp                    |   35 +-
 extensions/aws/s3/S3Wrapper.h                      |   19 +-
 extensions/azure/AzureLoader.h                     |    3 +-
 .../azure/processors/PutAzureBlobStorage.cpp       |    4 +-
 extensions/azure/processors/PutAzureBlobStorage.h  |   10 +-
 extensions/azure/storage/AzureBlobStorage.cpp      |   13 +-
 extensions/azure/storage/AzureBlobStorage.h        |    5 +-
 extensions/azure/storage/BlobStorage.h             |    7 +-
 extensions/civetweb/processors/ListenHTTP.cpp      |    7 +-
 extensions/coap/tests/CoapIntegrationBase.h        |   16 +-
 extensions/http-curl/sitetosite/HTTPProtocol.cpp   |    2 +-
 extensions/http-curl/sitetosite/HTTPProtocol.h     |    7 +-
 extensions/http-curl/tests/C2PauseResumeTest.cpp   |    8 +-
 extensions/http-curl/tests/C2RequestClassTest.cpp  |   10 +-
 extensions/http-curl/tests/HTTPHandlers.h          |    7 +-
 extensions/http-curl/tests/HTTPIntegrationBase.h   |    4 +-
 extensions/http-curl/tests/TestServer.h            |    4 +-
 extensions/http-curl/tests/VerifyInvokeHTTP.h      |   11 +-
 .../http-curl/tests/VerifyInvokeHTTPPostTest.cpp   |    4 +-
 extensions/libarchive/MergeContent.cpp             |   13 +-
 extensions/librdkafka/ConsumeKafka.cpp             |    6 +-
 extensions/librdkafka/ConsumeKafka.h               |    3 +-
 extensions/librdkafka/PublishKafka.cpp             |    8 +-
 extensions/librdkafka/rdkafka_utils.cpp            |    2 +-
 extensions/librdkafka/rdkafka_utils.h              |    4 +-
 extensions/librdkafka/tests/ConsumeKafkaTests.cpp  |   61 +-
 .../mqtt/processors/AbstractMQTTProcessor.cpp      |    4 +-
 extensions/mqtt/processors/PublishMQTT.cpp         |   13 +-
 extensions/opc/src/putopc.cpp                      |    9 +-
 extensions/pdh/PerformanceDataMonitor.cpp          |    2 +-
 extensions/pdh/PerformanceDataMonitor.h            |    9 +-
 extensions/rocksdb-repos/FlowFileRepository.cpp    |    5 +-
 .../rocksdb-repos/database/RocksDatabase.cpp       |    6 +-
 extensions/rocksdb-repos/database/RocksDatabase.h  |    4 +-
 .../rocksdb-repos/database/RocksDbInstance.cpp     |   12 +-
 .../rocksdb-repos/database/RocksDbInstance.h       |    6 +-
 extensions/sql/SQLLoader.h                         |    6 +-
 extensions/sql/data/SociConnectors.cpp             |    8 +-
 extensions/sql/data/SociConnectors.h               |    1 -
 extensions/sql/services/ODBCConnector.h            |    1 +
 .../processors/RetryFlowFile.cpp                   |   10 +-
 .../standard-processors/processors/RetryFlowFile.h |    4 +-
 .../TLSClientSocketSupportedProtocolsTest.cpp      |    2 +-
 .../TLSServerSocketSupportedProtocolsTest.cpp      |    2 +-
 .../tests/unit/ProcessGroupTestUtils.h             |    2 +-
 .../tests/unit/RetryFlowFileTests.cpp              |    4 +-
 extensions/systemd/ConsumeJournald.cpp             |   19 +-
 extensions/systemd/ConsumeJournald.h               |    6 +-
 extensions/systemd/libwrapper/DlopenWrapper.cpp    |    2 +-
 extensions/systemd/libwrapper/LibWrapper.cpp       |    3 +-
 extensions/systemd/tests/ConsumeJournaldTest.cpp   |    5 +-
 .../windows-event-log/tests/BookmarkTests.cpp      |    3 +-
 extensions/windows-event-log/tests/CWELTestUtils.h |   12 +-
 libminifi/CMakeLists.txt                           |    2 +-
 libminifi/include/FlowController.h                 |    2 +-
 libminifi/include/c2/C2Agent.h                     |   11 +-
 libminifi/include/c2/C2Client.h                    |   10 +-
 libminifi/include/c2/C2Payload.h                   |    2 +-
 .../include/core/AgentIdentificationProvider.h     |    6 +-
 libminifi/include/core/ConfigurationFactory.h      |    9 +-
 libminifi/include/core/CoreComponentState.h        |   11 +-
 libminifi/include/core/FlowConfiguration.h         |   10 +-
 libminifi/include/core/FlowFile.h                  |    4 +-
 libminifi/include/core/ProcessContext.h            |   23 +-
 libminifi/include/core/TypedValues.h               |   10 +-
 libminifi/include/core/logging/Logger.h            |    5 +-
 .../include/core/logging/internal/LogBuffer.h      |    2 +-
 .../include/core/state/nodes/AgentInformation.h    |    3 +-
 libminifi/include/core/yaml/YamlConfiguration.h    |    6 +-
 libminifi/include/core/yaml/YamlConnectionParser.h |   12 +-
 libminifi/include/io/CRCStream.h                   |    4 +-
 libminifi/include/properties/Configure.h           |   10 +-
 libminifi/include/properties/Decryptor.h           |    8 +-
 libminifi/include/properties/Properties.h          |    8 +-
 libminifi/include/properties/PropertiesFile.h      |   20 +-
 libminifi/include/utils/ChecksumCalculator.h       |    9 +-
 libminifi/include/utils/Enum.h                     |    6 +-
 libminifi/include/utils/GeneralUtils.h             |   96 --
 libminifi/include/utils/HTTPClient.h               |    6 +-
 libminifi/include/utils/Id.h                       |    9 +-
 libminifi/include/utils/JsonCallback.h             |   11 +-
 libminifi/include/utils/OptionalUtils.h            |   68 +-
 libminifi/include/utils/ProcessorConfigUtils.h     |    7 +-
 libminifi/include/utils/StringUtils.h              |   71 +-
 libminifi/include/utils/TryMoveCall.h              |    5 +-
 libminifi/include/utils/crypto/EncryptionManager.h |   14 +-
 .../include/utils/crypto/EncryptionProvider.h      |   13 +-
 libminifi/include/utils/file/FileSystem.h          |   10 +-
 libminifi/include/utils/file/PathUtils.h           |    6 +-
 .../include/utils/requirements/LegacyIterator.h    |    2 +-
 libminifi/include/utils/requirements/Swappable.h   |    2 +-
 libminifi/include/utils/tls/DistinguishedName.h    |    7 +-
 libminifi/src/Configure.cpp                        |    8 +-
 libminifi/src/DiskSpaceWatchdog.cpp                |   14 +-
 libminifi/src/FlowController.cpp                   |    9 +-
 libminifi/src/SchedulingAgent.cpp                  |    5 +-
 libminifi/src/ThreadedSchedulingAgent.cpp          |   20 +-
 libminifi/src/c2/C2Agent.cpp                       |   22 +-
 libminifi/src/c2/C2Client.cpp                      |    2 +-
 libminifi/src/controllers/SSLContextService.cpp    |    3 +-
 .../keyvalue/PersistableKeyValueStoreService.cpp   |    2 +-
 libminifi/src/core/ConfigurationFactory.cpp        |   25 +-
 libminifi/src/core/FlowConfiguration.cpp           |    6 +-
 libminifi/src/core/FlowFile.cpp                    |    4 +-
 libminifi/src/core/logging/LoggerConfiguration.cpp |   15 +-
 .../core/logging/internal/CompressionManager.cpp   |    5 +-
 libminifi/src/core/yaml/YamlConfiguration.cpp      |    4 +-
 libminifi/src/core/yaml/YamlConnectionParser.cpp   |   10 +-
 libminifi/src/io/ClientSocket.cpp                  |   17 +-
 libminifi/src/io/StreamFactory.cpp                 |    4 +-
 libminifi/src/io/tls/TLSSocket.cpp                 |   13 +-
 libminifi/src/properties/Properties.cpp            |    4 +-
 libminifi/src/properties/PropertiesFile.cpp        |    4 +-
 libminifi/src/utils/BackTrace.cpp                  |    4 +-
 libminifi/src/utils/HTTPClient.cpp                 |    8 +-
 libminifi/src/utils/Id.cpp                         |    4 +-
 libminifi/src/utils/OsUtils.cpp                    |   12 +-
 libminifi/src/utils/ProcessorConfigUtils.cpp       |    6 +-
 libminifi/src/utils/StringUtils.cpp                |    6 +-
 libminifi/src/utils/crypto/EncryptionManager.cpp   |   18 +-
 libminifi/src/utils/crypto/EncryptionProvider.cpp  |    2 +-
 libminifi/src/utils/file/FileSystem.cpp            |    9 +-
 libminifi/src/utils/tls/DistinguishedName.cpp      |    4 +-
 libminifi/test/aws-tests/MockS3RequestSender.h     |   21 +-
 .../test/azure-tests/PutAzureBlobStorageTests.cpp  |    7 +-
 libminifi/test/flow-tests/TestControllerWithFlow.h |    2 +-
 libminifi/test/integration/IntegrationBase.h       |    8 +-
 .../UnorderedMapKeyValueStoreServiceTest.cpp       |    3 +-
 libminifi/test/sql-tests/ExecuteSQLTests.cpp       |    4 +-
 libminifi/test/sql-tests/FlowFileMatcher.h         |   11 +-
 .../test/sql-tests/QueryDatabaseTableTests.cpp     |    2 +-
 libminifi/test/sql-tests/SQLTestPlan.h             |   11 +-
 libminifi/test/sql-tests/mocks/MockConnectors.cpp  |   10 +-
 libminifi/test/sql-tests/mocks/MockODBCService.h   |    3 +-
 libminifi/test/unit/DecryptorTests.cpp             |   23 +-
 libminifi/test/unit/FileSystemTests.cpp            |    9 +-
 libminifi/test/unit/GeneralUtilsTest.cpp           |   78 -
 libminifi/test/unit/LoggerTests.cpp                |    2 +-
 libminifi/test/unit/OptionalTest.cpp               |   24 +-
 libminifi/test/unit/ProcessSessionTests.cpp        |   18 +-
 libminifi/test/unit/StringUtilsTests.cpp           |   13 +-
 main/MiNiFiMain.cpp                                |    9 +-
 thirdparty/optional-lite-3.2.0/LICENSE.txt         |   23 -
 .../include/nonstd/optional.hpp                    | 1698 --------------------
 172 files changed, 752 insertions(+), 2714 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 82ffde6..aa91b02 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -319,10 +319,6 @@ if (STRICT_GSL_CHECKS STREQUAL "DEBUG_ONLY")
 endif()
 target_compile_definitions(gsl-lite INTERFACE ${GslDefinitions})
 
-# optional-lite
-add_library(optional-lite INTERFACE)
-target_include_directories(optional-lite SYSTEM INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/optional-lite-3.2.0/include")
-
 # date
 include(Date)
 
diff --git a/LICENSE b/LICENSE
index 403682a..6eec454 100644
--- a/LICENSE
+++ b/LICENSE
@@ -2899,35 +2899,6 @@ SOFTWARE.
 
 --------------------------------------------------------------------------
 
-This product bundles 'optional-lite' which is available under a Boost Software License.
-optional-lite - Copyright (c) 2015 - 2018 Martin Moene
-
-Boost Software License - Version 1.0 - August 17th, 2003
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-
---------------------------------------------------------------------------
-
 This product bundles 'libsodium' which is available under the ISC software license.
 libsodium - Copyright (c) 2013 - 2018 Frank Denis
 
diff --git a/NOTICE b/NOTICE
index 3f2efc7..33322ac 100644
--- a/NOTICE
+++ b/NOTICE
@@ -54,7 +54,6 @@ This software includes third party software subject to the following copyrights:
 - OpenSSL build files for cmake used for Android Builds - Copyright (C) 2007-2012 LuaDist and Copyright (C) 2013 Brian Sidebotham
 - Android tool chain cmake build files - Copyright (c) 2010-2011, Ethan Rublee and Copyright (c) 2011-2014, Andrey Kamaev
 - gsl-lite - Copyright (c) 2015 Martin Moene and Copyright (c) 2015 Microsoft Corporation. All rights reserved.
-- optional-lite - Copyright (c) 2015-2018 Martin Moene under the Boost Software License
 - libsodium - Copyright (c) 2013 - 2018 Frank Denis under the ISC software license
 - IANA timezone database - public domain
 - date (HowardHinnant/date) - notices below
diff --git a/encrypt-config/ArgParser.cpp b/encrypt-config/ArgParser.cpp
index 2b98637..f02e5b2 100644
--- a/encrypt-config/ArgParser.cpp
+++ b/encrypt-config/ArgParser.cpp
@@ -95,11 +95,11 @@ void Arguments::set(const std::string& flag) {
   flags_.insert(flag);
 }
 
-utils::optional<std::string> Arguments::get(const std::string &key) const {
+std::optional<std::string> Arguments::get(const std::string &key) const {
   return getArg(key) | utils::flatMap([&] (const Argument& arg) {return get(arg);});
 }
 
-utils::optional<std::string> Arguments::get(const Argument& arg) const {
+std::optional<std::string> Arguments::get(const Argument& arg) const {
   for (const auto& name : arg.names) {
     auto it = args_.find(name);
     if (it != args_.end()) {
@@ -110,7 +110,7 @@ utils::optional<std::string> Arguments::get(const Argument& arg) const {
 }
 
 bool Arguments::isSet(const std::string &flag) const {
-  utils::optional<Flag> opt_flag = getFlag(flag);
+  std::optional<Flag> opt_flag = getFlag(flag);
   if (!opt_flag) {
     return false;
   }
@@ -147,7 +147,7 @@ Arguments Arguments::parse(int argc, char* argv[]) {
   return args;
 }
 
-utils::optional<Flag> Arguments::getFlag(const std::string &name) {
+std::optional<Flag> Arguments::getFlag(const std::string &name) {
   for (const auto& flag : registered_flags_) {
     if (flag.names.count(name) > 0) {
       return flag;
@@ -156,7 +156,7 @@ utils::optional<Flag> Arguments::getFlag(const std::string &name) {
   return {};
 }
 
-utils::optional<Argument> Arguments::getArg(const std::string &key) {
+std::optional<Argument> Arguments::getArg(const std::string &key) {
   for (const auto& arg : registered_args_) {
     if (arg.names.count(key) > 0) {
       return arg;
diff --git a/encrypt-config/ArgParser.h b/encrypt-config/ArgParser.h
index d33d3ee..a25c328 100644
--- a/encrypt-config/ArgParser.h
+++ b/encrypt-config/ArgParser.h
@@ -20,7 +20,7 @@
 #include <set>
 #include <vector>
 #include <map>
-#include "utils/OptionalUtils.h"
+#include <optional>
 
 namespace org {
 namespace apache {
@@ -48,20 +48,20 @@ class Arguments {
 
   void set(const std::string& bool_key);
 
-  static utils::optional<Argument> getArg(const std::string& key);
-  static utils::optional<Flag> getFlag(const std::string& flag);
+  static std::optional<Argument> getArg(const std::string& key);
+  static std::optional<Flag> getFlag(const std::string& flag);
 
  public:
   static Arguments parse(int argc, char* argv[]);
 
   static std::string getHelp();
 
-  utils::optional<std::string> get(const std::string& key) const;
+  [[nodiscard]] std::optional<std::string> get(const std::string& key) const;
 
-  bool isSet(const std::string& flag) const;
+  [[nodiscard]] bool isSet(const std::string& flag) const;
 
  private:
-  utils::optional<std::string> get(const Argument& key) const;
+  [[nodiscard]] std::optional<std::string> get(const Argument& key) const;
 
   std::map<std::string, std::string> args_;
   std::set<std::string> flags_;
diff --git a/encrypt-config/ConfigFile.cpp b/encrypt-config/ConfigFile.cpp
index b361d6b..4175716 100644
--- a/encrypt-config/ConfigFile.cpp
+++ b/encrypt-config/ConfigFile.cpp
@@ -20,6 +20,7 @@
 #include <algorithm>
 #include <fstream>
 #include <utility>
+#include <optional>
 
 #include "utils/StringUtils.h"
 
@@ -37,7 +38,7 @@ namespace encrypt_config {
 
 std::vector<std::string> ConfigFile::getSensitiveProperties() const {
   std::vector<std::string> sensitive_properties(DEFAULT_SENSITIVE_PROPERTIES.begin(), DEFAULT_SENSITIVE_PROPERTIES.end());
-  const utils::optional<std::string> additional_sensitive_props_list = getValue(ADDITIONAL_SENSITIVE_PROPS_PROPERTY_NAME);
+  const std::optional<std::string> additional_sensitive_props_list = getValue(ADDITIONAL_SENSITIVE_PROPS_PROPERTY_NAME);
   if (additional_sensitive_props_list) {
     std::vector<std::string> additional_sensitive_properties = utils::StringUtils::split(*additional_sensitive_props_list, ",");
     sensitive_properties = mergeProperties(sensitive_properties, additional_sensitive_properties);
diff --git a/encrypt-config/ConfigFile.h b/encrypt-config/ConfigFile.h
index 59cb7ef..0fed2c8 100644
--- a/encrypt-config/ConfigFile.h
+++ b/encrypt-config/ConfigFile.h
@@ -21,7 +21,6 @@
 #include <vector>
 
 #include "utils/crypto/EncryptionUtils.h"
-#include "utils/OptionalUtils.h"
 #include "properties/PropertiesFile.h"
 
 namespace org {
@@ -34,7 +33,7 @@ class ConfigFile : public PropertiesFile {
  public:
   using PropertiesFile::PropertiesFile;
 
-  std::vector<std::string> getSensitiveProperties() const;
+  [[nodiscard]] std::vector<std::string> getSensitiveProperties() const;
 
  private:
   friend class ConfigFileTestAccessor;
diff --git a/encrypt-config/ConfigFileEncryptor.cpp b/encrypt-config/ConfigFileEncryptor.cpp
index 128931b..4e8d287 100644
--- a/encrypt-config/ConfigFileEncryptor.cpp
+++ b/encrypt-config/ConfigFileEncryptor.cpp
@@ -18,6 +18,7 @@
 #include "ConfigFileEncryptor.h"
 
 #include <iostream>
+#include <optional>
 #include <string>
 
 #include "utils/StringUtils.h"
@@ -28,7 +29,7 @@ namespace nifi {
 namespace minifi {
 namespace encrypt_config {
 
-bool isEncrypted(const utils::optional<std::string>& encryption_type) {
+bool isEncrypted(const std::optional<std::string>& encryption_type) {
   return encryption_type && !encryption_type->empty() && *encryption_type  != "plaintext";
 }
 
@@ -40,11 +41,11 @@ uint32_t encryptSensitivePropertiesInFile(ConfigFile& config_file, const Encrypt
   int num_properties_encrypted = 0;
 
   for (const auto& property_key : config_file.getSensitiveProperties()) {
-    utils::optional<std::string> property_value = config_file.getValue(property_key);
+    std::optional<std::string> property_value = config_file.getValue(property_key);
     if (!property_value) { continue; }
 
     std::string encryption_type_key = property_key + ".protected";
-    utils::optional<std::string> encryption_type = config_file.getValue(encryption_type_key);
+    std::optional<std::string> encryption_type = config_file.getValue(encryption_type_key);
 
     std::string raw_value = *property_value;
     if (isEncrypted(encryption_type)) {
diff --git a/encrypt-config/EncryptConfig.cpp b/encrypt-config/EncryptConfig.cpp
index 743674f..61354bc 100644
--- a/encrypt-config/EncryptConfig.cpp
+++ b/encrypt-config/EncryptConfig.cpp
@@ -19,12 +19,12 @@
 
 #include <sodium.h>
 
+#include <optional>
 #include <stdexcept>
 
 #include "ConfigFile.h"
 #include "ConfigFileEncryptor.h"
 #include "utils/file/FileUtils.h"
-#include "utils/OptionalUtils.h"
 #include "Defaults.h"
 
 namespace {
@@ -58,7 +58,7 @@ EncryptConfig::EncryptionType EncryptConfig::encryptSensitiveProperties() const
 
 void EncryptConfig::encryptFlowConfig() const {
   encrypt_config::ConfigFile properties_file{std::ifstream{propertiesFilePath()}};
-  utils::optional<std::string> config_path = properties_file.getValue(Configure::nifi_flow_configuration_file);
+  std::optional<std::string> config_path = properties_file.getValue(Configure::nifi_flow_configuration_file);
   if (!config_path) {
     config_path = utils::file::PathUtils::resolve(minifi_home_, "conf/config.yml");
     std::cout << "Couldn't find path of configuration file, using default: \"" << *config_path << "\"\n";
@@ -115,8 +115,8 @@ std::string EncryptConfig::propertiesFilePath() const {
 
 EncryptionKeys EncryptConfig::getEncryptionKeys() const {
   encrypt_config::ConfigFile bootstrap_file{std::ifstream{bootstrapFilePath()}};
-  utils::optional<std::string> decryption_key_hex = bootstrap_file.getValue(OLD_KEY_PROPERTY_NAME);
-  utils::optional<std::string> encryption_key_hex = bootstrap_file.getValue(ENCRYPTION_KEY_PROPERTY_NAME);
+  std::optional<std::string> decryption_key_hex = bootstrap_file.getValue(OLD_KEY_PROPERTY_NAME);
+  std::optional<std::string> encryption_key_hex = bootstrap_file.getValue(ENCRYPTION_KEY_PROPERTY_NAME);
 
   EncryptionKeys keys;
   if (decryption_key_hex && !decryption_key_hex->empty()) {
diff --git a/encrypt-config/Utils.h b/encrypt-config/Utils.h
index cf4975e..fd645e2 100644
--- a/encrypt-config/Utils.h
+++ b/encrypt-config/Utils.h
@@ -16,8 +16,9 @@
  */
 #pragma once
 
+#include <optional>
+
 #include "utils/crypto/EncryptionUtils.h"
-#include "utils/OptionalUtils.h"
 
 namespace org {
 namespace apache {
@@ -26,7 +27,7 @@ namespace minifi {
 namespace encrypt_config {
 
 struct EncryptionKeys {
-  utils::optional<utils::crypto::Bytes> old_key;
+  std::optional<utils::crypto::Bytes> old_key;
   utils::crypto::Bytes encryption_key;
 };
 
diff --git a/encrypt-config/tests/ConfigFileEncryptorTests.cpp b/encrypt-config/tests/ConfigFileEncryptorTests.cpp
index 8d07abb..2b893aa 100644
--- a/encrypt-config/tests/ConfigFileEncryptorTests.cpp
+++ b/encrypt-config/tests/ConfigFileEncryptorTests.cpp
@@ -15,6 +15,9 @@
  * limitations under the License.
  */
 
+#include <optional>
+#include <string>
+
 #include "ConfigFileEncryptor.h"
 
 #include "TestBase.h"
@@ -29,10 +32,10 @@ size_t base64_length(size_t unencoded_length) {
 }
 
 bool check_encryption(const ConfigFile& test_file, const std::string& property_name, size_t original_value_length) {
-    utils::optional<std::string> encrypted_value = test_file.getValue(property_name);
+    const auto encrypted_value = test_file.getValue(property_name);
     if (!encrypted_value) { return false; }
 
-    utils::optional<std::string> encryption_type = test_file.getValue(property_name + ".protected");
+    const auto encryption_type = test_file.getValue(property_name + ".protected");
     if (!encryption_type || *encryption_type != utils::crypto::EncryptionType::name()) { return false; }
 
     auto length = base64_length(utils::crypto::EncryptionType::nonceLength()) +
diff --git a/encrypt-config/tests/ConfigFileTests.cpp b/encrypt-config/tests/ConfigFileTests.cpp
index da11ca8..be1a146 100644
--- a/encrypt-config/tests/ConfigFileTests.cpp
+++ b/encrypt-config/tests/ConfigFileTests.cpp
@@ -15,6 +15,10 @@
  * limitations under the License.
  */
 
+#include <optional>
+#include <string>
+#include <vector>
+
 #include "ConfigFile.h"
 
 #include "gsl/gsl-lite.hpp"
@@ -130,11 +134,11 @@ TEST_CASE("ConfigFile can find the value for a key", "[encrypt-config][getValue]
   ConfigFile test_file{std::ifstream{"resources/minifi.properties"}};
 
   SECTION("valid key") {
-    REQUIRE(test_file.getValue("nifi.bored.yield.duration") == utils::optional<std::string>{"10 millis"});
+    REQUIRE(test_file.getValue("nifi.bored.yield.duration") == "10 millis");
   }
 
   SECTION("nonexistent key") {
-    REQUIRE(test_file.getValue("nifi.bored.panda") == utils::nullopt);
+    REQUIRE(test_file.getValue("nifi.bored.panda") == std::nullopt);
   }
 }
 
@@ -143,7 +147,7 @@ TEST_CASE("ConfigFile can update the value for a key", "[encrypt-config][update]
 
   SECTION("valid key") {
     test_file.update("nifi.bored.yield.duration", "20 millis");
-    REQUIRE(test_file.getValue("nifi.bored.yield.duration") == utils::optional<std::string>{"20 millis"});
+    REQUIRE(test_file.getValue("nifi.bored.yield.duration") == "20 millis");
   }
 
   SECTION("nonexistent key") {
@@ -157,7 +161,7 @@ TEST_CASE("ConfigFile can add a new setting after an existing setting", "[encryp
   SECTION("valid key") {
     test_file.insertAfter("nifi.rest.api.password", "nifi.rest.api.password.protected", "my-cipher-name");
     REQUIRE(test_file.size() == 102);
-    REQUIRE(test_file.getValue("nifi.rest.api.password.protected") == utils::optional<std::string>{"my-cipher-name"});
+    REQUIRE(test_file.getValue("nifi.rest.api.password.protected") == "my-cipher-name");
   }
 
   SECTION("nonexistent key") {
@@ -172,7 +176,7 @@ TEST_CASE("ConfigFile can add a new setting at the end", "[encrypt-config][appen
   const std::string VALUE = "aa411f289c91685ef9d5a9e5a4fad9393ff4c7a78ab978484323488caed7a9ab";
   test_file.append(KEY, VALUE);
   REQUIRE(test_file.size() == 102);
-  REQUIRE(test_file.getValue(KEY) == utils::make_optional(VALUE));
+  REQUIRE(test_file.getValue(KEY) == std::make_optional(VALUE));
 }
 
 TEST_CASE("ConfigFile can write to a new file", "[encrypt-config][writeTo]") {
@@ -188,7 +192,7 @@ TEST_CASE("ConfigFile can write to a new file", "[encrypt-config][writeTo]") {
 
   ConfigFile test_file_copy{std::ifstream{file_path}};
   REQUIRE(test_file.size() == test_file_copy.size());
-  REQUIRE(test_file_copy.getValue("nifi.bored.yield.duration") == utils::optional<std::string>{"20 millis"});
+  REQUIRE(test_file_copy.getValue("nifi.bored.yield.duration") == "20 millis");
 }
 
 TEST_CASE("ConfigFile will throw if we try to write to an invalid file name", "[encrypt-config][writeTo]") {
diff --git a/extensions/aws/AWSCredentialsProvider.cpp b/extensions/aws/AWSCredentialsProvider.cpp
index 7bc4dbd..d9bc7f7 100644
--- a/extensions/aws/AWSCredentialsProvider.cpp
+++ b/extensions/aws/AWSCredentialsProvider.cpp
@@ -60,7 +60,7 @@ void AWSCredentialsProvider::setCredentialsFile(const std::string &credentials_f
   credentials_file_ = credentials_file;
 }
 
-minifi::utils::optional<Aws::Auth::AWSCredentials> AWSCredentialsProvider::getAWSCredentials() {
+std::optional<Aws::Auth::AWSCredentials> AWSCredentialsProvider::getAWSCredentials() {
   if (use_default_credentials_) {
     logger_->log_debug("Trying to use default AWS credentials provider chain.");
     auto creds = Aws::Auth::DefaultAWSCredentialsProviderChain().GetAWSCredentials();
@@ -88,7 +88,7 @@ minifi::utils::optional<Aws::Auth::AWSCredentials> AWSCredentialsProvider::getAW
   }
 
   logger_->log_debug("No AWS credentials were set.");
-  return minifi::utils::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace aws
diff --git a/extensions/aws/AWSCredentialsProvider.h b/extensions/aws/AWSCredentialsProvider.h
index aef2c80..a3aa1e7 100644
--- a/extensions/aws/AWSCredentialsProvider.h
+++ b/extensions/aws/AWSCredentialsProvider.h
@@ -20,12 +20,12 @@
 
 #pragma once
 
-#include <string>
 #include <memory>
+#include <optional>
+#include <string>
 
 #include "aws/core/auth/AWSCredentials.h"
 #include "utils/AWSInitializer.h"
-#include "utils/OptionalUtils.h"
 #include "core/logging/Logger.h"
 #include "core/logging/LoggerConfiguration.h"
 
@@ -47,7 +47,7 @@ class AWSCredentialsProvider {
   void setSecretKey(const std::string &secret_key);
   void setCredentialsFile(const std::string &credentials_file);
   bool getUseDefaultCredentials() const;
-  minifi::utils::optional<Aws::Auth::AWSCredentials> getAWSCredentials();
+  std::optional<Aws::Auth::AWSCredentials> getAWSCredentials();
 
  private:
   const utils::AWSInitializer& AWS_INITIALIZER = utils::AWSInitializer::get();
diff --git a/extensions/aws/controllerservices/AWSCredentialsService.cpp b/extensions/aws/controllerservices/AWSCredentialsService.cpp
index b1960fa..7b21012 100644
--- a/extensions/aws/controllerservices/AWSCredentialsService.cpp
+++ b/extensions/aws/controllerservices/AWSCredentialsService.cpp
@@ -76,7 +76,7 @@ void AWSCredentialsService::onEnable() {
   }
 }
 
-minifi::utils::optional<Aws::Auth::AWSCredentials> AWSCredentialsService::getAWSCredentials() {
+std::optional<Aws::Auth::AWSCredentials> AWSCredentialsService::getAWSCredentials() {
   if (aws_credentials_provider_.getUseDefaultCredentials() || !aws_credentials_ || aws_credentials_->IsExpiredOrEmpty()) {
     aws_credentials_ = aws_credentials_provider_.getAWSCredentials();
   }
diff --git a/extensions/aws/controllerservices/AWSCredentialsService.h b/extensions/aws/controllerservices/AWSCredentialsService.h
index b38b54f..b3026d8 100644
--- a/extensions/aws/controllerservices/AWSCredentialsService.h
+++ b/extensions/aws/controllerservices/AWSCredentialsService.h
@@ -18,13 +18,13 @@
 
 #pragma once
 
-#include <string>
 #include <memory>
+#include <optional>
+#include <string>
 
 #include "aws/core/auth/AWSCredentials.h"
 
 #include "utils/AWSInitializer.h"
-#include "utils/OptionalUtils.h"
 #include "core/Resource.h"
 #include "core/controller/ControllerService.h"
 #include "core/logging/LoggerConfiguration.h"
@@ -69,13 +69,13 @@ class AWSCredentialsService : public core::controller::ControllerService {
 
   void onEnable() override;
 
-  minifi::utils::optional<Aws::Auth::AWSCredentials> getAWSCredentials();
+  std::optional<Aws::Auth::AWSCredentials> getAWSCredentials();
 
  private:
   friend class ::AWSCredentialsServiceTestAccessor;
 
   const utils::AWSInitializer& AWS_INITIALIZER = utils::AWSInitializer::get();
-  minifi::utils::optional<Aws::Auth::AWSCredentials> aws_credentials_;
+  std::optional<Aws::Auth::AWSCredentials> aws_credentials_;
   AWSCredentialsProvider aws_credentials_provider_;
 };
 
diff --git a/extensions/aws/processors/DeleteS3Object.cpp b/extensions/aws/processors/DeleteS3Object.cpp
index c20d57e..39601ae 100644
--- a/extensions/aws/processors/DeleteS3Object.cpp
+++ b/extensions/aws/processors/DeleteS3Object.cpp
@@ -51,7 +51,7 @@ void DeleteS3Object::initialize() {
   setSupportedRelationships({Failure, Success});
 }
 
-minifi::utils::optional<aws::s3::DeleteObjectRequestParameters> DeleteS3Object::buildDeleteS3RequestParams(
+std::optional<aws::s3::DeleteObjectRequestParameters> DeleteS3Object::buildDeleteS3RequestParams(
     const std::shared_ptr<core::ProcessContext> &context,
     const std::shared_ptr<core::FlowFile> &flow_file,
     const CommonProperties &common_properties) const {
@@ -59,7 +59,7 @@ minifi::utils::optional<aws::s3::DeleteObjectRequestParameters> DeleteS3Object::
   context->getProperty(ObjectKey, params.object_key, flow_file);
   if (params.object_key.empty() && (!flow_file->getAttribute("filename", params.object_key) || params.object_key.empty())) {
     logger_->log_error("No Object Key is set and default object key 'filename' attribute could not be found!");
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
   logger_->log_debug("DeleteS3Object: Object Key [%s]", params.object_key);
 
diff --git a/extensions/aws/processors/DeleteS3Object.h b/extensions/aws/processors/DeleteS3Object.h
index 41c15c0..52a6f19 100644
--- a/extensions/aws/processors/DeleteS3Object.h
+++ b/extensions/aws/processors/DeleteS3Object.h
@@ -20,10 +20,11 @@
 
 #pragma once
 
-#include <sstream>
-#include <utility>
 #include <memory>
+#include <optional>
+#include <sstream>
 #include <string>
+#include <utility>
 
 #include "S3Processor.h"
 #include "utils/GeneralUtils.h"
@@ -70,7 +71,7 @@ class DeleteS3Object : public S3Processor {
     : S3Processor(name, uuid, logging::LoggerFactory<DeleteS3Object>::getLogger(), std::move(s3_request_sender)) {
   }
 
-  minifi::utils::optional<aws::s3::DeleteObjectRequestParameters> buildDeleteS3RequestParams(
+  std::optional<aws::s3::DeleteObjectRequestParameters> buildDeleteS3RequestParams(
     const std::shared_ptr<core::ProcessContext> &context,
     const std::shared_ptr<core::FlowFile> &flow_file,
     const CommonProperties &common_properties) const;
diff --git a/extensions/aws/processors/FetchS3Object.cpp b/extensions/aws/processors/FetchS3Object.cpp
index 0ee6ab4..b913f43 100644
--- a/extensions/aws/processors/FetchS3Object.cpp
+++ b/extensions/aws/processors/FetchS3Object.cpp
@@ -65,7 +65,7 @@ void FetchS3Object::onSchedule(const std::shared_ptr<core::ProcessContext> &cont
   logger_->log_debug("FetchS3Object: RequesterPays [%s]", requester_pays_ ? "true" : "false");
 }
 
-minifi::utils::optional<aws::s3::GetObjectRequestParameters> FetchS3Object::buildFetchS3RequestParams(
+std::optional<aws::s3::GetObjectRequestParameters> FetchS3Object::buildFetchS3RequestParams(
     const std::shared_ptr<core::ProcessContext> &context,
     const std::shared_ptr<core::FlowFile> &flow_file,
     const CommonProperties &common_properties) const {
@@ -76,7 +76,7 @@ minifi::utils::optional<aws::s3::GetObjectRequestParameters> FetchS3Object::buil
   context->getProperty(ObjectKey, get_object_params.object_key, flow_file);
   if (get_object_params.object_key.empty() && (!flow_file->getAttribute("filename", get_object_params.object_key) || get_object_params.object_key.empty())) {
     logger_->log_error("No Object Key is set and default object key 'filename' attribute could not be found!");
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
   logger_->log_debug("FetchS3Object: Object Key [%s]", get_object_params.object_key);
 
diff --git a/extensions/aws/processors/FetchS3Object.h b/extensions/aws/processors/FetchS3Object.h
index 3b86efc..d248e73 100644
--- a/extensions/aws/processors/FetchS3Object.h
+++ b/extensions/aws/processors/FetchS3Object.h
@@ -20,10 +20,11 @@
 
 #pragma once
 
-#include <sstream>
-#include <utility>
 #include <memory>
+#include <optional>
 #include <string>
+#include <sstream>
+#include <utility>
 #include <vector>
 
 #include "S3Processor.h"
@@ -85,7 +86,7 @@ class FetchS3Object : public S3Processor {
     const minifi::aws::s3::GetObjectRequestParameters& get_object_params_;
     aws::s3::S3Wrapper& s3_wrapper_;
     uint64_t write_size_ = 0;
-    minifi::utils::optional<minifi::aws::s3::GetObjectResult> result_ = minifi::utils::nullopt;
+    std::optional<minifi::aws::s3::GetObjectResult> result_;
   };
 
  private:
@@ -99,7 +100,7 @@ class FetchS3Object : public S3Processor {
     : S3Processor(name, uuid, logging::LoggerFactory<FetchS3Object>::getLogger(), std::move(s3_request_sender)) {
   }
 
-  minifi::utils::optional<aws::s3::GetObjectRequestParameters> buildFetchS3RequestParams(
+  std::optional<aws::s3::GetObjectRequestParameters> buildFetchS3RequestParams(
     const std::shared_ptr<core::ProcessContext> &context,
     const std::shared_ptr<core::FlowFile> &flow_file,
     const CommonProperties &common_properties) const;
diff --git a/extensions/aws/processors/ListS3.cpp b/extensions/aws/processors/ListS3.cpp
index 974358a..ca6308f 100644
--- a/extensions/aws/processors/ListS3.cpp
+++ b/extensions/aws/processors/ListS3.cpp
@@ -99,7 +99,7 @@ void ListS3::onSchedule(const std::shared_ptr<core::ProcessContext> &context, co
   if (!common_properties) {
     throw Exception(PROCESS_SCHEDULE_EXCEPTION, "Required property is not set or invalid");
   }
-  list_request_params_ = minifi::utils::make_unique<aws::s3::ListRequestParameters>(common_properties->credentials, client_config_);
+  list_request_params_ = std::make_unique<aws::s3::ListRequestParameters>(common_properties->credentials, client_config_);
   list_request_params_->setClientConfig(common_properties->proxy, common_properties->endpoint_override_url);
   list_request_params_->bucket = common_properties->bucket;
 
diff --git a/extensions/aws/processors/PutS3Object.cpp b/extensions/aws/processors/PutS3Object.cpp
index 80a7483..bff91bf 100644
--- a/extensions/aws/processors/PutS3Object.cpp
+++ b/extensions/aws/processors/PutS3Object.cpp
@@ -202,7 +202,7 @@ bool PutS3Object::setAccessControl(
   return setCannedAcl(context, flow_file, put_s3_request_params);
 }
 
-minifi::utils::optional<aws::s3::PutObjectRequestParameters> PutS3Object::buildPutS3RequestParams(
+std::optional<aws::s3::PutObjectRequestParameters> PutS3Object::buildPutS3RequestParams(
     const std::shared_ptr<core::ProcessContext> &context,
     const std::shared_ptr<core::FlowFile> &flow_file,
     const CommonProperties &common_properties) const {
@@ -216,7 +216,7 @@ minifi::utils::optional<aws::s3::PutObjectRequestParameters> PutS3Object::buildP
   context->getProperty(ObjectKey, params.object_key, flow_file);
   if (params.object_key.empty() && (!flow_file->getAttribute("filename", params.object_key) || params.object_key.empty())) {
     logger_->log_error("No Object Key is set and default object key 'filename' attribute could not be found!");
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
   logger_->log_debug("PutS3Object: Object Key [%s]", params.object_key);
 
@@ -224,7 +224,7 @@ minifi::utils::optional<aws::s3::PutObjectRequestParameters> PutS3Object::buildP
   logger_->log_debug("PutS3Object: Content Type [%s]", params.content_type);
 
   if (!setAccessControl(context, flow_file, params)) {
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
   return params;
 }
@@ -277,7 +277,7 @@ void PutS3Object::onTrigger(const std::shared_ptr<core::ProcessContext> &context
 
   PutS3Object::ReadCallback callback(flow_file->getSize(), *put_s3_request_params, s3_wrapper_);
   session->read(flow_file, &callback);
-  if (callback.result_ == minifi::utils::nullopt) {
+  if (!callback.result_.has_value()) {
     logger_->log_error("Failed to upload S3 object to bucket '%s'", put_s3_request_params->bucket);
     session->transfer(flow_file, Failure);
   } else {
diff --git a/extensions/aws/processors/PutS3Object.h b/extensions/aws/processors/PutS3Object.h
index fb14d2b..6623e73 100644
--- a/extensions/aws/processors/PutS3Object.h
+++ b/extensions/aws/processors/PutS3Object.h
@@ -20,18 +20,19 @@
 
 #pragma once
 
+#include <algorithm>
+#include <map>
+#include <memory>
+#include <optional>
+#include <set>
 #include <sstream>
+#include <string>
 #include <utility>
 #include <vector>
-#include <memory>
-#include <string>
-#include <set>
-#include <map>
-#include <algorithm>
 
 #include "S3Processor.h"
-#include "utils/GeneralUtils.h"
 #include "utils/gsl.h"
+#include "utils/Id.h"
 
 template<typename T>
 class S3TestsFixture;
@@ -115,7 +116,7 @@ class PutS3Object : public S3Processor {
     const minifi::aws::s3::PutObjectRequestParameters& options_;
     aws::s3::S3Wrapper& s3_wrapper_;
     uint64_t read_size_ = 0;
-    minifi::utils::optional<minifi::aws::s3::PutObjectResult> result_ = minifi::utils::nullopt;
+    std::optional<minifi::aws::s3::PutObjectResult> result_;
   };
 
  private:
@@ -138,7 +139,7 @@ class PutS3Object : public S3Processor {
     const std::shared_ptr<core::FlowFile> &flow_file,
     const aws::s3::PutObjectRequestParameters &put_s3_request_params,
     const minifi::aws::s3::PutObjectResult &put_object_result) const;
-  minifi::utils::optional<aws::s3::PutObjectRequestParameters> buildPutS3RequestParams(
+  std::optional<aws::s3::PutObjectRequestParameters> buildPutS3RequestParams(
     const std::shared_ptr<core::ProcessContext> &context,
     const std::shared_ptr<core::FlowFile> &flow_file,
     const CommonProperties &common_properties) const;
diff --git a/extensions/aws/processors/S3Processor.cpp b/extensions/aws/processors/S3Processor.cpp
index d8cfa33..c720860 100644
--- a/extensions/aws/processors/S3Processor.cpp
+++ b/extensions/aws/processors/S3Processor.cpp
@@ -129,28 +129,28 @@ S3Processor::S3Processor(const std::string& name, const minifi::utils::Identifie
                           EndpointOverrideURL, ProxyHost, ProxyPort, ProxyUsername, ProxyPassword, UseDefaultCredentials});
 }
 
-minifi::utils::optional<Aws::Auth::AWSCredentials> S3Processor::getAWSCredentialsFromControllerService(const std::shared_ptr<core::ProcessContext> &context) const {
+std::optional<Aws::Auth::AWSCredentials> S3Processor::getAWSCredentialsFromControllerService(const std::shared_ptr<core::ProcessContext> &context) const {
   std::string service_name;
   if (!context->getProperty(AWSCredentialsProviderService.getName(), service_name) || service_name.empty()) {
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
 
   std::shared_ptr<core::controller::ControllerService> service = context->getControllerService(service_name);
   if (!service) {
     logger_->log_error("AWS credentials service with name: '%s' could not be found", service_name);
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
 
   auto aws_credentials_service = std::dynamic_pointer_cast<minifi::aws::controllers::AWSCredentialsService>(service);
   if (!aws_credentials_service) {
     logger_->log_error("Controller service with name: '%s' is not an AWS credentials service", service_name);
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
 
   return aws_credentials_service->getAWSCredentials();
 }
 
-minifi::utils::optional<Aws::Auth::AWSCredentials> S3Processor::getAWSCredentials(
+std::optional<Aws::Auth::AWSCredentials> S3Processor::getAWSCredentials(
     const std::shared_ptr<core::ProcessContext> &context,
     const std::shared_ptr<core::FlowFile> &flow_file) {
   auto service_cred = getAWSCredentialsFromControllerService(context);
@@ -178,13 +178,13 @@ minifi::utils::optional<Aws::Auth::AWSCredentials> S3Processor::getAWSCredential
   return aws_credentials_provider.getAWSCredentials();
 }
 
-minifi::utils::optional<aws::s3::ProxyOptions> S3Processor::getProxy(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::FlowFile> &flow_file) {
+std::optional<aws::s3::ProxyOptions> S3Processor::getProxy(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::FlowFile> &flow_file) {
   aws::s3::ProxyOptions proxy;
   context->getProperty(ProxyHost, proxy.host, flow_file);
   std::string port_str;
   if (context->getProperty(ProxyPort, port_str, flow_file) && !port_str.empty() && !core::Property::StringToInt(port_str, proxy.port)) {
     logger_->log_error("Proxy port invalid");
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
   context->getProperty(ProxyUsername, proxy.username, flow_file);
   context->getProperty(ProxyPassword, proxy.password, flow_file);
@@ -214,26 +214,26 @@ void S3Processor::onSchedule(const std::shared_ptr<core::ProcessContext>& contex
   }
 }
 
-minifi::utils::optional<CommonProperties> S3Processor::getCommonELSupportedProperties(
+std::optional<CommonProperties> S3Processor::getCommonELSupportedProperties(
     const std::shared_ptr<core::ProcessContext> &context,
     const std::shared_ptr<core::FlowFile> &flow_file) {
   CommonProperties properties;
   if (!context->getProperty(Bucket, properties.bucket, flow_file) || properties.bucket.empty()) {
     logger_->log_error("Bucket '%s' is invalid or empty!", properties.bucket);
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
   logger_->log_debug("S3Processor: Bucket [%s]", properties.bucket);
 
   auto credentials = getAWSCredentials(context, flow_file);
   if (!credentials) {
     logger_->log_error("AWS Credentials have not been set!");
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
   properties.credentials = credentials.value();
 
   auto proxy = getProxy(context, flow_file);
   if (!proxy) {
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
   properties.proxy = proxy.value();
 
diff --git a/extensions/aws/processors/S3Processor.h b/extensions/aws/processors/S3Processor.h
index 55f26db..eaad8fb 100644
--- a/extensions/aws/processors/S3Processor.h
+++ b/extensions/aws/processors/S3Processor.h
@@ -20,10 +20,11 @@
 
 #pragma once
 
-#include <utility>
 #include <memory>
-#include <string>
+#include <optional>
 #include <set>
+#include <string>
+#include <utility>
 
 #include "aws/core/auth/AWSCredentialsProvider.h"
 
@@ -107,10 +108,10 @@ class S3Processor : public core::Processor {
  protected:
   explicit S3Processor(const std::string& name, const minifi::utils::Identifier& uuid, const std::shared_ptr<logging::Logger> &logger, std::unique_ptr<aws::s3::S3RequestSender> s3_request_sender);
 
-  minifi::utils::optional<Aws::Auth::AWSCredentials> getAWSCredentialsFromControllerService(const std::shared_ptr<core::ProcessContext> &context) const;
-  minifi::utils::optional<Aws::Auth::AWSCredentials> getAWSCredentials(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::FlowFile> &flow_file);
-  minifi::utils::optional<aws::s3::ProxyOptions> getProxy(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::FlowFile> &flow_file);
-  minifi::utils::optional<CommonProperties> getCommonELSupportedProperties(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::FlowFile> &flow_file);
+  std::optional<Aws::Auth::AWSCredentials> getAWSCredentialsFromControllerService(const std::shared_ptr<core::ProcessContext> &context) const;
+  std::optional<Aws::Auth::AWSCredentials> getAWSCredentials(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::FlowFile> &flow_file);
+  std::optional<aws::s3::ProxyOptions> getProxy(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::FlowFile> &flow_file);
+  std::optional<CommonProperties> getCommonELSupportedProperties(const std::shared_ptr<core::ProcessContext> &context, const std::shared_ptr<core::FlowFile> &flow_file);
 
   std::shared_ptr<logging::Logger> logger_;
   aws::s3::S3Wrapper s3_wrapper_;
diff --git a/extensions/aws/s3/S3ClientRequestSender.cpp b/extensions/aws/s3/S3ClientRequestSender.cpp
index e8c0084..66d415f 100644
--- a/extensions/aws/s3/S3ClientRequestSender.cpp
+++ b/extensions/aws/s3/S3ClientRequestSender.cpp
@@ -28,7 +28,7 @@ namespace minifi {
 namespace aws {
 namespace s3 {
 
-minifi::utils::optional<Aws::S3::Model::PutObjectResult> S3ClientRequestSender::sendPutObjectRequest(
+std::optional<Aws::S3::Model::PutObjectResult> S3ClientRequestSender::sendPutObjectRequest(
     const Aws::S3::Model::PutObjectRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) {
@@ -40,7 +40,7 @@ minifi::utils::optional<Aws::S3::Model::PutObjectResult> S3ClientRequestSender::
       return outcome.GetResultWithOwnership();
   } else {
     logger_->log_error("PutS3Object failed with the following: '%s'", outcome.GetError().GetMessage());
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
 }
 
@@ -63,7 +63,7 @@ bool S3ClientRequestSender::sendDeleteObjectRequest(
   }
 }
 
-minifi::utils::optional<Aws::S3::Model::GetObjectResult> S3ClientRequestSender::sendGetObjectRequest(
+std::optional<Aws::S3::Model::GetObjectResult> S3ClientRequestSender::sendGetObjectRequest(
     const Aws::S3::Model::GetObjectRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) {
@@ -75,11 +75,11 @@ minifi::utils::optional<Aws::S3::Model::GetObjectResult> S3ClientRequestSender::
     return outcome.GetResultWithOwnership();
   } else {
     logger_->log_error("FetchS3Object failed with the following: '%s'", outcome.GetError().GetMessage());
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
 }
 
-minifi::utils::optional<Aws::S3::Model::ListObjectsV2Result> S3ClientRequestSender::sendListObjectsRequest(
+std::optional<Aws::S3::Model::ListObjectsV2Result> S3ClientRequestSender::sendListObjectsRequest(
     const Aws::S3::Model::ListObjectsV2Request& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) {
@@ -91,11 +91,11 @@ minifi::utils::optional<Aws::S3::Model::ListObjectsV2Result> S3ClientRequestSend
     return outcome.GetResultWithOwnership();
   } else {
     logger_->log_error("ListObjectsV2 failed with the following: '%s'", outcome.GetError().GetMessage());
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
 }
 
-minifi::utils::optional<Aws::S3::Model::ListObjectVersionsResult> S3ClientRequestSender::sendListVersionsRequest(
+std::optional<Aws::S3::Model::ListObjectVersionsResult> S3ClientRequestSender::sendListVersionsRequest(
     const Aws::S3::Model::ListObjectVersionsRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) {
@@ -107,11 +107,11 @@ minifi::utils::optional<Aws::S3::Model::ListObjectVersionsResult> S3ClientReques
     return outcome.GetResultWithOwnership();
   } else {
     logger_->log_error("ListObjectVersions failed with the following: '%s'", outcome.GetError().GetMessage());
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
 }
 
-minifi::utils::optional<Aws::S3::Model::GetObjectTaggingResult> S3ClientRequestSender::sendGetObjectTaggingRequest(
+std::optional<Aws::S3::Model::GetObjectTaggingResult> S3ClientRequestSender::sendGetObjectTaggingRequest(
     const Aws::S3::Model::GetObjectTaggingRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) {
@@ -123,11 +123,11 @@ minifi::utils::optional<Aws::S3::Model::GetObjectTaggingResult> S3ClientRequestS
     return outcome.GetResultWithOwnership();
   } else {
     logger_->log_error("GetObjectTagging failed with the following: '%s'", outcome.GetError().GetMessage());
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
 }
 
-minifi::utils::optional<Aws::S3::Model::HeadObjectResult> S3ClientRequestSender::sendHeadObjectRequest(
+std::optional<Aws::S3::Model::HeadObjectResult> S3ClientRequestSender::sendHeadObjectRequest(
     const Aws::S3::Model::HeadObjectRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) {
@@ -139,7 +139,7 @@ minifi::utils::optional<Aws::S3::Model::HeadObjectResult> S3ClientRequestSender:
     return outcome.GetResultWithOwnership();
   } else {
     logger_->log_error("HeadS3Object failed with the following: '%s'", outcome.GetError().GetMessage());
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
 }
 
diff --git a/extensions/aws/s3/S3ClientRequestSender.h b/extensions/aws/s3/S3ClientRequestSender.h
index f16293f..01b0e5c 100644
--- a/extensions/aws/s3/S3ClientRequestSender.h
+++ b/extensions/aws/s3/S3ClientRequestSender.h
@@ -19,6 +19,8 @@
  */
 #pragma once
 
+#include <optional>
+
 #include "S3RequestSender.h"
 
 namespace org {
@@ -30,7 +32,7 @@ namespace s3 {
 
 class S3ClientRequestSender : public S3RequestSender {
  public:
-  minifi::utils::optional<Aws::S3::Model::PutObjectResult> sendPutObjectRequest(
+  std::optional<Aws::S3::Model::PutObjectResult> sendPutObjectRequest(
     const Aws::S3::Model::PutObjectRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) override;
@@ -38,23 +40,23 @@ class S3ClientRequestSender : public S3RequestSender {
     const Aws::S3::Model::DeleteObjectRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) override;
-  minifi::utils::optional<Aws::S3::Model::GetObjectResult> sendGetObjectRequest(
+  std::optional<Aws::S3::Model::GetObjectResult> sendGetObjectRequest(
     const Aws::S3::Model::GetObjectRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) override;
-  minifi::utils::optional<Aws::S3::Model::ListObjectsV2Result> sendListObjectsRequest(
+  std::optional<Aws::S3::Model::ListObjectsV2Result> sendListObjectsRequest(
     const Aws::S3::Model::ListObjectsV2Request& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) override;
-  minifi::utils::optional<Aws::S3::Model::ListObjectVersionsResult> sendListVersionsRequest(
+  std::optional<Aws::S3::Model::ListObjectVersionsResult> sendListVersionsRequest(
     const Aws::S3::Model::ListObjectVersionsRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) override;
-  minifi::utils::optional<Aws::S3::Model::GetObjectTaggingResult> sendGetObjectTaggingRequest(
+  std::optional<Aws::S3::Model::GetObjectTaggingResult> sendGetObjectTaggingRequest(
     const Aws::S3::Model::GetObjectTaggingRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) override;
-  minifi::utils::optional<Aws::S3::Model::HeadObjectResult> sendHeadObjectRequest(
+  std::optional<Aws::S3::Model::HeadObjectResult> sendHeadObjectRequest(
     const Aws::S3::Model::HeadObjectRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) override;
diff --git a/extensions/aws/s3/S3RequestSender.h b/extensions/aws/s3/S3RequestSender.h
index 09a528d..dd8f043 100644
--- a/extensions/aws/s3/S3RequestSender.h
+++ b/extensions/aws/s3/S3RequestSender.h
@@ -19,8 +19,9 @@
  */
 #pragma once
 
-#include <string>
 #include <memory>
+#include <optional>
+#include <string>
 
 #include "aws/core/auth/AWSCredentials.h"
 #include "aws/core/client/ClientConfiguration.h"
@@ -40,7 +41,6 @@
 #include "aws/s3/model/HeadObjectResult.h"
 #include "core/logging/Logger.h"
 #include "core/logging/LoggerConfiguration.h"
-#include "utils/OptionalUtils.h"
 #include "utils/AWSInitializer.h"
 
 namespace org {
@@ -59,7 +59,7 @@ struct ProxyOptions {
 
 class S3RequestSender {
  public:
-  virtual minifi::utils::optional<Aws::S3::Model::PutObjectResult> sendPutObjectRequest(
+  virtual std::optional<Aws::S3::Model::PutObjectResult> sendPutObjectRequest(
     const Aws::S3::Model::PutObjectRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) = 0;
@@ -67,23 +67,23 @@ class S3RequestSender {
     const Aws::S3::Model::DeleteObjectRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) = 0;
-  virtual minifi::utils::optional<Aws::S3::Model::GetObjectResult> sendGetObjectRequest(
+  virtual std::optional<Aws::S3::Model::GetObjectResult> sendGetObjectRequest(
     const Aws::S3::Model::GetObjectRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) = 0;
-  virtual minifi::utils::optional<Aws::S3::Model::ListObjectsV2Result> sendListObjectsRequest(
+  virtual std::optional<Aws::S3::Model::ListObjectsV2Result> sendListObjectsRequest(
     const Aws::S3::Model::ListObjectsV2Request& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) = 0;
-  virtual minifi::utils::optional<Aws::S3::Model::ListObjectVersionsResult> sendListVersionsRequest(
+  virtual std::optional<Aws::S3::Model::ListObjectVersionsResult> sendListVersionsRequest(
     const Aws::S3::Model::ListObjectVersionsRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) = 0;
-  virtual minifi::utils::optional<Aws::S3::Model::GetObjectTaggingResult> sendGetObjectTaggingRequest(
+  virtual std::optional<Aws::S3::Model::GetObjectTaggingResult> sendGetObjectTaggingRequest(
     const Aws::S3::Model::GetObjectTaggingRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) = 0;
-  virtual minifi::utils::optional<Aws::S3::Model::HeadObjectResult> sendHeadObjectRequest(
+  virtual std::optional<Aws::S3::Model::HeadObjectResult> sendHeadObjectRequest(
     const Aws::S3::Model::HeadObjectRequest& request,
     const Aws::Auth::AWSCredentials& credentials,
     const Aws::Client::ClientConfiguration& client_config) = 0;
diff --git a/extensions/aws/s3/S3Wrapper.cpp b/extensions/aws/s3/S3Wrapper.cpp
index a01b331..4f7bbb5 100644
--- a/extensions/aws/s3/S3Wrapper.cpp
+++ b/extensions/aws/s3/S3Wrapper.cpp
@@ -25,7 +25,6 @@
 #include <vector>
 
 #include "S3ClientRequestSender.h"
-#include "utils/GeneralUtils.h"
 #include "utils/StringUtils.h"
 #include "utils/file/FileUtils.h"
 #include "utils/RegexUtils.h"
@@ -43,7 +42,7 @@ void HeadObjectResult::setFilePaths(const std::string& key) {
   std::tie(path, filename) = minifi::utils::file::FileUtils::split_path(key, true /*force_posix*/);
 }
 
-S3Wrapper::S3Wrapper() : request_sender_(minifi::utils::make_unique<S3ClientRequestSender>()) {
+S3Wrapper::S3Wrapper() : request_sender_(std::make_unique<S3ClientRequestSender>()) {
 }
 
 S3Wrapper::S3Wrapper(std::unique_ptr<S3RequestSender>&& request_sender) : request_sender_(std::move(request_sender)) {
@@ -81,7 +80,7 @@ std::string S3Wrapper::getEncryptionString(Aws::S3::Model::ServerSideEncryption
   return "";
 }
 
-minifi::utils::optional<PutObjectResult> S3Wrapper::putObject(const PutObjectRequestParameters& put_object_params, std::shared_ptr<Aws::IOStream> data_stream) {
+std::optional<PutObjectResult> S3Wrapper::putObject(const PutObjectRequestParameters& put_object_params, std::shared_ptr<Aws::IOStream> data_stream) {
   Aws::S3::Model::PutObjectRequest request;
   request.SetBucket(put_object_params.bucket);
   request.SetKey(put_object_params.object_key);
@@ -98,7 +97,7 @@ minifi::utils::optional<PutObjectResult> S3Wrapper::putObject(const PutObjectReq
 
   auto aws_result = request_sender_->sendPutObjectRequest(request, put_object_params.credentials, put_object_params.client_config);
   if (!aws_result) {
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
 
   PutObjectResult result;
@@ -141,11 +140,11 @@ int64_t S3Wrapper::writeFetchedBody(Aws::IOStream& source, const int64_t data_si
   return gsl::narrow<int64_t>(write_size);
 }
 
-minifi::utils::optional<GetObjectResult> S3Wrapper::getObject(const GetObjectRequestParameters& get_object_params, io::BaseStream& out_body) {
+std::optional<GetObjectResult> S3Wrapper::getObject(const GetObjectRequestParameters& get_object_params, io::BaseStream& out_body) {
   auto request = createFetchObjectRequest<Aws::S3::Model::GetObjectRequest>(get_object_params);
   auto aws_result = request_sender_->sendGetObjectRequest(request, get_object_params.credentials, get_object_params.client_config);
   if (!aws_result) {
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
   auto result = fillFetchObjectResult<Aws::S3::Model::GetObjectResult, GetObjectResult>(get_object_params, *aws_result);
   result.write_size = writeFetchedBody(aws_result->GetBody(), aws_result->GetContentLength(), out_body);
@@ -189,14 +188,14 @@ void S3Wrapper::addListResults(const Aws::Vector<Aws::S3::Model::Object>& conten
   }
 }
 
-minifi::utils::optional<std::vector<ListedObjectAttributes>> S3Wrapper::listVersions(const ListRequestParameters& params) {
+std::optional<std::vector<ListedObjectAttributes>> S3Wrapper::listVersions(const ListRequestParameters& params) {
   auto request = createListRequest<Aws::S3::Model::ListObjectVersionsRequest>(params);
   std::vector<ListedObjectAttributes> attribute_list;
-  minifi::utils::optional<Aws::S3::Model::ListObjectVersionsResult> aws_result;
+  std::optional<Aws::S3::Model::ListObjectVersionsResult> aws_result;
   do {
     aws_result = request_sender_->sendListVersionsRequest(request, params.credentials, params.client_config);
     if (!aws_result) {
-      return minifi::utils::nullopt;
+      return std::nullopt;
     }
     const auto& versions = aws_result->GetVersions();
     logger_->log_debug("AWS S3 List operation returned %zu versions. This result is%s truncated.", versions.size(), aws_result->GetIsTruncated() ? "" : " not");
@@ -210,14 +209,14 @@ minifi::utils::optional<std::vector<ListedObjectAttributes>> S3Wrapper::listVers
   return attribute_list;
 }
 
-minifi::utils::optional<std::vector<ListedObjectAttributes>> S3Wrapper::listObjects(const ListRequestParameters& params) {
+std::optional<std::vector<ListedObjectAttributes>> S3Wrapper::listObjects(const ListRequestParameters& params) {
   auto request = createListRequest<Aws::S3::Model::ListObjectsV2Request>(params);
   std::vector<ListedObjectAttributes> attribute_list;
-  minifi::utils::optional<Aws::S3::Model::ListObjectsV2Result> aws_result;
+  std::optional<Aws::S3::Model::ListObjectsV2Result> aws_result;
   do {
     aws_result = request_sender_->sendListObjectsRequest(request, params.credentials, params.client_config);
     if (!aws_result) {
-      return minifi::utils::nullopt;
+      return std::nullopt;
     }
     const auto& objects = aws_result->GetContents();
     logger_->log_debug("AWS S3 List operation returned %zu objects. This result is%s truncated.", objects.size(), aws_result->GetIsTruncated() ? "" : "not");
@@ -230,15 +229,15 @@ minifi::utils::optional<std::vector<ListedObjectAttributes>> S3Wrapper::listObje
   return attribute_list;
 }
 
-minifi::utils::optional<std::vector<ListedObjectAttributes>> S3Wrapper::listBucket(const ListRequestParameters& params) {
-  last_bucket_list_timestamp_ = Aws::Utils::DateTime::CurrentTimeMillis();
+std::optional<std::vector<ListedObjectAttributes>> S3Wrapper::listBucket(const ListRequestParameters& params) {
+  last_bucket_list_timestamp_ = gsl::narrow<uint64_t>(Aws::Utils::DateTime::CurrentTimeMillis());
   if (params.use_versions) {
     return listVersions(params);
   }
   return listObjects(params);
 }
 
-minifi::utils::optional<std::map<std::string, std::string>> S3Wrapper::getObjectTags(const GetObjectTagsParameters& params) {
+std::optional<std::map<std::string, std::string>> S3Wrapper::getObjectTags(const GetObjectTagsParameters& params) {
   Aws::S3::Model::GetObjectTaggingRequest request;
   request.SetBucket(params.bucket);
   request.SetKey(params.object_key);
@@ -247,7 +246,7 @@ minifi::utils::optional<std::map<std::string, std::string>> S3Wrapper::getObject
   }
   auto aws_result = request_sender_->sendGetObjectTaggingRequest(request, params.credentials, params.client_config);
   if (!aws_result) {
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
   std::map<std::string, std::string> tags;
   for (const auto& tag : aws_result->GetTagSet()) {
@@ -256,11 +255,11 @@ minifi::utils::optional<std::map<std::string, std::string>> S3Wrapper::getObject
   return tags;
 }
 
-minifi::utils::optional<HeadObjectResult> S3Wrapper::headObject(const HeadObjectRequestParameters& head_object_params) {
+std::optional<HeadObjectResult> S3Wrapper::headObject(const HeadObjectRequestParameters& head_object_params) {
   auto request = createFetchObjectRequest<Aws::S3::Model::HeadObjectRequest>(head_object_params);
   auto aws_result = request_sender_->sendHeadObjectRequest(request, head_object_params.credentials, head_object_params.client_config);
   if (!aws_result) {
-    return minifi::utils::nullopt;
+    return std::nullopt;
   }
   return fillFetchObjectResult<Aws::S3::Model::HeadObjectResult, HeadObjectResult>(head_object_params, aws_result.value());
 }
diff --git a/extensions/aws/s3/S3Wrapper.h b/extensions/aws/s3/S3Wrapper.h
index b59f5d2..8dd9ce1 100644
--- a/extensions/aws/s3/S3Wrapper.h
+++ b/extensions/aws/s3/S3Wrapper.h
@@ -20,11 +20,12 @@
 
 #pragma once
 
-#include <string>
 #include <map>
-#include <unordered_map>
 #include <memory>
+#include <optional>
 #include <sstream>
+#include <string>
+#include <unordered_map>
 #include <utility>
 #include <vector>
 
@@ -194,12 +195,12 @@ class S3Wrapper {
   S3Wrapper();
   explicit S3Wrapper(std::unique_ptr<S3RequestSender>&& request_sender);
 
-  minifi::utils::optional<PutObjectResult> putObject(const PutObjectRequestParameters& options, std::shared_ptr<Aws::IOStream> data_stream);
+  std::optional<PutObjectResult> putObject(const PutObjectRequestParameters& options, std::shared_ptr<Aws::IOStream> data_stream);
   bool deleteObject(const DeleteObjectRequestParameters& options);
-  minifi::utils::optional<GetObjectResult> getObject(const GetObjectRequestParameters& get_object_params, io::BaseStream& fetched_body);
-  minifi::utils::optional<std::vector<ListedObjectAttributes>> listBucket(const ListRequestParameters& params);
-  minifi::utils::optional<std::map<std::string, std::string>> getObjectTags(const GetObjectTagsParameters& params);
-  minifi::utils::optional<HeadObjectResult> headObject(const HeadObjectRequestParameters& head_object_params);
+  std::optional<GetObjectResult> getObject(const GetObjectRequestParameters& get_object_params, io::BaseStream& fetched_body);
+  std::optional<std::vector<ListedObjectAttributes>> listBucket(const ListRequestParameters& params);
+  std::optional<std::map<std::string, std::string>> getObjectTags(const GetObjectTagsParameters& params);
+  std::optional<HeadObjectResult> headObject(const HeadObjectRequestParameters& head_object_params);
 
   virtual ~S3Wrapper() = default;
 
@@ -210,8 +211,8 @@ class S3Wrapper {
   static int64_t writeFetchedBody(Aws::IOStream& source, const int64_t data_size, io::BaseStream& output);
   static std::string getEncryptionString(Aws::S3::Model::ServerSideEncryption encryption);
 
-  minifi::utils::optional<std::vector<ListedObjectAttributes>> listVersions(const ListRequestParameters& params);
-  minifi::utils::optional<std::vector<ListedObjectAttributes>> listObjects(const ListRequestParameters& params);
+  std::optional<std::vector<ListedObjectAttributes>> listVersions(const ListRequestParameters& params);
+  std::optional<std::vector<ListedObjectAttributes>> listObjects(const ListRequestParameters& params);
   void addListResults(const Aws::Vector<Aws::S3::Model::ObjectVersion>& content, uint64_t min_object_age, std::vector<ListedObjectAttributes>& listed_objects);
   void addListResults(const Aws::Vector<Aws::S3::Model::Object>& content, uint64_t min_object_age, std::vector<ListedObjectAttributes>& listed_objects);
 
diff --git a/extensions/azure/AzureLoader.h b/extensions/azure/AzureLoader.h
index 11224d8..97de2e7 100644
--- a/extensions/azure/AzureLoader.h
+++ b/extensions/azure/AzureLoader.h
@@ -24,7 +24,6 @@
 
 #include "core/ClassLoader.h"
 #include "utils/StringUtils.h"
-#include "utils/GeneralUtils.h"
 #include "controllerservices/AzureStorageCredentialsService.h"
 
 class AzureObjectFactory : public core::ObjectFactory {
@@ -55,7 +54,7 @@ class AzureObjectFactory : public core::ObjectFactory {
 
   std::unique_ptr<ObjectFactory> assign(const std::string &class_name) override {
     if (utils::StringUtils::equalsIgnoreCase(class_name, "AzureStorageCredentialsService")) {
-      return minifi::utils::make_unique<core::DefautObjectFactory<minifi::azure::controllers::AzureStorageCredentialsService>>();
+      return std::make_unique<core::DefautObjectFactory<minifi::azure::controllers::AzureStorageCredentialsService>>();
     } else {
       return nullptr;
     }
diff --git a/extensions/azure/processors/PutAzureBlobStorage.cpp b/extensions/azure/processors/PutAzureBlobStorage.cpp
index 275e23a..9c53505 100644
--- a/extensions/azure/processors/PutAzureBlobStorage.cpp
+++ b/extensions/azure/processors/PutAzureBlobStorage.cpp
@@ -183,7 +183,7 @@ void PutAzureBlobStorage::createAzureStorageClient(const std::string &connection
   // When used in multithreaded environment make sure to use the azure_storage_mutex_ to lock the wrapper so the
   // client is not reset with different configuration while another thread is using it.
   if (blob_storage_wrapper_ == nullptr) {
-    blob_storage_wrapper_ = minifi::utils::make_unique<storage::AzureBlobStorage>(connection_string, container_name);
+    blob_storage_wrapper_ = std::make_unique<storage::AzureBlobStorage>(connection_string, container_name);
     return;
   }
 
@@ -229,7 +229,7 @@ void PutAzureBlobStorage::onTrigger(const std::shared_ptr<core::ProcessContext>
     return;
   }
 
-  utils::optional<azure::storage::UploadBlobResult> upload_result;
+  std::optional<azure::storage::UploadBlobResult> upload_result;
   {
     std::lock_guard<std::mutex> lock(azure_storage_mutex_);
     createAzureStorageClient(connection_string, container_name);
diff --git a/extensions/azure/processors/PutAzureBlobStorage.h b/extensions/azure/processors/PutAzureBlobStorage.h
index 06a02f4..0867274 100644
--- a/extensions/azure/processors/PutAzureBlobStorage.h
+++ b/extensions/azure/processors/PutAzureBlobStorage.h
@@ -20,17 +20,17 @@
 
 #pragma once
 
+#include <memory>
+#include <optional>
+#include <string>
 #include <utility>
 #include <vector>
-#include <string>
-#include <memory>
 
 #include "core/Property.h"
 #include "core/Processor.h"
 #include "core/logging/Logger.h"
 #include "core/logging/LoggerConfiguration.h"
 #include "storage/BlobStorage.h"
-#include "utils/OptionalUtils.h"
 
 class PutAzureBlobStorageTestsFixture;
 
@@ -92,7 +92,7 @@ class PutAzureBlobStorage : public core::Processor {
       return result_->length;
     }
 
-    utils::optional<azure::storage::UploadBlobResult> getResult() const {
+    std::optional<azure::storage::UploadBlobResult> getResult() const {
       return result_;
     }
 
@@ -100,7 +100,7 @@ class PutAzureBlobStorage : public core::Processor {
     uint64_t flow_size_;
     azure::storage::BlobStorage &blob_storage_wrapper_;
     std::string blob_name_;
-    utils::optional<azure::storage::UploadBlobResult> result_ = utils::nullopt;
+    std::optional<azure::storage::UploadBlobResult> result_ = std::nullopt;
   };
 
  private:
diff --git a/extensions/azure/storage/AzureBlobStorage.cpp b/extensions/azure/storage/AzureBlobStorage.cpp
index 2427dcf..8be6729 100644
--- a/extensions/azure/storage/AzureBlobStorage.cpp
+++ b/extensions/azure/storage/AzureBlobStorage.cpp
@@ -20,10 +20,9 @@
 
 #include "AzureBlobStorage.h"
 
+#include <memory>
 #include <utility>
 
-#include "utils/GeneralUtils.h"
-
 namespace org {
 namespace apache {
 namespace nifi {
@@ -33,7 +32,7 @@ namespace storage {
 
 AzureBlobStorage::AzureBlobStorage(std::string connection_string, std::string container_name)
   : BlobStorage(std::move(connection_string), std::move(container_name))
-  , container_client_(minifi::utils::make_unique<Azure::Storage::Blobs::BlobContainerClient>(
+  , container_client_(std::make_unique<Azure::Storage::Blobs::BlobContainerClient>(
       Azure::Storage::Blobs::BlobContainerClient::CreateFromConnectionString(connection_string_, container_name_))) {
 }
 
@@ -45,7 +44,7 @@ void AzureBlobStorage::resetClientIfNeeded(const std::string &connection_string,
   connection_string_ = connection_string;
   container_name_ = container_name;
   logger_->log_debug("Client has been reset with new credentials");
-  container_client_ = minifi::utils::make_unique<Azure::Storage::Blobs::BlobContainerClient>(Azure::Storage::Blobs::BlobContainerClient::CreateFromConnectionString(connection_string, container_name));
+  container_client_ = std::make_unique<Azure::Storage::Blobs::BlobContainerClient>(Azure::Storage::Blobs::BlobContainerClient::CreateFromConnectionString(connection_string, container_name));
 }
 
 void AzureBlobStorage::createContainer() {
@@ -57,12 +56,12 @@ void AzureBlobStorage::createContainer() {
   }
 }
 
-utils::optional<UploadBlobResult> AzureBlobStorage::uploadBlob(const std::string &blob_name, const uint8_t* buffer, std::size_t buffer_size) {
+std::optional<UploadBlobResult> AzureBlobStorage::uploadBlob(const std::string &blob_name, const uint8_t* buffer, std::size_t buffer_size) {
   try {
     auto blob_client = container_client_->GetBlockBlobClient(blob_name);
     auto response = blob_client.UploadFrom(buffer, buffer_size);
     if (!response.HasValue()) {
-      return utils::nullopt;
+      return std::nullopt;
     }
 
     UploadBlobResult result;
@@ -75,7 +74,7 @@ utils::optional<UploadBlobResult> AzureBlobStorage::uploadBlob(const std::string
     return result;
   } catch (const std::runtime_error& err) {
     logger_->log_error("A runtime error occurred while uploading blob: %s", err.what());
-    return utils::nullopt;
+    return std::nullopt;
   }
 }
 
diff --git a/extensions/azure/storage/AzureBlobStorage.h b/extensions/azure/storage/AzureBlobStorage.h
index 3b2a602..90c7c44 100644
--- a/extensions/azure/storage/AzureBlobStorage.h
+++ b/extensions/azure/storage/AzureBlobStorage.h
@@ -19,9 +19,10 @@
  */
 #pragma once
 
+#include <memory>
+#include <optional>
 #include <string>
 #include <vector>
-#include <memory>
 
 #include "BlobStorage.h"
 #include "azure/storage/blobs.hpp"
@@ -40,7 +41,7 @@ class AzureBlobStorage : public BlobStorage {
   AzureBlobStorage(std::string connection_string, std::string container_name);
   void createContainer() override;
   void resetClientIfNeeded(const std::string &connection_string, const std::string &container_name) override;
-  utils::optional<UploadBlobResult> uploadBlob(const std::string &blob_name, const uint8_t* buffer, std::size_t buffer_size) override;
+  std::optional<UploadBlobResult> uploadBlob(const std::string &blob_name, const uint8_t* buffer, std::size_t buffer_size) override;
 
  private:
   std::unique_ptr<Azure::Storage::Blobs::BlobContainerClient> container_client_;
diff --git a/extensions/azure/storage/BlobStorage.h b/extensions/azure/storage/BlobStorage.h
index fe85cb1..f232ae3 100644
--- a/extensions/azure/storage/BlobStorage.h
+++ b/extensions/azure/storage/BlobStorage.h
@@ -19,11 +19,10 @@
  */
 #pragma once
 
+#include <optional>
 #include <string>
-#include <vector>
 #include <utility>
-
-#include "utils/OptionalUtils.h"
+#include <vector>
 
 namespace org {
 namespace apache {
@@ -48,7 +47,7 @@ class BlobStorage {
 
   virtual void createContainer() = 0;
   virtual void resetClientIfNeeded(const std::string &connection_string, const std::string &container_name) = 0;
-  virtual utils::optional<UploadBlobResult> uploadBlob(const std::string &blob_name, const uint8_t* buffer, std::size_t buffer_size) = 0;
+  virtual std::optional<UploadBlobResult> uploadBlob(const std::string &blob_name, const uint8_t* buffer, std::size_t buffer_size) = 0;
   virtual ~BlobStorage() = default;
 
  protected:
diff --git a/extensions/civetweb/processors/ListenHTTP.cpp b/extensions/civetweb/processors/ListenHTTP.cpp
index 09c52e8..4ccff70 100644
--- a/extensions/civetweb/processors/ListenHTTP.cpp
+++ b/extensions/civetweb/processors/ListenHTTP.cpp
@@ -20,10 +20,11 @@
  */
 #include "ListenHTTP.h"
 
+#include <memory>
 #include <set>
-#include <vector>
-#include <utility>
 #include <string>
+#include <utility>
+#include <vector>
 
 #include "utils/gsl.h"
 
@@ -475,7 +476,7 @@ void ListenHTTP::Handler::writeBody(mg_connection *conn, const mg_request_info *
 }
 
 std::unique_ptr<io::BufferStream> ListenHTTP::Handler::createContentBuffer(struct mg_connection *conn, const struct mg_request_info *req_info) {
-  auto content_buffer = utils::make_unique<io::BufferStream>();
+  auto content_buffer = std::make_unique<io::BufferStream>();
   size_t nlen = 0;
   int64_t tlen = req_info->content_length;
   uint8_t buf[16384];
diff --git a/extensions/coap/tests/CoapIntegrationBase.h b/extensions/coap/tests/CoapIntegrationBase.h
index 4c9ee67..e247954 100644
--- a/extensions/coap/tests/CoapIntegrationBase.h
+++ b/extensions/coap/tests/CoapIntegrationBase.h
@@ -17,9 +17,10 @@
  */
 #pragma once
 
-#include <utility>
 #include <memory>
+#include <optional>
 #include <string>
+#include <utility>
 
 #include "../tests/TestServer.h"
 #include "CivetServer.h"
@@ -47,7 +48,7 @@ class CoapIntegrationBase : public IntegrationBase {
     server.reset();
   }
 
-  void run(const utils::optional<std::string>& test_file_location = {}, const utils::optional<std::string>& = {}) override {
+  void run(const std::optional<std::string>& test_file_location = {}, const std::optional<std::string>& = {}) override {
     testSetup();
 
     std::shared_ptr<core::Repository> test_repo = std::make_shared<TestRepository>();
@@ -61,12 +62,11 @@ class CoapIntegrationBase : public IntegrationBase {
     std::shared_ptr<core::ContentRepository> content_repo = std::make_shared<core::repository::VolatileContentRepository>();
     content_repo->initialize(configuration);
     std::shared_ptr<minifi::io::StreamFactory> stream_factory = minifi::io::StreamFactory::getInstance(configuration);
-    std::unique_ptr<core::FlowConfiguration> yaml_ptr = std::unique_ptr<core::YamlConfiguration>(
-        new core::YamlConfiguration(test_repo, test_repo, content_repo, stream_factory, configuration, test_file_location));
+    auto yaml_ptr = std::make_unique<core::YamlConfiguration>(test_repo, test_repo, content_repo, stream_factory, configuration, test_file_location);
 
     core::YamlConfiguration yaml_config(test_repo, test_repo, content_repo, stream_factory, configuration, test_file_location);
 
-    std::shared_ptr<core::ProcessGroup> pg{ yaml_config.getRoot().release() };
+    std::shared_ptr<core::ProcessGroup> pg{ yaml_config.getRoot() };
 
     queryRootProcessGroup(pg);
 
@@ -101,14 +101,14 @@ void CoapIntegrationBase::setUrl(std::string url, CivetHandler *handler) {
       return;
     }
     if (scheme == "https" && !key_dir.empty()) {
-      std::string cert = "";
+      std::string cert;
       cert = key_dir + "nifi-cert.pem";
       callback.init_ssl = ssl_enable;
       port += "s";
       callback.log_message = log_message;
-      server = utils::make_unique<TestServer>(port, path, handler, &callback, cert, cert);
+      server = std::make_unique<TestServer>(port, path, handler, &callback, cert, cert);
     } else {
-      server = utils::make_unique<TestServer>(port, path, handler);
+      server = std::make_unique<TestServer>(port, path, handler);
     }
   }
 }
diff --git a/extensions/http-curl/sitetosite/HTTPProtocol.cpp b/extensions/http-curl/sitetosite/HTTPProtocol.cpp
index 14eff9e..f198b59 100644
--- a/extensions/http-curl/sitetosite/HTTPProtocol.cpp
+++ b/extensions/http-curl/sitetosite/HTTPProtocol.cpp
@@ -40,7 +40,7 @@ namespace sitetosite {
 
 std::shared_ptr<utils::IdGenerator> HttpSiteToSiteClient::id_generator_ = utils::IdGenerator::getIdGenerator();
 
-utils::optional<utils::Identifier> HttpSiteToSiteClient::parseTransactionId(const std::string &uri) {
+std::optional<utils::Identifier> HttpSiteToSiteClient::parseTransactionId(const std::string &uri) {
   const size_t last_slash_pos = uri.find_last_of('/');
   size_t id_start_pos = 0;
   if (last_slash_pos != std::string::npos) {
diff --git a/extensions/http-curl/sitetosite/HTTPProtocol.h b/extensions/http-curl/sitetosite/HTTPProtocol.h
index c128f48..1cabd54 100644
--- a/extensions/http-curl/sitetosite/HTTPProtocol.h
+++ b/extensions/http-curl/sitetosite/HTTPProtocol.h
@@ -17,11 +17,12 @@
  */
 #pragma once
 
-#include <string>
 #include <map>
 #include <memory>
-#include <vector>
+#include <optional>
+#include <string>
 #include <utility>
+#include <vector>
 #include "HTTPTransaction.h"
 #include "sitetosite/SiteToSite.h"
 #include "sitetosite/SiteToSiteClient.h"
@@ -144,7 +145,7 @@ class HttpSiteToSiteClient : public sitetosite::SiteToSiteClient {
 
   void tearDown() override;
 
-  utils::optional<utils::Identifier> parseTransactionId(const std::string &uri);
+  std::optional<utils::Identifier> parseTransactionId(const std::string &uri);
 
   std::unique_ptr<utils::HTTPClient> create_http_client(const std::string &uri, const std::string &method = "POST", bool setPropertyHeaders = false) {
     std::unique_ptr<utils::HTTPClient> http_client_ = std::unique_ptr<utils::HTTPClient>(new minifi::utils::HTTPClient(uri, ssl_context_service_));
diff --git a/extensions/http-curl/tests/C2PauseResumeTest.cpp b/extensions/http-curl/tests/C2PauseResumeTest.cpp
index 035a0aa..08e63e0 100644
--- a/extensions/http-curl/tests/C2PauseResumeTest.cpp
+++ b/extensions/http-curl/tests/C2PauseResumeTest.cpp
@@ -17,6 +17,9 @@
  */
 
 #undef NDEBUG
+
+#include <memory>
+
 #include "TestBase.h"
 #include "HTTPIntegrationBase.h"
 #include "HTTPHandlers.h"
@@ -27,7 +30,6 @@
 #include "properties/Configure.h"
 #include "io/StreamFactory.h"
 #include "integration/IntegrationBase.h"
-#include "utils/GeneralUtils.h"
 
 class VerifyC2PauseResume : public VerifyC2Base {
  public:
@@ -122,7 +124,7 @@ int main(int argc, char **argv) {
   std::shared_ptr<core::ContentRepository> content_repo = std::make_shared<core::repository::VolatileContentRepository>();
   content_repo->initialize(configuration);
 
-  std::unique_ptr<core::FlowConfiguration> yaml_ptr = utils::make_unique<core::YamlConfiguration>(
+  std::unique_ptr<core::FlowConfiguration> yaml_ptr = std::make_unique<core::YamlConfiguration>(
     test_repo, test_repo, content_repo, stream_factory, configuration, args.test_file);
 
   std::shared_ptr<minifi::FlowController> controller = std::make_shared<minifi::FlowController>(
@@ -140,7 +142,7 @@ int main(int argc, char **argv) {
   std::string port, scheme, path;
   std::unique_ptr<TestServer> server;
   parse_http_components(url, port, scheme, path);
-  server = utils::make_unique<TestServer>(port, path, &responder);
+  server = std::make_unique<TestServer>(port, path, &responder);
 
   harness.setUrl(args.url, &responder);
   harness.run(args.test_file);
diff --git a/extensions/http-curl/tests/C2RequestClassTest.cpp b/extensions/http-curl/tests/C2RequestClassTest.cpp
index 7cbcc95..ea0ca04 100644
--- a/extensions/http-curl/tests/C2RequestClassTest.cpp
+++ b/extensions/http-curl/tests/C2RequestClassTest.cpp
@@ -17,15 +17,15 @@
  */
 
 #undef NDEBUG
-#include <vector>
+#include <optional>
 #include <string>
+#include <vector>
 
 #include "HTTPIntegrationBase.h"
 #include "HTTPHandlers.h"
 #include "utils/IntegrationTestUtils.h"
 #include "CivetStream.h"
 #include "StreamPipe.h"
-#include "OptionalUtils.h"
 
 class C2AcknowledgeHandler : public ServerAwareHandler {
  public:
@@ -60,7 +60,7 @@ class C2HeartbeatHandler : public ServerAwareHandler {
     std::string req = readPayload(conn);
     rapidjson::Document root;
     root.Parse(req.data(), req.size());
-    utils::optional<std::string> agent_class;
+    std::optional<std::string> agent_class;
     if (root.IsObject() && root["agentInfo"].HasMember("agentClass")) {
       agent_class = root["agentInfo"]["agentClass"].GetString();
     }
@@ -76,7 +76,7 @@ class C2HeartbeatHandler : public ServerAwareHandler {
     return true;
   }
 
-  bool gotClassesInOrder(const std::vector<utils::optional<std::string>>& class_names) {
+  bool gotClassesInOrder(const std::vector<std::optional<std::string>>& class_names) {
     std::lock_guard<std::mutex> lock(mtx_);
     auto it = classes_.begin();
     for (const auto& class_name : class_names) {
@@ -91,7 +91,7 @@ class C2HeartbeatHandler : public ServerAwareHandler {
 
  private:
   std::mutex mtx_;
-  std::vector<utils::optional<std::string>> classes_;
+  std::vector<std::optional<std::string>> classes_;
   std::string response_;
 };
 
diff --git a/extensions/http-curl/tests/HTTPHandlers.h b/extensions/http-curl/tests/HTTPHandlers.h
index 4d8676e..de3f362 100644
--- a/extensions/http-curl/tests/HTTPHandlers.h
+++ b/extensions/http-curl/tests/HTTPHandlers.h
@@ -19,11 +19,12 @@
 
 #include <algorithm>
 #include <cinttypes>
-#include <utility>
+#include <map>
 #include <memory>
+#include <optional>
 #include <string>
+#include <utility>
 #include <vector>
-#include <map>
 
 #include "civetweb.h"
 #include "CivetServer.h"
@@ -509,7 +510,7 @@ class C2UpdateHandler : public C2FlowProvider {
     return true;
   }
 
-  void setC2RestResponse(const std::string& url, const std::string& name, const utils::optional<std::string>& persist = {}) {
+  void setC2RestResponse(const std::string& url, const std::string& name, const std::optional<std::string>& persist = {}) {
     std::string content = "{\"location\": \"" + url + "\"";
     if (persist) {
       content += ", \"persist\": \"" + *persist + "\"";
diff --git a/extensions/http-curl/tests/HTTPIntegrationBase.h b/extensions/http-curl/tests/HTTPIntegrationBase.h
index 1289364..5749394 100644
--- a/extensions/http-curl/tests/HTTPIntegrationBase.h
+++ b/extensions/http-curl/tests/HTTPIntegrationBase.h
@@ -93,9 +93,9 @@ void HTTPIntegrationBase::setUrl(const std::string &url, ServerAwareHandler *han
     callback.init_ssl = ssl_enable;
     port += "s";
     callback.log_message = log_message;
-    server = utils::make_unique<TestServer>(port, url_path, handler, &callback, cert, cert);
+    server = std::make_unique<TestServer>(port, url_path, handler, &callback, cert, cert);
   } else {
-    server = utils::make_unique<TestServer>(port, url_path, handler);
+    server = std::make_unique<TestServer>(port, url_path, handler);
   }
   bool secure{false};
   if (port == "0" || port == "0s") {
diff --git a/extensions/http-curl/tests/TestServer.h b/extensions/http-curl/tests/TestServer.h
index c6f371f..3ee3c97 100644
--- a/extensions/http-curl/tests/TestServer.h
+++ b/extensions/http-curl/tests/TestServer.h
@@ -61,13 +61,13 @@ class TestServer{
     const std::vector<std::string> cpp_options{ "document_root", ".", "listening_ports", port, "error_log_file",
                               "error.log", "ssl_certificate", ca_cert, "ssl_protocol_version", "4", "ssl_cipher_list",
                               "ALL", "request_timeout_ms", "10000", "enable_auth_domain_check", "no", "ssl_verify_peer", "no"};
-    server_ = utils::make_unique<CivetServer>(cpp_options, callbacks);
+    server_ = std::make_unique<CivetServer>(cpp_options, callbacks);
     addHandler(rooturi, handler);
   }
 
   TestServer(const std::string& port, const std::string& rooturi, CivetHandler* handler) {
     const std::vector<std::string> cpp_options{"document_root", ".", "listening_ports", port};
-    server_ = utils::make_unique<CivetServer>(cpp_options);
+    server_ = std::make_unique<CivetServer>(cpp_options);
     addHandler(rooturi, handler);
   }
 
diff --git a/extensions/http-curl/tests/VerifyInvokeHTTP.h b/extensions/http-curl/tests/VerifyInvokeHTTP.h
index 6546173..725273b 100644
--- a/extensions/http-curl/tests/VerifyInvokeHTTP.h
+++ b/extensions/http-curl/tests/VerifyInvokeHTTP.h
@@ -29,7 +29,6 @@
 #include "processors/LogAttribute.h"
 #include "core/state/ProcessorController.h"
 #include "HTTPIntegrationBase.h"
-#include "utils/GeneralUtils.h"
 
 class VerifyInvokeHTTP : public HTTPIntegrationBase {
  public:
@@ -73,7 +72,7 @@ class VerifyInvokeHTTP : public HTTPIntegrationBase {
     proc->setProperty(property, value);
   }
 
-  virtual void setupFlow(const utils::optional<std::string>& flow_yml_path) {
+  virtual void setupFlow(const std::optional<std::string>& flow_yml_path) {
     testSetup();
 
     std::shared_ptr<core::Repository> test_repo = std::make_shared<TestRepository>();
@@ -86,9 +85,7 @@ class VerifyInvokeHTTP : public HTTPIntegrationBase {
     std::shared_ptr<core::ContentRepository> content_repo = std::make_shared<core::repository::VolatileContentRepository>();
     content_repo->initialize(configuration);
     std::shared_ptr<minifi::io::StreamFactory> stream_factory = minifi::io::StreamFactory::getInstance(configuration);
-    std::unique_ptr<core::FlowConfiguration> yaml_ptr =
-      minifi::utils::make_unique<core::YamlConfiguration>(test_repo, test_repo, content_repo, stream_factory, configuration, flow_yml_path);
-
+    auto yaml_ptr = std::make_unique<core::YamlConfiguration>(test_repo, test_repo, content_repo, stream_factory, configuration, flow_yml_path);
     flowController_ = std::make_shared<minifi::FlowController>(test_repo, test_flow_repo, configuration, std::move(yaml_ptr), content_repo, DEFAULT_ROOT_GROUP_NAME, true);
     flowController_->load();
 
@@ -96,7 +93,7 @@ class VerifyInvokeHTTP : public HTTPIntegrationBase {
     setProperty(minifi::processors::InvokeHTTP::URL.getName(), url);
   }
 
-  void run(const utils::optional<std::string>& flow_yml_path = {}, const utils::optional<std::string>& = {}) override {
+  void run(const std::optional<std::string>& flow_yml_path = {}, const std::optional<std::string>& = {}) override {
     setupFlow(flow_yml_path);
     startFlowController();
 
@@ -127,5 +124,5 @@ class VerifyInvokeHTTP : public HTTPIntegrationBase {
   }
 
  private:
-  utils::optional<std::string> path_;
+  std::optional<std::string> path_;
 };
diff --git a/extensions/http-curl/tests/VerifyInvokeHTTPPostTest.cpp b/extensions/http-curl/tests/VerifyInvokeHTTPPostTest.cpp
index 7090346..a1630af 100644
--- a/extensions/http-curl/tests/VerifyInvokeHTTPPostTest.cpp
+++ b/extensions/http-curl/tests/VerifyInvokeHTTPPostTest.cpp
@@ -15,6 +15,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <optional>
+
 #include "VerifyInvokeHTTP.h"
 
 #include "HTTPHandlers.h"
@@ -42,7 +44,7 @@ class VerifyInvokeHTTPOK200Response : public VerifyInvokeHTTP {
 
 class VerifyInvokeHTTPRedirectResponse : public VerifyInvokeHTTP {
  public:
-  void setupFlow(const utils::optional<std::string>& flow_yml_path) override {
+  void setupFlow(const std::optional<std::string>& flow_yml_path) override {
     VerifyInvokeHTTP::setupFlow(flow_yml_path);
     setProperty(minifi::processors::InvokeHTTP::FollowRedirects.getName(), "false");
   }
diff --git a/extensions/libarchive/MergeContent.cpp b/extensions/libarchive/MergeContent.cpp
index fb4fb82..0400aa7 100644
--- a/extensions/libarchive/MergeContent.cpp
+++ b/extensions/libarchive/MergeContent.cpp
@@ -28,7 +28,6 @@
 #include <algorithm>
 #include <numeric>
 #include "utils/TimeUtil.h"
-#include "utils/GeneralUtils.h"
 #include "core/ProcessContext.h"
 #include "core/ProcessSession.h"
 #include "serialization/PayloadSerializer.h"
@@ -301,20 +300,20 @@ bool MergeContent::processBin(core::ProcessContext *context, core::ProcessSessio
 
   const char* mimeType;
   std::unique_ptr<MergeBin> mergeBin;
-  std::unique_ptr<minifi::FlowFileSerializer> serializer = utils::make_unique<PayloadSerializer>(flowFileReader);
+  std::unique_ptr<minifi::FlowFileSerializer> serializer = std::make_unique<PayloadSerializer>(flowFileReader);
   if (mergeFormat_ == merge_content_options::MERGE_FORMAT_CONCAT_VALUE) {
-    mergeBin = utils::make_unique<BinaryConcatenationMerge>(headerContent_, footerContent_, demarcatorContent_);
+    mergeBin = std::make_unique<BinaryConcatenationMerge>(headerContent_, footerContent_, demarcatorContent_);
     mimeType = "application/octet-stream";
   } else if (mergeFormat_ == merge_content_options::MERGE_FORMAT_FLOWFILE_STREAM_V3_VALUE) {
     // disregard header, demarcator, footer
-    mergeBin = utils::make_unique<BinaryConcatenationMerge>("", "", "");
-    serializer = utils::make_unique<FlowFileV3Serializer>(flowFileReader);
+    mergeBin = std::make_unique<BinaryConcatenationMerge>("", "", "");
+    serializer = std::make_unique<FlowFileV3Serializer>(flowFileReader);
     mimeType = "application/flowfile-v3";
   } else if (mergeFormat_ == merge_content_options::MERGE_FORMAT_TAR_VALUE) {
-    mergeBin = utils::make_unique<TarMerge>();
+    mergeBin = std::make_unique<TarMerge>();
     mimeType = "application/tar";
   } else if (mergeFormat_ == merge_content_options::MERGE_FORMAT_ZIP_VALUE) {
-    mergeBin = utils::make_unique<ZipMerge>();
+    mergeBin = std::make_unique<ZipMerge>();
     mimeType = "application/zip";
   } else {
     logger_->log_error("Merge format not supported %s", mergeFormat_);
diff --git a/extensions/librdkafka/ConsumeKafka.cpp b/extensions/librdkafka/ConsumeKafka.cpp
index a79e7b6..02e7877 100644
--- a/extensions/librdkafka/ConsumeKafka.cpp
+++ b/extensions/librdkafka/ConsumeKafka.cpp
@@ -469,7 +469,7 @@ std::vector<std::pair<std::string, std::string>> ConsumeKafka::get_flowfile_attr
 void ConsumeKafka::add_kafka_attributes_to_flowfile(std::shared_ptr<FlowFileRecord>& flow_file, const rd_kafka_message_t& message) const {
   // We do not currently support batching messages into a single flowfile
   flow_file->setAttribute(KAFKA_COUNT_ATTR, "1");
-  const utils::optional<std::string> message_key = utils::get_encoded_message_key(message, key_attr_encoding_attr_to_enum());
+  const std::optional<std::string> message_key = utils::get_encoded_message_key(message, key_attr_encoding_attr_to_enum());
   if (message_key) {
     flow_file->setAttribute(KAFKA_MESSAGE_KEY_ATTR, message_key.value());
   }
@@ -478,7 +478,7 @@ void ConsumeKafka::add_kafka_attributes_to_flowfile(std::shared_ptr<FlowFileReco
   flow_file->setAttribute(KAFKA_TOPIC_ATTR, rd_kafka_topic_name(message.rkt));
 }
 
-utils::optional<std::vector<std::shared_ptr<FlowFileRecord>>> ConsumeKafka::transform_pending_messages_into_flowfiles(core::ProcessSession& session) const {
+std::optional<std::vector<std::shared_ptr<FlowFileRecord>>> ConsumeKafka::transform_pending_messages_into_flowfiles(core::ProcessSession& session) const {
   std::vector<std::shared_ptr<FlowFileRecord>> flow_files_created;
   for (const auto& message : pending_messages_) {
     std::string message_content = extract_message(*message);
@@ -508,7 +508,7 @@ utils::optional<std::vector<std::shared_ptr<FlowFileRecord>>> ConsumeKafka::tran
 
 
 void ConsumeKafka::process_pending_messages(core::ProcessSession& session) {
-  utils::optional<std::vector<std::shared_ptr<FlowFileRecord>>> flow_files_created = transform_pending_messages_into_flowfiles(session);
+  std::optional<std::vector<std::shared_ptr<FlowFileRecord>>> flow_files_created = transform_pending_messages_into_flowfiles(session);
   if (!flow_files_created) {
     return;
   }
diff --git a/extensions/librdkafka/ConsumeKafka.h b/extensions/librdkafka/ConsumeKafka.h
index 1725e36..bd050c8 100644
--- a/extensions/librdkafka/ConsumeKafka.h
+++ b/extensions/librdkafka/ConsumeKafka.h
@@ -18,6 +18,7 @@
 #pragma once
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -136,7 +137,7 @@ class ConsumeKafka : public core::Processor {
   std::vector<std::string> get_matching_headers(const rd_kafka_message_t& message, const std::string& header_name) const;
   std::vector<std::pair<std::string, std::string>> get_flowfile_attributes_from_message_header(const rd_kafka_message_t& message) const;
   void add_kafka_attributes_to_flowfile(std::shared_ptr<FlowFileRecord>& flow_file, const rd_kafka_message_t& message) const;
-  utils::optional<std::vector<std::shared_ptr<FlowFileRecord>>> transform_pending_messages_into_flowfiles(core::ProcessSession& session) const;
+  std::optional<std::vector<std::shared_ptr<FlowFileRecord>>> transform_pending_messages_into_flowfiles(core::ProcessSession& session) const;
   void process_pending_messages(core::ProcessSession& session);
 
  private:
diff --git a/extensions/librdkafka/PublishKafka.cpp b/extensions/librdkafka/PublishKafka.cpp
index 5d8b3d1..9e47d15 100644
--- a/extensions/librdkafka/PublishKafka.cpp
+++ b/extensions/librdkafka/PublishKafka.cpp
@@ -25,12 +25,12 @@
 #include <string>
 #include <map>
 #include <set>
+#include <type_traits>
 #include <vector>
 
 #include "utils/gsl.h"
 #include "utils/TimeUtil.h"
 #include "utils/StringUtils.h"
-#include "utils/GeneralUtils.h"
 #include "core/ProcessContext.h"
 #include "core/ProcessSession.h"
 
@@ -267,7 +267,7 @@ class PublishKafka::Messages {
   }
 
   template<typename Func>
-  auto iterateFlowFiles(Func fun) -> utils::void_t<decltype(fun(size_t{0}, flow_files_.front()))> {
+  auto iterateFlowFiles(Func fun) -> std::void_t<decltype(fun(size_t{0}, flow_files_.front()))> {
     std::lock_guard<std::mutex> lock(mutex_);
     for (size_t index = 0U; index < flow_files_.size(); index++) {
       fun(index, flow_files_[index]);
@@ -338,7 +338,7 @@ class ReadCallback : public InputStreamCallback {
       });
     };
     // release()d below, deallocated in PublishKafka::messageDeliveryCallback
-    auto callback_ptr = utils::make_unique<std::function<void(rd_kafka_t*, const rd_kafka_message_t*)>>(std::move(produce_callback));
+    auto callback_ptr = std::make_unique<std::function<void(rd_kafka_t*, const rd_kafka_message_t*)>>(std::move(produce_callback));
 
     allocate_message_object(segment_num);
 
@@ -539,7 +539,7 @@ void PublishKafka::onSchedule(const std::shared_ptr<core::ProcessContext> &conte
   key_.brokers_ = brokers;
   key_.client_id_ = client_id;
 
-  conn_ = utils::make_unique<KafkaConnection>(key_);
+  conn_ = std::make_unique<KafkaConnection>(key_);
   configureNewConnection(context);
 
   std::string message_key_field;
diff --git a/extensions/librdkafka/rdkafka_utils.cpp b/extensions/librdkafka/rdkafka_utils.cpp
index baa3db3..fdddc81 100644
--- a/extensions/librdkafka/rdkafka_utils.cpp
+++ b/extensions/librdkafka/rdkafka_utils.cpp
@@ -107,7 +107,7 @@ std::string get_encoded_string(const std::string& input, KafkaEncoding encoding)
   throw std::runtime_error("Invalid encoding selected: " + input);
 }
 
-optional<std::string> get_encoded_message_key(const rd_kafka_message_t& message, KafkaEncoding encoding) {
+std::optional<std::string> get_encoded_message_key(const rd_kafka_message_t& message, KafkaEncoding encoding) {
   if (nullptr == message.key) {
     return {};
   }
diff --git a/extensions/librdkafka/rdkafka_utils.h b/extensions/librdkafka/rdkafka_utils.h
index b08d1c4..07154af 100644
--- a/extensions/librdkafka/rdkafka_utils.h
+++ b/extensions/librdkafka/rdkafka_utils.h
@@ -20,13 +20,13 @@
 #include <algorithm>
 #include <chrono>
 #include <memory>
+#include <optional>
 #include <string>
 #include <thread>
 #include <utility>
 #include <vector>
 
 #include "core/logging/LoggerConfiguration.h"
-#include "utils/OptionalUtils.h"
 #include "utils/gsl.h"
 #include "rdkafka.h"
 
@@ -96,7 +96,7 @@ void setKafkaConfigurationField(rd_kafka_conf_t& configuration, const std::strin
 void print_topics_list(logging::Logger& logger, rd_kafka_topic_partition_list_t& kf_topic_partition_list);
 void print_kafka_message(const rd_kafka_message_t& rkmessage, logging::Logger& logger);
 std::string get_encoded_string(const std::string& input, KafkaEncoding encoding);
-optional<std::string> get_encoded_message_key(const rd_kafka_message_t& message, KafkaEncoding encoding);
+std::optional<std::string> get_encoded_message_key(const rd_kafka_message_t& message, KafkaEncoding encoding);
 
 }  // namespace utils
 }  // namespace minifi
diff --git a/extensions/librdkafka/tests/ConsumeKafkaTests.cpp b/extensions/librdkafka/tests/ConsumeKafkaTests.cpp
index ab27088..dcd96d0 100644
--- a/extensions/librdkafka/tests/ConsumeKafkaTests.cpp
+++ b/extensions/librdkafka/tests/ConsumeKafkaTests.cpp
@@ -20,6 +20,7 @@
 
 #include <algorithm>
 #include <memory>
+#include <optional>
 #include <string>
 #include <set>
 
@@ -29,7 +30,6 @@
 #include "../rdkafka_utils.h"
 #include "../../standard-processors/processors/ExtractText.h"
 #include "utils/file/FileUtils.h"
-#include "utils/OptionalUtils.h"
 #include "utils/RegexUtils.h"
 #include "utils/StringUtils.h"
 #include "utils/TestUtils.h"
@@ -37,7 +37,6 @@
 #include "utils/IntegrationTestUtils.h"
 
 namespace {
-using org::apache::nifi::minifi::utils::optional;
 
 class KafkaTestProducer {
  public:
@@ -191,13 +190,13 @@ class ConsumeKafkaTest {
     logTestController_.setDebug<core::ProcessContext>();
   }
 
-  void optional_set_property(const std::shared_ptr<core::Processor>& processor, const std::string& property_name, const optional<std::string>& opt_value) {
+  void optional_set_property(const std::shared_ptr<core::Processor>& processor, const std::string& property_name, const std::optional<std::string>& opt_value) {
     if (opt_value) {
       plan_->setProperty(processor, property_name, opt_value.value());
     }
   }
 
-  std::string decode_key(const std::string& key, const optional<std::string>& key_attribute_encoding) {
+  std::string decode_key(const std::string& key, const std::optional<std::string>& key_attribute_encoding) {
     if (!key_attribute_encoding || utils::StringUtils::equalsIgnoreCase(ConsumeKafka::KEY_ATTR_ENCODING_UTF_8, key_attribute_encoding.value())) {
       return key;
     }
@@ -207,7 +206,7 @@ class ConsumeKafkaTest {
     throw std::runtime_error("Message Header Encoding does not match any of the presets in the test.");
   }
 
-  std::vector<std::string> sort_and_split_messages(const std::vector<std::string>& messages_on_topic, const optional<std::string>& message_demarcator) {
+  std::vector<std::string> sort_and_split_messages(const std::vector<std::string>& messages_on_topic, const std::optional<std::string>& message_demarcator) {
     if (message_demarcator) {
       std::vector<std::string> sorted_split_messages;
       for (const auto& message : messages_on_topic) {
@@ -248,18 +247,18 @@ class ConsumeKafkaPropertiesTest : public ConsumeKafkaTest {
       const std::string& kafka_brokers,
       const std::string& security_protocol,
       const std::string& topic_names,
-      const optional<std::string>& topic_name_format,
-      const optional<bool>& honor_transactions,
-      const optional<std::string>& group_id,
-      const optional<std::string>& offset_reset,
-      const optional<std::string>& key_attribute_encoding,
-      const optional<std::string>& message_demarcator,
-      const optional<std::string>& message_header_encoding,
-      const optional<std::string>& headers_to_add_as_attributes,
-      const optional<std::string>& duplicate_header_handling,
-      const optional<std::string>& max_poll_records,
-      const optional<std::string>& max_poll_time,
-      const optional<std::string>& session_timeout) {
+      const std::optional<std::string>& topic_name_format,
+      const std::optional<bool>& honor_transactions,
+      const std::optional<std::string>& group_id,
+      const std::optional<std::string>& offset_reset,
+      const std::optional<std::string>& key_attribute_encoding,
+      const std::optional<std::string>& message_demarcator,
+      const std::optional<std::string>& message_header_encoding,
+      const std::optional<std::string>& headers_to_add_as_attributes,
+      const std::optional<std::string>& duplicate_header_handling,
+      const std::optional<std::string>& max_poll_records,
+      const std::optional<std::string>& max_poll_time,
+      const std::optional<std::string>& session_timeout) {
     reInitialize();
 
     // Consumer chain
@@ -384,10 +383,10 @@ class ConsumeKafkaContinuousPublishingTest : public ConsumeKafkaTest {
   void single_consumer_with_continuous_message_producing(
       const uint64_t msg_periodicity_ms,
       const std::string& kafka_brokers,
-      const optional<std::string>& group_id,
-      const optional<std::string>& max_poll_records,
-      const optional<std::string>& max_poll_time,
-      const optional<std::string>& session_timeout) {
+      const std::optional<std::string>& group_id,
+      const std::optional<std::string>& max_poll_records,
+      const std::optional<std::string>& max_poll_time,
+      const std::optional<std::string>& session_timeout) {
     reInitialize();
 
     std::shared_ptr<core::Processor> consume_kafka = plan_->addProcessor("ConsumeKafka", "consume_kafka", {success}, false);
@@ -453,7 +452,7 @@ const std::string ConsumeKafkaTest::ATTRIBUTE_FOR_CAPTURING_CONTENT{ "flowfile_c
 const std::chrono::seconds ConsumeKafkaTest::MAX_CONSUMEKAFKA_POLL_TIME_SECONDS{ 5 };
 
 TEST_CASE_METHOD(ConsumeKafkaPropertiesTest, "ConsumeKafka parses and uses kafka topics.", "[ConsumeKafka][Kafka][Topic]") {
-  auto run_tests = [&] (const std::vector<std::string>& messages_on_topic, const std::string& topic_names, const optional<std::string>& topic_name_format) {
+  auto run_tests = [&] (const std::vector<std::string>& messages_on_topic, const std::string& topic_names, const std::optional<std::string>& topic_name_format) {
     single_consumer_with_plain_text_test(true, {}, messages_on_topic, NON_TRANSACTIONAL_MESSAGES, {}, "localhost:9092", "PLAINTEXT", topic_names, topic_name_format, {}, "test_group_id", {}, {}, {}, {}, {}, {}, "1", "2 sec", "60 sec"); // NOLINT
   };
   run_tests({ "Ulysses",              "James Joyce"         }, "ConsumeKafkaTest",         {});
@@ -477,7 +476,7 @@ TEST_CASE_METHOD(ConsumeKafkaPropertiesTest, "Offsets are reset to the latest wh
 }
 
 TEST_CASE_METHOD(ConsumeKafkaPropertiesTest, "Key attribute is encoded according to the \"Key Attribute Encoding\" property.", "[ConsumeKafka][Kafka][KeyAttributeEncoding]") {
-  auto run_tests = [&] (const std::vector<std::string>& messages_on_topic, const optional<std::string>& key_attribute_encoding) {
+  auto run_tests = [&] (const std::vector<std::string>& messages_on_topic, const std::optional<std::string>& key_attribute_encoding) {
     single_consumer_with_plain_text_test(true, {}, messages_on_topic, NON_TRANSACTIONAL_MESSAGES, {}, "localhost:9092", "PLAINTEXT", "ConsumeKafkaTest", {}, {}, "test_group_id", {}, key_attribute_encoding, {}, {}, {}, {}, "1", "2 sec", "60 sec"); // NOLINT
   };
 
@@ -488,7 +487,7 @@ TEST_CASE_METHOD(ConsumeKafkaPropertiesTest, "Key attribute is encoded according
 }
 
 TEST_CASE_METHOD(ConsumeKafkaPropertiesTest, "Transactional behaviour is supported.", "[ConsumeKafka][Kafka][Transaction]") {
-  auto run_tests = [&] (const std::vector<std::string>& messages_on_topic, const std::vector<KafkaTestProducer::PublishEvent>& transaction_events, const optional<bool>& honor_transactions) {
+  auto run_tests = [&] (const std::vector<std::string>& messages_on_topic, const std::vector<KafkaTestProducer::PublishEvent>& transaction_events, const std::optional<bool>& honor_transactions) {
     single_consumer_with_plain_text_test(true, {}, messages_on_topic, transaction_events, {}, "localhost:9092", "PLAINTEXT", "ConsumeKafkaTest", {}, honor_transactions, "test_group_id", {}, {}, {}, {}, {}, {}, "1", "2 sec", "60 sec"); // NOLINT
   };
   run_tests({  "Pride and Prejudice", "Jane Austen"      }, SINGLE_COMMITTED_TRANSACTION, {});
@@ -504,8 +503,8 @@ TEST_CASE_METHOD(ConsumeKafkaPropertiesTest, "Headers on consumed Kafka messages
       const std::vector<std::string>& messages_on_topic,
       const std::vector<std::pair<std::string, std::string>>& expect_header_attributes,
       const std::vector<std::pair<std::string, std::string>>& message_headers,
-      const optional<std::string>& headers_to_add_as_attributes,
-      const optional<std::string>& duplicate_header_handling) {
+      const std::optional<std::string>& headers_to_add_as_attributes,
+      const std::optional<std::string>& duplicate_header_handling) {
     single_consumer_with_plain_text_test(true, expect_header_attributes, messages_on_topic, NON_TRANSACTIONAL_MESSAGES, message_headers, "localhost:9092", "PLAINTEXT", "ConsumeKafkaTest", {}, {}, "test_group_id", {}, {}, {}, {}, headers_to_add_as_attributes, duplicate_header_handling, "1", "2 sec", "60 sec"); // NOLINT
   };
   run_tests({             "Homeland",   "R. A. Salvatore"},                                      {},             {{{"Contains dark elves"}, {"Yes"}}},         {},                    {});
@@ -519,7 +518,7 @@ TEST_CASE_METHOD(ConsumeKafkaPropertiesTest, "Headers on consumed Kafka messages
 TEST_CASE_METHOD(ConsumeKafkaPropertiesTest, "Messages are separated into multiple flowfiles if the message demarcator is present in the message.", "[ConsumeKafka][Kafka][MessageDemarcator]") {
   auto run_tests = [&] (
       const std::vector<std::string>& messages_on_topic,
-      const optional<std::string>& message_demarcator) {
+      const std::optional<std::string>& message_demarcator) {
     single_consumer_with_plain_text_test(true, {}, messages_on_topic, NON_TRANSACTIONAL_MESSAGES, {}, "localhost:9092", "PLAINTEXT", "ConsumeKafkaTest", {}, {}, "test_group_id", {}, {}, message_demarcator, {}, {}, {}, "1", "2 sec", "60 sec"); // NOLINT
   };
   run_tests({"Barbapapa", "Anette Tison and Talus Taylor"}, "a");
@@ -529,7 +528,7 @@ TEST_CASE_METHOD(ConsumeKafkaPropertiesTest, "The maximum poll records allows Co
   auto run_tests = [&] (
       const std::vector<std::string>& messages_on_topic,
       const std::vector<KafkaTestProducer::PublishEvent>& transaction_events,
-      const optional<std::string>& max_poll_records) {
+      const std::optional<std::string>& max_poll_records) {
     single_consumer_with_plain_text_test(true, {}, messages_on_topic, transaction_events, {}, "localhost:9092", "PLAINTEXT", "ConsumeKafkaTest", {}, {}, "test_group_id", {}, {}, {}, {}, {}, {}, max_poll_records, "2 sec", "60 sec"); // NOLINT
   };
   run_tests({"The Count of Monte Cristo", "Alexandre Dumas"}, NON_TRANSACTIONAL_MESSAGES, "2");
@@ -571,9 +570,9 @@ TEST_CASE_METHOD(ConsumeKafkaPropertiesTest, "Acceptable values for message head
 TEST_CASE_METHOD(ConsumeKafkaContinuousPublishingTest, "ConsumeKafka can spend no more time polling than allowed in the maximum poll time property.", "[ConsumeKafka][Kafka][Batching][MaxPollTime]") {
   auto run_tests = [&] (
       const uint64_t msg_periodicity_ms,
-      const optional<std::string>& max_poll_records,
-      const optional<std::string>& max_poll_time,
-      const optional<std::string>& session_timeout) {
+      const std::optional<std::string>& max_poll_records,
+      const std::optional<std::string>& max_poll_time,
+      const std::optional<std::string>& session_timeout) {
     single_consumer_with_continuous_message_producing(msg_periodicity_ms, "localhost:9092", "test_group_id", max_poll_records, max_poll_time, session_timeout);
   };
   // For some reason, a session time-out of a few seconds does not work at all, 10 seconds seems to be stable
diff --git a/extensions/mqtt/processors/AbstractMQTTProcessor.cpp b/extensions/mqtt/processors/AbstractMQTTProcessor.cpp
index a8ef810..1359e91 100644
--- a/extensions/mqtt/processors/AbstractMQTTProcessor.cpp
+++ b/extensions/mqtt/processors/AbstractMQTTProcessor.cpp
@@ -86,9 +86,9 @@ void AbstractMQTTProcessor::onSchedule(const std::shared_ptr<core::ProcessContex
     logger_->log_debug("AbstractMQTTProcessor: PassWord [%s]", passWord_);
   }
 
-  const auto cleanSession_parsed = [&] () -> utils::optional<bool> {
+  const auto cleanSession_parsed = [&] () -> std::optional<bool> {
     std::string property_value;
-    if (!context->getProperty(CleanSession.getName(), property_value)) return utils::nullopt;
+    if (!context->getProperty(CleanSession.getName(), property_value)) return std::nullopt;
     return utils::StringUtils::toBool(property_value);
   }();
   if ( cleanSession_parsed ) {
diff --git a/extensions/mqtt/processors/PublishMQTT.cpp b/extensions/mqtt/processors/PublishMQTT.cpp
index 351cd5f..4259f03 100644
--- a/extensions/mqtt/processors/PublishMQTT.cpp
+++ b/extensions/mqtt/processors/PublishMQTT.cpp
@@ -19,13 +19,14 @@
  */
 #include "PublishMQTT.h"
 
-#include <stdio.h>
 #include <algorithm>
-#include <memory>
-#include <string>
+#include <cinttypes>
+#include <cstdio>
 #include <map>
+#include <memory>
+#include <optional>
 #include <set>
-#include <cinttypes>
+#include <string>
 
 #include "utils/TimeUtil.h"
 #include "utils/StringUtils.h"
@@ -64,9 +65,9 @@ void PublishMQTT::onSchedule(const std::shared_ptr<core::ProcessContext> &contex
     logger_->log_debug("PublishMQTT: max flow segment size [%" PRIu64 "]", max_seg_size_);
   }
 
-  const auto retain_parsed = [&] () -> utils::optional<bool> {
+  const auto retain_parsed = [&] () -> std::optional<bool> {
     std::string property_value;
-    if (!context->getProperty(CleanSession.getName(), property_value)) return utils::nullopt;
+    if (!context->getProperty(CleanSession.getName(), property_value)) return std::nullopt;
     return utils::StringUtils::toBool(property_value);
   }();
   if ( retain_parsed ) {
diff --git a/extensions/opc/src/putopc.cpp b/extensions/opc/src/putopc.cpp
index 2e09369..d0a7e0a 100644
--- a/extensions/opc/src/putopc.cpp
+++ b/extensions/opc/src/putopc.cpp
@@ -17,11 +17,12 @@
  * limitations under the License.
  */
 
-#include <memory>
-#include <string>
 #include <list>
 #include <map>
+#include <memory>
 #include <mutex>
+#include <string>
+#include <optional>
 #include <thread>
 
 #include "opc.h"
@@ -301,7 +302,7 @@ namespace processors {
             break;
           }
           case opc::OPCNodeDataType::Boolean: {
-            utils::optional<bool> contentstr_parsed = utils::StringUtils::toBool(contentstr);
+            const auto contentstr_parsed = utils::StringUtils::toBool(contentstr);
             if (contentstr_parsed) {
               sc = connection_->update_node(targetnode, contentstr_parsed.value());
             } else {
@@ -378,7 +379,7 @@ namespace processors {
             break;
           }
           case opc::OPCNodeDataType::Boolean: {
-            utils::optional<bool> contentstr_parsed = utils::StringUtils::toBool(contentstr);
+            const auto contentstr_parsed = utils::StringUtils::toBool(contentstr);
             if (contentstr_parsed) {
               sc = connection_->add_node(parentNodeID_, targetnode, browsename, contentstr_parsed.value(), nodeDataType_, &resultnode);
             } else {
diff --git a/extensions/pdh/PerformanceDataMonitor.cpp b/extensions/pdh/PerformanceDataMonitor.cpp
index e1a8112..d449cae 100644
--- a/extensions/pdh/PerformanceDataMonitor.cpp
+++ b/extensions/pdh/PerformanceDataMonitor.cpp
@@ -315,7 +315,7 @@ void PerformanceDataMonitor::setupOutputFormatFromProperties(const std::shared_p
 void PerformanceDataMonitor::setupDecimalPlacesFromProperties(const std::shared_ptr<core::ProcessContext>& context) {
   std::string decimal_places_str;
   if (!context->getProperty(DecimalPlaces.getName(), decimal_places_str) || decimal_places_str == "") {
-    decimal_places_ = utils::nullopt;
+    decimal_places_ = std::nullopt;
     return;
   }
 
diff --git a/extensions/pdh/PerformanceDataMonitor.h b/extensions/pdh/PerformanceDataMonitor.h
index de316b0..363b446 100644
--- a/extensions/pdh/PerformanceDataMonitor.h
+++ b/extensions/pdh/PerformanceDataMonitor.h
@@ -18,10 +18,11 @@
 #pragma once
 
 #include <pdh.h>
-#include <string>
-#include <vector>
 #include <memory>
+#include <optional>
+#include <string>
 #include <utility>
+#include <vector>
 
 #include "core/Processor.h"
 
@@ -47,7 +48,7 @@ class PerformanceDataMonitor : public core::Processor {
 
   explicit PerformanceDataMonitor(const std::string& name, utils::Identifier uuid = utils::Identifier())
       : Processor(name, uuid), output_format_(OutputFormat::JSON), pretty_output_(false),
-        decimal_places_(utils::nullopt), logger_(logging::LoggerFactory<PerformanceDataMonitor>::getLogger()),
+        decimal_places_(std::nullopt), logger_(logging::LoggerFactory<PerformanceDataMonitor>::getLogger()),
         pdh_query_(nullptr), resource_consumption_counters_() {}
 
   ~PerformanceDataMonitor() override;
@@ -85,7 +86,7 @@ class PerformanceDataMonitor : public core::Processor {
   OutputFormat output_format_;
   bool pretty_output_;
 
-  utils::optional<uint8_t> decimal_places_;
+  std::optional<uint8_t> decimal_places_;
   std::shared_ptr<logging::Logger> logger_;
   PDH_HQUERY pdh_query_;
   std::vector<std::unique_ptr<PerformanceDataCounter>> resource_consumption_counters_;
diff --git a/extensions/rocksdb-repos/FlowFileRepository.cpp b/extensions/rocksdb-repos/FlowFileRepository.cpp
index 5393e89..3a60898 100644
--- a/extensions/rocksdb-repos/FlowFileRepository.cpp
+++ b/extensions/rocksdb-repos/FlowFileRepository.cpp
@@ -18,11 +18,12 @@
 #include "FlowFileRepository.h"
 
 #include <chrono>
+#include <list>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
-#include <list>
 
 #include "rocksdb/options.h"
 #include "rocksdb/write_batch.h"
@@ -144,7 +145,7 @@ void FlowFileRepository::prune_stored_flowfiles() {
     }
   };
   auto checkpointDB = minifi::internal::RocksDatabase::create(set_db_opts, {}, checkpoint_dir_, minifi::internal::RocksDbMode::ReadOnly);
-  utils::optional<minifi::internal::OpenRocksDb> opendb;
+  std::optional<minifi::internal::OpenRocksDb> opendb;
   if (nullptr != checkpoint_) {
     opendb = checkpointDB->open();
     if (opendb) {
diff --git a/extensions/rocksdb-repos/database/RocksDatabase.cpp b/extensions/rocksdb-repos/database/RocksDatabase.cpp
index 248a632..fa52a1d 100644
--- a/extensions/rocksdb-repos/database/RocksDatabase.cpp
+++ b/extensions/rocksdb-repos/database/RocksDatabase.cpp
@@ -60,7 +60,7 @@ std::unique_ptr<RocksDatabase> RocksDatabase::create(const DBOptionsPatch& db_op
 
   if (mode == RocksDbMode::ReadOnly) {
     // no need to cache anything with read-only databases
-    return utils::make_unique<RocksDatabase>(std::make_shared<RocksDbInstance>(db_path, mode), db_column, db_options_patch, cf_options_patch);
+    return std::make_unique<RocksDatabase>(std::make_shared<RocksDbInstance>(db_path, mode), db_column, db_options_patch, cf_options_patch);
   }
 
   static std::mutex mtx;
@@ -78,13 +78,13 @@ std::unique_ptr<RocksDatabase> RocksDatabase::create(const DBOptionsPatch& db_op
       logger_->log_info("Using previously opened rocksdb instance '%s'", db_path);
     }
   }
-  return utils::make_unique<RocksDatabase>(instance, db_column, db_options_patch, cf_options_patch);
+  return std::make_unique<RocksDatabase>(instance, db_column, db_options_patch, cf_options_patch);
 }
 
 RocksDatabase::RocksDatabase(std::shared_ptr<RocksDbInstance> db, std::string column, DBOptionsPatch db_options_patch, ColumnFamilyOptionsPatch cf_options_patch)
   : column_(std::move(column)), db_options_patch_(std::move(db_options_patch)), cf_options_patch_(std::move(cf_options_patch)), db_(std::move(db)) {}
 
-utils::optional<OpenRocksDb> RocksDatabase::open() {
+std::optional<OpenRocksDb> RocksDatabase::open() {
   return db_->open(column_, db_options_patch_, cf_options_patch_);
 }
 
diff --git a/extensions/rocksdb-repos/database/RocksDatabase.h b/extensions/rocksdb-repos/database/RocksDatabase.h
index 6f1ca32..a53c5cf 100644
--- a/extensions/rocksdb-repos/database/RocksDatabase.h
+++ b/extensions/rocksdb-repos/database/RocksDatabase.h
@@ -19,9 +19,9 @@
 #pragma once
 
 #include <memory>
+#include <optional>
 #include <string>
 
-#include "utils/OptionalUtils.h"
 #include "rocksdb/db.h"
 #include "logging/Logger.h"
 #include "RocksDbUtils.h"
@@ -48,7 +48,7 @@ class RocksDatabase {
 
   RocksDatabase(std::shared_ptr<RocksDbInstance> db, std::string column, DBOptionsPatch db_options_patch, ColumnFamilyOptionsPatch cf_options_patch);
 
-  utils::optional<OpenRocksDb> open();
+  std::optional<OpenRocksDb> open();
 
  private:
   const std::string column_;
diff --git a/extensions/rocksdb-repos/database/RocksDbInstance.cpp b/extensions/rocksdb-repos/database/RocksDbInstance.cpp
index da01d45..8f86fc5 100644
--- a/extensions/rocksdb-repos/database/RocksDbInstance.cpp
+++ b/extensions/rocksdb-repos/database/RocksDbInstance.cpp
@@ -40,7 +40,7 @@ void RocksDbInstance::invalidate() {
   impl_.reset();
 }
 
-utils::optional<OpenRocksDb> RocksDbInstance::open(const std::string& column, const DBOptionsPatch& db_options_patch, const ColumnFamilyOptionsPatch& cf_options_patch) {
+std::optional<OpenRocksDb> RocksDbInstance::open(const std::string& column, const DBOptionsPatch& db_options_patch, const ColumnFamilyOptionsPatch& cf_options_patch) {
   std::lock_guard<std::mutex> db_guard{mtx_};
   if (!impl_) {
     gsl_Expects(columns_.empty());
@@ -74,7 +74,7 @@ utils::optional<OpenRocksDb> RocksDbInstance::open(const std::string& column, co
       rocksdb::Status compat_status = rocksdb::CheckOptionsCompatibility(conf_options, db_name_, db_options_, cf_descriptors);
       if (!compat_status.ok()) {
         logger_->log_error("Incompatible database options: %s", compat_status.ToString());
-        return utils::nullopt;
+        return std::nullopt;
       }
     } else if (option_status.IsNotFound()) {
       logger_->log_trace("Database at '%s' not found, creating", db_name_);
@@ -91,7 +91,7 @@ utils::optional<OpenRocksDb> RocksDbInstance::open(const std::string& column, co
       }
     } else if (!option_status.ok()) {
       logger_->log_error("Couldn't query database '%s' for options: '%s'", db_name_, option_status.ToString());
-      return utils::nullopt;
+      return std::nullopt;
     }
     std::vector<rocksdb::ColumnFamilyHandle*> column_handles;
     switch (mode_) {
@@ -110,7 +110,7 @@ utils::optional<OpenRocksDb> RocksDbInstance::open(const std::string& column, co
     }
     if (!result.ok()) {
       // we failed to open the database
-      return utils::nullopt;
+      return std::nullopt;
     }
     gsl_Expects(db_instance);
     // the patcher could have internal resources the we need to keep alive
@@ -129,14 +129,14 @@ utils::optional<OpenRocksDb> RocksDbInstance::open(const std::string& column, co
       db_options_patch(writer);
       if (writer.isModified()) {
         logger_->log_error("Database '%s' has already been opened using a different configuration", db_name_);
-        return utils::nullopt;
+        return std::nullopt;
       }
     }
   }
   std::shared_ptr<ColumnHandle> column_handle = getOrCreateColumnFamily(column, cf_options_patch, db_guard);
   if (!column_handle) {
     // error is already logged by the method
-    return utils::nullopt;
+    return std::nullopt;
   }
   return OpenRocksDb(
       *this,
diff --git a/extensions/rocksdb-repos/database/RocksDbInstance.h b/extensions/rocksdb-repos/database/RocksDbInstance.h
index 4e2d8a3..fdc3e24 100644
--- a/extensions/rocksdb-repos/database/RocksDbInstance.h
+++ b/extensions/rocksdb-repos/database/RocksDbInstance.h
@@ -18,10 +18,10 @@
 
 #pragma once
 
-#include <string>
 #include <memory>
+#include <optional>
+#include <string>
 #include <unordered_map>
-#include "utils/OptionalUtils.h"
 #include "RocksDbUtils.h"
 #include "rocksdb/db.h"
 #include "logging/Logger.h"
@@ -44,7 +44,7 @@ class RocksDbInstance {
  public:
   explicit RocksDbInstance(const std::string& path, RocksDbMode mode = RocksDbMode::ReadWrite);
 
-  utils::optional<OpenRocksDb> open(const std::string& column, const DBOptionsPatch& db_options_patch, const ColumnFamilyOptionsPatch& cf_options_patch);
+  std::optional<OpenRocksDb> open(const std::string& column, const DBOptionsPatch& db_options_patch, const ColumnFamilyOptionsPatch& cf_options_patch);
 
  protected:
   // caller must hold the mtx_ mutex
diff --git a/extensions/sql/SQLLoader.h b/extensions/sql/SQLLoader.h
index ac9d4df..d3d050b 100644
--- a/extensions/sql/SQLLoader.h
+++ b/extensions/sql/SQLLoader.h
@@ -17,12 +17,14 @@
  */
 
 #pragma once
+
+#include <memory>
+
 #include "core/ClassLoader.h"
 #include "processors/ExecuteSQL.h"
 #include "processors/PutSQL.h"
 #include "processors/QueryDatabaseTable.h"
 #include "services/ODBCConnector.h"
-#include "utils/GeneralUtils.h"
 
 class SQLFactory : public core::ObjectFactory {
  public:
@@ -49,7 +51,7 @@ class SQLFactory : public core::ObjectFactory {
 
   template <typename T>
   static std::unique_ptr<ObjectFactory> getObjectFactory() {
-    return utils::make_unique<core::DefautObjectFactory<T>>();
+    return std::make_unique<core::DefautObjectFactory<T>>();
   }
 
   std::unique_ptr<ObjectFactory> assign(const std::string &class_name) override {
diff --git a/extensions/sql/data/SociConnectors.cpp b/extensions/sql/data/SociConnectors.cpp
index 235c481..8987a1b 100644
--- a/extensions/sql/data/SociConnectors.cpp
+++ b/extensions/sql/data/SociConnectors.cpp
@@ -120,7 +120,7 @@ std::unique_ptr<Rowset> SociStatement::execute(const std::vector<std::string>& a
     // binds arguments to the prepared statement
     stmt.operator,(soci::use(arg));
   }
-  return utils::make_unique<SociRowset>(stmt);
+  return std::make_unique<SociRowset>(stmt);
 }
 
 void SociSession::begin() {
@@ -141,7 +141,7 @@ void SociSession::execute(const std::string &statement) {
 
 ODBCConnection::ODBCConnection(std::string connectionString)
   : connection_string_(std::move(connectionString)) {
-    session_ = utils::make_unique<soci::session>(getSessionParameters());
+    session_ = std::make_unique<soci::session>(getSessionParameters());
 }
 
 bool ODBCConnection::connected(std::string& exception) const {
@@ -158,11 +158,11 @@ bool ODBCConnection::connected(std::string& exception) const {
 }
 
 std::unique_ptr<sql::Statement> ODBCConnection::prepareStatement(const std::string& query) const {
-  return utils::make_unique<sql::SociStatement>(*session_, query);
+  return std::make_unique<sql::SociStatement>(*session_, query);
 }
 
 std::unique_ptr<Session> ODBCConnection::getSession() const {
-  return utils::make_unique<sql::SociSession>(*session_);
+  return std::make_unique<sql::SociSession>(*session_);
 }
 
 soci::connection_parameters ODBCConnection::getSessionParameters() const {
diff --git a/extensions/sql/data/SociConnectors.h b/extensions/sql/data/SociConnectors.h
index 388adf8..7eee768 100644
--- a/extensions/sql/data/SociConnectors.h
+++ b/extensions/sql/data/SociConnectors.h
@@ -23,7 +23,6 @@
 #include <ctime>
 
 #include "Exception.h"
-#include "utils/GeneralUtils.h"
 #include "data/DatabaseConnectors.h"
 #include <soci/soci.h>
 #include <soci/odbc/soci-odbc.h>
diff --git a/extensions/sql/services/ODBCConnector.h b/extensions/sql/services/ODBCConnector.h
index 692ce12..5474134 100644
--- a/extensions/sql/services/ODBCConnector.h
+++ b/extensions/sql/services/ODBCConnector.h
@@ -20,6 +20,7 @@
 
 #include "core/logging/LoggerConfiguration.h"
 #include "core/controller/ControllerService.h"
+
 #include "DatabaseService.h"
 #include "core/Resource.h"
 #include "data/SociConnectors.h"
diff --git a/extensions/standard-processors/processors/RetryFlowFile.cpp b/extensions/standard-processors/processors/RetryFlowFile.cpp
index cd88e45..1169c2e 100644
--- a/extensions/standard-processors/processors/RetryFlowFile.cpp
+++ b/extensions/standard-processors/processors/RetryFlowFile.cpp
@@ -104,7 +104,7 @@ void RetryFlowFile::onTrigger(core::ProcessContext* context, core::ProcessSessio
     return;
   }
 
-  utils::optional<uint64_t> maybe_retry_property_value = getRetryPropertyValue(flow_file);
+  const auto maybe_retry_property_value = getRetryPropertyValue(flow_file);
   if (!maybe_retry_property_value) {
     session->transfer(flow_file, Failure);
     return;
@@ -154,22 +154,22 @@ void RetryFlowFile::readDynamicPropertyKeys(core::ProcessContext* context) {
   }
 }
 
-utils::optional<uint64_t> RetryFlowFile::getRetryPropertyValue(const std::shared_ptr<core::FlowFile>& flow_file) const {
+std::optional<uint64_t> RetryFlowFile::getRetryPropertyValue(const std::shared_ptr<core::FlowFile>& flow_file) const {
   std::string value_as_string;
   flow_file->getAttribute(retry_attribute_, value_as_string);
   uint64_t value;
   try {
     utils::internal::ValueParser(value_as_string).parse(value).parseEnd();
-    return utils::make_optional<uint64_t>(value);
+    return value;
   }
   catch(const utils::internal::ParseException&) {
     if (fail_on_non_numerical_overwrite_) {
       logger_->log_info("Non-numerical retry property in RetryFlowFile (value: %s). Sending flowfile to failure...", value_as_string);
-      return {};
+      return std::nullopt;
     }
   }
   logger_->log_info("Non-numerical retry property in RetryFlowFile: overwriting %s with 0.", value_as_string);
-  return utils::make_optional<uint64_t>(0);
+  return 0;
 }
 
 void RetryFlowFile::setRetriesExceededAttributesOnFlowFile(core::ProcessContext* context, const std::shared_ptr<core::FlowFile>& flow_file) const {
diff --git a/extensions/standard-processors/processors/RetryFlowFile.h b/extensions/standard-processors/processors/RetryFlowFile.h
index c45edf0..62daa3d 100644
--- a/extensions/standard-processors/processors/RetryFlowFile.h
+++ b/extensions/standard-processors/processors/RetryFlowFile.h
@@ -20,6 +20,7 @@
 
 #include <atomic>
 #include <memory>
+#include <optional>
 #include <queue>
 #include <string>
 #include <utility>
@@ -32,7 +33,6 @@
 #include "core/Core.h"
 #include "core/Resource.h"
 #include "core/logging/LoggerConfiguration.h"
-#include "utils/OptionalUtils.h"
 
 namespace org {
 namespace apache {
@@ -88,7 +88,7 @@ class RetryFlowFile : public core::Processor {
 
  private:
   void readDynamicPropertyKeys(core::ProcessContext* context);
-  utils::optional<uint64_t> getRetryPropertyValue(const std::shared_ptr<core::FlowFile>& flow_file) const;
+  std::optional<uint64_t> getRetryPropertyValue(const std::shared_ptr<core::FlowFile>& flow_file) const;
   void setRetriesExceededAttributesOnFlowFile(core::ProcessContext* context, const std::shared_ptr<core::FlowFile>& flow_file) const;
 
   core::annotation::Input getInputRequirement() const override {
diff --git a/extensions/standard-processors/tests/integration/TLSClientSocketSupportedProtocolsTest.cpp b/extensions/standard-processors/tests/integration/TLSClientSocketSupportedProtocolsTest.cpp
index 9c9b562..1f600a1 100644
--- a/extensions/standard-processors/tests/integration/TLSClientSocketSupportedProtocolsTest.cpp
+++ b/extensions/standard-processors/tests/integration/TLSClientSocketSupportedProtocolsTest.cpp
@@ -167,7 +167,7 @@ class TLSClientSocketSupportedProtocolsTest {
     server.waitForConnection();
 
     const auto socket_context = std::make_shared<org::apache::nifi::minifi::io::TLSContext>(configuration_);
-    client_socket_ = utils::make_unique<org::apache::nifi::minifi::io::TLSSocket>(socket_context, host_, std::stoi(port_), 0);
+    client_socket_ = std::make_unique<org::apache::nifi::minifi::io::TLSSocket>(socket_context, host_, std::stoi(port_), 0);
     const bool client_initialized_successfully = (client_socket_->initialize() == 0);
     assert(client_initialized_successfully == should_be_compatible);
     server.shutdownServer();
diff --git a/extensions/standard-processors/tests/integration/TLSServerSocketSupportedProtocolsTest.cpp b/extensions/standard-processors/tests/integration/TLSServerSocketSupportedProtocolsTest.cpp
index 55800b0..d892cda 100644
--- a/extensions/standard-processors/tests/integration/TLSServerSocketSupportedProtocolsTest.cpp
+++ b/extensions/standard-processors/tests/integration/TLSServerSocketSupportedProtocolsTest.cpp
@@ -244,7 +244,7 @@ class TLSServerSocketSupportedProtocolsTest {
 
     void createServerSocket() {
       const auto socket_context = std::make_shared<org::apache::nifi::minifi::io::TLSContext>(configuration_);
-      server_socket_ = utils::make_unique<org::apache::nifi::minifi::io::TLSServerSocket>(socket_context, host_, std::stoi(port_), 3);
+      server_socket_ = std::make_unique<org::apache::nifi::minifi::io::TLSServerSocket>(socket_context, host_, std::stoi(port_), 3);
       assert(0 == server_socket_->initialize());
 
       is_running_ = true;
diff --git a/extensions/standard-processors/tests/unit/ProcessGroupTestUtils.h b/extensions/standard-processors/tests/unit/ProcessGroupTestUtils.h
index e492f87..3b50b97 100644
--- a/extensions/standard-processors/tests/unit/ProcessGroupTestUtils.h
+++ b/extensions/standard-processors/tests/unit/ProcessGroupTestUtils.h
@@ -82,7 +82,7 @@ struct MaybeProc {
   MaybeProc(const UnresolvedProc& proc) : id(proc.id) {}  // NOLINT
 
   std::string id;
-  utils::optional<std::string> name;
+  std::optional<std::string> name;
 };
 
 struct Conn {
diff --git a/extensions/standard-processors/tests/unit/RetryFlowFileTests.cpp b/extensions/standard-processors/tests/unit/RetryFlowFileTests.cpp
index ec27b1a..150642a 100644
--- a/extensions/standard-processors/tests/unit/RetryFlowFileTests.cpp
+++ b/extensions/standard-processors/tests/unit/RetryFlowFileTests.cpp
@@ -19,6 +19,7 @@
 #define CATCH_CONFIG_MAIN
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <set>
 
@@ -30,12 +31,11 @@
 #include "processors/PutFile.h"
 #include "processors/LogAttribute.h"
 #include "utils/file/FileUtils.h"
-#include "utils/OptionalUtils.h"
 #include "utils/RegexUtils.h"
 #include "utils/TestUtils.h"
 
 namespace {
-using org::apache::nifi::minifi::utils::optional;
+using std::optional;
 namespace FileUtils = org::apache::nifi::minifi::utils::file;
 
 class RetryFlowFileTest {
diff --git a/extensions/systemd/ConsumeJournald.cpp b/extensions/systemd/ConsumeJournald.cpp
index b5a3c26..162ec51 100644
--- a/extensions/systemd/ConsumeJournald.cpp
+++ b/extensions/systemd/ConsumeJournald.cpp
@@ -23,6 +23,7 @@
 #include "date/date.h"
 #include "spdlog/spdlog.h"  // TODO(szaszm): make fmt directly available
 #include "utils/GeneralUtils.h"
+#include "utils/OptionalUtils.h"
 
 namespace org { namespace apache { namespace nifi { namespace minifi { namespace extensions { namespace systemd {
 
@@ -77,7 +78,7 @@ void ConsumeJournald::initialize() {
   setSupportedProperties({BatchSize, PayloadFormat, IncludeTimestamp, JournalType, ProcessOldMessages, TimestampFormat});
   setSupportedRelationships({Success});
 
-  worker_ = utils::make_unique<Worker>();
+  worker_ = std::make_unique<Worker>();
 }
 
 void ConsumeJournald::notifyStop() {
@@ -93,16 +94,16 @@ void ConsumeJournald::onSchedule(core::ProcessContext* const context, core::Proc
   gsl_Expects(context && sessionFactory && !running_ && worker_);
   using JournalTypeEnum = systemd::JournalType;
 
-  const auto parse_payload_format = [](const std::string& property_value) -> utils::optional<systemd::PayloadFormat> {
+  const auto parse_payload_format = [](const std::string& property_value) -> std::optional<systemd::PayloadFormat> {
     if (property_value == PAYLOAD_FORMAT_RAW) return systemd::PayloadFormat::Raw;
     if (property_value == PAYLOAD_FORMAT_SYSLOG) return systemd::PayloadFormat::Syslog;
-    return utils::nullopt;
+    return std::nullopt;
   };
-  const auto parse_journal_type = [](const std::string& property_value) -> utils::optional<JournalTypeEnum> {
+  const auto parse_journal_type = [](const std::string& property_value) -> std::optional<JournalTypeEnum> {
     if (property_value == JOURNAL_TYPE_USER) return JournalTypeEnum::User;
     if (property_value == JOURNAL_TYPE_SYSTEM) return JournalTypeEnum::System;
     if (property_value == JOURNAL_TYPE_BOTH) return JournalTypeEnum::Both;
-    return utils::nullopt;
+    return std::nullopt;
   };
   batch_size_ = context->getProperty<size_t>(BatchSize).value();
   payload_format_ = (context->getProperty(PayloadFormat) | utils::flatMap(parse_payload_format)
@@ -172,11 +173,11 @@ void ConsumeJournald::onTrigger(core::ProcessContext* const context, core::Proce
   state_manager_->set({{"cursor", std::move(cursor_and_messages.first)}});
 }
 
-utils::optional<gsl::span<const char>> ConsumeJournald::enumerateJournalEntry(libwrapper::Journal& journal) {
+std::optional<gsl::span<const char>> ConsumeJournald::enumerateJournalEntry(libwrapper::Journal& journal) {
   const void* data_ptr{};
   size_t data_length{};
   const auto status_code = journal.enumerateData(&data_ptr, &data_length);
-  if (status_code == 0) return {};
+  if (status_code == 0) return std::nullopt;
   if (status_code < 0) throw SystemErrorException{ "sd_journal_enumerate_data", std::generic_category().default_error_condition(-status_code) };
   gsl_Ensures(data_ptr && "if sd_journal_enumerate_data was successful, then data_ptr must be set");
   gsl_Ensures(data_length > 0 && "if sd_journal_enumerate_data was successful, then data_length must be greater than zero");
@@ -184,7 +185,7 @@ utils::optional<gsl::span<const char>> ConsumeJournald::enumerateJournalEntry(li
   return gsl::make_span(data_str_ptr, data_length);
 }
 
-utils::optional<ConsumeJournald::journal_field> ConsumeJournald::getNextField(libwrapper::Journal& journal) {
+std::optional<ConsumeJournald::journal_field> ConsumeJournald::getNextField(libwrapper::Journal& journal) {
   return enumerateJournalEntry(journal) | utils::map([](gsl::span<const char> field) {
     const auto eq_pos = std::find(std::begin(field), std::end(field), '=');
     gsl_Ensures(eq_pos != std::end(field) && "field string must contain an equals sign");
@@ -203,7 +204,7 @@ std::future<std::pair<std::string, std::vector<ConsumeJournald::journal_message>
     messages.reserve(batch_size_);
     for (size_t i = 0; i < batch_size_ && journal_->next() > 0; ++i) {
       journal_message message;
-      utils::optional<journal_field> field;
+      std::optional<journal_field> field;
       while ((field = getNextField(*journal_)).has_value()) {
         message.fields.push_back(std::move(*field));
       }
diff --git a/extensions/systemd/ConsumeJournald.h b/extensions/systemd/ConsumeJournald.h
index 6099fed..e3468bb 100644
--- a/extensions/systemd/ConsumeJournald.h
+++ b/extensions/systemd/ConsumeJournald.h
@@ -22,6 +22,7 @@
 #include <chrono>
 #include <future>
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <unordered_map>
@@ -35,7 +36,6 @@
 #include "libwrapper/LibWrapper.h"
 #include "utils/Deleters.h"
 #include "utils/gsl.h"
-#include "utils/OptionalUtils.h"
 #include "WorkerThread.h"
 
 namespace org { namespace apache { namespace nifi { namespace minifi { namespace extensions { namespace systemd {
@@ -84,8 +84,8 @@ class ConsumeJournald final : public core::Processor {
     std::chrono::system_clock::time_point timestamp;
   };
 
-  static utils::optional<gsl::span<const char>> enumerateJournalEntry(libwrapper::Journal&);
-  static utils::optional<journal_field> getNextField(libwrapper::Journal&);
+  static std::optional<gsl::span<const char>> enumerateJournalEntry(libwrapper::Journal&);
+  static std::optional<journal_field> getNextField(libwrapper::Journal&);
   std::future<std::pair<std::string, std::vector<journal_message>>> getCursorAndMessageBatch();
   std::string formatSyslogMessage(const journal_message&) const;
   std::string getCursor() const;
diff --git a/extensions/systemd/libwrapper/DlopenWrapper.cpp b/extensions/systemd/libwrapper/DlopenWrapper.cpp
index 2c8f452..355370f 100644
--- a/extensions/systemd/libwrapper/DlopenWrapper.cpp
+++ b/extensions/systemd/libwrapper/DlopenWrapper.cpp
@@ -98,7 +98,7 @@ class DlopenJournal : public Journal {
 };
 
 std::unique_ptr<Journal> DlopenWrapper::openJournal(const JournalType type) {
-  return utils::make_unique<DlopenJournal>(type);
+  return std::make_unique<DlopenJournal>(type);
 }
 
 }  // namespace libwrapper
diff --git a/extensions/systemd/libwrapper/LibWrapper.cpp b/extensions/systemd/libwrapper/LibWrapper.cpp
index d58e393..c405b5e 100644
--- a/extensions/systemd/libwrapper/LibWrapper.cpp
+++ b/extensions/systemd/libwrapper/LibWrapper.cpp
@@ -17,12 +17,11 @@
 
 #include "LibWrapper.h"
 #include "DlopenWrapper.h"
-#include "utils/GeneralUtils.h"
 
 namespace org { namespace apache { namespace nifi { namespace minifi { namespace extensions { namespace systemd { namespace libwrapper {
 
 std::unique_ptr<LibWrapper> createLibWrapper() {
-  return utils::make_unique<DlopenWrapper>();
+  return std::make_unique<DlopenWrapper>();
 }
 
 }  // namespace libwrapper
diff --git a/extensions/systemd/tests/ConsumeJournaldTest.cpp b/extensions/systemd/tests/ConsumeJournaldTest.cpp
index 2735930..5902a45 100644
--- a/extensions/systemd/tests/ConsumeJournaldTest.cpp
+++ b/extensions/systemd/tests/ConsumeJournaldTest.cpp
@@ -23,7 +23,6 @@
 #include "TestBase.h"
 #include "ConsumeJournald.h"
 #include "libwrapper/LibWrapper.h"
-#include "utils/GeneralUtils.h"
 #include "utils/gsl.h"
 #include "utils/StringUtils.h"
 #include "Utils.h"
@@ -132,7 +131,7 @@ struct TestLibWrapper final : libwrapper::LibWrapper {
   { }
 
   std::unique_ptr<libwrapper::Journal> openJournal(JournalType) override {
-    return utils::make_unique<TestJournal>(journal);
+    return std::make_unique<TestJournal>(journal);
   }
 
   std::vector<JournalEntry> journal;
@@ -150,7 +149,7 @@ TEST_CASE("ConsumeJournald", "[consumejournald]") {
   TestController test_controller;
   LogTestController::getInstance().setTrace<ConsumeJournald>();
   const auto plan = test_controller.createPlan();
-  auto libwrapper = utils::make_unique<TestLibWrapper>(TestLibWrapper{{
+  auto libwrapper = std::make_unique<TestLibWrapper>(TestLibWrapper{{
       {"kernel", "Linux version 5.10.12-gentoo-x86_64 (root@test-pc.test.local) (x86_64-pc-linux-gnu-gcc (Gentoo 10.2.0-r5 p6) 10.2.0, GNU ld (Gentoo 2.35.2 p1) 2.35.2) #1 SMP Sat Feb 20 03:13:45 CET 2021"},  // NOLINT
       {"kernel", "NX (Execute Disable) protection: active"},
       {"kernel", "ACPI: Local APIC address 0xfee00000"},
diff --git a/extensions/windows-event-log/tests/BookmarkTests.cpp b/extensions/windows-event-log/tests/BookmarkTests.cpp
index ffe3026..dbdf093 100644
--- a/extensions/windows-event-log/tests/BookmarkTests.cpp
+++ b/extensions/windows-event-log/tests/BookmarkTests.cpp
@@ -17,6 +17,7 @@
 
 #include "Bookmark.h"
 
+#include <memory>
 #include <regex>
 
 #include "TestBase.h"
@@ -40,7 +41,7 @@ std::unique_ptr<Bookmark> createBookmark(TestPlan &test_plan,
                                          const utils::Identifier &uuid = IdGenerator::getIdGenerator()->generate()) {
   const auto state_manager = test_plan.getStateManagerProvider()->getCoreComponentStateManager(uuid);
   const auto logger = test_plan.getLogger();
-  return utils::make_unique<Bookmark>(channel, L"*", "", uuid, false, state_manager, logger);
+  return std::make_unique<Bookmark>(channel, L"*", "", uuid, false, state_manager, logger);
 }
 
 void reportEvent(const std::wstring& channel, const char* message) {
diff --git a/extensions/windows-event-log/tests/CWELTestUtils.h b/extensions/windows-event-log/tests/CWELTestUtils.h
index 1457905..58dd96f 100644
--- a/extensions/windows-event-log/tests/CWELTestUtils.h
+++ b/extensions/windows-event-log/tests/CWELTestUtils.h
@@ -17,18 +17,18 @@
 
 #pragma once
 
-#include <utility>
-#include <memory>
-#include <string>
 #include <fstream>
 #include <iterator>
+#include <memory>
+#include <optional>
+#include <string>
+#include <utility>
 
 #include "ConsumeWindowsEventLog.h"
 #include "processors/PutFile.h"
 #include "TestBase.h"
 #include "utils/TestUtils.h"
 #include "utils/file/FileUtils.h"
-#include "utils/OptionalUtils.h"
 
 core::Relationship Success{"success", "Everything is fine"};
 
@@ -37,7 +37,7 @@ using PutFile = org::apache::nifi::minifi::processors::PutFile;
 
 class OutputFormatTestController : public TestController {
  public:
-  OutputFormatTestController(std::string channel, std::string query, std::string output_format, utils::optional<std::string> json_format = {})
+  OutputFormatTestController(std::string channel, std::string query, std::string output_format, std::optional<std::string> json_format = {})
     : channel_(std::move(channel)),
       query_(std::move(query)),
       output_format_(std::move(output_format)),
@@ -91,5 +91,5 @@ class OutputFormatTestController : public TestController {
   std::string channel_;
   std::string query_;
   std::string output_format_;
-  utils::optional<std::string> json_format_;
+  std::optional<std::string> json_format_;
 };
diff --git a/libminifi/CMakeLists.txt b/libminifi/CMakeLists.txt
index fc77c00..dc061bd 100644
--- a/libminifi/CMakeLists.txt
+++ b/libminifi/CMakeLists.txt
@@ -90,7 +90,7 @@ if(NOT EXCLUDE_BOOST)
   endif()
 endif()
 
-list(APPEND LIBMINIFI_LIBRARIES yaml-cpp ZLIB::ZLIB concurrentqueue RapidJSON spdlog cron Threads::Threads gsl-lite optional-lite libsodium)
+list(APPEND LIBMINIFI_LIBRARIES yaml-cpp ZLIB::ZLIB concurrentqueue RapidJSON spdlog cron Threads::Threads gsl-lite libsodium)
 if(NOT WIN32)
 	list(APPEND LIBMINIFI_LIBRARIES OSSP::libuuid++)
 endif()
diff --git a/libminifi/include/FlowController.h b/libminifi/include/FlowController.h
index 932fbbb..e764f82 100644
--- a/libminifi/include/FlowController.h
+++ b/libminifi/include/FlowController.h
@@ -204,7 +204,7 @@ class FlowController : public core::controller::ForwardingControllerServiceProvi
   void loadFlowRepo();
   void initializeExternalComponents();
 
-  utils::optional<std::chrono::milliseconds> loadShutdownTimeoutFromConfiguration();
+  std::optional<std::chrono::milliseconds> loadShutdownTimeoutFromConfiguration();
 
  private:
   template <typename T, typename = typename std::enable_if<std::is_base_of<SchedulingAgent, T>::value>::type>
diff --git a/libminifi/include/c2/C2Agent.h b/libminifi/include/c2/C2Agent.h
index 379fff9..44ed1e0 100644
--- a/libminifi/include/c2/C2Agent.h
+++ b/libminifi/include/c2/C2Agent.h
@@ -18,15 +18,16 @@
 
 #pragma once
 
-#include <map>
-#include <string>
-#include <vector>
-#include <utility>
 #include <functional>
 #include <future>
+#include <map>
 #include <memory>
 #include <mutex>
+#include <optional>
+#include <string>
 #include <thread>
+#include <utility>
+#include <vector>
 
 #include "../core/state/nodes/MetricsBase.h"
 #include "../core/state/Value.h"
@@ -88,7 +89,7 @@ class C2Agent : public state::UpdateController {
     return heart_beat_period_;
   }
 
-  utils::optional<std::string> fetchFlow(const std::string& uri) const;
+  std::optional<std::string> fetchFlow(const std::string& uri) const;
 
  protected:
   void restart_agent();
diff --git a/libminifi/include/c2/C2Client.h b/libminifi/include/c2/C2Client.h
index ab912e1..16b3b01 100644
--- a/libminifi/include/c2/C2Client.h
+++ b/libminifi/include/c2/C2Client.h
@@ -18,11 +18,13 @@
 
 #pragma once
 
-#include <memory>
-#include <vector>
 #include <map>
-#include <string>
+#include <memory>
 #include <mutex>
+#include <optional>
+#include <string>
+#include <vector>
+
 #include "c2/C2Agent.h"
 #include "core/controller/ControllerServiceProvider.h"
 #include "properties/Configure.h"
@@ -58,7 +60,7 @@ class C2Client : public core::Flow, public state::response::NodeReporter {
 
  protected:
   bool isC2Enabled() const;
-  utils::optional<std::string> fetchFlow(const std::string& uri) const;
+  std::optional<std::string> fetchFlow(const std::string& uri) const;
 
  private:
   void initializeComponentMetrics();
diff --git a/libminifi/include/c2/C2Payload.h b/libminifi/include/c2/C2Payload.h
index da9d43a..8f63b2c 100644
--- a/libminifi/include/c2/C2Payload.h
+++ b/libminifi/include/c2/C2Payload.h
@@ -63,7 +63,7 @@ struct AnnotatedValue : state::response::ValueNode {
   using state::response::ValueNode::ValueNode;
   using state::response::ValueNode::operator=;
 
-  utils::optional<std::reference_wrapper<const AnnotatedValue>> getAnnotation(const std::string& name) const {
+  [[nodiscard]] std::optional<std::reference_wrapper<const AnnotatedValue>> getAnnotation(const std::string& name) const {
     auto it = annotations.find(name);
     if (it == annotations.end()) {
       return {};
diff --git a/libminifi/include/core/AgentIdentificationProvider.h b/libminifi/include/core/AgentIdentificationProvider.h
index 40f77f4..6e297b6 100644
--- a/libminifi/include/core/AgentIdentificationProvider.h
+++ b/libminifi/include/core/AgentIdentificationProvider.h
@@ -18,8 +18,8 @@
 
 #pragma once
 
+#include <optional>
 #include <string>
-#include "utils/OptionalUtils.h"
 
 namespace org {
 namespace apache {
@@ -32,9 +32,9 @@ namespace core {
  */
 class AgentIdentificationProvider {
  public:
-  virtual utils::optional<std::string> getAgentClass() const = 0;
+  [[nodiscard]] virtual std::optional<std::string> getAgentClass() const = 0;
 
-  virtual std::string getAgentIdentifier() const = 0;
+  [[nodiscard]] virtual std::string getAgentIdentifier() const = 0;
 
   virtual ~AgentIdentificationProvider() = default;
 };
diff --git a/libminifi/include/core/ConfigurationFactory.h b/libminifi/include/core/ConfigurationFactory.h
index e094b56..ae0016f 100644
--- a/libminifi/include/core/ConfigurationFactory.h
+++ b/libminifi/include/core/ConfigurationFactory.h
@@ -20,10 +20,11 @@
 #define LIBMINIFI_INCLUDE_CORE_CONFIGURATIONFACTORY_H_
 
 #include <memory>
+#include <optional>
 #include <string>
+#include <type_traits>
 
 #include "FlowConfiguration.h"
-#include  <type_traits>
 
 namespace org {
 namespace apache {
@@ -35,7 +36,7 @@ template<typename T>
 typename std::enable_if<!class_operations<T>::value, T*>::type instantiate(
     const std::shared_ptr<core::Repository>& /*repo*/, const std::shared_ptr<core::Repository>& /*flow_file_repo*/,
     const std::shared_ptr<core::ContentRepository>& /*content_repo*/, std::shared_ptr<Configure> /*configuration*/,
-    const utils::optional<std::string>& /*path*/, const std::shared_ptr<utils::file::FileSystem>& /*filesystem*/) {
+    const std::optional<std::string>& /*path*/, const std::shared_ptr<utils::file::FileSystem>& /*filesystem*/) {
   throw std::runtime_error("Cannot instantiate class");
 }
 
@@ -43,7 +44,7 @@ template<typename T>
 typename std::enable_if<class_operations<T>::value, T*>::type instantiate(
     const std::shared_ptr<core::Repository> &repo, const std::shared_ptr<core::Repository> &flow_file_repo,
     const std::shared_ptr<core::ContentRepository> &content_repo, const std::shared_ptr<io::StreamFactory> &stream_factory,
-    std::shared_ptr<Configure> configuration, const utils::optional<std::string>& path,
+    std::shared_ptr<Configure> configuration, const std::optional<std::string>& path,
     const std::shared_ptr<utils::file::FileSystem>& filesystem) {
   return new T(repo, flow_file_repo, content_repo, stream_factory, configuration, path, filesystem);
 }
@@ -56,7 +57,7 @@ std::unique_ptr<core::FlowConfiguration> createFlowConfiguration(
     std::shared_ptr<core::Repository> repo, std::shared_ptr<core::Repository> flow_file_repo,
     std::shared_ptr<core::ContentRepository> content_repo, std::shared_ptr<Configure> configure,
     std::shared_ptr<io::StreamFactory> stream_factory, const std::string& configuration_class_name,
-    const utils::optional<std::string>& path = {}, std::shared_ptr<utils::file::FileSystem> filesystem = std::make_shared<utils::file::FileSystem>(),
+    const std::optional<std::string>& path = {}, std::shared_ptr<utils::file::FileSystem> filesystem = std::make_shared<utils::file::FileSystem>(),
     bool fail_safe = false);
 
 }  // namespace core
diff --git a/libminifi/include/core/CoreComponentState.h b/libminifi/include/core/CoreComponentState.h
index 2bdc04a..9a4d466 100644
--- a/libminifi/include/core/CoreComponentState.h
+++ b/libminifi/include/core/CoreComponentState.h
@@ -21,12 +21,11 @@
 #include "Core.h"
 
 #include <cstdint>
-#include <memory>
-#include <unordered_map>
 #include <map>
+#include <memory>
+#include <optional>
 #include <string>
-
-#include "utils/OptionalUtils.h"
+#include <unordered_map>
 
 namespace org {
 namespace apache {
@@ -44,12 +43,12 @@ class CoreComponentStateManager {
 
   virtual bool get(CoreComponentState& kvs) = 0;
 
-  utils::optional<std::unordered_map<std::string, std::string>> get() {
+  std::optional<std::unordered_map<std::string, std::string>> get() {
     std::unordered_map<std::string, std::string> out;
     if (get(out)) {
       return out;
     } else {
-      return utils::nullopt;
+      return std::nullopt;
     }
   }
 
diff --git a/libminifi/include/core/FlowConfiguration.h b/libminifi/include/core/FlowConfiguration.h
index b6ad108..9211566 100644
--- a/libminifi/include/core/FlowConfiguration.h
+++ b/libminifi/include/core/FlowConfiguration.h
@@ -19,9 +19,10 @@
 #define LIBMINIFI_INCLUDE_CORE_FLOWCONFIGURATION_H_
 
 #include <memory>
+#include <optional>
 #include <string>
-#include <vector>
 #include <utility>
+#include <vector>
 
 #include "core/Core.h"
 #include "Connection.h"
@@ -41,7 +42,6 @@
 #include "core/state/nodes/FlowInformation.h"
 #include "utils/file/FileSystem.h"
 #include "utils/ChecksumCalculator.h"
-#include "utils/OptionalUtils.h"
 
 namespace org {
 namespace apache {
@@ -69,7 +69,7 @@ class FlowConfiguration : public CoreComponent {
    */
   explicit FlowConfiguration(std::shared_ptr<core::Repository> /*repo*/, std::shared_ptr<core::Repository> flow_file_repo,
                              std::shared_ptr<core::ContentRepository> content_repo, std::shared_ptr<io::StreamFactory> stream_factory,
-                             std::shared_ptr<Configure> configuration, const utils::optional<std::string>& path,
+                             std::shared_ptr<Configure> configuration, const std::optional<std::string>& path,
                              std::shared_ptr<utils::file::FileSystem> filesystem = std::make_shared<utils::file::FileSystem>())
       : CoreComponent(core::getClassName<FlowConfiguration>()),
         flow_file_repo_(std::move(flow_file_repo)),
@@ -133,7 +133,7 @@ class FlowConfiguration : public CoreComponent {
    * Returns the configuration path string
    * @return config_path_
    */
-  const utils::optional<std::string> &getConfigurationPath() {
+  const std::optional<std::string> &getConfigurationPath() {
     return config_path_;
   }
 
@@ -180,7 +180,7 @@ class FlowConfiguration : public CoreComponent {
   // based, shared controller service map.
   std::shared_ptr<core::controller::ControllerServiceMap> controller_services_;
   // configuration path
-  utils::optional<std::string> config_path_;
+  std::optional<std::string> config_path_;
   // flow file repo
   std::shared_ptr<core::Repository> flow_file_repo_;
   // content repository.
diff --git a/libminifi/include/core/FlowFile.h b/libminifi/include/core/FlowFile.h
index dcca83d..a807a68 100644
--- a/libminifi/include/core/FlowFile.h
+++ b/libminifi/include/core/FlowFile.h
@@ -20,12 +20,12 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <set>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "utils/OptionalUtils.h"
 #include "utils/TimeUtil.h"
 #include "ResourceClaim.h"
 #include "Connectable.h"
@@ -137,7 +137,7 @@ class FlowFile : public CoreComponent, public ReferenceContainer {
    */
   bool getAttribute(const std::string& key, std::string& value) const;
 
-  utils::optional<std::string> getAttribute(const std::string& key) const;
+  std::optional<std::string> getAttribute(const std::string& key) const;
 
   /**
    * Updates the value in the attribute map that corresponds
diff --git a/libminifi/include/core/ProcessContext.h b/libminifi/include/core/ProcessContext.h
index 7f7f6d6..18389b2 100644
--- a/libminifi/include/core/ProcessContext.h
+++ b/libminifi/include/core/ProcessContext.h
@@ -18,15 +18,17 @@
 #ifndef LIBMINIFI_INCLUDE_CORE_PROCESSCONTEXT_H_
 #define LIBMINIFI_INCLUDE_CORE_PROCESSCONTEXT_H_
 
+#include <algorithm>
+#include <atomic>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <optional>
+#include <queue>
 #include <string>
 #include <vector>
-#include <queue>
-#include <map>
 #include <unordered_map>
-#include <mutex>
-#include <atomic>
-#include <algorithm>
-#include <memory>
+
 #include "Property.h"
 #include "core/Core.h"
 #include "core/ContentRepository.h"
@@ -40,7 +42,6 @@
 #include "core/FlowFile.h"
 #include "core/CoreComponentState.h"
 #include "utils/file/FileUtils.h"
-#include "utils/OptionalUtils.h"
 #include "utils/PropertyErrors.h"
 #include "VariableRegistry.h"
 
@@ -100,13 +101,13 @@ class ProcessContext : public controller::ControllerServiceLookup, public core::
   }
 
   template<typename T = std::string>
-  typename std::enable_if<std::is_default_constructible<T>::value, utils::optional<T>>::type
+  std::enable_if_t<std::is_default_constructible<T>::value, std::optional<T>>
   getProperty(const Property& property) {
     T value;
     try {
-      if (!getProperty(property.getName(), value)) return utils::nullopt;
+      if (!getProperty(property.getName(), value)) return std::nullopt;
     } catch (const utils::internal::ValueException&) {
-      return utils::nullopt;
+      return std::nullopt;
     }
     return value;
   }
@@ -255,7 +256,7 @@ class ProcessContext : public controller::ControllerServiceLookup, public core::
     std::string always_persist, auto_persistence_interval;
     configuration->get(Configure::nifi_state_management_provider_local_always_persist, always_persist);
     configuration->get(Configure::nifi_state_management_provider_local_auto_persistence_interval, auto_persistence_interval);
-    utils::optional<std::string> path = configuration->get(Configure::nifi_state_management_provider_local_path);
+    const auto path = configuration->get(Configure::nifi_state_management_provider_local_path);
 
     /* Function to help creating a provider */
     auto create_provider = [&](
diff --git a/libminifi/include/core/TypedValues.h b/libminifi/include/core/TypedValues.h
index 09050f1..4edf3b6 100644
--- a/libminifi/include/core/TypedValues.h
+++ b/libminifi/include/core/TypedValues.h
@@ -19,16 +19,16 @@
 #define LIBMINIFI_INCLUDE_CORE_TYPEDVALUES_H_
 
 #include <algorithm>
-#include <string>
-#include <typeindex>
 #include <map>
 #include <memory>
+#include <optional>
+#include <string>
+#include <typeindex>
 
 #include "state/Value.h"
 #include "utils/StringUtils.h"
 #include "utils/ValueParser.h"
 #include "utils/PropertyErrors.h"
-#include "utils/OptionalUtils.h"
 #include "utils/Literals.h"
 
 namespace org {
@@ -72,11 +72,11 @@ class TimePeriodValue : public TransformableValue, public state::response::UInt6
     return getValue();
   }
 
-  static utils::optional<TimePeriodValue> fromString(const std::string& str) {
+  static std::optional<TimePeriodValue> fromString(const std::string& str) {
     try {
       return TimePeriodValue(str);
     } catch (const utils::internal::ValueException&) {
-      return utils::nullopt;
+      return std::nullopt;
     }
   }
 
diff --git a/libminifi/include/core/logging/Logger.h b/libminifi/include/core/logging/Logger.h
index 28053ef..7b5ff0b 100644
--- a/libminifi/include/core/logging/Logger.h
+++ b/libminifi/include/core/logging/Logger.h
@@ -29,6 +29,7 @@
 
 #include "spdlog/common.h"
 #include "spdlog/logger.h"
+#include "utils/gsl.h"
 #include "utils/SmallString.h"
 
 namespace org {
@@ -79,14 +80,14 @@ inline std::string format_string(int max_size, char const* format_str, Args&&...
   }
   if (result <= LOG_BUFFER_SIZE) {
     // static buffer was large enough
-    return std::string(buf, result);
+    return std::string(buf, gsl::narrow<size_t>(result));
   }
   if (max_size >= 0 && max_size <= LOG_BUFFER_SIZE) {
     // static buffer was already larger than allowed, use the filled buffer
     return std::string(buf, LOG_BUFFER_SIZE);
   }
   // try to use dynamic buffer
-  size_t dynamic_buffer_size = max_size < 0 ? result : std::min(result, max_size);
+  size_t dynamic_buffer_size = max_size < 0 ? gsl::narrow<size_t>(result) : gsl::narrow<size_t>(std::min(result, max_size));
   std::vector<char> buffer(dynamic_buffer_size + 1);  // extra '\0' character
   result = std::snprintf(buffer.data(), buffer.size(), format_str, conditional_conversion(std::forward<Args>(args))...);
   if (result < 0) {
diff --git a/libminifi/include/core/logging/internal/LogBuffer.h b/libminifi/include/core/logging/internal/LogBuffer.h
index 968be80..bfc63eb 100644
--- a/libminifi/include/core/logging/internal/LogBuffer.h
+++ b/libminifi/include/core/logging/internal/LogBuffer.h
@@ -37,7 +37,7 @@ class LogBuffer {
   explicit LogBuffer(std::unique_ptr<io::BufferStream> buffer): buffer_{std::move(buffer)} {}
 
   static LogBuffer allocate(size_t max_size) {
-    LogBuffer instance{utils::make_unique<io::BufferStream>()};
+    LogBuffer instance{std::make_unique<io::BufferStream>()};
     instance.buffer_->extend(max_size);
     return instance;
   }
diff --git a/libminifi/include/core/state/nodes/AgentInformation.h b/libminifi/include/core/state/nodes/AgentInformation.h
index 349ecb4..a656786 100644
--- a/libminifi/include/core/state/nodes/AgentInformation.h
+++ b/libminifi/include/core/state/nodes/AgentInformation.h
@@ -60,7 +60,6 @@
 #include "core/state/nodes/StateMonitor.h"
 #include "io/ClientSocket.h"
 #include "SchedulingNodes.h"
-#include "utils/OptionalUtils.h"
 #include "utils/OsUtils.h"
 #include "utils/ProcessCpuUsageTracker.h"
 #include "core/AgentIdentificationProvider.h"
@@ -698,7 +697,7 @@ class AgentNode : public DeviceInformation, public AgentMonitor, public AgentIde
     ident.value = provider_->getAgentIdentifier();
     serialized.push_back(ident);
 
-    utils::optional<std::string> agent_class = provider_->getAgentClass();
+    const auto agent_class = provider_->getAgentClass();
     if (agent_class) {
       SerializedResponseNode agentClass;
       agentClass.name = "agentClass";
diff --git a/libminifi/include/core/yaml/YamlConfiguration.h b/libminifi/include/core/yaml/YamlConfiguration.h
index 767e7fd..e99c47c 100644
--- a/libminifi/include/core/yaml/YamlConfiguration.h
+++ b/libminifi/include/core/yaml/YamlConfiguration.h
@@ -19,6 +19,7 @@
 #define LIBMINIFI_INCLUDE_CORE_YAML_YAMLCONFIGURATION_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 
 #include "core/FlowConfiguration.h"
@@ -31,7 +32,6 @@
 #include "utils/Id.h"
 #include "utils/StringUtils.h"
 #include "utils/file/FileSystem.h"
-#include "utils/OptionalUtils.h"
 #include "yaml-cpp/yaml.h"
 
 class YamlConfigurationTestAccessor;
@@ -60,7 +60,7 @@ class YamlConfiguration : public FlowConfiguration {
  public:
   explicit YamlConfiguration(const std::shared_ptr<core::Repository>& repo, const std::shared_ptr<core::Repository>& flow_file_repo,
                              const std::shared_ptr<core::ContentRepository>& content_repo, const std::shared_ptr<io::StreamFactory>& stream_factory,
-                             const std::shared_ptr<Configure>& configuration, const utils::optional<std::string>& path = {},
+                             const std::shared_ptr<Configure>& configuration, const std::optional<std::string>& path = {},
                              const std::shared_ptr<utils::file::FileSystem>& filesystem = std::make_shared<utils::file::FileSystem>());
 
   ~YamlConfiguration() override = default;
@@ -77,7 +77,7 @@ class YamlConfiguration : public FlowConfiguration {
       logger_->log_error("Cannot instantiate flow, no config file is set.");
       throw Exception(ExceptionType::FLOW_EXCEPTION, "No config file specified");
     }
-    utils::optional<std::string> configuration = filesystem_->read(config_path_.value());
+    const auto configuration = filesystem_->read(config_path_.value());
     if (!configuration) {
       return nullptr;
     }
diff --git a/libminifi/include/core/yaml/YamlConnectionParser.h b/libminifi/include/core/yaml/YamlConnectionParser.h
index 512b928..a35d776 100644
--- a/libminifi/include/core/yaml/YamlConnectionParser.h
+++ b/libminifi/include/core/yaml/YamlConnectionParser.h
@@ -45,12 +45,12 @@ class YamlConnectionParser {
       logger_(logger) {}
 
   void configureConnectionSourceRelationshipsFromYaml(const std::shared_ptr<minifi::Connection>& connection) const;
-  uint64_t getWorkQueueSizeFromYaml() const;
-  uint64_t getWorkQueueDataSizeFromYaml() const;
-  utils::Identifier getSourceUUIDFromYaml() const;
-  utils::Identifier getDestinationUUIDFromYaml() const;
-  uint64_t getFlowFileExpirationFromYaml() const;
-  bool getDropEmptyFromYaml() const;
+  [[nodiscard]] uint64_t getWorkQueueSizeFromYaml() const;
+  [[nodiscard]] uint64_t getWorkQueueDataSizeFromYaml() const;
+  [[nodiscard]] utils::Identifier getSourceUUIDFromYaml() const;
+  [[nodiscard]] utils::Identifier getDestinationUUIDFromYaml() const;
+  [[nodiscard]] uint64_t getFlowFileExpirationFromYaml() const;
+  [[nodiscard]] bool getDropEmptyFromYaml() const;
  private:
   const YAML::Node& connectionNode_;
   const std::string& name_;
diff --git a/libminifi/include/io/CRCStream.h b/libminifi/include/io/CRCStream.h
index 70949a4..0b12d97 100644
--- a/libminifi/include/io/CRCStream.h
+++ b/libminifi/include/io/CRCStream.h
@@ -135,8 +135,8 @@ class CRCStream : public std::conditional<std::is_base_of<InputStream, StreamTyp
   }
 
   CRCStream(CRCStream &&stream) noexcept {
-    child_stream_ = utils::exchange(stream.child_stream_, nullptr);
-    crc_ = utils::exchange(stream.crc_, 0);
+    child_stream_ = std::exchange(stream.child_stream_, nullptr);
+    crc_ = std::exchange(stream.crc_, 0);
   }
 };
 
diff --git a/libminifi/include/properties/Configure.h b/libminifi/include/properties/Configure.h
index 7073681..55bb74f 100644
--- a/libminifi/include/properties/Configure.h
+++ b/libminifi/include/properties/Configure.h
@@ -16,12 +16,12 @@
  */
 #pragma once
 
+#include <optional>
 #include <string>
 #include <utility>
 
 #include "properties/Configuration.h"
 #include "properties/Decryptor.h"
-#include "utils/OptionalUtils.h"
 #include "core/AgentIdentificationProvider.h"
 
 namespace org {
@@ -31,21 +31,21 @@ namespace minifi {
 
 class Configure : public Configuration, public core::AgentIdentificationProvider {
  public:
-  explicit Configure(utils::optional<Decryptor> decryptor = utils::nullopt)
+  explicit Configure(std::optional<Decryptor> decryptor = std::nullopt)
       : Configuration{}, decryptor_(std::move(decryptor)) {}
 
   bool get(const std::string& key, std::string& value) const;
   bool get(const std::string& key, const std::string& alternate_key, std::string& value) const;
-  utils::optional<std::string> get(const std::string& key) const;
+  std::optional<std::string> get(const std::string& key) const;
 
-  utils::optional<std::string> getAgentClass() const override;
+  std::optional<std::string> getAgentClass() const override;
   std::string getAgentIdentifier() const override;
   void setFallbackAgentIdentifier(const std::string& id);
 
  private:
   bool isEncrypted(const std::string& key) const;
 
-  utils::optional<Decryptor> decryptor_;
+  std::optional<Decryptor> decryptor_;
   mutable std::mutex fallback_identifier_mutex_;
   std::string fallback_identifier_;
 };
diff --git a/libminifi/include/properties/Decryptor.h b/libminifi/include/properties/Decryptor.h
index eda34d1..a8ca4bc 100644
--- a/libminifi/include/properties/Decryptor.h
+++ b/libminifi/include/properties/Decryptor.h
@@ -16,11 +16,11 @@
  */
 #pragma once
 
+#include <optional>
 #include <string>
 #include <utility>
 
 #include "utils/crypto/EncryptionUtils.h"
-#include "utils/OptionalUtils.h"
 #include "utils/crypto/EncryptionProvider.h"
 
 namespace org {
@@ -33,15 +33,15 @@ class Decryptor {
   explicit Decryptor(utils::crypto::EncryptionProvider provider)
       : provider_(std::move(provider)) {}
 
-  static bool isValidEncryptionMarker(const utils::optional<std::string>& encryption_marker) {
+  static bool isValidEncryptionMarker(const std::optional<std::string>& encryption_marker) {
     return encryption_marker && *encryption_marker == utils::crypto::EncryptionType::name();
   }
 
-  std::string decrypt(const std::string& encrypted_text) const {
+  [[nodiscard]] std::string decrypt(const std::string& encrypted_text) const {
     return provider_.decrypt(encrypted_text);
   }
 
-  static utils::optional<Decryptor> create(const std::string& minifi_home) {
+  static std::optional<Decryptor> create(const std::string& minifi_home) {
     return utils::crypto::EncryptionProvider::create(minifi_home)
         | utils::map([](const utils::crypto::EncryptionProvider& provider) {return Decryptor{provider};});
   }
diff --git a/libminifi/include/properties/Properties.h b/libminifi/include/properties/Properties.h
index f11fe05..a778101 100644
--- a/libminifi/include/properties/Properties.h
+++ b/libminifi/include/properties/Properties.h
@@ -20,15 +20,15 @@
 #ifndef LIBMINIFI_INCLUDE_PROPERTIES_PROPERTIES_H_
 #define LIBMINIFI_INCLUDE_PROPERTIES_PROPERTIES_H_
 
+#include <map>
 #include <memory>
-#include <vector>
+#include <optional>
 #include <string>
-#include <map>
 #include <utility>
+#include <vector>
 
 #include "core/logging/Logger.h"
 #include "utils/ChecksumCalculator.h"
-#include "utils/OptionalUtils.h"
 
 namespace org {
 namespace apache {
@@ -86,7 +86,7 @@ class Properties {
    * @param key key to look up
    * @returns the value if found, nullopt otherwise.
    */
-  utils::optional<std::string> getString(const std::string& key) const;
+  std::optional<std::string> getString(const std::string& key) const;
 
   /**
    * Load configure file
diff --git a/libminifi/include/properties/PropertiesFile.h b/libminifi/include/properties/PropertiesFile.h
index 6444168..a6c15a1 100644
--- a/libminifi/include/properties/PropertiesFile.h
+++ b/libminifi/include/properties/PropertiesFile.h
@@ -17,11 +17,11 @@
 #pragma once
 
 #include <istream>
+#include <optional>
 #include <string>
 #include <vector>
 
 #include "utils/crypto/EncryptionUtils.h"
-#include "utils/OptionalUtils.h"
 
 namespace org {
 namespace apache {
@@ -37,9 +37,9 @@ class PropertiesFile {
 
     void updateValue(const std::string& value);
 
-    std::string getLine() const { return line_; }
-    std::string getKey() const { return key_; }
-    std::string getValue() const { return value_; }
+    [[nodiscard]] std::string getLine() const { return line_; }
+    [[nodiscard]] std::string getKey() const { return key_; }
+    [[nodiscard]] std::string getValue() const { return value_; }
 
     static bool isValidKey(const std::string& key);
 
@@ -56,8 +56,8 @@ class PropertiesFile {
   explicit PropertiesFile(std::istream& input_stream);
   explicit PropertiesFile(std::istream&& input_stream) : PropertiesFile{input_stream} {}
 
-  bool hasValue(const std::string& key) const;
-  utils::optional<std::string> getValue(const std::string& key) const;
+  [[nodiscard]] bool hasValue(const std::string& key) const;
+  [[nodiscard]] std::optional<std::string> getValue(const std::string& key) const;
   void update(const std::string& key, const std::string& value);
   void insertAfter(const std::string& after_key, const std::string& key, const std::string& value);
   void append(const std::string& key, const std::string& value);
@@ -65,17 +65,17 @@ class PropertiesFile {
 
   void writeTo(const std::string& file_path) const;
 
-  size_t size() const { return lines_.size(); }
+  [[nodiscard]] size_t size() const { return lines_.size(); }
 
  protected:
   using Lines = std::vector<Line>;
 
-  Lines::const_iterator findKey(const std::string& key) const;
+  [[nodiscard]] Lines::const_iterator findKey(const std::string& key) const;
   Lines::iterator findKey(const std::string& key);
 
  public:
-  Lines::const_iterator begin() const;
-  Lines::const_iterator end() const;
+  [[nodiscard]] Lines::const_iterator begin() const;
+  [[nodiscard]] Lines::const_iterator end() const;
 
  protected:
   Lines lines_;
diff --git a/libminifi/include/utils/ChecksumCalculator.h b/libminifi/include/utils/ChecksumCalculator.h
index a8230bb..99a47d1 100644
--- a/libminifi/include/utils/ChecksumCalculator.h
+++ b/libminifi/include/utils/ChecksumCalculator.h
@@ -17,11 +17,10 @@
 
 #pragma once
 
+#include <optional>
 #include <string>
 #include <utility>
 
-#include "utils/OptionalUtils.h"
-
 namespace org {
 namespace apache {
 namespace nifi {
@@ -41,9 +40,9 @@ class ChecksumCalculator {
  private:
   static std::string computeChecksum(const std::string& file_location);
 
-  utils::optional<std::string> file_location_;
-  utils::optional<std::string> file_name_;
-  utils::optional<std::string> checksum_;
+  std::optional<std::string> file_location_;
+  std::optional<std::string> file_name_;
+  std::optional<std::string> checksum_;
 };
 
 inline void ChecksumCalculator::invalidateChecksum() {
diff --git a/libminifi/include/utils/Enum.h b/libminifi/include/utils/Enum.h
index b452307..86032ca 100644
--- a/libminifi/include/utils/Enum.h
+++ b/libminifi/include/utils/Enum.h
@@ -17,11 +17,11 @@
 
 #pragma once
 
-#include <string>
 #include <cstring>
+#include <optional>
 #include <set>
+#include <string>
 
-#include "OptionalUtils.h"
 #include "StringUtils.h"
 
 namespace org {
@@ -142,7 +142,7 @@ namespace utils {
       int idx = static_cast<int>(value_); \
       return 0 <= idx && idx < length; \
     } \
-    static Clazz parse(const char* str, const ::org::apache::nifi::minifi::utils::optional<Clazz>& fallback = {}, bool caseSensitive = true) { \
+    static Clazz parse(const char* str, const ::std::optional<Clazz>& fallback = {}, bool caseSensitive = true) { \
       for (int idx = 0; idx < length; ++idx) { \
         if (::org::apache::nifi::minifi::utils::StringUtils::equals(str, detail::toStringImpl(static_cast<Type>(idx), #Clazz), caseSensitive)) \
           return static_cast<Type>(idx); \
diff --git a/libminifi/include/utils/GeneralUtils.h b/libminifi/include/utils/GeneralUtils.h
index 92d7e93..a433403 100644
--- a/libminifi/include/utils/GeneralUtils.h
+++ b/libminifi/include/utils/GeneralUtils.h
@@ -19,11 +19,9 @@
 #ifndef LIBMINIFI_INCLUDE_UTILS_GENERALUTILS_H_
 #define LIBMINIFI_INCLUDE_UTILS_GENERALUTILS_H_
 
-#include <algorithm>
 #include <memory>
 #include <type_traits>
 #include <utility>
-#include <functional>
 
 #include "gsl.h"
 
@@ -33,15 +31,6 @@ namespace nifi {
 namespace minifi {
 namespace utils {
 
-#if __cplusplus < 201402L
-template<typename T, typename... Args>
-std::unique_ptr<T> make_unique(Args&&... args) {
-  return std::unique_ptr<T>{ new T(std::forward<Args>(args)...) };
-}
-#else
-using std::make_unique;
-#endif /* < C++14 */
-
 template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
 constexpr T intdiv_ceil(T numerator, T denominator) {
   // note: division and remainder is 1 instruction on x86
@@ -73,25 +62,6 @@ struct type_identity {
 
 using gsl::owner;
 
-#if __cplusplus < 201402L
-// from https://en.cppreference.com/w/cpp/utility/exchange
-template<typename T, typename U = T>
-T exchange(T& obj, U&& new_value) {
-  T old_value = std::move(obj);
-  obj = std::forward<U>(new_value);
-  return old_value;
-}
-#else
-using std::exchange;
-#endif /* < C++14 */
-
-#if __cplusplus < 201703L
-template<typename...>
-using void_t = void;
-#else
-using std::void_t;
-#endif /* < C++17 */
-
 namespace internal {
 
 /*
@@ -120,71 +90,6 @@ struct EnableSharedFromThis : virtual internal::EnableSharedFromThisBase {
 #define MINIFICPP_UTIL_DEDUCED(...) noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
 #define MINIFICPP_UTIL_DEDUCED_CONDITIONAL(condition, ...) noexcept(noexcept(__VA_ARGS__)) -> typename std::enable_if<(condition), decltype(__VA_ARGS__)>::type { return __VA_ARGS__; }
 
-#if __cplusplus < 201703L
-namespace detail {
-template<typename>
-struct is_reference_wrapper : std::false_type {};
-
-template<typename T>
-struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};
-
-// invoke on pointer to member function
-template<typename T, typename Clazz, typename Obj, typename... Args>
-auto invoke_member_function_impl(T Clazz::*f, Obj&& obj, Args&&... args) MINIFICPP_UTIL_DEDUCED_CONDITIONAL(
-    /* cond: */ (std::is_base_of<Clazz, typename std::decay<decltype(obj)>::type>::value),
-    /* expr: */ (std::forward<Obj>(obj).*f)(std::forward<Args>(args)...))
-
-template<typename T, typename Clazz, typename Obj, typename... Args>
-auto invoke_member_function_impl(T Clazz::*f, Obj&& obj, Args&&... args) MINIFICPP_UTIL_DEDUCED_CONDITIONAL(
-    /* cond: */ (!std::is_base_of<Clazz, typename std::decay<decltype(obj)>::type>::value && is_reference_wrapper<typename std::decay<decltype(obj)>::type>::value),
-    /* expr: */ (std::forward<Obj>(obj).get().*f)(std::forward<Args>(args)...))
-
-template<typename T, typename Clazz, typename Obj, typename... Args>
-auto invoke_member_function_impl(T Clazz::*f, Obj&& obj, Args&&... args) MINIFICPP_UTIL_DEDUCED_CONDITIONAL(
-    /* cond: */ (!std::is_base_of<Clazz, typename std::decay<decltype(obj)>::type>::value && !is_reference_wrapper<typename std::decay<decltype(obj)>::type>::value),
-    /* expr: */ ((*std::forward<Obj>(obj)).*f)(std::forward<Args>(args)...))
-
-// invoke on pointer to data member
-template<typename T, typename Clazz, typename Obj>
-auto invoke_member_object_impl(T Clazz::*f, Obj&& obj) MINIFICPP_UTIL_DEDUCED_CONDITIONAL(
-    /* cond: */ (std::is_base_of<Clazz, typename std::decay<decltype(obj)>::type>::value),
-    /* expr: */ std::forward<Obj>(obj).*f)
-
-template<typename T, typename Clazz, typename Obj>
-auto invoke_member_object_impl(T Clazz::*f, Obj&& obj) MINIFICPP_UTIL_DEDUCED_CONDITIONAL(
-    /* cond: */ (!std::is_base_of<Clazz, typename std::decay<decltype(obj)>::type>::value && is_reference_wrapper<typename std::decay<decltype(obj)>::type>::value),
-    /* expr: */ std::forward<Obj>(obj).get().*f)
-
-template<typename T, typename Clazz, typename Obj>
-auto invoke_member_object_impl(T Clazz::*f, Obj&& obj) MINIFICPP_UTIL_DEDUCED_CONDITIONAL(
-    /* cond: */ (!std::is_base_of<Clazz, typename std::decay<decltype(obj)>::type>::value && !is_reference_wrapper<typename std::decay<decltype(obj)>::type>::value),
-    /* expr: */ (*std::forward<Obj>(obj)).*f)
-
-// invoke_impl
-template<typename T, typename Clazz, typename Obj, typename... Args>
-auto invoke_impl(T Clazz::*f, Obj&& obj, Args&&... args) MINIFICPP_UTIL_DEDUCED_CONDITIONAL(
-    /* cond: */ std::is_member_function_pointer<decltype(f)>::value,
-    /* expr: */ invoke_member_function_impl(f, std::forward<Obj>(obj), std::forward<Args>(args)...))
-
-template<typename T, typename Clazz, typename Obj>
-auto invoke_impl(T Clazz::*f, Obj&& obj) MINIFICPP_UTIL_DEDUCED_CONDITIONAL(
-    /* cond: */ std::is_member_object_pointer<decltype(f)>::value,
-    /* expr: */ invoke_member_object_impl(f, std::forward<Obj>(obj)))
-
-template<typename F, typename... Args>
-auto invoke_impl(F&& f, Args&&... args) MINIFICPP_UTIL_DEDUCED_CONDITIONAL(
-    /* cond: */ !std::is_member_function_pointer<F>::value && !std::is_member_object_pointer<F>::value,
-    /* expr: */ std::forward<F>(f)(std::forward<Args>(args)...))
-
-}  // namespace detail
-
-template<typename F, typename... Args>
-auto invoke(F&& f, Args&&... args) MINIFICPP_UTIL_DEDUCED(detail::invoke_impl(std::forward<F>(f), std::forward<Args>(args)...))
-#else
-using std::invoke;
-#endif /* < C++17 */
-
-
 namespace detail {
 struct dereference_t {
   template<typename T>
@@ -194,7 +99,6 @@ struct dereference_t {
 
 constexpr detail::dereference_t dereference{};
 
-
 #if __cpp_lib_remove_cvref >= 201711L
 using std::remove_cvref_t;
 #else
diff --git a/libminifi/include/utils/HTTPClient.h b/libminifi/include/utils/HTTPClient.h
index 425c716..20e70c8 100644
--- a/libminifi/include/utils/HTTPClient.h
+++ b/libminifi/include/utils/HTTPClient.h
@@ -29,6 +29,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -36,7 +37,6 @@
 #include "controllers/SSLContextService.h"
 #include "core/Deprecated.h"
 #include "utils/gsl.h"
-#include "utils/OptionalUtils.h"
 
 namespace org {
 namespace apache {
@@ -378,8 +378,8 @@ class URL {
  private:
   std::string protocol_;
   std::string host_;
-  utils::optional<int> port_;
-  utils::optional<std::string> path_;
+  std::optional<int> port_;
+  std::optional<std::string> path_;
   bool is_valid_ = false;
   std::shared_ptr<logging::Logger> logger_ = logging::LoggerFactory<URL>::getLogger();
 };
diff --git a/libminifi/include/utils/Id.h b/libminifi/include/utils/Id.h
index 687d19f..d94d469 100644
--- a/libminifi/include/utils/Id.h
+++ b/libminifi/include/utils/Id.h
@@ -17,13 +17,13 @@
 #ifndef LIBMINIFI_INCLUDE_UTILS_ID_H_
 #define LIBMINIFI_INCLUDE_UTILS_ID_H_
 
-#include <utility>
-#include <cstddef>
 #include <atomic>
+#include <cstddef>
 #include <memory>
+#include <optional>
 #include <string>
 #include <thread>
-#include "SmallString.h"
+#include <utility>
 
 #ifndef WIN32
 class uuid;
@@ -31,7 +31,6 @@ class uuid;
 
 #include "core/logging/Logger.h"
 #include "properties/Properties.h"
-#include "OptionalUtils.h"
 #include "SmallString.h"
 
 #define UUID_TIME_IMPL 0
@@ -85,7 +84,7 @@ class Identifier {
   // 70ns more.
   SmallString<36> to_string() const;
 
-  static utils::optional<Identifier> parse(const std::string& str);
+  static std::optional<Identifier> parse(const std::string& str);
 
  private:
   static bool parseByte(Data& data, const uint8_t* input, int& charIdx, int& byteIdx);
diff --git a/libminifi/include/utils/JsonCallback.h b/libminifi/include/utils/JsonCallback.h
index 4acc71e..3fb278d 100644
--- a/libminifi/include/utils/JsonCallback.h
+++ b/libminifi/include/utils/JsonCallback.h
@@ -16,9 +16,10 @@
  */
 #pragma once
 
+#include <memory>
+#include <optional>
 #include <string>
 #include <utility>
-#include <memory>
 
 #include "rapidjson/stream.h"
 #include "rapidjson/writer.h"
@@ -34,7 +35,7 @@ namespace utils {
 
 class JsonOutputCallback : public OutputStreamCallback {
  public:
-  explicit JsonOutputCallback(rapidjson::Document&& root, utils::optional<uint8_t> decimal_places)
+  explicit JsonOutputCallback(rapidjson::Document&& root, std::optional<uint8_t> decimal_places)
       : root_(std::move(root)), decimal_places_(decimal_places) {}
 
   int64_t process(const std::shared_ptr<io::BaseStream>& stream) override {
@@ -48,12 +49,12 @@ class JsonOutputCallback : public OutputStreamCallback {
 
  protected:
   rapidjson::Document root_;
-  utils::optional<uint8_t> decimal_places_;
+  std::optional<uint8_t> decimal_places_;
 };
 
 class PrettyJsonOutputCallback : public OutputStreamCallback {
  public:
-  explicit PrettyJsonOutputCallback(rapidjson::Document&& root, utils::optional<uint8_t> decimal_places)
+  explicit PrettyJsonOutputCallback(rapidjson::Document&& root, std::optional<uint8_t> decimal_places)
       : root_(std::move(root)), decimal_places_(decimal_places) {}
 
   int64_t process(const std::shared_ptr<io::BaseStream>& stream) override {
@@ -67,7 +68,7 @@ class PrettyJsonOutputCallback : public OutputStreamCallback {
 
  protected:
   rapidjson::Document root_;
-  utils::optional<uint8_t> decimal_places_;
+  std::optional<uint8_t> decimal_places_;
 };
 
 }  // namespace utils
diff --git a/libminifi/include/utils/OptionalUtils.h b/libminifi/include/utils/OptionalUtils.h
index 2ff3c50..cee564a 100644
--- a/libminifi/include/utils/OptionalUtils.h
+++ b/libminifi/include/utils/OptionalUtils.h
@@ -18,13 +18,11 @@
 #ifndef LIBMINIFI_INCLUDE_UTILS_OPTIONALUTILS_H_
 #define LIBMINIFI_INCLUDE_UTILS_OPTIONALUTILS_H_
 
+#include <functional>
+#include <optional>
 #include <type_traits>
 #include <utility>
-#if __cplusplus >= 201703L
-#include <optional>
-#endif  /* >= C++17 */
 
-#include <nonstd/optional.hpp>
 #include "utils/GeneralUtils.h"
 #include "utils/gsl.h"
 
@@ -33,23 +31,15 @@ namespace apache {
 namespace nifi {
 namespace minifi {
 namespace utils {
-using nonstd::optional;
-using nonstd::nullopt;
-using nonstd::make_optional;
 
 template<typename T>
-optional<utils::remove_cvref_t<T>> optional_from_ptr(T&& obj) {
-  return obj == nullptr ? nullopt : optional<utils::remove_cvref_t<T>>{ std::forward<T>(obj) };
+std::optional<utils::remove_cvref_t<T>> optional_from_ptr(T&& obj) {
+  return obj == nullptr ? std::nullopt : std::optional<utils::remove_cvref_t<T>>{ std::forward<T>(obj) };
 }
 
-// two partial specializations because nonstd::optional<T> might or might not be the same as std::optional<T>,
-// and if they are the same, this would be a redefinition error
 template<typename, typename = void>
 struct is_optional : std::false_type {};
 
-template<typename T, typename Void>
-struct is_optional<nonstd::optional<T>, Void> : std::true_type {};
-
 template<typename T>
 struct is_optional<std::optional<T>, void> : std::true_type {};
 
@@ -61,22 +51,22 @@ struct map_wrapper {
 
 // map implementation
 template<typename SourceType, typename F>
-auto operator|(const optional<SourceType>& o, map_wrapper<F> f) noexcept(noexcept(utils::invoke(std::forward<F>(f.function), *o)))
-    -> optional<typename std::decay<decltype(utils::invoke(std::forward<F>(f.function), *o))>::type> {
+auto operator|(const std::optional<SourceType>& o, map_wrapper<F> f) noexcept(noexcept(std::invoke(std::forward<F>(f.function), *o)))
+    -> std::optional<typename std::decay<decltype(std::invoke(std::forward<F>(f.function), *o))>::type> {
   if (o.has_value()) {
-    return make_optional(utils::invoke(std::forward<F>(f.function), *o));
+    return std::make_optional(std::invoke(std::forward<F>(f.function), *o));
   } else {
-    return nullopt;
+    return std::nullopt;
   }
 }
 
 template<typename SourceType, typename F>
-auto operator|(optional<SourceType>&& o, map_wrapper<F> f) noexcept(noexcept(utils::invoke(std::forward<F>(f.function), std::move(*o))))
-    -> optional<typename std::decay<decltype(utils::invoke(std::forward<F>(f.function), std::move(*o)))>::type> {
+auto operator|(std::optional<SourceType>&& o, map_wrapper<F> f) noexcept(noexcept(std::invoke(std::forward<F>(f.function), std::move(*o))))
+    -> std::optional<typename std::decay<decltype(std::invoke(std::forward<F>(f.function), std::move(*o)))>::type> {
   if (o.has_value()) {
-    return make_optional(utils::invoke(std::forward<F>(f.function), std::move(*o)));
+    return std::make_optional(std::invoke(std::forward<F>(f.function), std::move(*o)));
   } else {
-    return nullopt;
+    return std::nullopt;
   }
 }
 
@@ -87,23 +77,23 @@ struct flat_map_wrapper {
 
 // flatMap implementation
 template<typename SourceType, typename F>
-auto operator|(const optional<SourceType>& o, flat_map_wrapper<F> f) noexcept(noexcept(utils::invoke(std::forward<F>(f.function), *o)))
-    -> optional<typename std::decay<decltype(*utils::invoke(std::forward<F>(f.function), *o))>::type> {
-  static_assert(is_optional<decltype(utils::invoke(std::forward<F>(f.function), *o))>::value, "flatMap expects a function returning optional");
+auto operator|(const std::optional<SourceType>& o, flat_map_wrapper<F> f) noexcept(noexcept(std::invoke(std::forward<F>(f.function), *o)))
+    -> std::optional<typename std::decay<decltype(*std::invoke(std::forward<F>(f.function), *o))>::type> {
+  static_assert(is_optional<decltype(std::invoke(std::forward<F>(f.function), *o))>::value, "flatMap expects a function returning optional");
   if (o.has_value()) {
-    return utils::invoke(std::forward<F>(f.function), *o);
+    return std::invoke(std::forward<F>(f.function), *o);
   } else {
-    return nullopt;
+    return std::nullopt;
   }
 }
 template<typename SourceType, typename F>
-auto operator|(optional<SourceType>&& o, flat_map_wrapper<F> f) noexcept(noexcept(utils::invoke(std::forward<F>(f.function), std::move(*o))))
-    -> optional<typename std::decay<decltype(*utils::invoke(std::forward<F>(f.function), std::move(*o)))>::type> {
-  static_assert(is_optional<decltype(utils::invoke(std::forward<F>(f.function), std::move(*o)))>::value, "flatMap expects a function returning optional");
+auto operator|(std::optional<SourceType>&& o, flat_map_wrapper<F> f) noexcept(noexcept(std::invoke(std::forward<F>(f.function), std::move(*o))))
+    -> std::optional<typename std::decay<decltype(*std::invoke(std::forward<F>(f.function), std::move(*o)))>::type> {
+  static_assert(is_optional<decltype(std::invoke(std::forward<F>(f.function), std::move(*o)))>::value, "flatMap expects a function returning optional");
   if (o.has_value()) {
-    return utils::invoke(std::forward<F>(f.function), std::move(*o));
+    return std::invoke(std::forward<F>(f.function), std::move(*o));
   } else {
-    return nullopt;
+    return std::nullopt;
   }
 }
 
@@ -114,23 +104,23 @@ struct or_else_wrapper {
 
 // orElse implementation
 template<typename SourceType, typename F>
-auto operator|(optional<SourceType> o, or_else_wrapper<F> f) noexcept(noexcept(utils::invoke(std::forward<F>(f.function))))
-    -> typename std::enable_if<std::is_same<decltype(utils::invoke(std::forward<F>(f.function))), void>::value, optional<SourceType>>::type {
+auto operator|(std::optional<SourceType> o, or_else_wrapper<F> f) noexcept(noexcept(std::invoke(std::forward<F>(f.function))))
+    -> typename std::enable_if<std::is_same<decltype(std::invoke(std::forward<F>(f.function))), void>::value, std::optional<SourceType>>::type {
   if (o.has_value()) {
     return o;
   } else {
-    utils::invoke(std::forward<F>(f.function));
-    return nullopt;
+    std::invoke(std::forward<F>(f.function));
+    return std::nullopt;
   }
 }
 
 template<typename SourceType, typename F>
-auto operator|(optional<SourceType> o, or_else_wrapper<F> f) noexcept(noexcept(utils::invoke(std::forward<F>(f.function))))
-    -> typename std::enable_if<std::is_same<typename std::decay<decltype(utils::invoke(std::forward<F>(f.function)))>::type, optional<SourceType>>::value, optional<SourceType>>::type {
+auto operator|(std::optional<SourceType> o, or_else_wrapper<F> f) noexcept(noexcept(std::invoke(std::forward<F>(f.function))))
+    -> typename std::enable_if<std::is_same<typename std::decay<decltype(std::invoke(std::forward<F>(f.function)))>::type, std::optional<SourceType>>::value, std::optional<SourceType>>::type {
   if (o.has_value()) {
     return o;
   } else {
-    return utils::invoke(std::forward<F>(f.function));
+    return std::invoke(std::forward<F>(f.function));
   }
 }
 }  // namespace detail
diff --git a/libminifi/include/utils/ProcessorConfigUtils.h b/libminifi/include/utils/ProcessorConfigUtils.h
index 2971bd6..a5282c8 100644
--- a/libminifi/include/utils/ProcessorConfigUtils.h
+++ b/libminifi/include/utils/ProcessorConfigUtils.h
@@ -17,9 +17,10 @@
 
 #pragma once
 
-#include <vector>
-#include <string>
+#include <optional>
 #include <set>
+#include <string>
+#include <vector>
 
 #include "core/ProcessContext.h"
 
@@ -34,7 +35,7 @@ std::vector<std::string> listFromCommaSeparatedProperty(const core::ProcessConte
 std::vector<std::string> listFromRequiredCommaSeparatedProperty(const core::ProcessContext* context, const std::string& property_name);
 bool parseBooleanPropertyOrThrow(core::ProcessContext* context, const std::string& property_name);
 std::chrono::milliseconds parseTimePropertyMSOrThrow(core::ProcessContext* context, const std::string& property_name);
-utils::optional<uint64_t> getOptionalUintProperty(const core::ProcessContext& context, const std::string& property_name);
+std::optional<uint64_t> getOptionalUintProperty(const core::ProcessContext& context, const std::string& property_name);
 std::string parsePropertyWithAllowableValuesOrThrow(const core::ProcessContext& context, const std::string& property_name, const std::set<std::string>& allowable_values);
 
 }  // namespace utils
diff --git a/libminifi/include/utils/StringUtils.h b/libminifi/include/utils/StringUtils.h
index de6b6cb..b33006e 100644
--- a/libminifi/include/utils/StringUtils.h
+++ b/libminifi/include/utils/StringUtils.h
@@ -17,34 +17,25 @@
 #ifndef LIBMINIFI_INCLUDE_UTILS_STRINGUTILS_H_
 #define LIBMINIFI_INCLUDE_UTILS_STRINGUTILS_H_
 
-#include <string>
-#include <utility>
-#include <iostream>
+#include <algorithm>
 #include <cstring>
 #include <functional>
+#include <iostream>
+#include <map>
+#include <optional>
+#include <sstream>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
 #ifdef WIN32
   #include <cwctype>
   #include <cctype>
 #endif
-#include <algorithm>
-#include <sstream>
-#include <vector>
-#include <map>
-#include <type_traits>
 #include "utils/FailurePolicy.h"
-#include "utils/GeneralUtils.h"
 #include "utils/gsl.h"
-#include "utils/OptionalUtils.h"
 
-#if defined(WIN32) || (__cplusplus >= 201103L && (!defined(__GLIBCXX__) || (__cplusplus >= 201402L) ||  (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE > 4)))
-#define HAVE_REGEX_CPP 1
-#else
-#define HAVE_REGEX_CPP 0
-#endif
-namespace org {
-namespace apache {
-namespace nifi {
-namespace minifi {
+namespace org::apache::nifi::minifi {
 namespace utils {
 
 template<class Char>
@@ -79,7 +70,7 @@ class StringUtils {
    * @param input input string
    * @returns an optional of a boolean: true if the string is "true" (ignoring case), false if it is "false" (ignoring case), nullopt for any other value
    */
-  static utils::optional<bool> toBool(const std::string& input);
+  static std::optional<bool> toBool(const std::string& input);
 
   static std::string toLower(std::string str);
 
@@ -196,16 +187,6 @@ class StringUtils {
   static size_t size(const CharT* str) noexcept { return std::char_traits<CharT>::length(str); }
 
   struct detail {
-    // add all args
-    template<typename... SizeT>
-    static size_t sum(SizeT... ns) {
-      size_t result = 0;
-      (void)(std::initializer_list<size_t>{( result += ns )...});
-      return result;  // (ns + ...)
-    }
-
-#ifndef _MSC_VER
-
     // partial detection idiom impl, from cppreference.com
     struct nonesuch{};
 
@@ -216,7 +197,7 @@ class StringUtils {
     };
 
     template<typename Default, template<class...> class Op, typename... Args>
-    struct detector<Default, void_t<Op<Args...>>, Op, Args...> {
+    struct detector<Default, std::void_t<Op<Args...>>, Op, Args...> {
       using value_t = std::true_type;
       using type = Op<Args...>;
     };
@@ -224,18 +205,6 @@ class StringUtils {
     template<template<class...> class Op, typename... Args>
     using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
 
-    // and operation for boolean template argument packs
-    template<bool...>
-    struct and_;
-
-    template<bool Head, bool... Tail>
-    struct and_<Head, Tail...> : std::integral_constant<bool, Head && and_<Tail...>::value>
-    {};
-
-    template<bool B>
-    struct and_<B> : std::integral_constant<bool, B>
-    {};
-
     // implementation detail of join_pack
     template<typename CharT>
     struct str_detector {
@@ -244,18 +213,13 @@ class StringUtils {
     };
 
     template<typename ResultT, typename CharT, typename... Strs>
-    using valid_string_pack_t = typename std::enable_if<and_<is_detected<str_detector<CharT>::template valid_string_t, Strs>::value...>::value, ResultT>::type;
-#else
-    // MSVC is broken without /permissive-
-  template<typename ResultT, typename...>
-  using valid_string_pack_t = ResultT;
-#endif
+    using valid_string_pack_t = std::enable_if_t<(is_detected<str_detector<CharT>::template valid_string_t, Strs>::value && ...), ResultT>;
 
     template<typename CharT, typename... Strs, valid_string_pack_t<void, CharT, Strs...>* = nullptr>
     static std::basic_string<CharT> join_pack(const Strs&... strs) {
       std::basic_string<CharT> result;
-      result.reserve(sum(size(strs)...));
-      (void)(std::initializer_list<int>{( result.append(strs) , 0)...});
+      result.reserve((size(strs) + ...));
+      (result.append(strs), ...);
       return result;
     }
   }; /* struct detail */
@@ -610,9 +574,6 @@ enum TimeUnit {
 };
 
 }  // namespace core
-}  // namespace minifi
-}  // namespace nifi
-}  // namespace apache
-}  // namespace org
+}  // namespace org::apache::nifi::minifi
 
 #endif  // LIBMINIFI_INCLUDE_UTILS_STRINGUTILS_H_
diff --git a/libminifi/include/utils/TryMoveCall.h b/libminifi/include/utils/TryMoveCall.h
index 3970321..7f5a596 100644
--- a/libminifi/include/utils/TryMoveCall.h
+++ b/libminifi/include/utils/TryMoveCall.h
@@ -16,10 +16,9 @@
  */
 #pragma once
 
+#include <type_traits>
 #include <utility>
 
-#include <utils/GeneralUtils.h> // NOLINT
-
 namespace org {
 namespace apache {
 namespace nifi {
@@ -50,7 +49,7 @@ struct TryMoveCall {
 //     If 3. is ill-formed, then this specialization is ignored through SFINAE.
 //     If well-formed, then it's considered more specialized than the other and takes precedence.
 template<typename FunType, typename T>
-struct TryMoveCall<FunType, T, void_t<decltype(std::declval<FunType>()(std::declval<T>()))>> {
+struct TryMoveCall<FunType, T, std::void_t<decltype(std::declval<FunType>()(std::declval<T>()))>> {
     template<typename Fun>
     static auto call(Fun&& fun, T& elem) -> decltype(std::forward<Fun>(fun)(std::move(elem))) { return std::forward<Fun>(fun)(std::move(elem)); }
 };
diff --git a/libminifi/include/utils/crypto/EncryptionManager.h b/libminifi/include/utils/crypto/EncryptionManager.h
index 8772977..a21dda8 100644
--- a/libminifi/include/utils/crypto/EncryptionManager.h
+++ b/libminifi/include/utils/crypto/EncryptionManager.h
@@ -17,11 +17,11 @@
 
 #pragma once
 
-#include <utility>
-#include <string>
 #include <memory>
+#include <optional>
+#include <string>
+#include <utility>
 #include "utils/crypto/EncryptionUtils.h"
-#include "utils/OptionalUtils.h"
 #include "utils/crypto/ciphers/XSalsa20.h"
 #include "utils/crypto/ciphers/Aes256Ecb.h"
 #include "core/logging/Logger.h"
@@ -38,11 +38,11 @@ class EncryptionManager {
  public:
   explicit EncryptionManager(std::string key_dir) : key_dir_(std::move(key_dir)) {}
 
-  utils::optional<XSalsa20Cipher> createXSalsa20Cipher(const std::string& key_name) const;
-  utils::optional<Aes256EcbCipher> createAes256EcbCipher(const std::string& key_name) const;
+  [[nodiscard]] std::optional<XSalsa20Cipher> createXSalsa20Cipher(const std::string& key_name) const;
+  [[nodiscard]] std::optional<Aes256EcbCipher> createAes256EcbCipher(const std::string& key_name) const;
  private:
-  utils::optional<Bytes> readKey(const std::string& key_name) const;
-  bool writeKey(const std::string& key_name, const Bytes& key) const;
+  [[nodiscard]] std::optional<Bytes> readKey(const std::string& key_name) const;
+  [[nodiscard]] bool writeKey(const std::string& key_name, const Bytes& key) const;
 
   std::string key_dir_;
 };
diff --git a/libminifi/include/utils/crypto/EncryptionProvider.h b/libminifi/include/utils/crypto/EncryptionProvider.h
index aa26f52..6c20ff1 100644
--- a/libminifi/include/utils/crypto/EncryptionProvider.h
+++ b/libminifi/include/utils/crypto/EncryptionProvider.h
@@ -17,11 +17,12 @@
 
 #pragma once
 
-#include <utility>
-#include <string>
 #include <memory>
+#include <optional>
+#include <string>
+#include <utility>
+
 #include "utils/crypto/EncryptionUtils.h"
-#include "utils/OptionalUtils.h"
 #include "utils/crypto/ciphers/XSalsa20.h"
 #include "core/logging/Logger.h"
 
@@ -37,13 +38,13 @@ class EncryptionProvider {
   explicit EncryptionProvider(Bytes key) : cipher_impl_(std::move(key)) {}
   explicit EncryptionProvider(XSalsa20Cipher cipher_impl) : cipher_impl_(std::move(cipher_impl)) {}
 
-  static utils::optional<EncryptionProvider> create(const std::string& home_path);
+  static std::optional<EncryptionProvider> create(const std::string& home_path);
 
-  std::string encrypt(const std::string& data) const {
+  [[nodiscard]] std::string encrypt(const std::string& data) const {
     return cipher_impl_.encrypt(data);
   }
 
-  std::string decrypt(const std::string& data) const {
+  [[nodiscard]] std::string decrypt(const std::string& data) const {
     return cipher_impl_.decrypt(data);
   }
 
diff --git a/libminifi/include/utils/file/FileSystem.h b/libminifi/include/utils/file/FileSystem.h
index d835c1d..dbf3476 100644
--- a/libminifi/include/utils/file/FileSystem.h
+++ b/libminifi/include/utils/file/FileSystem.h
@@ -17,9 +17,9 @@
 
 #pragma once
 
-#include <string>
 #include <memory>
-#include "utils/OptionalUtils.h"
+#include <optional>
+#include <string>
 #include "utils/crypto/EncryptionProvider.h"
 #include "core/logging/LoggerConfiguration.h"
 
@@ -32,20 +32,20 @@ namespace file {
 
 class FileSystem {
  public:
-  explicit FileSystem(bool should_encrypt = false, utils::optional<utils::crypto::EncryptionProvider> encryptor = {});
+  explicit FileSystem(bool should_encrypt = false, std::optional<utils::crypto::EncryptionProvider> encryptor = {});
 
   FileSystem(const FileSystem&) = delete;
   FileSystem(FileSystem&&) = delete;
   FileSystem& operator=(const FileSystem&) = delete;
   FileSystem& operator=(FileSystem&&) = delete;
 
-  utils::optional<std::string> read(const std::string& file_name);
+  std::optional<std::string> read(const std::string& file_name);
 
   bool write(const std::string& file_name, const std::string& file_content);
 
  private:
   bool should_encrypt_on_write_;
-  utils::optional<utils::crypto::EncryptionProvider> encryptor_;
+  std::optional<utils::crypto::EncryptionProvider> encryptor_;
   std::shared_ptr<logging::Logger> logger_{logging::LoggerFactory<FileSystem>::getLogger()};
 };
 
diff --git a/libminifi/include/utils/file/PathUtils.h b/libminifi/include/utils/file/PathUtils.h
index 4960472..fe07e28 100644
--- a/libminifi/include/utils/file/PathUtils.h
+++ b/libminifi/include/utils/file/PathUtils.h
@@ -21,10 +21,10 @@
 #include <cctype>
 #include <cinttypes>
 #include <memory>
+#include <optional>
 #include <string>
 #include <system_error>
 #include <utility>
-#include "utils/OptionalUtils.h"
 
 namespace org {
 namespace apache {
@@ -64,7 +64,7 @@ inline bool isAbsolutePath(const char* const path) noexcept {
 #endif
 }
 
-inline utils::optional<std::string> canonicalize(const std::string &path) {
+inline std::optional<std::string> canonicalize(const std::string &path) {
   const char *resolved = nullptr;
 #ifndef WIN32
   char full_path[PATH_MAX];
@@ -74,7 +74,7 @@ inline utils::optional<std::string> canonicalize(const std::string &path) {
 #endif
 
   if (resolved == nullptr) {
-    return utils::nullopt;
+    return std::nullopt;
   }
   return std::string(path);
 }
diff --git a/libminifi/include/utils/requirements/LegacyIterator.h b/libminifi/include/utils/requirements/LegacyIterator.h
index 69b14ef..fea38bb 100644
--- a/libminifi/include/utils/requirements/LegacyIterator.h
+++ b/libminifi/include/utils/requirements/LegacyIterator.h
@@ -36,7 +36,7 @@ template<typename T, typename = void>
 struct is_dereferenceable : std::false_type {};
 
 template<typename T>
-struct is_dereferenceable<T, void_t<decltype(*std::declval<T&>())>> : std::true_type {};
+struct is_dereferenceable<T, std::void_t<decltype(*std::declval<T&>())>> : std::true_type {};
 
 template<typename T, typename = void>
 struct is_incrementable : std::false_type {};
diff --git a/libminifi/include/utils/requirements/Swappable.h b/libminifi/include/utils/requirements/Swappable.h
index 6a26e29..9369004 100644
--- a/libminifi/include/utils/requirements/Swappable.h
+++ b/libminifi/include/utils/requirements/Swappable.h
@@ -37,7 +37,7 @@ struct is_swappable_with_impl: std::false_type {};
 
 template<typename T, typename U>
 struct is_swappable_with_impl<T, U,
-    void_t<decltype(
+    std::void_t<decltype(
       swap(std::declval<T>(), std::declval<U>()),
       swap(std::declval<U>(), std::declval<T>()))
     >> : std::true_type {};
diff --git a/libminifi/include/utils/tls/DistinguishedName.h b/libminifi/include/utils/tls/DistinguishedName.h
index 4bad9fa..c122092 100644
--- a/libminifi/include/utils/tls/DistinguishedName.h
+++ b/libminifi/include/utils/tls/DistinguishedName.h
@@ -16,12 +16,11 @@
  */
 #pragma once
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "utils/OptionalUtils.h"
-
 namespace org {
 namespace apache {
 namespace nifi {
@@ -35,8 +34,8 @@ class DistinguishedName {
   static DistinguishedName fromCommaSeparated(const std::string& comma_separated_components);
   static DistinguishedName fromSlashSeparated(const std::string& slash_separated_components);
 
-  utils::optional<std::string> getCN() const;
-  std::string toString() const;
+  [[nodiscard]] std::optional<std::string> getCN() const;
+  [[nodiscard]] std::string toString() const;
 
   friend bool operator==(const DistinguishedName& left, const DistinguishedName& right) { return left.components_ == right.components_; }
   friend bool operator!=(const DistinguishedName& left, const DistinguishedName& right) { return !(left == right); }
diff --git a/libminifi/src/Configure.cpp b/libminifi/src/Configure.cpp
index f02d2bb..e0ee22b 100644
--- a/libminifi/src/Configure.cpp
+++ b/libminifi/src/Configure.cpp
@@ -51,8 +51,8 @@ bool Configure::get(const std::string& key, const std::string& alternate_key, st
   }
 }
 
-utils::optional<std::string> Configure::get(const std::string& key) const {
-  utils::optional<std::string> value = getString(key);
+std::optional<std::string> Configure::get(const std::string& key) const {
+  auto value = getString(key);
   if (decryptor_ && value && isEncrypted(key)) {
     return decryptor_->decrypt(*value);
   } else {
@@ -62,11 +62,11 @@ utils::optional<std::string> Configure::get(const std::string& key) const {
 
 bool Configure::isEncrypted(const std::string& key) const {
   gsl_Expects(decryptor_);
-  utils::optional<std::string> encryption_marker = getString(key + ".protected");
+  const auto encryption_marker = getString(key + ".protected");
   return decryptor_->isValidEncryptionMarker(encryption_marker);
 }
 
-utils::optional<std::string> Configure::getAgentClass() const {
+std::optional<std::string> Configure::getAgentClass() const {
   std::string agent_class;
   if (get("nifi.c2.agent.class", "c2.agent.class", agent_class) && !agent_class.empty()) {
     return agent_class;
diff --git a/libminifi/src/DiskSpaceWatchdog.cpp b/libminifi/src/DiskSpaceWatchdog.cpp
index 9a7f26c..49b79f2 100644
--- a/libminifi/src/DiskSpaceWatchdog.cpp
+++ b/libminifi/src/DiskSpaceWatchdog.cpp
@@ -30,20 +30,20 @@ namespace minifi {
 namespace {
 namespace chr = std::chrono;
 
-utils::optional<chr::milliseconds> time_string_to_milliseconds(const std::string& str) {
+std::optional<chr::milliseconds> time_string_to_milliseconds(const std::string& str) {
   uint64_t millisec_value{};
   const bool success = core::Property::getTimeMSFromString(str, millisec_value);
-  if (!success) return utils::nullopt;
-  return utils::make_optional(chr::milliseconds{millisec_value});
+  if (!success) return std::nullopt;
+  return chr::milliseconds{millisec_value};
 }
 
-template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
-utils::optional<T> data_size_string_to_int(const std::string& str) {
+template<typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
+std::optional<T> data_size_string_to_int(const std::string& str) {
   T result{};
   // actually aware of data units like B, kB, MB, etc.
   const bool success = core::Property::StringToInt(str, result);
-  if (!success) return utils::nullopt;
-  return utils::make_optional(result);
+  if (!success) return std::nullopt;
+  return std::make_optional(result);
 }
 
 
diff --git a/libminifi/src/FlowController.cpp b/libminifi/src/FlowController.cpp
index 0f70d8c..d46ef23 100644
--- a/libminifi/src/FlowController.cpp
+++ b/libminifi/src/FlowController.cpp
@@ -49,7 +49,6 @@
 #include "utils/file/PathUtils.h"
 #include "utils/file/FileSystem.h"
 #include "utils/HTTPClient.h"
-#include "utils/GeneralUtils.h"
 #include "io/NetworkPrioritizer.h"
 #include "io/validation.h"
 
@@ -80,7 +79,7 @@ FlowController::FlowController(std::shared_ptr<core::Repository> provenance_repo
   running_ = false;
   initialized_ = false;
 
-  protocol_ = utils::make_unique<FlowControlProtocol>(this, configuration_);
+  protocol_ = std::make_unique<FlowControlProtocol>(this, configuration_);
 
   if (!headless_mode) {
     initializeExternalComponents();
@@ -101,15 +100,15 @@ void FlowController::initializeExternalComponents() {
   }
 }
 
-utils::optional<std::chrono::milliseconds> FlowController::loadShutdownTimeoutFromConfiguration() {
+std::optional<std::chrono::milliseconds> FlowController::loadShutdownTimeoutFromConfiguration() {
   std::string shutdown_timeout_str;
   if (configuration_->get(minifi::Configure::nifi_flowcontroller_drain_timeout, shutdown_timeout_str)) {
-    const utils::optional<core::TimePeriodValue> time_from_config = core::TimePeriodValue::fromString(shutdown_timeout_str);
+    const auto time_from_config = core::TimePeriodValue::fromString(shutdown_timeout_str);
     if (time_from_config) {
       return { std::chrono::milliseconds{ time_from_config.value().getMilliseconds() }};
     }
   }
-  return utils::nullopt;
+  return std::nullopt;
 }
 
 FlowController::~FlowController() {
diff --git a/libminifi/src/SchedulingAgent.cpp b/libminifi/src/SchedulingAgent.cpp
index a6ef4b0..0f5db51 100644
--- a/libminifi/src/SchedulingAgent.cpp
+++ b/libminifi/src/SchedulingAgent.cpp
@@ -23,7 +23,6 @@
 #include <utility>
 #include <memory>
 #include "core/Processor.h"
-#include "utils/GeneralUtils.h"
 #include "utils/gsl.h"
 
 namespace org {
@@ -48,7 +47,7 @@ std::future<utils::TaskRescheduleInfo> SchedulingAgent::enableControllerService(
     };
 
   // only need to run this once.
-  auto monitor = utils::make_unique<utils::ComplexMonitor>();
+  auto monitor = std::make_unique<utils::ComplexMonitor>();
   utils::Worker<utils::TaskRescheduleInfo> functor(f_ex, serviceNode->getUUIDStr(), std::move(monitor));
   // move the functor into the thread pool. While a future is returned
   // we aren't terribly concerned with the result.
@@ -68,7 +67,7 @@ std::future<utils::TaskRescheduleInfo> SchedulingAgent::disableControllerService
   };
 
   // only need to run this once.
-  auto monitor = utils::make_unique<utils::ComplexMonitor>();
+  auto monitor = std::make_unique<utils::ComplexMonitor>();
   utils::Worker<utils::TaskRescheduleInfo> functor(f_ex, serviceNode->getUUIDStr(), std::move(monitor));
 
   // move the functor into the thread pool. While a future is returned
diff --git a/libminifi/src/ThreadedSchedulingAgent.cpp b/libminifi/src/ThreadedSchedulingAgent.cpp
index 7dda0b0..a635bcb 100644
--- a/libminifi/src/ThreadedSchedulingAgent.cpp
+++ b/libminifi/src/ThreadedSchedulingAgent.cpp
@@ -19,14 +19,15 @@
  */
 #include "ThreadedSchedulingAgent.h"
 
+#include <cinttypes>
+#include <iostream>
+#include <map>
 #include <memory>
+#include <optional>
 #include <string>
-#include <vector>
-#include <utility>
-#include <map>
 #include <thread>
-#include <iostream>
-#include <cinttypes>
+#include <utility>
+#include <vector>
 
 #include "core/ClassLoader.h"
 #include "core/Connectable.h"
@@ -35,9 +36,7 @@
 #include "core/ProcessContextBuilder.h"
 #include "core/ProcessSession.h"
 #include "core/ProcessSessionFactory.h"
-#include "utils/GeneralUtils.h"
 #include "utils/ValueParser.h"
-#include "utils/OptionalUtils.h"
 
 namespace org {
 namespace apache {
@@ -51,7 +50,7 @@ void ThreadedSchedulingAgent::schedule(std::shared_ptr<core::Processor> processo
   std::string yieldValue;
 
   if (configure_->get(Configure::nifi_administrative_yield_duration, yieldValue)) {
-    utils::optional<core::TimePeriodValue> value = core::TimePeriodValue::fromString(yieldValue);
+    std::optional<core::TimePeriodValue> value = core::TimePeriodValue::fromString(yieldValue);
     if (value) {
       admin_yield_duration_ = value->getMilliseconds();
       logger_->log_debug("nifi_administrative_yield_duration: [%" PRId64 "] ms", admin_yield_duration_);
@@ -60,7 +59,7 @@ void ThreadedSchedulingAgent::schedule(std::shared_ptr<core::Processor> processo
 
   bored_yield_duration_ = 0;
   if (configure_->get(Configure::nifi_bored_yield_duration, yieldValue)) {
-    utils::optional<core::TimePeriodValue> value = core::TimePeriodValue::fromString(yieldValue);
+    std::optional<core::TimePeriodValue> value = core::TimePeriodValue::fromString(yieldValue);
     if (value) {
       bored_yield_duration_ = value->getMilliseconds();
       logger_->log_debug("nifi_bored_yield_duration: [%" PRId64 "] ms", bored_yield_duration_);
@@ -102,8 +101,7 @@ void ThreadedSchedulingAgent::schedule(std::shared_ptr<core::Processor> processo
     };
 
     // create a functor that will be submitted to the thread pool.
-    auto monitor = utils::make_unique<utils::ComplexMonitor>();
-    utils::Worker<utils::TaskRescheduleInfo> functor(f_ex, processor->getUUIDStr(), std::move(monitor));
+    utils::Worker<utils::TaskRescheduleInfo> functor(f_ex, processor->getUUIDStr(), std::make_unique<utils::ComplexMonitor>());
     // move the functor into the thread pool. While a future is returned
     // we aren't terribly concerned with the result.
     std::future<utils::TaskRescheduleInfo> future;
diff --git a/libminifi/src/c2/C2Agent.cpp b/libminifi/src/c2/C2Agent.cpp
index 2dfa459..738ac4d 100644
--- a/libminifi/src/c2/C2Agent.cpp
+++ b/libminifi/src/c2/C2Agent.cpp
@@ -18,15 +18,16 @@
 
 #include "c2/C2Agent.h"
 
+#include <cinttypes>
 #include <cstdio>
 #include <csignal>
-#include <utility>
 #include <limits>
-#include <vector>
 #include <map>
-#include <string>
 #include <memory>
-#include <cinttypes>
+#include <optional>
+#include <string>
+#include <utility>
+#include <vector>
 
 #include "c2/ControllerSocketProtocol.h"
 #include "core/ProcessContext.h"
@@ -38,11 +39,9 @@
 #include "utils/file/FileUtils.h"
 #include "utils/file/FileManager.h"
 #include "utils/file/FileSystem.h"
-#include "utils/GeneralUtils.h"
 #include "utils/HTTPClient.h"
 #include "utils/Environment.h"
 #include "utils/Monitors.h"
-#include "utils/OptionalUtils.h"
 #include "utils/StringUtils.h"
 
 namespace org {
@@ -95,8 +94,7 @@ void C2Agent::start() {
   for (const auto& function : functions_) {
     utils::Identifier uuid = utils::IdGenerator::getIdGenerator()->generate();
     task_ids_.push_back(uuid);
-    auto monitor = utils::make_unique<utils::ComplexMonitor>();
-    utils::Worker<utils::TaskRescheduleInfo> functor(function, uuid.to_string(), std::move(monitor));
+    utils::Worker<utils::TaskRescheduleInfo> functor(function, uuid.to_string(), std::make_unique<utils::ComplexMonitor>());
     std::future<utils::TaskRescheduleInfo> future;
     thread_pool_.execute(std::move(functor), future);
   }
@@ -659,10 +657,10 @@ utils::TaskRescheduleInfo C2Agent::consume() {
   return utils::TaskRescheduleInfo::RetryIn(std::chrono::milliseconds(C2RESPONSE_POLL_MS));
 }
 
-utils::optional<std::string> C2Agent::fetchFlow(const std::string& uri) const {
+std::optional<std::string> C2Agent::fetchFlow(const std::string& uri) const {
   if (!utils::StringUtils::startsWith(uri, "http") || protocol_.load() == nullptr) {
     // try to open the file
-    utils::optional<std::string> content = filesystem_->read(uri);
+    auto content = filesystem_->read(uri);
     if (content) {
       return content;
     }
@@ -688,7 +686,7 @@ utils::optional<std::string> C2Agent::fetchFlow(const std::string& uri) const {
       utils::URL base_url{utils::StringUtils::trim(base)};
       if (!base_url.isValid()) {
         logger_->log_error("Could not parse C2 REST URL '%s'", base);
-        return {};
+        return std::nullopt;
       }
       resolved_url = base_url.hostPort() + "/c2/api/" + uri;
     }
@@ -709,7 +707,7 @@ bool C2Agent::handleConfigurationUpdate(const C2ContentResponse &resp) {
 
   if (url != resp.operation_arguments.end()) {
     file_uri = url->second.to_string();
-    utils::optional<std::string> optional_configuration_str = fetchFlow(file_uri);
+    std::optional<std::string> optional_configuration_str = fetchFlow(file_uri);
     if (!optional_configuration_str) {
       logger_->log_error("Couldn't load new flow configuration from: \"%s\"", file_uri);
       C2Payload response(Operation::ACKNOWLEDGE, state::UpdateState::SET_ERROR, resp.ident, true);
diff --git a/libminifi/src/c2/C2Client.cpp b/libminifi/src/c2/C2Client.cpp
index 5502376..a5da18e 100644
--- a/libminifi/src/c2/C2Client.cpp
+++ b/libminifi/src/c2/C2Client.cpp
@@ -132,7 +132,7 @@ void C2Client::initialize(core::controller::ControllerServiceProvider *controlle
   }
 }
 
-utils::optional<std::string> C2Client::fetchFlow(const std::string& uri) const {
+std::optional<std::string> C2Client::fetchFlow(const std::string& uri) const {
   if (!c2_agent_) {
     return {};
   }
diff --git a/libminifi/src/controllers/SSLContextService.cpp b/libminifi/src/controllers/SSLContextService.cpp
index c6d92fc..ea93533 100644
--- a/libminifi/src/controllers/SSLContextService.cpp
+++ b/libminifi/src/controllers/SSLContextService.cpp
@@ -25,6 +25,7 @@
 #ifdef WIN32
 #pragma comment(lib, "crypt32.lib")
 #pragma comment(lib, "Ws2_32.lib")
+#include <optional>
 #endif  // WIN32
 #endif  // OPENSSL_SUPPORT
 
@@ -293,7 +294,7 @@ bool SSLContextService::useClientCertificate(SSL_CTX* ctx, PCCERT_CONTEXT certif
 
   if (!client_cert_cn_.empty()) {
     utils::tls::DistinguishedName dn = utils::tls::DistinguishedName::fromSlashSeparated(x509_cert->name);
-    utils::optional<std::string> cn = dn.getCN();
+    std::optional<std::string> cn = dn.getCN();
     if (!cn || *cn != client_cert_cn_) {
       logger_->log_debug("Skipping client certificate %s because it doesn't match CN=%s", x509_cert->name, client_cert_cn_);
       return false;
diff --git a/libminifi/src/controllers/keyvalue/PersistableKeyValueStoreService.cpp b/libminifi/src/controllers/keyvalue/PersistableKeyValueStoreService.cpp
index a194f0e..39f4c2d 100644
--- a/libminifi/src/controllers/keyvalue/PersistableKeyValueStoreService.cpp
+++ b/libminifi/src/controllers/keyvalue/PersistableKeyValueStoreService.cpp
@@ -45,7 +45,7 @@ bool PersistableKeyValueStoreService::getImpl(std::map<utils::Identifier, std::s
   }
   kvs.clear();
   for (const auto& state : states) {
-    utils::optional<utils::Identifier> optional_uuid = utils::Identifier::parse(state.first);
+    const auto optional_uuid = utils::Identifier::parse(state.first);
     if (optional_uuid) {
       kvs[optional_uuid.value()] = state.second;
     } else {
diff --git a/libminifi/src/core/ConfigurationFactory.cpp b/libminifi/src/core/ConfigurationFactory.cpp
index 82ec9f4..ea4c403 100644
--- a/libminifi/src/core/ConfigurationFactory.cpp
+++ b/libminifi/src/core/ConfigurationFactory.cpp
@@ -15,19 +15,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include <type_traits>
-#include <utility>
-#include <string>
-#include <memory>
 #include <algorithm>
+#include <memory>
+#include <optional>
 #include <set>
+#include <string>
+#include <type_traits>
+#include <utility>
+
 #include "core/Core.h"
 #include "core/ConfigurationFactory.h"
 #include "core/FlowConfiguration.h"
 #include "io/StreamFactory.h"
 
 #include "core/yaml/YamlConfiguration.h"
-#include "utils/OptionalUtils.h"
 
 namespace org {
 namespace apache {
@@ -39,34 +40,28 @@ std::unique_ptr<core::FlowConfiguration> createFlowConfiguration(
     std::shared_ptr<core::Repository> repo, std::shared_ptr<core::Repository> flow_file_repo,
     std::shared_ptr<core::ContentRepository> content_repo, std::shared_ptr<Configure> configure,
     std::shared_ptr<io::StreamFactory> stream_factory, const std::string& configuration_class_name,
-    const utils::optional<std::string>& path, std::shared_ptr<utils::file::FileSystem> filesystem,
+    const std::optional<std::string>& path, std::shared_ptr<utils::file::FileSystem> filesystem,
     bool fail_safe) {
   std::string class_name_lc = configuration_class_name;
   std::transform(class_name_lc.begin(), class_name_lc.end(), class_name_lc.begin(), ::tolower);
   try {
     if (class_name_lc == "flowconfiguration") {
       // load the base configuration.
-
-      return std::unique_ptr<core::FlowConfiguration>(new core::FlowConfiguration(
-          repo, flow_file_repo, content_repo, stream_factory, configure, path, filesystem));
-
+      return std::make_unique<core::FlowConfiguration>(repo, flow_file_repo, content_repo, stream_factory, configure, path, filesystem);
     } else if (class_name_lc == "yamlconfiguration") {
       // only load if the class is defined.
       return std::unique_ptr<core::FlowConfiguration>(instantiate<core::YamlConfiguration>(
           repo, flow_file_repo, content_repo, stream_factory, configure, path, filesystem));
-
     } else {
       if (fail_safe) {
-        return std::unique_ptr<core::FlowConfiguration>(new core::FlowConfiguration(
-            repo, flow_file_repo, content_repo, stream_factory, configure, path, filesystem));
+        return std::make_unique<core::FlowConfiguration>(repo, flow_file_repo, content_repo, stream_factory, configure, path, filesystem);
       } else {
         throw std::runtime_error("Support for the provided configuration class could not be found");
       }
     }
   } catch (const std::runtime_error &) {
     if (fail_safe) {
-      return std::unique_ptr<core::FlowConfiguration>(new core::FlowConfiguration(
-          repo, flow_file_repo, content_repo, stream_factory, configure, path, filesystem));
+      return std::make_unique<core::FlowConfiguration>(repo, flow_file_repo, content_repo, stream_factory, configure, path, filesystem);
     }
   }
 
diff --git a/libminifi/src/core/FlowConfiguration.cpp b/libminifi/src/core/FlowConfiguration.cpp
index d8aad17..dc3a4e6 100644
--- a/libminifi/src/core/FlowConfiguration.cpp
+++ b/libminifi/src/core/FlowConfiguration.cpp
@@ -115,15 +115,15 @@ bool FlowConfiguration::persist(const std::string &configuration) {
 }
 
 std::unique_ptr<core::ProcessGroup> FlowConfiguration::createRootProcessGroup(const std::string &name, const utils::Identifier &uuid, int version) {
-  return utils::make_unique<core::ProcessGroup>(core::ROOT_PROCESS_GROUP, name, uuid, version);
+  return std::make_unique<core::ProcessGroup>(core::ROOT_PROCESS_GROUP, name, uuid, version);
 }
 
 std::unique_ptr<core::ProcessGroup> FlowConfiguration::createSimpleProcessGroup(const std::string &name, const utils::Identifier &uuid, int version) {
-  return utils::make_unique<core::ProcessGroup>(core::SIMPLE_PROCESS_GROUP, name, uuid, version);
+  return std::make_unique<core::ProcessGroup>(core::SIMPLE_PROCESS_GROUP, name, uuid, version);
 }
 
 std::unique_ptr<core::ProcessGroup> FlowConfiguration::createRemoteProcessGroup(const std::string &name, const utils::Identifier &uuid) {
-  return utils::make_unique<core::ProcessGroup>(core::REMOTE_PROCESS_GROUP, name, uuid);
+  return std::make_unique<core::ProcessGroup>(core::REMOTE_PROCESS_GROUP, name, uuid);
 }
 
 std::shared_ptr<minifi::Connection> FlowConfiguration::createConnection(const std::string& name, const utils::Identifier& uuid) const {
diff --git a/libminifi/src/core/FlowFile.cpp b/libminifi/src/core/FlowFile.cpp
index 6027ca8..9606184 100644
--- a/libminifi/src/core/FlowFile.cpp
+++ b/libminifi/src/core/FlowFile.cpp
@@ -154,12 +154,12 @@ bool FlowFile::getAttribute(const std::string& key, std::string& value) const {
   return true;
 }
 
-utils::optional<std::string> FlowFile::getAttribute(const std::string& key) const {
+std::optional<std::string> FlowFile::getAttribute(const std::string& key) const {
   auto it = attributes_.find(key);
   if (it != attributes_.end()) {
     return it->second;
   }
-  return utils::nullopt;
+  return std::nullopt;
 }
 
 // Get Size
diff --git a/libminifi/src/core/logging/LoggerConfiguration.cpp b/libminifi/src/core/logging/LoggerConfiguration.cpp
index ece4f4c..a08314c 100644
--- a/libminifi/src/core/logging/LoggerConfiguration.cpp
+++ b/libminifi/src/core/logging/LoggerConfiguration.cpp
@@ -22,12 +22,13 @@
 
 #include <sys/stat.h>
 #include <algorithm>
-#include <vector>
-#include <queue>
-#include <memory>
+#include <atomic>
 #include <map>
+#include <memory>
+#include <optional>
+#include <queue>
 #include <string>
-#include <atomic>
+#include <vector>
 
 #include "core/Core.h"
 #include "utils/StringUtils.h"
@@ -64,7 +65,8 @@ namespace logging {
 
 const char* LoggerConfiguration::spdlog_default_pattern = "[%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %v";
 
-utils::optional<spdlog::level::level_enum> parse_log_level(const std::string& level_name) {
+namespace {
+std::optional<spdlog::level::level_enum> parse_log_level(const std::string& level_name) {
   if (utils::StringUtils::equalsIgnoreCase(level_name, "trace")) {
     return spdlog::level::trace;
   } else if (utils::StringUtils::equalsIgnoreCase(level_name, "debug")) {
@@ -80,8 +82,9 @@ utils::optional<spdlog::level::level_enum> parse_log_level(const std::string& le
   } else if (utils::StringUtils::equalsIgnoreCase(level_name, "off")) {
     return spdlog::level::off;
   }
-  return utils::nullopt;
+  return std::nullopt;
 }
+}  // namespace
 
 std::vector<std::string> LoggerProperties::get_keys_of_type(const std::string &type) {
   std::vector<std::string> appenders;
diff --git a/libminifi/src/core/logging/internal/CompressionManager.cpp b/libminifi/src/core/logging/internal/CompressionManager.cpp
index 6347988..b7453f5 100644
--- a/libminifi/src/core/logging/internal/CompressionManager.cpp
+++ b/libminifi/src/core/logging/internal/CompressionManager.cpp
@@ -18,6 +18,7 @@
 
 #include <memory>
 #include <mutex>
+#include <optional>
 
 #include "core/logging/internal/CompressionManager.h"
 #include "core/logging/internal/LogCompressorSink.h"
@@ -36,7 +37,7 @@ namespace internal {
 
 std::shared_ptr<LogCompressorSink> CompressionManager::initialize(
     const std::shared_ptr<LoggerProperties>& properties, const std::shared_ptr<Logger>& error_logger, const LoggerFactory& logger_factory) {
-  auto get_size = [&] (const char* const property_name) -> utils::optional<size_t> {
+  const auto get_size = [&] (const char* const property_name) -> std::optional<size_t> {
     auto size_str = properties->getString(property_name);
     if (!size_str) return {};
     size_t value;
@@ -46,7 +47,7 @@ std::shared_ptr<LogCompressorSink> CompressionManager::initialize(
     if (error_logger) {
       error_logger->log_error("Invalid format for %s", property_name);
     }
-    return {};
+    return std::nullopt;
   };
   auto cached_log_max_size = get_size(compression_cached_log_max_size_).value_or(8_MiB);
   auto compressed_log_max_size = get_size(compression_compressed_log_max_size_).value_or(8_MiB);
diff --git a/libminifi/src/core/yaml/YamlConfiguration.cpp b/libminifi/src/core/yaml/YamlConfiguration.cpp
index 1a4850b..9eb60db 100644
--- a/libminifi/src/core/yaml/YamlConfiguration.cpp
+++ b/libminifi/src/core/yaml/YamlConfiguration.cpp
@@ -41,7 +41,7 @@ std::shared_ptr<utils::IdGenerator> YamlConfiguration::id_generator_ = utils::Id
 
 YamlConfiguration::YamlConfiguration(const std::shared_ptr<core::Repository>& repo, const std::shared_ptr<core::Repository>& flow_file_repo,
                                      const std::shared_ptr<core::ContentRepository>& content_repo, const std::shared_ptr<io::StreamFactory>& stream_factory,
-                                     const std::shared_ptr<Configure>& configuration, const utils::optional<std::string>& path,
+                                     const std::shared_ptr<Configure>& configuration, const std::optional<std::string>& path,
                                      const std::shared_ptr<utils::file::FileSystem>& filesystem)
     : FlowConfiguration(repo, flow_file_repo, content_repo, stream_factory, configuration,
                         path.value_or(DEFAULT_NIFI_CONFIG_YML), filesystem),
@@ -605,7 +605,7 @@ void YamlConfiguration::parseConnectionYaml(const YAML::Node& connectionsNode, c
     // If name is specified in configuration, use the value
     std::string name = connectionNode["name"].as<std::string>(id);
 
-    const utils::optional<utils::Identifier> uuid = utils::Identifier::parse(id);
+    const auto uuid = utils::Identifier::parse(id);
     if (!uuid) {
       logger_->log_debug("Incorrect connection UUID format.");
       throw Exception(ExceptionType::GENERAL_EXCEPTION, "Incorrect connection UUID format.");
diff --git a/libminifi/src/core/yaml/YamlConnectionParser.cpp b/libminifi/src/core/yaml/YamlConnectionParser.cpp
index 81d53ad..e3438d1 100644
--- a/libminifi/src/core/yaml/YamlConnectionParser.cpp
+++ b/libminifi/src/core/yaml/YamlConnectionParser.cpp
@@ -81,7 +81,7 @@ uint64_t YamlConnectionParser::getWorkQueueDataSizeFromYaml() const {
 utils::Identifier YamlConnectionParser::getSourceUUIDFromYaml() const {
   const YAML::Node source_id_node = connectionNode_["source id"];
   if (source_id_node) {
-    const utils::optional<utils::Identifier> srcUUID = utils::Identifier::parse(source_id_node.as<std::string>());
+    const auto srcUUID = utils::Identifier::parse(source_id_node.as<std::string>());
     if (srcUUID) {
       logger_->log_debug("Using 'source id' to match source with same id for connection '%s': source id => [%s]", name_, srcUUID.value().to_string());
       return srcUUID.value();
@@ -91,8 +91,8 @@ utils::Identifier YamlConnectionParser::getSourceUUIDFromYaml() const {
   }
   // if we don't have a source id, try to resolve using source name. config schema v2 will make this unnecessary
   checkRequiredField(&connectionNode_, "source name", logger_, CONFIG_YAML_CONNECTIONS_KEY);
-  const std::string connectionSrcProcName = connectionNode_["source name"].as<std::string>();
-  const utils::optional<utils::Identifier> srcUUID = utils::Identifier::parse(connectionSrcProcName);
+  const auto connectionSrcProcName = connectionNode_["source name"].as<std::string>();
+  const auto srcUUID = utils::Identifier::parse(connectionSrcProcName);
   if (srcUUID && parent_->findProcessorById(srcUUID.value(), ProcessGroup::Traverse::ExcludeChildren)) {
     // the source name is a remote port id, so use that as the source id
     logger_->log_debug("Using 'source name' containing a remote port id to match the source for connection '%s': source name => [%s]", name_, connectionSrcProcName);
@@ -113,7 +113,7 @@ utils::Identifier YamlConnectionParser::getSourceUUIDFromYaml() const {
 utils::Identifier YamlConnectionParser::getDestinationUUIDFromYaml() const {
   const YAML::Node destination_id_node = connectionNode_["destination id"];
   if (destination_id_node) {
-    const utils::optional<utils::Identifier> destUUID = utils::Identifier::parse(destination_id_node.as<std::string>());
+    const auto destUUID = utils::Identifier::parse(destination_id_node.as<std::string>());
     if (destUUID) {
       logger_->log_debug("Using 'destination id' to match destination with same id for connection '%s': destination id => [%s]", name_, destUUID.value().to_string());
       return destUUID.value();
@@ -125,7 +125,7 @@ utils::Identifier YamlConnectionParser::getDestinationUUIDFromYaml() const {
   // for looking up the destination processor in absence of a processor id
   checkRequiredField(&connectionNode_, "destination name", logger_, CONFIG_YAML_CONNECTIONS_KEY);
   std::string connectionDestProcName = connectionNode_["destination name"].as<std::string>();
-  const utils::optional<utils::Identifier> destUUID = utils::Identifier::parse(connectionDestProcName);
+  const auto destUUID = utils::Identifier::parse(connectionDestProcName);
   if (destUUID && parent_->findProcessorById(destUUID.value(), ProcessGroup::Traverse::ExcludeChildren)) {
     // the destination name is a remote port id, so use that as the dest id
     logger_->log_debug("Using 'destination name' containing a remote port id to match the destination for connection '%s': destination name => [%s]", name_, connectionDestProcName);
diff --git a/libminifi/src/io/ClientSocket.cpp b/libminifi/src/io/ClientSocket.cpp
index 430f019..2538a5f 100644
--- a/libminifi/src/io/ClientSocket.cpp
+++ b/libminifi/src/io/ClientSocket.cpp
@@ -46,7 +46,6 @@
 #include "io/validation.h"
 #include "core/logging/LoggerConfiguration.h"
 #include "utils/file/FileUtils.h"
-#include "utils/GeneralUtils.h"
 #include "utils/gsl.h"
 #include "utils/OsUtils.h"
 
@@ -175,12 +174,12 @@ Socket::Socket(Socket &&other) noexcept
 
 Socket& Socket::operator=(Socket &&other) noexcept {
   if (&other == this) return *this;
-  requested_hostname_ = util::exchange(other.requested_hostname_, "");
-  canonical_hostname_ = util::exchange(other.canonical_hostname_, "");
-  port_ = util::exchange(other.port_, 0);
-  is_loopback_only_ = util::exchange(other.is_loopback_only_, false);
-  local_network_interface_ = util::exchange(other.local_network_interface_, {});
-  socket_file_descriptor_ = util::exchange(other.socket_file_descriptor_, INVALID_SOCKET);
+  requested_hostname_ = std::exchange(other.requested_hostname_, "");
+  canonical_hostname_ = std::exchange(other.canonical_hostname_, "");
+  port_ = std::exchange(other.port_, 0);
+  is_loopback_only_ = std::exchange(other.is_loopback_only_, false);
+  local_network_interface_ = std::exchange(other.local_network_interface_, {});
+  socket_file_descriptor_ = std::exchange(other.socket_file_descriptor_, INVALID_SOCKET);
   total_list_ = other.total_list_;
   FD_ZERO(&other.total_list_);
   read_fds_ = other.read_fds_;
@@ -191,8 +190,8 @@ Socket& Socket::operator=(Socket &&other) noexcept {
   other.total_written_.exchange(0);
   total_read_.exchange(other.total_read_);
   other.total_read_.exchange(0);
-  listeners_ = util::exchange(other.listeners_, 0);
-  nonBlocking_ = util::exchange(other.nonBlocking_, false);
+  listeners_ = std::exchange(other.listeners_, 0);
+  nonBlocking_ = std::exchange(other.nonBlocking_, false);
   logger_ = other.logger_;
   return *this;
 }
diff --git a/libminifi/src/io/StreamFactory.cpp b/libminifi/src/io/StreamFactory.cpp
index 55a7cea..9ec2a06 100644
--- a/libminifi/src/io/StreamFactory.cpp
+++ b/libminifi/src/io/StreamFactory.cpp
@@ -19,10 +19,8 @@
 
 #include <atomic>
 #include <memory>
-#include <mutex>
 #include <string>
 
-#include "utils/GeneralUtils.h"
 #ifdef OPENSSL_SUPPORT
 #include "io/tls/TLSSocket.h"
 #endif
@@ -65,7 +63,7 @@ class SocketCreator : public AbstractStreamFactory {
 #ifdef OPENSSL_SUPPORT
     if (ssl_service != nullptr) {
       auto context = std::make_shared<TLSContext>(configuration_, ssl_service);
-      return utils::make_unique<TLSSocket>(context, host, port);
+      return std::make_unique<TLSSocket>(context, host, port);
     }
 #endif /* OPENSSL_SUPPORT */
     return nullptr;
diff --git a/libminifi/src/io/tls/TLSSocket.cpp b/libminifi/src/io/tls/TLSSocket.cpp
index 1cb6268..c1d1d81 100644
--- a/libminifi/src/io/tls/TLSSocket.cpp
+++ b/libminifi/src/io/tls/TLSSocket.cpp
@@ -32,7 +32,6 @@
 #include "properties/Configure.h"
 #include "utils/StringUtils.h"
 #include "core/logging/LoggerConfiguration.h"
-#include "utils/GeneralUtils.h"
 #include "utils/gsl.h"
 #include "utils/tls/TLSUtils.h"
 
@@ -180,13 +179,13 @@ TLSSocket::TLSSocket(const std::shared_ptr<TLSContext> &context, const std::stri
 
 TLSSocket::TLSSocket(TLSSocket &&other)
     : Socket(std::move(other)),
-      context_{ utils::exchange(other.context_, nullptr) } {
+      context_{ std::exchange(other.context_, nullptr) } {
   std::lock_guard<std::mutex> lg{ other.ssl_mutex_ };
 
   connected_.exchange(other.connected_.load());
   other.connected_.exchange(false);
-  ssl_ = utils::exchange(other.ssl_, nullptr);
-  ssl_map_ = utils::exchange(other.ssl_map_, {});
+  ssl_ = std::exchange(other.ssl_, nullptr);
+  ssl_map_ = std::exchange(other.ssl_map_, {});
 }
 
 TLSSocket& TLSSocket::operator=(TLSSocket&& other) {
@@ -195,9 +194,9 @@ TLSSocket& TLSSocket::operator=(TLSSocket&& other) {
   std::lock_guard<std::mutex> lg{ other.ssl_mutex_ };
   connected_.exchange(other.connected_.load());
   other.connected_.exchange(false);
-  context_ = utils::exchange(other.context_, nullptr);
-  ssl_ = utils::exchange(other.ssl_, nullptr);
-  ssl_map_ = utils::exchange(other.ssl_map_, {});
+  context_ = std::exchange(other.context_, nullptr);
+  ssl_ = std::exchange(other.ssl_, nullptr);
+  ssl_map_ = std::exchange(other.ssl_map_, {});
   return *this;
 }
 
diff --git a/libminifi/src/properties/Properties.cpp b/libminifi/src/properties/Properties.cpp
index 34d265d..79c5559 100644
--- a/libminifi/src/properties/Properties.cpp
+++ b/libminifi/src/properties/Properties.cpp
@@ -49,13 +49,13 @@ bool Properties::getString(const std::string &key, std::string &value) const {
   }
 }
 
-utils::optional<std::string> Properties::getString(const std::string& key) const {
+std::optional<std::string> Properties::getString(const std::string& key) const {
   std::string result;
   const bool found = getString(key, result);
   if (found) {
     return result;
   } else {
-    return utils::nullopt;
+    return std::nullopt;
   }
 }
 
diff --git a/libminifi/src/properties/PropertiesFile.cpp b/libminifi/src/properties/PropertiesFile.cpp
index be69d92..1af4f77 100644
--- a/libminifi/src/properties/PropertiesFile.cpp
+++ b/libminifi/src/properties/PropertiesFile.cpp
@@ -88,12 +88,12 @@ bool PropertiesFile::hasValue(const std::string& key) const {
   return findKey(key) != lines_.end();
 }
 
-utils::optional<std::string> PropertiesFile::getValue(const std::string& key) const {
+std::optional<std::string> PropertiesFile::getValue(const std::string& key) const {
   const auto it = findKey(key);
   if (it != lines_.end()) {
     return it->getValue();
   } else {
-    return utils::nullopt;
+    return std::nullopt;
   }
 }
 
diff --git a/libminifi/src/utils/BackTrace.cpp b/libminifi/src/utils/BackTrace.cpp
index 9375f98..1719fd0 100644
--- a/libminifi/src/utils/BackTrace.cpp
+++ b/libminifi/src/utils/BackTrace.cpp
@@ -34,8 +34,8 @@
 
 #ifdef HAS_EXECINFO
 namespace {
-  using org::apache::nifi::minifi::utils::optional;
-  using org::apache::nifi::minifi::utils::nullopt;
+  using std::optional;
+  using std::nullopt;
   /**
    * Demangles a symbol name using the cxx abi.
    * @param symbol_name the mangled name of the symbol
diff --git a/libminifi/src/utils/HTTPClient.cpp b/libminifi/src/utils/HTTPClient.cpp
index fe9d702..dd81743 100644
--- a/libminifi/src/utils/HTTPClient.cpp
+++ b/libminifi/src/utils/HTTPClient.cpp
@@ -26,17 +26,17 @@ namespace {
 constexpr const char* HTTP = "http://";
 constexpr const char* HTTPS = "https://";
 
-utils::optional<std::string> parseProtocol(const std::string& url_input) {
+std::optional<std::string> parseProtocol(const std::string& url_input) {
   if (utils::StringUtils::startsWith(url_input, HTTP)) {
     return HTTP;
   } else if (utils::StringUtils::startsWith(url_input, HTTPS)) {
     return HTTPS;
   } else {
-    return {};
+    return std::nullopt;
   }
 }
 
-utils::optional<int> parsePortNumber(const std::string& port_string) {
+std::optional<int> parsePortNumber(const std::string& port_string) {
   try {
     size_t pos;
     int port = std::stoi(port_string, &pos);
@@ -47,7 +47,7 @@ utils::optional<int> parsePortNumber(const std::string& port_string) {
   } catch (const std::out_of_range&) {
   }
 
-  return {};
+  return std::nullopt;
 }
 
 }  // namespace
diff --git a/libminifi/src/utils/Id.cpp b/libminifi/src/utils/Id.cpp
index dc8132f..926b7ab 100644
--- a/libminifi/src/utils/Id.cpp
+++ b/libminifi/src/utils/Id.cpp
@@ -83,7 +83,7 @@ Identifier& Identifier::operator=(const Data& data) {
 }
 
 Identifier& Identifier::operator=(const std::string& idStr) {
-  utils::optional<Identifier> id = Identifier::parse(idStr);
+  const auto id = Identifier::parse(idStr);
   if (!id) {
     throw std::runtime_error("Couldn't parse UUID");
   }
@@ -141,7 +141,7 @@ SmallString<36> Identifier::to_string() const {
   return uuidStr;
 }
 
-utils::optional<Identifier> Identifier::parse(const std::string &str) {
+std::optional<Identifier> Identifier::parse(const std::string &str) {
   Identifier id;
   // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 36 long: 16 bytes * 2 hex digits / byte + 4 hyphens
   if (str.length() != 36) return {};
diff --git a/libminifi/src/utils/OsUtils.cpp b/libminifi/src/utils/OsUtils.cpp
index 38ab30c..c4bc58f 100644
--- a/libminifi/src/utils/OsUtils.cpp
+++ b/libminifi/src/utils/OsUtils.cpp
@@ -26,8 +26,8 @@
 
 #ifdef __linux__
 #include <sys/sysinfo.h>
+#include <optional>
 #include <sstream>
-#include "utils/OptionalUtils.h"
 #endif
 
 #ifdef _WIN32
@@ -212,8 +212,8 @@ int64_t OsUtils::getSystemPhysicalMemoryUsage() {
   std::ifstream meminfo_file("/proc/meminfo");
   std::string line;
 
-  minifi::utils::optional<uint64_t> total_memory_kByte;
-  minifi::utils::optional<uint64_t> available_memory_kByte;
+  std::optional<uint64_t> total_memory_kByte;
+  std::optional<uint64_t> available_memory_kByte;
   while ((!total_memory_kByte.has_value() || !available_memory_kByte.has_value()) && std::getline(meminfo_file, line)) {
     if (line.rfind(total_memory_prefix, 0) == 0) {
       std::istringstream total_memory_line(line.substr(total_memory_prefix.length()));
@@ -226,7 +226,7 @@ int64_t OsUtils::getSystemPhysicalMemoryUsage() {
     }
   }
   if (total_memory_kByte.has_value() && available_memory_kByte.has_value())
-    return (total_memory_kByte.value() - available_memory_kByte.value()) * 1024;
+    return (gsl::narrow<int64_t>(total_memory_kByte.value()) - gsl::narrow<int64_t>(available_memory_kByte.value())) * 1024;
 
   return -1;
 #elif defined(__APPLE__)
@@ -256,11 +256,11 @@ int64_t OsUtils::getSystemPhysicalMemoryUsage() {
 
 int64_t OsUtils::getSystemTotalPhysicalMemory() {
 #if defined(__linux__)
-  struct sysinfo memory_info;
+  struct sysinfo memory_info{};
   sysinfo(&memory_info);
   uint64_t total_physical_memory = memory_info.totalram;
   total_physical_memory *= memory_info.mem_unit;
-  return total_physical_memory;
+  return gsl::narrow<int64_t>(total_physical_memory);
 #elif defined(__APPLE__)
   int mib[2];
   int64_t total_physical_memory = 0;
diff --git a/libminifi/src/utils/ProcessorConfigUtils.cpp b/libminifi/src/utils/ProcessorConfigUtils.cpp
index 9cbdab5..a423d87 100644
--- a/libminifi/src/utils/ProcessorConfigUtils.cpp
+++ b/libminifi/src/utils/ProcessorConfigUtils.cpp
@@ -48,7 +48,7 @@ std::vector<std::string> listFromRequiredCommaSeparatedProperty(const core::Proc
 
 bool parseBooleanPropertyOrThrow(core::ProcessContext* context, const std::string& property_name) {
   const std::string value_str = getRequiredPropertyOrThrow(context, property_name);
-  utils::optional<bool> maybe_value = utils::StringUtils::toBool(value_str);
+  const auto maybe_value = utils::StringUtils::toBool(value_str);
   if (!maybe_value) {
     throw std::runtime_error(property_name + " property is invalid: value is " + value_str);
   }
@@ -65,12 +65,12 @@ std::chrono::milliseconds parseTimePropertyMSOrThrow(core::ProcessContext* conte
   return std::chrono::milliseconds(time_value_ms);
 }
 
-utils::optional<uint64_t> getOptionalUintProperty(const core::ProcessContext& context, const std::string& property_name) {
+std::optional<uint64_t> getOptionalUintProperty(const core::ProcessContext& context, const std::string& property_name) {
   uint64_t value;
   if (context.getProperty(property_name, value)) {
     return { value };
   }
-  return utils::nullopt;
+  return std::nullopt;
 }
 
 std::string parsePropertyWithAllowableValuesOrThrow(const core::ProcessContext& context, const std::string& property_name, const std::set<std::string>& allowable_values) {
diff --git a/libminifi/src/utils/StringUtils.cpp b/libminifi/src/utils/StringUtils.cpp
index 13667cb..8909ec5 100644
--- a/libminifi/src/utils/StringUtils.cpp
+++ b/libminifi/src/utils/StringUtils.cpp
@@ -17,8 +17,8 @@
 
 #include <limits>
 
+#include "utils/GeneralUtils.h"
 #include "utils/StringUtils.h"
-
 #include "utils/Environment.h"
 
 namespace org {
@@ -27,7 +27,7 @@ namespace nifi {
 namespace minifi {
 namespace utils {
 
-utils::optional<bool> StringUtils::toBool(const std::string& str) {
+std::optional<bool> StringUtils::toBool(const std::string& str) {
   std::string trimmed = trim(str);
   if (equalsIgnoreCase(trimmed, "true")) {
     return true;
@@ -35,7 +35,7 @@ utils::optional<bool> StringUtils::toBool(const std::string& str) {
   if (equalsIgnoreCase(trimmed, "false")) {
     return false;
   }
-  return {};
+  return std::nullopt;
 }
 
 std::string StringUtils::toLower(std::string str) {
diff --git a/libminifi/src/utils/crypto/EncryptionManager.cpp b/libminifi/src/utils/crypto/EncryptionManager.cpp
index 8778bec..635c3e9 100644
--- a/libminifi/src/utils/crypto/EncryptionManager.cpp
+++ b/libminifi/src/utils/crypto/EncryptionManager.cpp
@@ -15,11 +15,11 @@
  * limitations under the License.
  */
 
-#include <string>
 #include <memory>
+#include <optional>
+#include <string>
 #include "utils/crypto/EncryptionManager.h"
 #include "properties/Properties.h"
-#include "utils/OptionalUtils.h"
 #include "utils/StringUtils.h"
 #include "utils/crypto/ciphers/XSalsa20.h"
 #include "utils/crypto/ciphers/Aes256Ecb.h"
@@ -40,22 +40,24 @@ constexpr const char* DEFAULT_NIFI_BOOTSTRAP_FILE = "./conf/bootstrap.conf";
 
 std::shared_ptr<core::logging::Logger> EncryptionManager::logger_{core::logging::LoggerFactory<EncryptionManager>::getLogger()};
 
-utils::optional<XSalsa20Cipher> EncryptionManager::createXSalsa20Cipher(const std::string &key_name) const {
+std::optional<XSalsa20Cipher> EncryptionManager::createXSalsa20Cipher(const std::string &key_name) const {
   return readKey(key_name)
          | utils::map([] (const Bytes& key) {return XSalsa20Cipher{key};});
 }
 
-utils::optional<Aes256EcbCipher> EncryptionManager::createAes256EcbCipher(const std::string &key_name) const {
-  utils::optional<Bytes> key = readKey(key_name);
+std::optional<Aes256EcbCipher> EncryptionManager::createAes256EcbCipher(const std::string &key_name) const {
+  auto key = readKey(key_name);
   if (!key) {
     logger_->log_info("No encryption key found for '%s'", key_name);
-    return {};
+    return std::nullopt;
   }
   if (key->empty()) {
     // generate new key
     logger_->log_info("Generating encryption key '%s'", key_name);
     key = Aes256EcbCipher::generateKey();
-    writeKey(key_name, key.value());
+    if (!writeKey(key_name, key.value())) {
+      logger_->log_warn("Failed to write key '%s'", key_name);
+    }
   } else {
     logger_->log_info("Using existing encryption key '%s'", key_name);
   }
@@ -63,7 +65,7 @@ utils::optional<Aes256EcbCipher> EncryptionManager::createAes256EcbCipher(const
 }
 
 
-utils::optional<Bytes> EncryptionManager::readKey(const std::string& key_name) const {
+std::optional<Bytes> EncryptionManager::readKey(const std::string& key_name) const {
   minifi::Properties bootstrap_conf;
   bootstrap_conf.setHome(key_dir_);
   bootstrap_conf.loadConfigureFile(DEFAULT_NIFI_BOOTSTRAP_FILE);
diff --git a/libminifi/src/utils/crypto/EncryptionProvider.cpp b/libminifi/src/utils/crypto/EncryptionProvider.cpp
index ecc7b48..8b711ed 100644
--- a/libminifi/src/utils/crypto/EncryptionProvider.cpp
+++ b/libminifi/src/utils/crypto/EncryptionProvider.cpp
@@ -30,7 +30,7 @@ namespace crypto {
 
 constexpr const char* CONFIG_ENCRYPTION_KEY_PROPERTY_NAME = "nifi.bootstrap.sensitive.key";
 
-utils::optional<EncryptionProvider> EncryptionProvider::create(const std::string& home_path) {
+std::optional<EncryptionProvider> EncryptionProvider::create(const std::string& home_path) {
   return EncryptionManager{home_path}.createXSalsa20Cipher(CONFIG_ENCRYPTION_KEY_PROPERTY_NAME)
     | utils::map([] (const XSalsa20Cipher& cipher) {return EncryptionProvider{cipher};});
 }
diff --git a/libminifi/src/utils/file/FileSystem.cpp b/libminifi/src/utils/file/FileSystem.cpp
index cbb5f79..acb6265 100644
--- a/libminifi/src/utils/file/FileSystem.cpp
+++ b/libminifi/src/utils/file/FileSystem.cpp
@@ -15,10 +15,9 @@
  * limitations under the License.
  */
 
-#include <string>
 #include <fstream>
+#include <string>
 #include "utils/file/FileSystem.h"
-#include "utils/OptionalUtils.h"
 #include "utils/crypto/EncryptionProvider.h"
 
 namespace org {
@@ -28,7 +27,7 @@ namespace minifi {
 namespace utils {
 namespace file {
 
-FileSystem::FileSystem(bool should_encrypt_on_write, utils::optional<utils::crypto::EncryptionProvider> encryptor)
+FileSystem::FileSystem(bool should_encrypt_on_write, std::optional<utils::crypto::EncryptionProvider> encryptor)
     : should_encrypt_on_write_(should_encrypt_on_write),
       encryptor_(std::move(encryptor)) {
   if (should_encrypt_on_write_ && !encryptor) {
@@ -38,10 +37,10 @@ FileSystem::FileSystem(bool should_encrypt_on_write, utils::optional<utils::cryp
   }
 }
 
-utils::optional<std::string> FileSystem::read(const std::string& file_name) {
+std::optional<std::string> FileSystem::read(const std::string& file_name) {
   std::ifstream input{file_name, std::ios::binary};
   if (!input) {
-    return {};
+    return std::nullopt;
   }
   input.exceptions(std::ios::failbit | std::ios::badbit);
   std::string content{std::istreambuf_iterator<char>(input), {}};
diff --git a/libminifi/src/utils/tls/DistinguishedName.cpp b/libminifi/src/utils/tls/DistinguishedName.cpp
index 229f13b..a68e9b4 100644
--- a/libminifi/src/utils/tls/DistinguishedName.cpp
+++ b/libminifi/src/utils/tls/DistinguishedName.cpp
@@ -42,13 +42,13 @@ DistinguishedName DistinguishedName::fromSlashSeparated(const std::string &slash
   return DistinguishedName{utils::StringUtils::splitRemovingEmpty(slash_separated_components, "/")};
 }
 
-utils::optional<std::string> DistinguishedName::getCN() const {
+std::optional<std::string> DistinguishedName::getCN() const {
   const auto it = std::find_if(components_.begin(), components_.end(),
       [](const std::string& component) { return component.compare(0, 3, "CN=") == 0; });
   if (it != components_.end()) {
     return it->substr(3);
   } else {
-    return utils::nullopt;
+    return std::nullopt;
   }
 }
 
diff --git a/libminifi/test/aws-tests/MockS3RequestSender.h b/libminifi/test/aws-tests/MockS3RequestSender.h
index ce28690..6e4c4b6 100644
--- a/libminifi/test/aws-tests/MockS3RequestSender.h
+++ b/libminifi/test/aws-tests/MockS3RequestSender.h
@@ -18,11 +18,12 @@
 
 #pragma once
 
+#include <map>
+#include <optional>
 #include <string>
 #include <sstream>
-#include <vector>
-#include <map>
 #include <utility>
+#include <vector>
 
 #include "s3/S3RequestSender.h"
 #include "aws/core/utils/DateTime.h"
@@ -90,7 +91,7 @@ class MockS3RequestSender : public minifi::aws::s3::S3RequestSender {
     }
   }
 
-  minifi::utils::optional<Aws::S3::Model::PutObjectResult> sendPutObjectRequest(
+  std::optional<Aws::S3::Model::PutObjectResult> sendPutObjectRequest(
       const Aws::S3::Model::PutObjectRequest& request,
       const Aws::Auth::AWSCredentials& credentials,
       const Aws::Client::ClientConfiguration& client_config) override {
@@ -118,7 +119,7 @@ class MockS3RequestSender : public minifi::aws::s3::S3RequestSender {
     return delete_object_result_;
   }
 
-  minifi::utils::optional<Aws::S3::Model::GetObjectResult> sendGetObjectRequest(
+  std::optional<Aws::S3::Model::GetObjectResult> sendGetObjectRequest(
       const Aws::S3::Model::GetObjectRequest& request,
       const Aws::Auth::AWSCredentials& credentials,
       const Aws::Client::ClientConfiguration& client_config) override {
@@ -137,10 +138,10 @@ class MockS3RequestSender : public minifi::aws::s3::S3RequestSender {
       get_s3_result.SetContentLength(S3_CONTENT.size());
       get_s3_result.SetMetadata(S3_OBJECT_USER_METADATA);
     }
-    return minifi::utils::make_optional(std::move(get_s3_result));
+    return std::make_optional(std::move(get_s3_result));
   }
 
-  minifi::utils::optional<Aws::S3::Model::ListObjectsV2Result> sendListObjectsRequest(
+  std::optional<Aws::S3::Model::ListObjectsV2Result> sendListObjectsRequest(
       const Aws::S3::Model::ListObjectsV2Request& request,
       const Aws::Auth::AWSCredentials& credentials,
       const Aws::Client::ClientConfiguration& client_config) override {
@@ -171,7 +172,7 @@ class MockS3RequestSender : public minifi::aws::s3::S3RequestSender {
     return list_object_result;
   }
 
-  minifi::utils::optional<Aws::S3::Model::ListObjectVersionsResult> sendListVersionsRequest(
+  std::optional<Aws::S3::Model::ListObjectVersionsResult> sendListVersionsRequest(
       const Aws::S3::Model::ListObjectVersionsRequest& request,
       const Aws::Auth::AWSCredentials& credentials,
       const Aws::Client::ClientConfiguration& client_config) override {
@@ -203,7 +204,7 @@ class MockS3RequestSender : public minifi::aws::s3::S3RequestSender {
     return list_version_result;
   }
 
-  minifi::utils::optional<Aws::S3::Model::GetObjectTaggingResult> sendGetObjectTaggingRequest(
+  std::optional<Aws::S3::Model::GetObjectTaggingResult> sendGetObjectTaggingRequest(
       const Aws::S3::Model::GetObjectTaggingRequest& request,
       const Aws::Auth::AWSCredentials& credentials,
       const Aws::Client::ClientConfiguration& client_config) override {
@@ -220,7 +221,7 @@ class MockS3RequestSender : public minifi::aws::s3::S3RequestSender {
     return result;
   }
 
-  minifi::utils::optional<Aws::S3::Model::HeadObjectResult> sendHeadObjectRequest(
+  std::optional<Aws::S3::Model::HeadObjectResult> sendHeadObjectRequest(
       const Aws::S3::Model::HeadObjectRequest& request,
       const Aws::Auth::AWSCredentials& credentials,
       const Aws::Client::ClientConfiguration& client_config) override {
@@ -238,7 +239,7 @@ class MockS3RequestSender : public minifi::aws::s3::S3RequestSender {
       head_s3_result.SetContentLength(S3_CONTENT.size());
       head_s3_result.SetMetadata(S3_OBJECT_USER_METADATA);
     }
-    return minifi::utils::make_optional(std::move(head_s3_result));
+    return std::make_optional(std::move(head_s3_result));
   }
 
   Aws::Auth::AWSCredentials getCredentials() const {
diff --git a/libminifi/test/azure-tests/PutAzureBlobStorageTests.cpp b/libminifi/test/azure-tests/PutAzureBlobStorageTests.cpp
index 98bbee4..f9ba883 100644
--- a/libminifi/test/azure-tests/PutAzureBlobStorageTests.cpp
+++ b/libminifi/test/azure-tests/PutAzureBlobStorageTests.cpp
@@ -16,6 +16,9 @@
  * limitations under the License.
  */
 
+#include <memory>
+#include <optional>
+
 #include "../TestBase.h"
 #include "core/Processor.h"
 #include "processors/PutAzureBlobStorage.h"
@@ -53,7 +56,7 @@ class MockBlobStorage : public minifi::azure::storage::BlobStorage {
     container_name_ = container_name;
   }
 
-  utils::optional<minifi::azure::storage::UploadBlobResult> uploadBlob(const std::string& /*blob_name*/, const uint8_t* buffer, std::size_t buffer_size) override {
+  std::optional<minifi::azure::storage::UploadBlobResult> uploadBlob(const std::string& /*blob_name*/, const uint8_t* buffer, std::size_t buffer_size) override {
     input_data = std::string(buffer, buffer + buffer_size);
     minifi::azure::storage::UploadBlobResult result;
     result.etag = ETAG;
@@ -94,7 +97,7 @@ class PutAzureBlobStorageTestsFixture {
 
     // Build MiNiFi processing graph
     plan = test_controller.createPlan();
-    auto mock_blob_storage = utils::make_unique<MockBlobStorage>();
+    auto mock_blob_storage = std::make_unique<MockBlobStorage>();
     mock_blob_storage_ptr = mock_blob_storage.get();
     put_azure_blob_storage = std::shared_ptr<minifi::azure::processors::PutAzureBlobStorage>(
       new minifi::azure::processors::PutAzureBlobStorage("PutAzureBlobStorage", utils::Identifier(), std::move(mock_blob_storage)));
diff --git a/libminifi/test/flow-tests/TestControllerWithFlow.h b/libminifi/test/flow-tests/TestControllerWithFlow.h
index 6ffe5d9..130fa96 100644
--- a/libminifi/test/flow-tests/TestControllerWithFlow.h
+++ b/libminifi/test/flow-tests/TestControllerWithFlow.h
@@ -50,7 +50,7 @@ class TestControllerWithFlow: public TestController{
     REQUIRE(content_repo->initialize(configuration_));
     std::shared_ptr<minifi::io::StreamFactory> stream_factory = minifi::io::StreamFactory::getInstance(configuration_);
 
-    std::unique_ptr<core::FlowConfiguration> flow = utils::make_unique<core::YamlConfiguration>(prov_repo, ff_repo, content_repo, stream_factory, configuration_, yamlPath);
+    auto flow = std::make_unique<core::YamlConfiguration>(prov_repo, ff_repo, content_repo, stream_factory, configuration_, yamlPath);
     root_ = flow->getRoot();
     controller_ = std::make_shared<minifi::FlowController>(
         prov_repo, ff_repo, configuration_,
diff --git a/libminifi/test/integration/IntegrationBase.h b/libminifi/test/integration/IntegrationBase.h
index 7fb4218..582b0b0 100644
--- a/libminifi/test/integration/IntegrationBase.h
+++ b/libminifi/test/integration/IntegrationBase.h
@@ -20,8 +20,9 @@
 #define DEFAULT_WAITTIME_MSECS 3000
 
 #include <memory>
-#include <utility>
+#include <optional>
 #include <string>
+#include <utility>
 #include "core/logging/Logger.h"
 #include "core/ProcessGroup.h"
 #include "core/yaml/YamlConfiguration.h"
@@ -33,7 +34,6 @@
 #include "core/ConfigurableComponent.h"
 #include "controllers/SSLContextService.h"
 #include "HTTPUtils.h"
-#include "utils/OptionalUtils.h"
 
 class IntegrationBase {
  public:
@@ -41,7 +41,7 @@ class IntegrationBase {
 
   virtual ~IntegrationBase() = default;
 
-  virtual void run(const utils::optional<std::string>& test_file_location = {}, const utils::optional<std::string>& bootstrap_file = {});
+  virtual void run(const std::optional<std::string>& test_file_location = {}, const std::optional<std::string>& bootstrap_file = {});
 
   void setKeyDir(const std::string key_dir) {
     this->key_dir = key_dir;
@@ -102,7 +102,7 @@ void IntegrationBase::configureSecurity() {
   }
 }
 
-void IntegrationBase::run(const utils::optional<std::string>& test_file_location, const utils::optional<std::string>& home_path) {
+void IntegrationBase::run(const std::optional<std::string>& test_file_location, const std::optional<std::string>& home_path) {
   testSetup();
 
   std::shared_ptr<core::Repository> test_repo = std::make_shared<TestRepository>();
diff --git a/libminifi/test/keyvalue-tests/UnorderedMapKeyValueStoreServiceTest.cpp b/libminifi/test/keyvalue-tests/UnorderedMapKeyValueStoreServiceTest.cpp
index 7f875a2..08d6026 100644
--- a/libminifi/test/keyvalue-tests/UnorderedMapKeyValueStoreServiceTest.cpp
+++ b/libminifi/test/keyvalue-tests/UnorderedMapKeyValueStoreServiceTest.cpp
@@ -17,6 +17,7 @@
  */
 
 #define CATCH_CONFIG_RUNNER
+#include <memory>
 #include <string>
 #include "../TestBase.h"
 #include "core/controller/ControllerService.h"
@@ -90,7 +91,7 @@ class UnorderedMapKeyValueStoreServiceTestFixture {
   std::shared_ptr<core::ContentRepository> content_repo = std::make_shared<core::repository::VolatileContentRepository>();
   std::shared_ptr<minifi::io::StreamFactory> stream_factory = minifi::io::StreamFactory::getInstance(configuration);
 
-  std::unique_ptr<core::YamlConfiguration> yaml_config = utils::make_unique<core::YamlConfiguration>(test_repo, test_repo, content_repo, stream_factory, configuration, config_yaml);
+  std::unique_ptr<core::YamlConfiguration> yaml_config = std::make_unique<core::YamlConfiguration>(test_repo, test_repo, content_repo, stream_factory, configuration, config_yaml);
   std::unique_ptr<core::ProcessGroup> process_group;
 
   std::shared_ptr<core::controller::ControllerServiceNode> key_value_store_service_node;
diff --git a/libminifi/test/sql-tests/ExecuteSQLTests.cpp b/libminifi/test/sql-tests/ExecuteSQLTests.cpp
index a819d13..fd1245c 100644
--- a/libminifi/test/sql-tests/ExecuteSQLTests.cpp
+++ b/libminifi/test/sql-tests/ExecuteSQLTests.cpp
@@ -18,6 +18,8 @@
 
 #undef NDEBUG
 
+#include <optional>
+
 #include "SQLTestController.h"
 #include "processors/ExecuteSQL.h"
 #include "Utils.h"
@@ -169,7 +171,7 @@ TEST_CASE("ExecuteSQL honors Max Rows Per Flow File", "[ExecuteSQL5]") {
       processors::ExecuteSQL::FRAGMENT_IDENTIFIER
   }};
 
-  utils::optional<std::string> fragment_id;
+  std::optional<std::string> fragment_id;
 
   auto flow_files = plan->getOutputs({"success", "d"});
   REQUIRE(flow_files.size() == 3);
diff --git a/libminifi/test/sql-tests/FlowFileMatcher.h b/libminifi/test/sql-tests/FlowFileMatcher.h
index f8a0be7..4807cf5 100644
--- a/libminifi/test/sql-tests/FlowFileMatcher.h
+++ b/libminifi/test/sql-tests/FlowFileMatcher.h
@@ -19,10 +19,11 @@
 #pragma once
 
 #include <functional>
-#include <vector>
-#include <string>
 #include <memory>
+#include <optional>
+#include <string>
 #include <utility>
+#include <vector>
 
 #include "../TestBase.h"
 #include "core/FlowFile.h"
@@ -34,14 +35,14 @@ struct AttributeValue {
   explicit AttributeValue(const char* value)
       : value{value} {}
 
-  AttributeValue(std::string value, utils::optional<std::string>& capture)
+  AttributeValue(std::string value, std::optional<std::string>& capture)
       : value{std::move(value)}, capture{&capture} {}
 
   std::string value;
-  utils::optional<std::string>* capture{nullptr};
+  std::optional<std::string>* capture{nullptr};
 };
 
-AttributeValue capture(utils::optional<std::string>& value) {
+AttributeValue capture(std::optional<std::string>& value) {
   return {"", value};
 }
 
diff --git a/libminifi/test/sql-tests/QueryDatabaseTableTests.cpp b/libminifi/test/sql-tests/QueryDatabaseTableTests.cpp
index ce1eb2e..c7678e6 100644
--- a/libminifi/test/sql-tests/QueryDatabaseTableTests.cpp
+++ b/libminifi/test/sql-tests/QueryDatabaseTableTests.cpp
@@ -159,7 +159,7 @@ TEST_CASE("QueryDatabaseTable honors Max Rows Per Flow File and sets output attr
   auto flow_files = plan->getOutputs({"success", "d"});
   REQUIRE(flow_files.size() == 2);
 
-  utils::optional<std::string> fragment_id;
+  std::optional<std::string> fragment_id;
 
   matcher.verify(flow_files[0],
     { AttributeValue("test_table"), AttributeValue("3"), AttributeValue("2"), AttributeValue("0"), capture(fragment_id), AttributeValue("105") },
diff --git a/libminifi/test/sql-tests/SQLTestPlan.h b/libminifi/test/sql-tests/SQLTestPlan.h
index 1e348c9..9fbb8de 100644
--- a/libminifi/test/sql-tests/SQLTestPlan.h
+++ b/libminifi/test/sql-tests/SQLTestPlan.h
@@ -18,12 +18,13 @@
 
 #pragma once
 
-#include <string>
-#include <vector>
-#include <set>
-#include <utility>
 #include <map>
 #include <memory>
+#include <optional>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
 
 #include "../TestBase.h"
 
@@ -54,7 +55,7 @@ class SQLTestPlan {
     return plan_->getContent(flow_file);
   }
 
-  std::shared_ptr<core::FlowFile> addInput(std::initializer_list<std::pair<std::string, std::string>> attributes = {}, const utils::optional<std::string>& content = {}) {
+  std::shared_ptr<core::FlowFile> addInput(std::initializer_list<std::pair<std::string, std::string>> attributes = {}, const std::optional<std::string>& content = {}) {
     auto flow_file = std::make_shared<minifi::FlowFileRecord>();
     for (const auto& attr : attributes) {
       flow_file->setAttribute(attr.first, attr.second);
diff --git a/libminifi/test/sql-tests/mocks/MockConnectors.cpp b/libminifi/test/sql-tests/mocks/MockConnectors.cpp
index f963867..246c814 100644
--- a/libminifi/test/sql-tests/mocks/MockConnectors.cpp
+++ b/libminifi/test/sql-tests/mocks/MockConnectors.cpp
@@ -24,8 +24,6 @@
 #include <string>
 #include <memory>
 
-#include "utils/GeneralUtils.h"
-
 namespace org {
 namespace apache {
 namespace nifi {
@@ -149,13 +147,13 @@ std::unique_ptr<MockRowset> MockRowset::select(const std::vector<std::string>& c
 
   std::unique_ptr<MockRowset> rowset;
   if (cols.empty()) {
-    rowset = utils::make_unique<MockRowset>(column_names_, column_types_);
+    rowset = std::make_unique<MockRowset>(column_names_, column_types_);
   } else {
     std::vector<DataType> col_types;
     for (const auto& col : cols) {
       col_types.push_back(column_types_.at(getColumnIndex(col)));
     }
-    rowset = utils::make_unique<MockRowset>(cols, col_types);
+    rowset = std::make_unique<MockRowset>(cols, col_types);
   }
 
   std::vector<std::string> used_cols = cols.empty() ? column_names_ : cols;
@@ -402,11 +400,11 @@ bool MockODBCConnection::connected(std::string& /*exception*/) const {
 }
 
 std::unique_ptr<sql::Statement> MockODBCConnection::prepareStatement(const std::string& query) const {
-  return utils::make_unique<sql::MockStatement>(query, file_path_);
+  return std::make_unique<sql::MockStatement>(query, file_path_);
 }
 
 std::unique_ptr<Session> MockODBCConnection::getSession() const {
-  return utils::make_unique<sql::MockSession>();
+  return std::make_unique<sql::MockSession>();
 }
 
 } /* namespace sql */
diff --git a/libminifi/test/sql-tests/mocks/MockODBCService.h b/libminifi/test/sql-tests/mocks/MockODBCService.h
index 6b60ab9..ba12a27 100644
--- a/libminifi/test/sql-tests/mocks/MockODBCService.h
+++ b/libminifi/test/sql-tests/mocks/MockODBCService.h
@@ -25,7 +25,6 @@
 #include "services/DatabaseService.h"
 #include "core/Resource.h"
 #include "data/DatabaseConnectors.h"
-#include "utils/GeneralUtils.h"
 
 namespace org {
 namespace apache {
@@ -50,7 +49,7 @@ class MockODBCService : public DatabaseService {
   }
 
   std::unique_ptr<sql::Connection> getConnection() const {
-    return minifi::utils::make_unique<sql::MockODBCConnection>(connection_string_);
+    return std::make_unique<sql::MockODBCConnection>(connection_string_);
   }
 
  private:
diff --git a/libminifi/test/unit/DecryptorTests.cpp b/libminifi/test/unit/DecryptorTests.cpp
index 404c8aa..3893e83 100644
--- a/libminifi/test/unit/DecryptorTests.cpp
+++ b/libminifi/test/unit/DecryptorTests.cpp
@@ -25,12 +25,11 @@ TEST_CASE("Decryptor can decide whether a property is encrypted", "[isValidEncry
   utils::crypto::Bytes encryption_key;
   minifi::Decryptor decryptor{utils::crypto::EncryptionProvider{encryption_key}};
 
-  REQUIRE(minifi::Decryptor::isValidEncryptionMarker(utils::nullopt) == false);
-  REQUIRE(minifi::Decryptor::isValidEncryptionMarker(utils::optional<std::string>{""}) == false);
-  REQUIRE(minifi::Decryptor::isValidEncryptionMarker(utils::optional<std::string>{"plaintext"}) == false);
-  REQUIRE(minifi::Decryptor::isValidEncryptionMarker(utils::optional<std::string>{"AES256-GCM"}) == false);
-  REQUIRE(
-      minifi::Decryptor::isValidEncryptionMarker(utils::optional<std::string>{utils::crypto::EncryptionType::name()}) == true);
+  REQUIRE(minifi::Decryptor::isValidEncryptionMarker(std::nullopt) == false);
+  REQUIRE(minifi::Decryptor::isValidEncryptionMarker(std::optional<std::string>{""}) == false);
+  REQUIRE(minifi::Decryptor::isValidEncryptionMarker(std::optional<std::string>{"plaintext"}) == false);
+  REQUIRE(minifi::Decryptor::isValidEncryptionMarker(std::optional<std::string>{"AES256-GCM"}) == false);
+  REQUIRE(minifi::Decryptor::isValidEncryptionMarker(utils::crypto::EncryptionType::name()) == true);
 }
 
 TEST_CASE("Decryptor can decrypt a property", "[decrypt]") {
@@ -94,11 +93,11 @@ TEST_CASE("Decryptor can decrypt a configuration file", "[decryptSensitiveProper
   configuration.loadConfigureFile("encrypted.minifi.properties");
   REQUIRE(configuration.getConfiguredKeys().size() > 0);
 
-  utils::optional<std::string> passphrase = configuration.get(minifi::Configure::nifi_security_client_pass_phrase);
+  const auto passphrase = configuration.get(minifi::Configure::nifi_security_client_pass_phrase);
   REQUIRE(passphrase);
   REQUIRE(*passphrase == "SpeakFriendAndEnter");
 
-  utils::optional<std::string> password = configuration.get(minifi::Configure::nifi_rest_api_password);
+  const auto password = configuration.get(minifi::Configure::nifi_rest_api_password);
   REQUIRE(password);
   REQUIRE(*password == "OpenSesame");
 
@@ -106,19 +105,19 @@ TEST_CASE("Decryptor can decrypt a configuration file", "[decryptSensitiveProper
   REQUIRE(configuration.get("nifi.c2.agent.identifier", "c2.agent.identifier", agent_identifier));
   REQUIRE(agent_identifier == "TailFileTester-001");
 
-  utils::optional<std::string> unencrypted_property = configuration.get(minifi::Configure::nifi_bored_yield_duration);
+  const auto unencrypted_property = configuration.get(minifi::Configure::nifi_bored_yield_duration);
   REQUIRE(unencrypted_property);
   REQUIRE(*unencrypted_property == "10 millis");
 
-  utils::optional<std::string> nonexistent_property = configuration.get("this.property.does.not.exist");
+  const auto nonexistent_property = configuration.get("this.property.does.not.exist");
   REQUIRE_FALSE(nonexistent_property);
 }
 
 TEST_CASE("Decryptor can be created from a bootstrap file", "[create]") {
-  utils::optional<minifi::Decryptor> valid_decryptor = minifi::Decryptor::create("resources");
+  const auto valid_decryptor = minifi::Decryptor::create("resources");
   REQUIRE(valid_decryptor);
   REQUIRE(valid_decryptor->decrypt("HvbPejGT3ur9/00gXQK/dJCYwaNqhopf||CiXKiNaljSN7VkLXP5zfJnb4+4UcKIG3ddwuVfSPpkRRfT4=") == "SpeakFriendAndEnter");
 
-  utils::optional<minifi::Decryptor> invalid_decryptor = minifi::Decryptor::create("there.is.no.such.directory");
+  const auto invalid_decryptor = minifi::Decryptor::create("there.is.no.such.directory");
   REQUIRE_FALSE(invalid_decryptor);
 }
diff --git a/libminifi/test/unit/FileSystemTests.cpp b/libminifi/test/unit/FileSystemTests.cpp
index 507c98d..e382fb2 100644
--- a/libminifi/test/unit/FileSystemTests.cpp
+++ b/libminifi/test/unit/FileSystemTests.cpp
@@ -16,9 +16,10 @@
  * limitations under the License.
  */
 
-#include <string>
 #include <fstream>
 #include <iterator>
+#include <optional>
+#include <string>
 #include "../TestBase.h"
 #include "utils/file/FileSystem.h"
 
@@ -74,12 +75,12 @@ TEST_CASE_METHOD(FileSystemTest, "Can read encrypted but writes non-encrypted",
 }
 
 TEST_CASE_METHOD(FileSystemTest, "Can't read encrypted file without encryption provider", "[file_system]") {
-  FileSystem fs{false, utils::nullopt};
+  FileSystem fs{false, std::nullopt};
   REQUIRE(fs.read(encrypted_file) != "banana");
 }
 
 TEST_CASE_METHOD(FileSystemTest, "Can read and write unencrypted", "[file_system]") {
-  FileSystem fs{false, utils::nullopt};
+  FileSystem fs{false, std::nullopt};
   fs.write(new_file, "red lorry, yellow lorry");
 
   std::ifstream file{new_file, std::ios::binary};
@@ -88,5 +89,5 @@ TEST_CASE_METHOD(FileSystemTest, "Can read and write unencrypted", "[file_system
 }
 
 TEST_CASE_METHOD(FileSystemTest, "Required to encrypt but no key was provided", "[file_system]") {
-  REQUIRE_THROWS((FileSystem{true, utils::nullopt}));
+  REQUIRE_THROWS((FileSystem{true, std::nullopt}));
 }
diff --git a/libminifi/test/unit/GeneralUtilsTest.cpp b/libminifi/test/unit/GeneralUtilsTest.cpp
index 1d01f33..b75e880 100644
--- a/libminifi/test/unit/GeneralUtilsTest.cpp
+++ b/libminifi/test/unit/GeneralUtilsTest.cpp
@@ -25,13 +25,6 @@
 
 namespace utils = org::apache::nifi::minifi::utils;
 
-static_assert(std::is_same<decltype(utils::make_unique<char16_t>()), std::unique_ptr<char16_t>>::value, "utils::make_unique type must be correct");
-
-TEST_CASE("GeneralUtils::make_unique", "[make_unique]") {
-  const auto pstr = utils::make_unique<std::string>("test string");
-  REQUIRE("test string" == *pstr);
-}
-
 // intdiv_ceil
 static_assert(0 == utils::intdiv_ceil(0, 1), "");
 static_assert(0 == utils::intdiv_ceil(0, 2), "");
@@ -64,77 +57,6 @@ struct does_compile<N, D,
 static_assert(does_compile<2, 3>::value, "does_compile should work");
 static_assert(!does_compile<1, 0>::value, "constexpr division by zero shouldn't compile");
 
-
-TEST_CASE("GeneralUtils::exchange", "[exchange]") {
-  int a = 1;
-  int b = 2;
-  a = utils::exchange(b, 0);
-  REQUIRE(2 == a);
-  REQUIRE(0 == b);
-}
-
-static_assert(std::is_same<decltype(utils::void_t<char16_t>()), void>::value, "utils::void_t single arg must work");
-static_assert(std::is_same<decltype(utils::void_t<int, double, bool, void, char16_t>()), void>::value, "utils::void_t multi arg must work");
-
-TEST_CASE("GeneralUtils::invoke pointer to member function", "[invoke memfnptr]") {
-  const int result{0xc1ca};
-  struct Tester {
-    bool called{};
-    int memfn(const int arg) {
-      REQUIRE(42 == arg);
-      called = true;
-      return result;
-    }
-  };
-
-  // normal
-  REQUIRE(result == utils::invoke(&Tester::memfn, Tester{}, 42));
-
-  // reference_wrapper
-  Tester t2;
-  const auto ref_wrapper = std::ref(t2);
-  REQUIRE(result == utils::invoke(&Tester::memfn, ref_wrapper, 42));
-  REQUIRE(t2.called);
-
-  // pointer
-  Tester t3;
-  REQUIRE(result == utils::invoke(&Tester::memfn, &t3, 42));
-  REQUIRE(t3.called);
-}
-
-TEST_CASE("GeneralUtils::invoke pointer to data member", "[invoke data member]") {
-  struct Times2 {
-    int value;
-    explicit Times2(const int i) :value{i * 2} {}
-  };
-
-  // normal
-  REQUIRE(24 == utils::invoke(&Times2::value, Times2{12}));
-
-  // reference_wrapper
-  Times2 t2{42};
-  const auto ref_wrapper = std::ref(t2);
-  REQUIRE(84 == utils::invoke(&Times2::value, ref_wrapper));
-
-  // pointer
-  Times2 t3{0};
-  REQUIRE(0 == utils::invoke(&Times2::value, &t3));
-}
-
-namespace {
-bool free_function(const bool b) { return b; }
-}  // namespace
-
-TEST_CASE("GeneralUtils::invoke FunctionObject", "[invoke function object]") {
-  REQUIRE(true == utils::invoke(&free_function, true));
-  REQUIRE(false == utils::invoke(&free_function, false));
-
-  const auto int_timesn = [](const int i) { return 3 * i; };
-
-  // invoking lambda
-  REQUIRE(60 == utils::invoke(int_timesn, 20));
-}
-
 TEST_CASE("GeneralUtils::dereference", "[dereference]") {
   const int a = 42;
   const auto* const pa = &a;
diff --git a/libminifi/test/unit/LoggerTests.cpp b/libminifi/test/unit/LoggerTests.cpp
index 8750df7..a2ff302 100644
--- a/libminifi/test/unit/LoggerTests.cpp
+++ b/libminifi/test/unit/LoggerTests.cpp
@@ -114,7 +114,7 @@ TEST_CASE("Test ShortenNames", "[ttl6]") {
 using namespace minifi::io;
 
 std::string decompress(const std::shared_ptr<InputStream>& input) {
-  auto output = utils::make_unique<BufferStream>();
+  auto output = std::make_unique<BufferStream>();
   auto decompressor = std::make_shared<ZlibDecompressStream>(gsl::make_not_null(output.get()));
   minifi::internal::pipe(input, decompressor);
   decompressor->close();
diff --git a/libminifi/test/unit/OptionalTest.cpp b/libminifi/test/unit/OptionalTest.cpp
index 08a0034..3be8870 100644
--- a/libminifi/test/unit/OptionalTest.cpp
+++ b/libminifi/test/unit/OptionalTest.cpp
@@ -22,41 +22,41 @@
 namespace utils = org::apache::nifi::minifi::utils;
 
 TEST_CASE("optional map", "[optional map]") {
-  const auto test1 = utils::make_optional(6) | utils::map([](const int i) { return i * 2; });
+  const auto test1 = std::make_optional(6) | utils::map([](const int i) { return i * 2; });
   REQUIRE(12 == test1.value());
 
-  const auto test2 = utils::optional<int>{} | utils::map([](const int i) { return i * 2; });
+  const auto test2 = std::optional<int>{} | utils::map([](const int i) { return i * 2; });
   REQUIRE(!test2.has_value());
 }
 
 TEST_CASE("optional flatMap", "[optional flat map]") {
   const auto make_intdiv_noremainder = [](const int denom) {
-    return [denom](const int num) { return num % denom == 0 ? utils::make_optional(num / denom) : utils::optional<int>{}; };
+    return [denom](const int num) { return num % denom == 0 ? std::make_optional(num / denom) : std::optional<int>{}; };
   };
 
-  const auto test1 = utils::make_optional(6) | utils::flatMap(make_intdiv_noremainder(3));
+  const auto test1 = std::make_optional(6) | utils::flatMap(make_intdiv_noremainder(3));
   REQUIRE(2 == test1.value());
 
   const auto const_lval_func = make_intdiv_noremainder(4);
-  const auto test2 = utils::optional<int>{} | utils::flatMap(const_lval_func);
+  const auto test2 = std::optional<int>{} | utils::flatMap(const_lval_func);
   REQUIRE(!test2.has_value());
 
   auto mutable_lval_func = make_intdiv_noremainder(3);
-  const auto test3 = utils::make_optional(7) | utils::flatMap(mutable_lval_func);
+  const auto test3 = std::make_optional(7) | utils::flatMap(mutable_lval_func);
   REQUIRE(!test3.has_value());
 }
 
 TEST_CASE("optional orElse", "[optional or else]") {
-  const auto opt_7 = [] { return utils::make_optional(7); };
-  const auto test1 = utils::make_optional(6) | utils::orElse(opt_7);
-  const auto test2 = utils::optional<int>{} | utils::orElse(opt_7);
-  const auto test3 = utils::make_optional(3) | utils::orElse([]{});
-  const auto test4 = utils::optional<int>{} | utils::orElse([]{});
+  const auto opt_7 = [] { return std::make_optional(7); };
+  const auto test1 = std::make_optional(6) | utils::orElse(opt_7);
+  const auto test2 = std::optional<int>{} | utils::orElse(opt_7);
+  const auto test3 = std::make_optional(3) | utils::orElse([]{});
+  const auto test4 = std::optional<int>{} | utils::orElse([]{});
   struct ex : std::exception {};
 
   REQUIRE(6 == test1.value());
   REQUIRE(7 == test2.value());
   REQUIRE(3 == test3.value());
   REQUIRE(!test4);
-  REQUIRE_THROWS_AS(utils::optional<bool>{} | utils::orElse([]{ throw ex{}; }), ex);
+  REQUIRE_THROWS_AS(std::optional<bool>{} | utils::orElse([]{ throw ex{}; }), ex);
 }
diff --git a/libminifi/test/unit/ProcessSessionTests.cpp b/libminifi/test/unit/ProcessSessionTests.cpp
index 06a921e..7c93b20 100644
--- a/libminifi/test/unit/ProcessSessionTests.cpp
+++ b/libminifi/test/unit/ProcessSessionTests.cpp
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+#include <memory>
 #include <string>
 
 #include <catch.hpp>
@@ -31,25 +32,16 @@ REGISTER_RESOURCE(DummyProcessor, "A processor that does nothing.");
 
 class Fixture {
  public:
-  Fixture();
   core::ProcessSession &processSession() { return *process_session_; }
 
  private:
   TestController test_controller_;
-  std::shared_ptr<TestPlan> test_plan_;
-  std::shared_ptr<core::Processor> dummy_processor_;
-  std::shared_ptr<core::ProcessContext> context_;
-  std::unique_ptr<core::ProcessSession> process_session_;
+  std::shared_ptr<TestPlan> test_plan_ = test_controller_.createPlan();
+  std::shared_ptr<core::Processor> dummy_processor_ = test_plan_->addProcessor("DummyProcessor", "dummyProcessor");
+  std::shared_ptr<core::ProcessContext> context_ = [this] { test_plan_->runNextProcessor(); return test_plan_->getCurrentContext(); }();
+  std::unique_ptr<core::ProcessSession> process_session_ = std::make_unique<core::ProcessSession>(context_);
 };
 
-Fixture::Fixture() {
-  test_plan_ = test_controller_.createPlan();
-  dummy_processor_ = test_plan_->addProcessor("DummyProcessor", "dummyProcessor");
-  test_plan_->runNextProcessor();  // set the dummy processor as current
-  context_ = test_plan_->getCurrentContext();
-  process_session_ = utils::make_unique<core::ProcessSession>(context_);
-}
-
 const core::Relationship Success{"success", "everything is fine"};
 const core::Relationship Failure{"failure", "something has gone awry"};
 
diff --git a/libminifi/test/unit/StringUtilsTests.cpp b/libminifi/test/unit/StringUtilsTests.cpp
index 38b2f83..307050e 100644
--- a/libminifi/test/unit/StringUtilsTests.cpp
+++ b/libminifi/test/unit/StringUtilsTests.cpp
@@ -16,13 +16,14 @@
  * limitations under the License.
  */
 
-#include <string>
-#include <list>
-#include <vector>
-#include <cstdlib>
-#include <random>
 #include <algorithm>
 #include <cstdint>
+#include <cstdlib>
+#include <list>
+#include <optional>
+#include <random>
+#include <string>
+#include <vector>
 #include "../TestBase.h"
 #include "core/Core.h"
 #include "utils/StringUtils.h"
@@ -219,7 +220,7 @@ TEST_CASE("TestStringUtils::endsWith", "[test endsWith]") {
 }
 
 TEST_CASE("TestStringUtils::toBool", "[test toBool]") {
-  std::vector<std::pair<std::string, utils::optional<bool>>> cases{
+  std::vector<std::pair<std::string, std::optional<bool>>> cases{
       {"", {}},
       {"true", true},
       {"false", false},
diff --git a/main/MiNiFiMain.cpp b/main/MiNiFiMain.cpp
index 4204ab1..c8061f1 100644
--- a/main/MiNiFiMain.cpp
+++ b/main/MiNiFiMain.cpp
@@ -44,8 +44,9 @@
 #include <sodium.h>
 
 #include <cstdlib>
-#include <vector>
 #include <iostream>
+#include <memory>
+#include <vector>
 
 #include "ResourceClaim.h"
 #include "core/Core.h"
@@ -208,14 +209,14 @@ int main(int argc, char **argv) {
   // Make a record of minifi home in the configured log file.
   logger->log_info("MINIFI_HOME=%s", minifiHome);
 
-  utils::optional<minifi::Decryptor> decryptor = minifi::Decryptor::create(minifiHome);
+  auto decryptor = minifi::Decryptor::create(minifiHome);
   if (decryptor) {
     logger->log_info("Found encryption key, will decrypt sensitive properties in the configuration");
   } else {
     logger->log_info("No encryption key found, will not decrypt sensitive properties in the configuration");
   }
 
-  const std::shared_ptr<minifi::Configure> configure = std::make_shared<minifi::Configure>(decryptor);
+  const std::shared_ptr<minifi::Configure> configure = std::make_shared<minifi::Configure>(std::move(decryptor));
   configure->setHome(minifiHome);
   configure->loadConfigureFile(DEFAULT_NIFI_PROPERTIES_FILE);
 
@@ -337,7 +338,7 @@ int main(int argc, char **argv) {
         return -1;
       }
       auto interval_switch = minifi::disk_space_watchdog::disk_space_interval_switch(config);
-      disk_space_watchdog = utils::make_unique<utils::CallBackTimer>(config.interval, [interval_switch, min_space, repo_paths, logger, &controller]() mutable {
+      disk_space_watchdog = std::make_unique<utils::CallBackTimer>(config.interval, [interval_switch, min_space, repo_paths, logger, &controller]() mutable {
         const auto stop = [&]{ controller->stop(); controller->unload(); };
         const auto restart = [&]{ controller->load(); controller->start(); };
         const auto switch_state = interval_switch(min_space(minifi::disk_space_watchdog::check_available_space(repo_paths, logger.get())));
diff --git a/thirdparty/optional-lite-3.2.0/LICENSE.txt b/thirdparty/optional-lite-3.2.0/LICENSE.txt
deleted file mode 100644
index 36b7cd9..0000000
--- a/thirdparty/optional-lite-3.2.0/LICENSE.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Boost Software License - Version 1.0 - August 17th, 2003
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/thirdparty/optional-lite-3.2.0/include/nonstd/optional.hpp b/thirdparty/optional-lite-3.2.0/include/nonstd/optional.hpp
deleted file mode 100644
index 33a9b98..0000000
--- a/thirdparty/optional-lite-3.2.0/include/nonstd/optional.hpp
+++ /dev/null
@@ -1,1698 +0,0 @@
-//
-// Copyright (c) 2014-2018 Martin Moene
-//
-// https://github.com/martinmoene/optional-lite
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#pragma once
-
-#ifndef NONSTD_OPTIONAL_LITE_HPP
-#define NONSTD_OPTIONAL_LITE_HPP
-
-#define optional_lite_MAJOR  3
-#define optional_lite_MINOR  2
-#define optional_lite_PATCH  0
-
-#define optional_lite_VERSION  optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY(optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH)
-
-#define optional_STRINGIFY(  x )  optional_STRINGIFY_( x )
-#define optional_STRINGIFY_( x )  #x
-
-// optional-lite configuration:
-
-#define optional_OPTIONAL_DEFAULT  0
-#define optional_OPTIONAL_NONSTD   1
-#define optional_OPTIONAL_STD      2
-
-#if !defined( optional_CONFIG_SELECT_OPTIONAL )
-# define optional_CONFIG_SELECT_OPTIONAL  ( optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD : optional_OPTIONAL_NONSTD )
-#endif
-
-// Control presence of exception handling (try and auto discover):
-
-#ifndef optional_CONFIG_NO_EXCEPTIONS
-# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
-#  define optional_CONFIG_NO_EXCEPTIONS  0
-# else
-#  define optional_CONFIG_NO_EXCEPTIONS  1
-# endif
-#endif
-
-// C++ language version detection (C++20 is speculative):
-// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
-
-#ifndef   optional_CPLUSPLUS
-# if defined(_MSVC_LANG ) && !defined(__clang__)
-#  define optional_CPLUSPLUS  (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
-# else
-#  define optional_CPLUSPLUS  __cplusplus
-# endif
-#endif
-
-#define optional_CPP98_OR_GREATER  ( optional_CPLUSPLUS >= 199711L )
-#define optional_CPP11_OR_GREATER  ( optional_CPLUSPLUS >= 201103L )
-#define optional_CPP11_OR_GREATER_ ( optional_CPLUSPLUS >= 201103L )
-#define optional_CPP14_OR_GREATER  ( optional_CPLUSPLUS >= 201402L )
-#define optional_CPP17_OR_GREATER  ( optional_CPLUSPLUS >= 201703L )
-#define optional_CPP20_OR_GREATER  ( optional_CPLUSPLUS >= 202000L )
-
-// C++ language version (represent 98 as 3):
-
-#define optional_CPLUSPLUS_V  ( optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994) )
-
-// Use C++17 std::optional if available and requested:
-
-#if optional_CPP17_OR_GREATER && defined(__has_include )
-# if __has_include( <optional> )
-#  define optional_HAVE_STD_OPTIONAL  1
-# else
-#  define optional_HAVE_STD_OPTIONAL  0
-# endif
-#else
-# define  optional_HAVE_STD_OPTIONAL  0
-#endif
-
-#define optional_USES_STD_OPTIONAL  ( (optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_STD) || ((optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_DEFAULT) && optional_HAVE_STD_OPTIONAL) )
-
-//
-// in_place: code duplicated in any-lite, expected-lite, optional-lite, value-ptr-lite, variant-lite:
-//
-
-#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
-#define nonstd_lite_HAVE_IN_PLACE_TYPES  1
-
-// C++17 std::in_place in <utility>:
-
-#if optional_CPP17_OR_GREATER
-
-#include <utility>
-
-namespace nonstd {
-
-using std::in_place;
-using std::in_place_type;
-using std::in_place_index;
-using std::in_place_t;
-using std::in_place_type_t;
-using std::in_place_index_t;
-
-#define nonstd_lite_in_place_t(      T)  std::in_place_t
-#define nonstd_lite_in_place_type_t( T)  std::in_place_type_t<T>
-#define nonstd_lite_in_place_index_t(K)  std::in_place_index_t<K>
-
-#define nonstd_lite_in_place(      T)    std::in_place_t{}
-#define nonstd_lite_in_place_type( T)    std::in_place_type_t<T>{}
-#define nonstd_lite_in_place_index(K)    std::in_place_index_t<K>{}
-
-} // namespace nonstd
-
-#else // optional_CPP17_OR_GREATER
-
-#include <cstddef>
-
-namespace nonstd {
-namespace detail {
-
-template< class T >
-struct in_place_type_tag {};
-
-template< std::size_t K >
-struct in_place_index_tag {};
-
-} // namespace detail
-
-struct in_place_t {};
-
-template< class T >
-inline in_place_t in_place( detail::in_place_type_tag<T> /*unused*/ = detail::in_place_type_tag<T>() )
-{
-    return in_place_t();
-}
-
-template< std::size_t K >
-inline in_place_t in_place( detail::in_place_index_tag<K> /*unused*/ = detail::in_place_index_tag<K>() )
-{
-    return in_place_t();
-}
-
-template< class T >
-inline in_place_t in_place_type( detail::in_place_type_tag<T> /*unused*/ = detail::in_place_type_tag<T>() )
-{
-    return in_place_t();
-}
-
-template< std::size_t K >
-inline in_place_t in_place_index( detail::in_place_index_tag<K> /*unused*/ = detail::in_place_index_tag<K>() )
-{
-    return in_place_t();
-}
-
-// mimic templated typedef:
-
-#define nonstd_lite_in_place_t(      T)  nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T>  )
-#define nonstd_lite_in_place_type_t( T)  nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T>  )
-#define nonstd_lite_in_place_index_t(K)  nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
-
-#define nonstd_lite_in_place(      T)    nonstd::in_place_type<T>
-#define nonstd_lite_in_place_type( T)    nonstd::in_place_type<T>
-#define nonstd_lite_in_place_index(K)    nonstd::in_place_index<K>
-
-} // namespace nonstd
-
-#endif // optional_CPP17_OR_GREATER
-#endif // nonstd_lite_HAVE_IN_PLACE_TYPES
-
-//
-// Using std::optional:
-//
-
-#if optional_USES_STD_OPTIONAL
-
-#include <optional>
-
-namespace nonstd {
-
-    using std::optional;
-    using std::bad_optional_access;
-    using std::hash;
-
-    using std::nullopt;
-    using std::nullopt_t;
-
-    using std::operator==;
-    using std::operator!=;
-    using std::operator<;
-    using std::operator<=;
-    using std::operator>;
-    using std::operator>=;
-    using std::make_optional;
-    using std::swap;
-}
-
-#else // optional_USES_STD_OPTIONAL
-
-#include <cassert>
-#include <utility>
-
-// optional-lite alignment configuration:
-
-#ifndef  optional_CONFIG_MAX_ALIGN_HACK
-# define optional_CONFIG_MAX_ALIGN_HACK  0
-#endif
-
-#ifndef  optional_CONFIG_ALIGN_AS
-// no default, used in #if defined()
-#endif
-
-#ifndef  optional_CONFIG_ALIGN_AS_FALLBACK
-# define optional_CONFIG_ALIGN_AS_FALLBACK  double
-#endif
-
-// Compiler warning suppression:
-
-#if defined(__clang__)
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wundef"
-#elif defined(__GNUC__)
-# pragma GCC   diagnostic push
-# pragma GCC   diagnostic ignored "-Wundef"
-#elif defined(_MSC_VER )
-# pragma warning( push )
-#endif
-
-// half-open range [lo..hi):
-#define optional_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
-
-// Compiler versions:
-//
-// MSVC++ 6.0  _MSC_VER == 1200 (Visual Studio 6.0)
-// MSVC++ 7.0  _MSC_VER == 1300 (Visual Studio .NET 2002)
-// MSVC++ 7.1  _MSC_VER == 1310 (Visual Studio .NET 2003)
-// MSVC++ 8.0  _MSC_VER == 1400 (Visual Studio 2005)
-// MSVC++ 9.0  _MSC_VER == 1500 (Visual Studio 2008)
-// MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
-// MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
-// MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
-// MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
-// MSVC++ 14.1 _MSC_VER >= 1910 (Visual Studio 2017)
-
-#if defined(_MSC_VER ) && !defined(__clang__)
-# define optional_COMPILER_MSVC_VER      (_MSC_VER )
-# define optional_COMPILER_MSVC_VERSION  (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
-#else
-# define optional_COMPILER_MSVC_VER      0
-# define optional_COMPILER_MSVC_VERSION  0
-#endif
-
-#define optional_COMPILER_VERSION( major, minor, patch )  ( 10 * (10 * (major) + (minor) ) + (patch) )
-
-#if defined(__GNUC__) && !defined(__clang__)
-# define optional_COMPILER_GNUC_VERSION   optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
-#else
-# define optional_COMPILER_GNUC_VERSION   0
-#endif
-
-#if defined(__clang__)
-# define optional_COMPILER_CLANG_VERSION  optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
-#else
-# define optional_COMPILER_CLANG_VERSION  0
-#endif
-
-#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 )
-# pragma warning( disable: 4345 )   // initialization behavior changed
-#endif
-
-#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 )
-# pragma warning( disable: 4814 )   // in C++14 'constexpr' will not imply 'const'
-#endif
-
-// Presence of language and library features:
-
-#define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE )
-
-#ifdef _HAS_CPP0X
-# define optional_HAS_CPP0X  _HAS_CPP0X
-#else
-# define optional_HAS_CPP0X  0
-#endif
-
-// Unless defined otherwise below, consider VC14 as C++11 for optional-lite:
-
-#if optional_COMPILER_MSVC_VER >= 1900
-# undef  optional_CPP11_OR_GREATER
-# define optional_CPP11_OR_GREATER  1
-#endif
-
-#define optional_CPP11_90   (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1500)
-#define optional_CPP11_100  (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1600)
-#define optional_CPP11_110  (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1700)
-#define optional_CPP11_120  (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1800)
-#define optional_CPP11_140  (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1900)
-#define optional_CPP11_141  (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1910)
-
-#define optional_CPP14_000  (optional_CPP14_OR_GREATER)
-#define optional_CPP17_000  (optional_CPP17_OR_GREATER)
-
-// Presence of C++11 language features:
-
-#define optional_HAVE_CONSTEXPR_11      optional_CPP11_140
-#define optional_HAVE_IS_DEFAULT        optional_CPP11_140
-#define optional_HAVE_NOEXCEPT          optional_CPP11_140
-#define optional_HAVE_NULLPTR           optional_CPP11_100
-#define optional_HAVE_REF_QUALIFIER     optional_CPP11_140
-
-// Presence of C++14 language features:
-
-#define optional_HAVE_CONSTEXPR_14      optional_CPP14_000
-
-// Presence of C++17 language features:
-
-#define optional_HAVE_NODISCARD         optional_CPP17_000
-
-// Presence of C++ library features:
-
-#define optional_HAVE_CONDITIONAL       optional_CPP11_120
-#define optional_HAVE_REMOVE_CV         optional_CPP11_120
-#define optional_HAVE_TYPE_TRAITS       optional_CPP11_90
-
-#define optional_HAVE_TR1_TYPE_TRAITS   (!! optional_COMPILER_GNUC_VERSION )
-#define optional_HAVE_TR1_ADD_POINTER   (!! optional_COMPILER_GNUC_VERSION )
-
-// C++ feature usage:
-
-#if optional_HAVE( CONSTEXPR_11 )
-# define optional_constexpr  constexpr
-#else
-# define optional_constexpr  /*constexpr*/
-#endif
-
-#if optional_HAVE( IS_DEFAULT )
-# define optional_is_default  = default;
-#else
-# define optional_is_default  {}
-#endif
-
-#if optional_HAVE( CONSTEXPR_14 )
-# define optional_constexpr14  constexpr
-#else
-# define optional_constexpr14  /*constexpr*/
-#endif
-
-#if optional_HAVE( NODISCARD )
-# define optional_nodiscard  [[nodiscard]]
-#else
-# define optional_nodiscard  /*[[nodiscard]]*/
-#endif
-
-#if optional_HAVE( NOEXCEPT )
-# define optional_noexcept  noexcept
-#else
-# define optional_noexcept  /*noexcept*/
-#endif
-
-#if optional_HAVE( NULLPTR )
-# define optional_nullptr  nullptr
-#else
-# define optional_nullptr  NULL
-#endif
-
-#if optional_HAVE( REF_QUALIFIER )
-// NOLINTNEXTLINE( bugprone-macro-parentheses )
-# define optional_ref_qual  &
-# define optional_refref_qual  &&
-#else
-# define optional_ref_qual  /*&*/
-# define optional_refref_qual  /*&&*/
-#endif
-
-// additional includes:
-
-#if optional_CONFIG_NO_EXCEPTIONS
-// already included: <cassert>
-#else
-# include <stdexcept>
-#endif
-
-#if optional_CPP11_OR_GREATER
-# include <functional>
-#endif
-
-#if optional_HAVE( INITIALIZER_LIST )
-# include <initializer_list>
-#endif
-
-#if optional_HAVE( TYPE_TRAITS )
-# include <type_traits>
-#elif optional_HAVE( TR1_TYPE_TRAITS )
-# include <tr1/type_traits>
-#endif
-
-// Method enabling
-
-#if optional_CPP11_OR_GREATER
-
-#define optional_REQUIRES_0(...) \
-    template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
-
-#define optional_REQUIRES_T(...) \
-    , typename = typename std::enable_if< (__VA_ARGS__), nonstd::optional_lite::detail::enabler >::type
-
-#define optional_REQUIRES_R(R, ...) \
-    typename std::enable_if< (__VA_ARGS__), R>::type
-
-#define optional_REQUIRES_A(...) \
-    , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr
-
-#endif
-
-//
-// optional:
-//
-
-namespace nonstd { namespace optional_lite {
-
-namespace std11 {
-
-#if optional_CPP11_OR_GREATER
-    using std::move;
-#else
-    template< typename T > T & move( T & t ) { return t; }
-#endif
-
-#if optional_HAVE( CONDITIONAL )
-    using std::conditional;
-#else
-    template< bool B, typename T, typename F > struct conditional              { typedef T type; };
-    template<         typename T, typename F > struct conditional<false, T, F> { typedef F type; };
-#endif // optional_HAVE_CONDITIONAL
-
-} // namespace std11
-
-#if optional_CPP11_OR_GREATER
-
-/// type traits C++17:
-
-namespace std17 {
-
-#if optional_CPP17_OR_GREATER
-
-using std::is_swappable;
-using std::is_nothrow_swappable;
-
-#elif optional_CPP11_OR_GREATER
-
-namespace detail {
-
-using std::swap;
-
-struct is_swappable
-{
-    template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
-    static std::true_type test( int /*unused*/ );
-
-    template< typename >
-    static std::false_type test(...);
-};
-
-struct is_nothrow_swappable
-{
-    // wrap noexcept(expr) in separate function as work-around for VC140 (VS2015):
-
-    template< typename T >
-    static constexpr bool satisfies()
-    {
-        return noexcept( swap( std::declval<T&>(), std::declval<T&>() ) );
-    }
-
-    template< typename T >
-    static auto test( int /*unused*/ ) -> std::integral_constant<bool, satisfies<T>()>{}
-
-    template< typename >
-    static auto test(...) -> std::false_type;
-};
-
-} // namespace detail
-
-// is [nothow] swappable:
-
-template< typename T >
-struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
-
-template< typename T >
-struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
-
-#endif // optional_CPP17_OR_GREATER
-
-} // namespace std17
-
-/// type traits C++20:
-
-namespace std20 {
-
-template< typename T >
-struct remove_cvref
-{
-    typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
-};
-
-} // namespace std20
-
-#endif // optional_CPP11_OR_GREATER
-
-/// class optional
-
-template< typename T >
-class optional;
-
-namespace detail {
-
-// for optional_REQUIRES_T
-
-#if optional_CPP11_OR_GREATER
-enum class enabler{};
-#endif
-
-// C++11 emulation:
-
-struct nulltype{};
-
-template< typename Head, typename Tail >
-struct typelist
-{
-    typedef Head head;
-    typedef Tail tail;
-};
-
-#if optional_CONFIG_MAX_ALIGN_HACK
-
-// Max align, use most restricted type for alignment:
-
-#define optional_UNIQUE(  name )       optional_UNIQUE2( name, __LINE__ )
-#define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line )
-#define optional_UNIQUE3( name, line ) name ## line
-
-#define optional_ALIGN_TYPE( type ) \
-    type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st )
-
-template< typename T >
-struct struct_t { T _; };
-
-union max_align_t
-{
-    optional_ALIGN_TYPE( char );
-    optional_ALIGN_TYPE( short int );
-    optional_ALIGN_TYPE( int );
-    optional_ALIGN_TYPE( long int  );
-    optional_ALIGN_TYPE( float  );
-    optional_ALIGN_TYPE( double );
-    optional_ALIGN_TYPE( long double );
-    optional_ALIGN_TYPE( char * );
-    optional_ALIGN_TYPE( short int * );
-    optional_ALIGN_TYPE( int *  );
-    optional_ALIGN_TYPE( long int * );
-    optional_ALIGN_TYPE( float * );
-    optional_ALIGN_TYPE( double * );
-    optional_ALIGN_TYPE( long double * );
-    optional_ALIGN_TYPE( void * );
-
-#ifdef HAVE_LONG_LONG
-    optional_ALIGN_TYPE( long long );
-#endif
-
-    struct Unknown;
-
-    Unknown ( * optional_UNIQUE(_) )( Unknown );
-    Unknown * Unknown::* optional_UNIQUE(_);
-    Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown );
-
-    struct_t< Unknown ( * )( Unknown)         > optional_UNIQUE(_);
-    struct_t< Unknown * Unknown::*            > optional_UNIQUE(_);
-    struct_t< Unknown ( Unknown::* )(Unknown) > optional_UNIQUE(_);
-};
-
-#undef optional_UNIQUE
-#undef optional_UNIQUE2
-#undef optional_UNIQUE3
-
-#undef optional_ALIGN_TYPE
-
-#elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK
-
-// Use user-specified type for alignment:
-
-#define optional_ALIGN_AS( unused ) \
-    optional_CONFIG_ALIGN_AS
-
-#else // optional_CONFIG_MAX_ALIGN_HACK
-
-// Determine POD type to use for alignment:
-
-#define optional_ALIGN_AS( to_align ) \
-    typename type_of_size< alignment_types, alignment_of< to_align >::value >::type
-
-template< typename T >
-struct alignment_of;
-
-template< typename T >
-struct alignment_of_hack
-{
-    char c;
-    T t;
-    alignment_of_hack();
-};
-
-template< size_t A, size_t S >
-struct alignment_logic
-{
-    enum { value = A < S ? A : S };
-};
-
-template< typename T >
-struct alignment_of
-{
-    enum { value = alignment_logic<
-        sizeof( alignment_of_hack<T> ) - sizeof(T), sizeof(T) >::value };
-};
-
-template< typename List, size_t N >
-struct type_of_size
-{
-    typedef typename std11::conditional<
-        N == sizeof( typename List::head ),
-            typename List::head,
-            typename type_of_size<typename List::tail, N >::type >::type type;
-};
-
-template< size_t N >
-struct type_of_size< nulltype, N >
-{
-    typedef optional_CONFIG_ALIGN_AS_FALLBACK type;
-};
-
-template< typename T>
-struct struct_t { T _; };
-
-#define optional_ALIGN_TYPE( type ) \
-    typelist< type , typelist< struct_t< type >
-
-struct Unknown;
-
-typedef
-    optional_ALIGN_TYPE( char ),
-    optional_ALIGN_TYPE( short ),
-    optional_ALIGN_TYPE( int ),
-    optional_ALIGN_TYPE( long ),
-    optional_ALIGN_TYPE( float ),
-    optional_ALIGN_TYPE( double ),
-    optional_ALIGN_TYPE( long double ),
-
-    optional_ALIGN_TYPE( char *),
-    optional_ALIGN_TYPE( short * ),
-    optional_ALIGN_TYPE( int * ),
-    optional_ALIGN_TYPE( long * ),
-    optional_ALIGN_TYPE( float * ),
-    optional_ALIGN_TYPE( double * ),
-    optional_ALIGN_TYPE( long double * ),
-
-    optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ),
-    optional_ALIGN_TYPE( Unknown * Unknown::*     ),
-    optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ),
-
-    nulltype
-    > > > > > > >    > > > > > > >
-    > > > > > > >    > > > > > > >
-    > > > > > >
-    alignment_types;
-
-#undef optional_ALIGN_TYPE
-
-#endif // optional_CONFIG_MAX_ALIGN_HACK
-
-/// C++03 constructed union to hold value.
-
-template< typename T >
-union storage_t
-{
-//private:
-//    template< typename > friend class optional;
-
-    typedef T value_type;
-
-    storage_t() optional_is_default
-
-    explicit storage_t( value_type const & v )
-    {
-        construct_value( v );
-    }
-
-    void construct_value( value_type const & v )
-    {
-        ::new( value_ptr() ) value_type( v );
-    }
-
-#if optional_CPP11_OR_GREATER
-
-    explicit storage_t( value_type && v )
-    {
-        construct_value( std::move( v ) );
-    }
-
-    void construct_value( value_type && v )
-    {
-        ::new( value_ptr() ) value_type( std::move( v ) );
-    }
-
-    template< class... Args >
-    void emplace( Args&&... args )
-    {
-        ::new( value_ptr() ) value_type( std::forward<Args>(args)... );
-    }
-
-    template< class U, class... Args >
-    void emplace( std::initializer_list<U> il, Args&&... args )
-    {
-        ::new( value_ptr() ) value_type( il, std::forward<Args>(args)... );
-    }
-
-#endif
-
-    void destruct_value()
-    {
-        value_ptr()->~T();
-    }
-
-    optional_nodiscard value_type const * value_ptr() const
-    {
-        return as<value_type>();
-    }
-
-    value_type * value_ptr()
-    {
-        return as<value_type>();
-    }
-
-    optional_nodiscard value_type const & value() const optional_ref_qual
-    {
-        return * value_ptr();
-    }
-
-    value_type & value() optional_ref_qual
-    {
-        return * value_ptr();
-    }
-
-#if optional_CPP11_OR_GREATER
-
-    optional_nodiscard value_type const && value() const optional_refref_qual
-    {
-        return std::move( value() );
-    }
-
-    value_type && value() optional_refref_qual
-    {
-        return std::move( value() );
-    }
-
-#endif
-
-#if optional_CPP11_OR_GREATER
-
-    using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type;
-    aligned_storage_t data;
-
-#elif optional_CONFIG_MAX_ALIGN_HACK
-
-    typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t;
-
-    max_align_t hack;
-    aligned_storage_t data;
-
-#else
-    typedef optional_ALIGN_AS(value_type) align_as_type;
-
-    typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t;
-    aligned_storage_t data;
-
-#   undef optional_ALIGN_AS
-
-#endif // optional_CONFIG_MAX_ALIGN_HACK
-
-    optional_nodiscard void * ptr() optional_noexcept
-    {
-        return &data;
-    }
-
-    optional_nodiscard void const * ptr() const optional_noexcept
-    {
-        return &data;
-    }
-
-    template <typename U>
-    optional_nodiscard U * as()
-    {
-        return reinterpret_cast<U*>( ptr() );
-    }
-
-    template <typename U>
-    optional_nodiscard U const * as() const
-    {
-        return reinterpret_cast<U const *>( ptr() );
-    }
-};
-
-} // namespace detail
-
-/// disengaged state tag
-
-struct nullopt_t
-{
-    struct init{};
-    explicit optional_constexpr nullopt_t( init /*unused*/ ) optional_noexcept {}
-};
-
-#if optional_HAVE( CONSTEXPR_11 )
-constexpr nullopt_t nullopt{ nullopt_t::init{} };
-#else
-// extra parenthesis to prevent the most vexing parse:
-const nullopt_t nullopt(( nullopt_t::init() ));
-#endif
-
-/// optional access error
-
-#if ! optional_CONFIG_NO_EXCEPTIONS
-
-class bad_optional_access : public std::logic_error
-{
-public:
-  explicit bad_optional_access()
-  : logic_error( "bad optional access" ) {}
-};
-
-#endif //optional_CONFIG_NO_EXCEPTIONS
-
-/// optional
-
-template< typename T>
-class optional
-{
-private:
-    template< typename > friend class optional;
-
-    typedef void (optional::*safe_bool)() const;
-
-public:
-    typedef T value_type;
-
-    // x.x.3.1, constructors
-
-    // 1a - default construct
-    optional_constexpr optional() optional_noexcept
-    : has_value_( false )
-    , contained()
-    {}
-
-    // 1b - construct explicitly empty
-    // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
-    optional_constexpr optional( nullopt_t /*unused*/ ) optional_noexcept
-    : has_value_( false )
-    , contained()
-    {}
-
-    // 2 - copy-construct
-    optional_constexpr14 optional( optional const & other
-#if optional_CPP11_OR_GREATER
-        optional_REQUIRES_A(
-            true || std::is_copy_constructible<T>::value
-        )
-#endif
-    )
-    : has_value_( other.has_value() )
-    {
-        if ( other.has_value() )
-        {
-            contained.construct_value( other.contained.value() );
-        }
-    }
-
-#if optional_CPP11_OR_GREATER
-
-    // 3 (C++11) - move-construct from optional
-    optional_constexpr14 optional( optional && other
-        optional_REQUIRES_A(
-            true || std::is_move_constructible<T>::value
-        )
-        // NOLINTNEXTLINE( performance-noexcept-move-constructor )
-    ) noexcept( std::is_nothrow_move_constructible<T>::value )
-    : has_value_( other.has_value() )
-    {
-        if ( other.has_value() )
-        {
-            contained.construct_value( std::move( other.contained.value() ) );
-        }
-    }
-
-    // 4a (C++11) - explicit converting copy-construct from optional
-    template< typename U >
-    explicit optional( optional<U> const & other
-        optional_REQUIRES_A(
-            std::is_constructible<T, U const &>::value
-            && !std::is_constructible<T, optional<U> &          >::value
-            && !std::is_constructible<T, optional<U> &&         >::value
-            && !std::is_constructible<T, optional<U> const &    >::value
-            && !std::is_constructible<T, optional<U> const &&   >::value
-            && !std::is_convertible<     optional<U> &       , T>::value
-            && !std::is_convertible<     optional<U> &&      , T>::value
-            && !std::is_convertible<     optional<U> const & , T>::value
-            && !std::is_convertible<     optional<U> const &&, T>::value
-            && !std::is_convertible<               U const & , T>::value /*=> explicit */
-        )
-    )
-    : has_value_( other.has_value() )
-    {
-        if ( other.has_value() )
-        {
-            contained.construct_value( T{ other.contained.value() } );
-        }
-    }
-#endif // optional_CPP11_OR_GREATER
-
-    // 4b (C++98 and later) - non-explicit converting copy-construct from optional
-    template< typename U >
-    // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
-    optional( optional<U> const & other
-#if optional_CPP11_OR_GREATER
-        optional_REQUIRES_A(
-            std::is_constructible<T, U const &>::value
-            && !std::is_constructible<T, optional<U> &          >::value
-            && !std::is_constructible<T, optional<U> &&         >::value
-            && !std::is_constructible<T, optional<U> const &    >::value
-            && !std::is_constructible<T, optional<U> const &&   >::value
-            && !std::is_convertible<     optional<U> &       , T>::value
-            && !std::is_convertible<     optional<U> &&      , T>::value
-            && !std::is_convertible<     optional<U> const & , T>::value
-            && !std::is_convertible<     optional<U> const &&, T>::value
-            &&  std::is_convertible<               U const & , T>::value /*=> non-explicit */
-        )
-#endif // optional_CPP11_OR_GREATER
-    )
-    : has_value_( other.has_value() )
-    {
-        if ( other.has_value() )
-        {
-            contained.construct_value( other.contained.value() );
-        }
-    }
-
-#if optional_CPP11_OR_GREATER
-
-    // 5a (C++11) - explicit converting move-construct from optional
-    template< typename U >
-    explicit optional( optional<U> && other
-        optional_REQUIRES_A(
-            std::is_constructible<T, U &&>::value
-            && !std::is_constructible<T, optional<U> &          >::value
-            && !std::is_constructible<T, optional<U> &&         >::value
-            && !std::is_constructible<T, optional<U> const &    >::value
-            && !std::is_constructible<T, optional<U> const &&   >::value
-            && !std::is_convertible<     optional<U> &       , T>::value
-            && !std::is_convertible<     optional<U> &&      , T>::value
-            && !std::is_convertible<     optional<U> const & , T>::value
-            && !std::is_convertible<     optional<U> const &&, T>::value
-            && !std::is_convertible<                     U &&, T>::value /*=> explicit */
-        )
-    )
-    : has_value_( other.has_value() )
-    {
-        if ( other.has_value() )
-        {
-            contained.construct_value( T{ std::move( other.contained.value() ) } );
-        }
-    }
-
-    // 5a (C++11) - non-explicit converting move-construct from optional
-    template< typename U >
-    // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
-    optional( optional<U> && other
-        optional_REQUIRES_A(
-            std::is_constructible<T, U &&>::value
-            && !std::is_constructible<T, optional<U> &          >::value
-            && !std::is_constructible<T, optional<U> &&         >::value
-            && !std::is_constructible<T, optional<U> const &    >::value
-            && !std::is_constructible<T, optional<U> const &&   >::value
-            && !std::is_convertible<     optional<U> &       , T>::value
-            && !std::is_convertible<     optional<U> &&      , T>::value
-            && !std::is_convertible<     optional<U> const & , T>::value
-            && !std::is_convertible<     optional<U> const &&, T>::value
-            &&  std::is_convertible<                     U &&, T>::value /*=> non-explicit */
-        )
-    )
-    : has_value_( other.has_value() )
-    {
-        if ( other.has_value() )
-        {
-            contained.construct_value( std::move( other.contained.value() ) );
-        }
-    }
-
-    // 6 (C++11) - in-place construct
-    template< typename... Args
-        optional_REQUIRES_T(
-            std::is_constructible<T, Args&&...>::value
-        )
-    >
-    optional_constexpr explicit optional( nonstd_lite_in_place_t(T), Args&&... args )
-    : has_value_( true )
-    , contained( T( std::forward<Args>(args)...) )
-    {}
-
-    // 7 (C++11) - in-place construct,  initializer-list
-    template< typename U, typename... Args
-        optional_REQUIRES_T(
-            std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value
-        )
-    >
-    optional_constexpr explicit optional( nonstd_lite_in_place_t(T), std::initializer_list<U> il, Args&&... args )
-    : has_value_( true )
-    , contained( T( il, std::forward<Args>(args)...) )
-    {}
-
-    // 8a (C++11) - explicit move construct from value
-    template< typename U = value_type >
-    optional_constexpr explicit optional( U && value
-        optional_REQUIRES_A(
-            std::is_constructible<T, U&&>::value
-            && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
-            && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
-            && !std::is_convertible<U&&, T>::value /*=> explicit */
-        )
-    )
-    : has_value_( true )
-    , contained( T{ std::forward<U>( value ) } )
-    {}
-
-    // 8b (C++11) - non-explicit move construct from value
-    template< typename U = value_type >
-    // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
-    optional_constexpr optional( U && value
-        optional_REQUIRES_A(
-            std::is_constructible<T, U&&>::value
-            && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
-            && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
-            && std::is_convertible<U&&, T>::value /*=> non-explicit */
-        )
-    )
-    : has_value_( true )
-    , contained( std::forward<U>( value ) )
-    {}
-
-#else // optional_CPP11_OR_GREATER
-
-    // 8 (C++98)
-    optional( value_type const & value )
-    : has_value_( true )
-    , contained( value )
-    {}
-
-#endif // optional_CPP11_OR_GREATER
-
-    // x.x.3.2, destructor
-
-    ~optional()
-    {
-        if ( has_value() )
-        {
-            contained.destruct_value();
-        }
-    }
-
-    // x.x.3.3, assignment
-
-    // 1 (C++98and later) -  assign explicitly empty
-    optional & operator=( nullopt_t /*unused*/) optional_noexcept
-    {
-        reset();
-        return *this;
-    }
-
-    // 2 (C++98and later) - copy-assign from optional
-#if optional_CPP11_OR_GREATER
-    // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
-    optional_REQUIRES_R(
-        optional &,
-        true
-//      std::is_copy_constructible<T>::value
-//      && std::is_copy_assignable<T>::value
-    )
-    operator=( optional const & other )
-        noexcept(
-            std::is_nothrow_move_assignable<T>::value
-            && std::is_nothrow_move_constructible<T>::value
-        )
-#else
-    optional & operator=( optional const & other )
-#endif
-    {
-        if      ( (has_value() == true ) && (other.has_value() == false) ) { reset(); }
-        else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( *other ); }
-        else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = *other; }
-        return *this;
-    }
-
-#if optional_CPP11_OR_GREATER
-
-    // 3 (C++11) - move-assign from optional
-    // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
-    optional_REQUIRES_R(
-        optional &,
-        true
-//      std::is_move_constructible<T>::value
-//      && std::is_move_assignable<T>::value
-    )
-    operator=( optional && other ) noexcept
-    {
-        if      ( (has_value() == true ) && (other.has_value() == false) ) { reset(); }
-        else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std::move( *other ) ); }
-        else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = std::move( *other ); }
-        return *this;
-    }
-
-    // 4 (C++11) - move-assign from value
-    template< typename U = T >
-        // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
-        optional_REQUIRES_R(
-            optional &,
-            std::is_constructible<T , U>::value
-            && std::is_assignable<T&, U>::value
-            && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
-            && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
-            && !(std::is_scalar<T>::value && std::is_same<T, typename std::decay<U>::type>::value)
-        )
-    operator=( U && value )
-    {
-        if ( has_value() )
-        {
-            contained.value() = std::forward<U>( value );
-        }
-        else
-        {
-            initialize( T( std::forward<U>( value ) ) );
-        }
-        return *this;
-    }
-
-#else // optional_CPP11_OR_GREATER
-
-    // 4 (C++98) - copy-assign from value
-    template< typename U /*= T*/ >
-    optional & operator=( U const & value )
-    {
-        if ( has_value() ) contained.value() = value;
-        else               initialize( T( value ) );
-        return *this;
-    }
-
-#endif // optional_CPP11_OR_GREATER
-
-    // 5 (C++98 and later) - converting copy-assign from optional
-    template< typename U >
-#if optional_CPP11_OR_GREATER
-        // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
-        optional_REQUIRES_R(
-            optional&,
-            std::is_constructible<  T , U const &>::value
-            &&  std::is_assignable< T&, U const &>::value
-            && !std::is_constructible<T, optional<U> &          >::value
-            && !std::is_constructible<T, optional<U> &&         >::value
-            && !std::is_constructible<T, optional<U> const &    >::value
-            && !std::is_constructible<T, optional<U> const &&   >::value
-            && !std::is_convertible<     optional<U> &       , T>::value
-            && !std::is_convertible<     optional<U> &&      , T>::value
-            && !std::is_convertible<     optional<U> const & , T>::value
-            && !std::is_convertible<     optional<U> const &&, T>::value
-            && !std::is_assignable<  T&, optional<U> &          >::value
-            && !std::is_assignable<  T&, optional<U> &&         >::value
-            && !std::is_assignable<  T&, optional<U> const &    >::value
-            && !std::is_assignable<  T&, optional<U> const &&   >::value
-        )
-#else
-    optional&
-#endif // optional_CPP11_OR_GREATER
-    operator=( optional<U> const & other )
-    {
-        return *this = optional( other );
-    }
-
-#if optional_CPP11_OR_GREATER
-
-    // 6 (C++11) -  converting move-assign from optional
-    template< typename U >
-        // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
-        optional_REQUIRES_R(
-            optional&,
-            std::is_constructible<  T , U>::value
-            &&  std::is_assignable< T&, U>::value
-            && !std::is_constructible<T, optional<U> &          >::value
-            && !std::is_constructible<T, optional<U> &&         >::value
-            && !std::is_constructible<T, optional<U> const &    >::value
-            && !std::is_constructible<T, optional<U> const &&   >::value
-            && !std::is_convertible<     optional<U> &       , T>::value
-            && !std::is_convertible<     optional<U> &&      , T>::value
-            && !std::is_convertible<     optional<U> const & , T>::value
-            && !std::is_convertible<     optional<U> const &&, T>::value
-            && !std::is_assignable<  T&, optional<U> &          >::value
-            && !std::is_assignable<  T&, optional<U> &&         >::value
-            && !std::is_assignable<  T&, optional<U> const &    >::value
-            && !std::is_assignable<  T&, optional<U> const &&   >::value
-        )
-    operator=( optional<U> && other )
-    {
-        return *this = optional( std::move( other ) );
-    }
-
-    // 7 (C++11) - emplace
-    template< typename... Args
-        optional_REQUIRES_T(
-            std::is_constructible<T, Args&&...>::value
-        )
-    >
-    T& emplace( Args&&... args )
-    {
-        *this = nullopt;
-        contained.emplace( std::forward<Args>(args)...  );
-        has_value_ = true;
-        return contained.value();
-    }
-
-    // 8 (C++11) - emplace, initializer-list
-    template< typename U, typename... Args
-        optional_REQUIRES_T(
-            std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value
-        )
-    >
-    T& emplace( std::initializer_list<U> il, Args&&... args )
-    {
-        *this = nullopt;
-        contained.emplace( il, std::forward<Args>(args)...  );
-        has_value_ = true;
-        return contained.value();
-    }
-
-#endif // optional_CPP11_OR_GREATER
-
-    // x.x.3.4, swap
-
-    void swap( optional & other )
-#if optional_CPP11_OR_GREATER
-        noexcept(
-            std::is_nothrow_move_constructible<T>::value
-            && std17::is_nothrow_swappable<T>::value
-        )
-#endif
-    {
-        using std::swap;
-        if      ( (has_value() == true ) && (other.has_value() == true ) ) { swap( **this, *other ); }
-        else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std11::move(*other) ); other.reset(); }
-        else if ( (has_value() == true ) && (other.has_value() == false) ) { other.initialize( std11::move(**this) ); reset(); }
-    }
-
-    // x.x.3.5, observers
-
-    optional_constexpr value_type const * operator ->() const
-    {
-        return assert( has_value() ),
-            contained.value_ptr();
-    }
-
-    optional_constexpr14 value_type * operator ->()
-    {
-        return assert( has_value() ),
-            contained.value_ptr();
-    }
-
-    optional_constexpr value_type const & operator *() const optional_ref_qual
-    {
-        return assert( has_value() ),
-            contained.value();
-    }
-
-    optional_constexpr14 value_type & operator *() optional_ref_qual
-    {
-        return assert( has_value() ),
-            contained.value();
-    }
-
-#if optional_HAVE( REF_QUALIFIER )  &&  ( !optional_COMPILER_GNUC_VERSION || optional_COMPILER_GNUC_VERSION >= 490 )
-
-    optional_constexpr value_type const && operator *() const optional_refref_qual
-    {
-        return std::move( **this );
-    }
-
-    optional_constexpr14 value_type && operator *() optional_refref_qual
-    {
-        return std::move( **this );
-    }
-
-#endif
-
-#if optional_CPP11_OR_GREATER
-    optional_constexpr explicit operator bool() const optional_noexcept
-    {
-        return has_value();
-    }
-#else
-    optional_constexpr operator safe_bool() const optional_noexcept
-    {
-        return has_value() ? &optional::this_type_does_not_support_comparisons : 0;
-    }
-#endif
-
-    // NOLINTNEXTLINE( modernize-use-nodiscard )
-    /*optional_nodiscard*/ optional_constexpr bool has_value() const optional_noexcept
-    {
-        return has_value_;
-    }
-
-    // NOLINTNEXTLINE( modernize-use-nodiscard )
-    /*optional_nodiscard*/ optional_constexpr14 value_type const & value() const optional_ref_qual
-    {
-#if optional_CONFIG_NO_EXCEPTIONS
-        assert( has_value() );
-#else
-        if ( ! has_value() )
-        {
-            throw bad_optional_access();
-        }
-#endif
-        return contained.value();
-    }
-
-    optional_constexpr14 value_type & value() optional_ref_qual
-    {
-#if optional_CONFIG_NO_EXCEPTIONS
-        assert( has_value() );
-#else
-        if ( ! has_value() )
-        {
-            throw bad_optional_access();
-        }
-#endif
-        return contained.value();
-    }
-
-#if optional_HAVE( REF_QUALIFIER )  &&  ( !optional_COMPILER_GNUC_VERSION || optional_COMPILER_GNUC_VERSION >= 490 )
-
-    // NOLINTNEXTLINE( modernize-use-nodiscard )
-    /*optional_nodiscard*/ optional_constexpr value_type const && value() const optional_refref_qual
-    {
-        return std::move( value() );
-    }
-
-    optional_constexpr14 value_type && value() optional_refref_qual
-    {
-        return std::move( value() );
-    }
-
-#endif
-
-#if optional_CPP11_OR_GREATER
-
-    template< typename U >
-    optional_constexpr value_type value_or( U && v ) const optional_ref_qual
-    {
-        return has_value() ? contained.value() : static_cast<T>(std::forward<U>( v ) );
-    }
-
-    template< typename U >
-    optional_constexpr14 value_type value_or( U && v ) optional_refref_qual
-    {
-        return has_value() ? std::move( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
-    }
-
-#else
-
-    template< typename U >
-    optional_constexpr value_type value_or( U const & v ) const
-    {
-        return has_value() ? contained.value() : static_cast<value_type>( v );
-    }
-
-#endif // optional_CPP11_OR_GREATER
-
-    // x.x.3.6, modifiers
-
-    void reset() optional_noexcept
-    {
-        if ( has_value() )
-        {
-            contained.destruct_value();
-        }
-
-        has_value_ = false;
-    }
-
-private:
-    void this_type_does_not_support_comparisons() const {}
-
-    template< typename V >
-    void initialize( V const & value )
-    {
-        assert( ! has_value()  );
-        contained.construct_value( value );
-        has_value_ = true;
-    }
-
-#if optional_CPP11_OR_GREATER
-    template< typename V >
-    void initialize( V && value )
-    {
-        assert( ! has_value()  );
-        contained.construct_value( std::move( value ) );
-        has_value_ = true;
-    }
-
-#endif
-
-private:
-    bool has_value_;
-    detail::storage_t< value_type > contained;
-
-};
-
-// Relational operators
-
-template< typename T, typename U >
-inline optional_constexpr bool operator==( optional<T> const & x, optional<U> const & y )
-{
-    return bool(x) != bool(y) ? false : !bool( x ) ? true : *x == *y;
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator!=( optional<T> const & x, optional<U> const & y )
-{
-    return !(x == y);
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator<( optional<T> const & x, optional<U> const & y )
-{
-    return (!y) ? false : (!x) ? true : *x < *y;
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator>( optional<T> const & x, optional<U> const & y )
-{
-    return (y < x);
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator<=( optional<T> const & x, optional<U> const & y )
-{
-    return !(y < x);
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator>=( optional<T> const & x, optional<U> const & y )
-{
-    return !(x < y);
-}
-
-// Comparison with nullopt
-
-template< typename T >
-inline optional_constexpr bool operator==( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
-{
-    return (!x);
-}
-
-template< typename T >
-inline optional_constexpr bool operator==( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
-{
-    return (!x);
-}
-
-template< typename T >
-inline optional_constexpr bool operator!=( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
-{
-    return bool(x);
-}
-
-template< typename T >
-inline optional_constexpr bool operator!=( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
-{
-    return bool(x);
-}
-
-template< typename T >
-inline optional_constexpr bool operator<( optional<T> const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept
-{
-    return false;
-}
-
-template< typename T >
-inline optional_constexpr bool operator<( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
-{
-    return bool(x);
-}
-
-template< typename T >
-inline optional_constexpr bool operator<=( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
-{
-    return (!x);
-}
-
-template< typename T >
-inline optional_constexpr bool operator<=( nullopt_t /*unused*/, optional<T> const & /*unused*/ ) optional_noexcept
-{
-    return true;
-}
-
-template< typename T >
-inline optional_constexpr bool operator>( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
-{
-    return bool(x);
-}
-
-template< typename T >
-inline optional_constexpr bool operator>( nullopt_t /*unused*/, optional<T> const & /*unused*/ ) optional_noexcept
-{
-    return false;
-}
-
-template< typename T >
-inline optional_constexpr bool operator>=( optional<T> const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept
-{
-    return true;
-}
-
-template< typename T >
-inline optional_constexpr bool operator>=( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
-{
-    return (!x);
-}
-
-// Comparison with T
-
-template< typename T, typename U >
-inline optional_constexpr bool operator==( optional<T> const & x, U const & v )
-{
-    return bool(x) ? *x == v : false;
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator==( U const & v, optional<T> const & x )
-{
-    return bool(x) ? v == *x : false;
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator!=( optional<T> const & x, U const & v )
-{
-    return bool(x) ? *x != v : true;
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator!=( U const & v, optional<T> const & x )
-{
-    return bool(x) ? v != *x : true;
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator<( optional<T> const & x, U const & v )
-{
-    return bool(x) ? *x < v : true;
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator<( U const & v, optional<T> const & x )
-{
-    return bool(x) ? v < *x : false;
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator<=( optional<T> const & x, U const & v )
-{
-    return bool(x) ? *x <= v : true;
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator<=( U const & v, optional<T> const & x )
-{
-    return bool(x) ? v <= *x : false;
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator>( optional<T> const & x, U const & v )
-{
-    return bool(x) ? *x > v : false;
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator>( U const & v, optional<T> const & x )
-{
-    return bool(x) ? v > *x : true;
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator>=( optional<T> const & x, U const & v )
-{
-    return bool(x) ? *x >= v : false;
-}
-
-template< typename T, typename U >
-inline optional_constexpr bool operator>=( U const & v, optional<T> const & x )
-{
-    return bool(x) ? v >= *x : true;
-}
-
-// Specialized algorithms
-
-template< typename T
-#if optional_CPP11_OR_GREATER
-    optional_REQUIRES_T(
-        std::is_move_constructible<T>::value
-        && std17::is_swappable<T>::value )
-#endif
->
-void swap( optional<T> & x, optional<T> & y )
-#if optional_CPP11_OR_GREATER
-    noexcept( noexcept( x.swap(y) ) )
-#endif
-{
-    x.swap( y );
-}
-
-#if optional_CPP11_OR_GREATER
-
-template< typename T >
-optional_constexpr optional< typename std::decay<T>::type > make_optional( T && value )
-{
-    return optional< typename std::decay<T>::type >( std::forward<T>( value ) );
-}
-
-template< typename T, typename...Args >
-optional_constexpr optional<T> make_optional( Args&&... args )
-{
-    return optional<T>( nonstd_lite_in_place(T), std::forward<Args>(args)...);
-}
-
-template< typename T, typename U, typename... Args >
-optional_constexpr optional<T> make_optional( std::initializer_list<U> il, Args&&... args )
-{
-    return optional<T>( nonstd_lite_in_place(T), il, std::forward<Args>(args)...);
-}
-
-#else
-
-template< typename T >
-optional<T> make_optional( T const & value )
-{
-    return optional<T>( value );
-}
-
-#endif // optional_CPP11_OR_GREATER
-
-} // namespace optional_lite
-
-using optional_lite::optional;
-using optional_lite::nullopt_t;
-using optional_lite::nullopt;
-using optional_lite::bad_optional_access;
-
-using optional_lite::make_optional;
-
-} // namespace nonstd
-
-#if optional_CPP11_OR_GREATER
-
-// specialize the std::hash algorithm:
-
-namespace std {
-
-template< class T >
-struct hash< nonstd::optional<T> >
-{
-public:
-    std::size_t operator()( nonstd::optional<T> const & v ) const optional_noexcept
-    {
-        return bool( v ) ? std::hash<T>{}( *v ) : 0;
-    }
-};
-
-} //namespace std
-
-#endif // optional_CPP11_OR_GREATER
-
-#if defined(__clang__)
-# pragma clang diagnostic pop
-#elif defined(__GNUC__)
-# pragma GCC   diagnostic pop
-#elif defined(_MSC_VER )
-# pragma warning( pop )
-#endif
-
-#endif // optional_USES_STD_OPTIONAL
-
-#endif // NONSTD_OPTIONAL_LITE_HPP

[nifi-minifi-cpp] 03/03: MINIFICPP-1617 Update CONTRIB.md with actual practice

Posted by fg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

fgerlits pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git

commit a6049776dca54731a9c4b966a5e64543839ab77f
Author: Marton Szasz <sz...@apache.org>
AuthorDate: Thu Jul 29 11:58:15 2021 +0200

    MINIFICPP-1617 Update CONTRIB.md with actual practice
    
    - divergence from the Google Style Guide
    - recommendation to follow the C++ Core Guidelines
    
    Signed-off-by: Ferenc Gerlits <fg...@gmail.com>
    
    This closes #1146
---
 CONTRIB.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 README.md  | 18 +----------------
 2 files changed, 58 insertions(+), 28 deletions(-)

diff --git a/CONTRIB.md b/CONTRIB.md
index 44e7284..ceb8b43 100644
--- a/CONTRIB.md
+++ b/CONTRIB.md
@@ -15,24 +15,70 @@
 
 # Apache NiFi - MiNiFi - C++ Contribution Guide
 
-
-We welcome all contributions to Apache MiNiFi. To make development easier, we've included
-the linter for the Google Style guide. Google provides an Eclipse formatter for their style
-guide. It is located [here](https://github.com/google/styleguide/blob/gh-pages/eclipse-cpp-google-style.xml).
-New contributions are expected to follow the Google style guide when it is reasonable.
-Additionally, all new files must include a copy of the Apache License Header.
-
+We welcome all contributions to Apache MiNiFi. All new files must include a copy of the Apache License Header.
+To make development easier, we've included the linter for the Google Style guide. Google provides an Eclipse formatter
+for their style guide. It is located
+[here](https://github.com/google/styleguide/blob/gh-pages/eclipse-cpp-google-style.xml).
+New contributions are expected to follow the 
+[Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html), except for the following points:
+- Use .cpp extension for implementation files
+- Use lowerCamelCase for functions, including accessors/mutators
+- Use UPPER_SNAKE_CASE for constants
+- Filenames are typically class names or a description of the contents in UpperCamelCase
+- If a class is imitating something from STL, boost or similar, then STL-style lower_snake_case is used for naming the
+  class. UpperCamelCase is used for most classes, in line with the Google Style Guide.
+- Prefer `#pragma once` over include guards
+- Forward declarations are OK
+- Using-directives (`using namespace foo`) are discouraged, except for user-defined literal namespaces
+- Some patterns in the codebase rely on objects with static storage duration without being trivially destructible and
+  initialized with a constant expression. It's OK to use these.
+- User-defined literal suffixes are OK
+- Public mutable data members are allowed
+- Inline function definition is OK
+- Rvalue references, exceptions and RTTI are allowed
+- Use gsl::narrow and gsl::narrow_cast in addition to standard casts. The codebase doesn't use abseil.
+- We are more liberal regarding the use of `auto`. The Google Style Guide only allows using it when it makes the code
+  clearer. In MiNiFi C++, it's up to the personal preferences of the contributor.
+- Template metaprogramming is OK when necessary, as long as the usage is clear. Prefer the more readable alternatives
+  when applicable.
+- Enums are either UPPER_SNAKE_CASE or UpperCamelCase.
+- File-level comments describing the contents are not required and typically not used in the codebase. A license header
+  is required.
+- Function comments use /** Javadoc style */
+- Line length is not limited, but the linter warns on lines longer than 200 characters. Use a NOLINT line comment in the
+  rare case when a longer line is more readable than splitting it up.
+- Continuation indentation is ok with either 2 levels of indentation (4 spaces) or aligned.
+
+It's ok to diverge from any of the rules with a good enough reason. We recommend following the C++ Core Guidelines, when
+it doesn't contradict any of the Google Style Guide or the above exceptions.
+
+C++ is a powerful language and "with great power comes great responsibility". Please aim for simple, readable and
+maintainable solutions and avoid footguns. Be open for respectful debate in pull request reviews.
+
+Shell script files shall follow the guidelines and best practices defined by the [shellcheck](https://github.com/koalaman/shellcheck) analysis tool.
+New contributions are expected to pass the shellcheck analysis as part of the verification process.
+If a shellcheck requested change is unfeasible it shall be disabled on per-line basis and will be subjected to review.
+For more information on an issue please check the [shellcheck wiki page](https://github.com/koalaman/shellcheck/wiki).
+You can run shellcheck by invoking the shellcheck cmake target, e.g. `make shellcheck`.
+
+Python script files shall follow the PEP8 guidelines and best practices. The project includes [flake8](https://flake8.pycqa.org/en/latest/) checks
+as part of the verification process, that is applied to all new contributions.
 
 ## Issues and Pull Requests
 
-Issues within MiNiFi C++ are tracked in the official [Apache JIRA](https://issues.apache.org/jira/projects/MINIFICPP/issues)
-Unassigned tickets may be assigned to yourself or filed via this JIRA instance. Pull requests can be submitted via our [Github
-Mirror](https://github.com/apache/nifi-minifi-cpp) . When doing so try and have a ticket filed when submitting your pull request.
+Issues within MiNiFi C++ are tracked in the official [Apache JIRA](https://issues.apache.org/jira/projects/MINIFICPP/issues).
+New users can register freely and ask for contributor access on the
+[Developers Mailing List](https://nifi.apache.org/mailing_lists.html).
+Unassigned tickets may be assigned to yourself or filed via this JIRA instance. Pull requests can be submitted via our
+[Github Mirror](https://github.com/apache/nifi-minifi-cpp) . When doing so please create a JIRA issue for your pull
+request.
 
 Apache NiFi MiNiFi C++ is a review then commit community. As a result, we will review your commits and merge them following 
-review. We ask that you provide tests and documentation when possible. 
+review. We ask that you provide tests and documentation when possible. Typically PRs are merged after they get 2-3
+approvals, usually in a week or two.
 
 Once you have completed your changes, including source code and tests, you can verify that you follow the Google style guide by running the following command:
+
 ##### Linux or macOS
 ```
 $ make linter
diff --git a/README.md b/README.md
index 55af4f7..7c3038d 100644
--- a/README.md
+++ b/README.md
@@ -560,23 +560,7 @@ See https://nifi.apache.org/minifi for the latest documentation.
 See our [examples page](examples/README.md) for flow examples.
 
 ## Contributing
-
-We welcome all contributions to Apache MiNiFi. To make development easier, we've included
-the linter for the Google Style guide. Google provides an Eclipse formatter for their style
-guide. It is located [here](https://github.com/google/styleguide/blob/gh-pages/eclipse-cpp-google-style.xml).
-New contributions are expected to follow the Google style guide when it is reasonable.
-
-Shell script files shall follow the guidelines and best practices defined by the [shellcheck](https://github.com/koalaman/shellcheck) analysis tool.
-New contributions are expected to pass the shellcheck analysis as part of the verification process.
-If a shellcheck requested change is unfeasable it shall be disabled on per-line basis and will be subjected to review.
-For more information on an issue please check the [shellcheck wiki page](https://github.com/koalaman/shellcheck/wiki).
-
-Python script files shall follow the PEP8 guidelines and best practices. The project includes [flake8](https://flake8.pycqa.org/en/latest/) checks
-as part of the verification process, that is applied to all new contributions.
-
-Additionally, all new files must include a copy of the Apache License Header.
-
-For more details on how to contribute please see our [Contribution Guide](CONTRIB.md)
+See our [Contribution Guide](CONTRIB.md).
 
 ## License
 Except as otherwise noted this software is licensed under the

[nifi-minifi-cpp] 01/03: MINIFICPP-1522 Log invalid attribute in case of YAML parse failure

Posted by fg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

fgerlits pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git

commit e1433c1b4e04aaaa1bac46d338631e7689549a0c
Author: Gabor Gyimesi <ga...@gmail.com>
AuthorDate: Mon Jul 26 14:07:24 2021 +0200

    MINIFICPP-1522 Log invalid attribute in case of YAML parse failure
    
    Signed-off-by: Ferenc Gerlits <fg...@gmail.com>
    
    This closes #1143
---
 .../tests/unit/YamlConfigurationTests.cpp          | 327 +++++++++++----------
 libminifi/src/core/yaml/YamlConfiguration.cpp      |  10 +-
 2 files changed, 186 insertions(+), 151 deletions(-)

diff --git a/extensions/standard-processors/tests/unit/YamlConfigurationTests.cpp b/extensions/standard-processors/tests/unit/YamlConfigurationTests.cpp
index b4b8f6b..8121bda 100644
--- a/extensions/standard-processors/tests/unit/YamlConfigurationTests.cpp
+++ b/extensions/standard-processors/tests/unit/YamlConfigurationTests.cpp
@@ -18,6 +18,7 @@
 
 #include <map>
 #include <memory>
+#include <chrono>
 #include "core/repository/VolatileContentRepository.h"
 #include "core/ProcessGroup.h"
 #include "core/RepositoryFactory.h"
@@ -26,6 +27,8 @@
 #include "TestBase.h"
 #include "utils/TestUtils.h"
 
+using namespace std::chrono_literals;  // NOLINT using namespace directive is required for literals
+
 TEST_CASE("Test YAML Config Processing", "[YamlConfiguration]") {
   TestController test_controller;
 
@@ -37,160 +40,184 @@ TEST_CASE("Test YAML Config Processing", "[YamlConfiguration]") {
   core::YamlConfiguration yamlConfig(testProvRepo, testFlowFileRepo, content_repo, streamFactory, configuration);
 
   SECTION("loading YAML without optional component IDs works") {
-  static const std::string CONFIG_YAML_WITHOUT_IDS = ""
-      "MiNiFi Config Version: 1\n"
-      "Flow Controller:\n"
-      "    name: MiNiFi Flow\n"
-      "    comment:\n"
-      "\n"
-      "Core Properties:\n"
-      "    flow controller graceful shutdown period: 10 sec\n"
-      "    flow service write delay interval: 500 ms\n"
-      "    administrative yield duration: 30 sec\n"
-      "    bored yield duration: 10 millis\n"
-      "\n"
-      "FlowFile Repository:\n"
-      "    partitions: 256\n"
-      "    checkpoint interval: 2 mins\n"
-      "    always sync: false\n"
-      "    Swap:\n"
-      "        threshold: 20000\n"
-      "        in period: 5 sec\n"
-      "        in threads: 1\n"
-      "        out period: 5 sec\n"
-      "        out threads: 4\n"
-      "\n"
-      "Provenance Repository:\n"
-      "    provenance rollover time: 1 min\n"
-      "\n"
-      "Content Repository:\n"
-      "    content claim max appendable size: 10 MB\n"
-      "    content claim max flow files: 100\n"
-      "    always sync: false\n"
-      "\n"
-      "Component Status Repository:\n"
-      "    buffer size: 1440\n"
-      "    snapshot frequency: 1 min\n"
-      "\n"
-      "Security Properties:\n"
-      "    keystore: /tmp/ssl/localhost-ks.jks\n"
-      "    keystore type: JKS\n"
-      "    keystore password: localtest\n"
-      "    key password: localtest\n"
-      "    truststore: /tmp/ssl/localhost-ts.jks\n"
-      "    truststore type: JKS\n"
-      "    truststore password: localtest\n"
-      "    ssl protocol: TLS\n"
-      "    Sensitive Props:\n"
-      "        key:\n"
-      "        algorithm: PBEWITHMD5AND256BITAES-CBC-OPENSSL\n"
-      "        provider: BC\n"
-      "\n"
-      "Processors:\n"
-      "    - name: TailFile\n"
-      "      class: org.apache.nifi.processors.standard.TailFile\n"
-      "      max concurrent tasks: 1\n"
-      "      scheduling strategy: TIMER_DRIVEN\n"
-      "      scheduling period: 1 sec\n"
-      "      penalization period: 30 sec\n"
-      "      yield period: 1 sec\n"
-      "      run duration nanos: 0\n"
-      "      auto-terminated relationships list:\n"
-      "      Properties:\n"
-      "          File to Tail: logs/minifi-app.log\n"
-      "          Rolling Filename Pattern: minifi-app*\n"
-      "          Initial Start Position: Beginning of File\n"
-      "\n"
-      "Connections:\n"
-      "    - name: TailToS2S\n"
-      "      source name: TailFile\n"
-      "      source relationship name: success\n"
-      "      destination name: 8644cbcc-a45c-40e0-964d-5e536e2ada61\n"
-      "      max work queue size: 0\n"
-      "      max work queue data size: 1 MB\n"
-      "      flowfile expiration: 60 sec\n"
-      "      queue prioritizer class: org.apache.nifi.prioritizer.NewestFlowFileFirstPrioritizer\n"
-      "\n"
-      "Remote Processing Groups:\n"
-      "    - name: NiFi Flow\n"
-      "      comment:\n"
-      "      url: https://localhost:8090/nifi\n"
-      "      timeout: 30 secs\n"
-      "      yield period: 10 sec\n"
-      "      Input Ports:\n"
-      "          - id: 8644cbcc-a45c-40e0-964d-5e536e2ada61\n"
-      "            name: tailed log\n"
-      "            comments:\n"
-      "            max concurrent tasks: 1\n"
-      "            use compression: false\n"
-      "\n"
-      "Provenance Reporting:\n"
-      "    comment:\n"
-      "    scheduling strategy: TIMER_DRIVEN\n"
-      "    scheduling period: 30 sec\n"
-      "    host: localhost\n"
-      "    port name: provenance\n"
-      "    port: 8090\n"
-      "    port uuid: 2f389b8d-83f2-48d3-b465-048f28a1cb56\n"
-      "    url: https://localhost:8090/\n"
-      "    originating url: http://${hostname(true)}:8081/nifi\n"
-      "    use compression: true\n"
-      "    timeout: 30 secs\n"
-      "    batch size: 1000";
-
-  std::istringstream configYamlStream(CONFIG_YAML_WITHOUT_IDS);
-  std::unique_ptr<core::ProcessGroup> rootFlowConfig = yamlConfig.getYamlRoot(configYamlStream);
+    static const std::string CONFIG_YAML_WITHOUT_IDS =
+      R"(
+MiNiFi Config Version: 1
+Flow Controller:
+    name: MiNiFi Flow
+    comment:
 
-  REQUIRE(rootFlowConfig);
-  REQUIRE(rootFlowConfig->findProcessorByName("TailFile"));
-  utils::Identifier uuid = rootFlowConfig->findProcessorByName("TailFile")->getUUID();
-  REQUIRE(uuid);
-  REQUIRE(!rootFlowConfig->findProcessorByName("TailFile")->getUUIDStr().empty());
-  REQUIRE(1 == rootFlowConfig->findProcessorByName("TailFile")->getMaxConcurrentTasks());
-  REQUIRE(
-      core::SchedulingStrategy::TIMER_DRIVEN == rootFlowConfig->findProcessorByName("TailFile")->getSchedulingStrategy());
-  REQUIRE(1 == rootFlowConfig->findProcessorByName("TailFile")->getMaxConcurrentTasks());
-  REQUIRE(1 * 1000 * 1000 * 1000 == rootFlowConfig->findProcessorByName("TailFile")->getSchedulingPeriodNano());
-  REQUIRE(std::chrono::seconds(30) == rootFlowConfig->findProcessorByName("TailFile")->getPenalizationPeriod());
-  REQUIRE(1 * 1000 == rootFlowConfig->findProcessorByName("TailFile")->getYieldPeriodMsec());
-  REQUIRE(0 == rootFlowConfig->findProcessorByName("TailFile")->getRunDurationNano());
+Core Properties:
+    flow controller graceful shutdown period: 10 sec
+    flow service write delay interval: 500 ms
+    administrative yield duration: 30 sec
+    bored yield duration: 10 millis
 
-  std::map<std::string, std::shared_ptr<minifi::Connection>> connectionMap;
-  rootFlowConfig->getConnections(connectionMap);
-  REQUIRE(2 == connectionMap.size());
-  // This is a map of UUID->Connection, and we don't know UUID, so just going to loop over it
-  for (auto it : connectionMap) {
-    REQUIRE(it.second);
-    REQUIRE(!it.second->getUUIDStr().empty());
-    REQUIRE(it.second->getDestination());
-    REQUIRE(it.second->getSource());
-    REQUIRE(60000 == it.second->getFlowExpirationDuration());
+FlowFile Repository:
+    partitions: 256
+    checkpoint interval: 2 mins
+    always sync: false
+    Swap:
+        threshold: 20000
+        in period: 5 sec
+        in threads: 1
+        out period: 5 sec
+        out threads: 4
+
+Provenance Repository:
+    provenance rollover time: 1 min
+
+Content Repository:
+    content claim max appendable size: 10 MB
+    content claim max flow files: 100
+    always sync: false
+
+Component Status Repository:
+    buffer size: 1440
+    snapshot frequency: 1 min
+
+Security Properties:
+    keystore: /tmp/ssl/localhost-ks.jks
+    keystore type: JKS
+    keystore password: localtest
+    key password: localtest
+    truststore: /tmp/ssl/localhost-ts.jks
+    truststore type: JKS
+    truststore password: localtest
+    ssl protocol: TLS
+    Sensitive Props:
+        key:
+        algorithm: PBEWITHMD5AND256BITAES-CBC-OPENSSL
+        provider: BC
+
+Processors:
+    - name: TailFile
+      class: org.apache.nifi.processors.standard.TailFile
+      max concurrent tasks: 1
+      scheduling strategy: TIMER_DRIVEN
+      scheduling period: 1 sec
+      penalization period: 30 sec
+      yield period: 1 sec
+      run duration nanos: 0
+      auto-terminated relationships list:
+      Properties:
+          File to Tail: logs/minifi-app.log
+          Rolling Filename Pattern: minifi-app*
+          Initial Start Position: Beginning of File
+
+Connections:
+    - name: TailToS2S
+      source name: TailFile
+      source relationship name: success
+      destination name: 8644cbcc-a45c-40e0-964d-5e536e2ada61
+      max work queue size: 0
+      max work queue data size: 1 MB
+      flowfile expiration: 60 sec
+      queue prioritizer class: org.apache.nifi.prioritizer.NewestFlowFileFirstPrioritizer
+
+Remote Processing Groups:
+    - name: NiFi Flow
+      comment:
+      url: https://localhost:8090/nifi
+      timeout: 30 secs
+      yield period: 10 sec
+      Input Ports:
+          - id: 8644cbcc-a45c-40e0-964d-5e536e2ada61
+            name: tailed log
+            comments:
+            max concurrent tasks: 1
+            use compression: false
+
+Provenance Reporting:
+    comment:
+    scheduling strategy: TIMER_DRIVEN
+    scheduling period: 30 sec
+    host: localhost
+    port name: provenance
+    port: 8090
+    port uuid: 2f389b8d-83f2-48d3-b465-048f28a1cb56
+    url: https://localhost:8090/
+    originating url: http://${hostname(true)}:8081/nifi
+    use compression: true
+    timeout: 30 secs
+    batch size: 1000;
+        )";
+
+    std::istringstream configYamlStream(CONFIG_YAML_WITHOUT_IDS);
+    std::unique_ptr<core::ProcessGroup> rootFlowConfig = yamlConfig.getYamlRoot(configYamlStream);
+
+    REQUIRE(rootFlowConfig);
+    REQUIRE(rootFlowConfig->findProcessorByName("TailFile"));
+    utils::Identifier uuid = rootFlowConfig->findProcessorByName("TailFile")->getUUID();
+    REQUIRE(uuid);
+    REQUIRE(!rootFlowConfig->findProcessorByName("TailFile")->getUUIDStr().empty());
+    REQUIRE(1 == rootFlowConfig->findProcessorByName("TailFile")->getMaxConcurrentTasks());
+    REQUIRE(core::SchedulingStrategy::TIMER_DRIVEN == rootFlowConfig->findProcessorByName("TailFile")->getSchedulingStrategy());
+    REQUIRE(1 * 1000 * 1000 * 1000 == rootFlowConfig->findProcessorByName("TailFile")->getSchedulingPeriodNano());
+    REQUIRE(30s == rootFlowConfig->findProcessorByName("TailFile")->getPenalizationPeriod());
+    REQUIRE(1 * 1000 == rootFlowConfig->findProcessorByName("TailFile")->getYieldPeriodMsec());
+    REQUIRE(0 == rootFlowConfig->findProcessorByName("TailFile")->getRunDurationNano());
+
+    std::map<std::string, std::shared_ptr<minifi::Connection>> connectionMap;
+    rootFlowConfig->getConnections(connectionMap);
+    REQUIRE(2 == connectionMap.size());
+    // This is a map of UUID->Connection, and we don't know UUID, so just going to loop over it
+    for (auto it : connectionMap) {
+      REQUIRE(it.second);
+      REQUIRE(!it.second->getUUIDStr().empty());
+      REQUIRE(it.second->getDestination());
+      REQUIRE(it.second->getSource());
+      REQUIRE(60000 == it.second->getFlowExpirationDuration());
+    }
   }
-}
 
   SECTION("missing required field in YAML throws exception") {
-  static const std::string CONFIG_YAML_NO_RPG_PORT_ID = ""
-  "MiNiFi Config Version: 1\n"
-  "Flow Controller:\n"
-  "  name: MiNiFi Flow\n"
-  "Processors: []\n"
-  "Connections: []\n"
-  "Remote Processing Groups:\n"
-  "    - name: NiFi Flow\n"
-  "      comment:\n"
-  "      url: https://localhost:8090/nifi\n"
-  "      timeout: 30 secs\n"
-  "      yield period: 10 sec\n"
-  "      Input Ports:\n"
-  "          - name: tailed log\n"
-  "            comments:\n"
-  "            max concurrent tasks: 1\n"
-  "            use compression: false\n"
-  "\n";
-
-  std::istringstream configYamlStream(CONFIG_YAML_NO_RPG_PORT_ID);
-  REQUIRE_THROWS_AS(yamlConfig.getYamlRoot(configYamlStream), std::invalid_argument);
-}
+    static const std::string CONFIG_YAML_NO_RPG_PORT_ID =
+      R"(
+MiNiFi Config Version: 1
+Flow Controller:
+  name: MiNiFi Flow
+Processors: []
+Connections: []
+Remote Processing Groups:
+    - name: NiFi Flow
+      comment:
+      url: https://localhost:8090/nifi
+      timeout: 30 secs
+      yield period: 10 sec
+      Input Ports:
+          - name: tailed log
+            comments:
+            max concurrent tasks: 1
+            use compression: false
+      )";
+
+    std::istringstream configYamlStream(CONFIG_YAML_NO_RPG_PORT_ID);
+    REQUIRE_THROWS_AS(yamlConfig.getYamlRoot(configYamlStream), std::invalid_argument);
+  }
+
+  SECTION("Validated YAML property failure throws exception and logs invalid attribute name") {
+    static const std::string CONFIG_YAML_EMPTY_RETRY_ATTRIBUTE =
+      R"(
+Flow Controller:
+  name: MiNiFi Flow
+Processors:
+  - name: RetryFlowFile
+    class: org.apache.nifi.processors.standard.RetryFlowFile
+    scheduling strategy: TIMER_DRIVEN
+    scheduling period: 1 sec
+    auto-terminated relationships list:
+    Properties:
+        Retry Attribute: ""
+Connections: []
+Remote Processing Groups: []
+Provenance Reporting:
+      )";
+
+    std::istringstream configYamlStream(CONFIG_YAML_EMPTY_RETRY_ATTRIBUTE);
+    REQUIRE_THROWS_AS(yamlConfig.getYamlRoot(configYamlStream), utils::internal::InvalidValueException);
+    REQUIRE(LogTestController::getInstance().contains("Invalid value was set for property 'Retry Attribute' creating component 'RetryFlowFile'"));
+  }
 }
 
 TEST_CASE("Test YAML v3 Invalid Type", "[YamlConfiguration3]") {
@@ -452,7 +479,7 @@ NiFi Properties Overrides: {}
   REQUIRE(core::SchedulingStrategy::TIMER_DRIVEN == rootFlowConfig->findProcessorByName("TailFile")->getSchedulingStrategy());
   REQUIRE(1 == rootFlowConfig->findProcessorByName("TailFile")->getMaxConcurrentTasks());
   REQUIRE(1 * 1000 * 1000 * 1000 == rootFlowConfig->findProcessorByName("TailFile")->getSchedulingPeriodNano());
-  REQUIRE(std::chrono::seconds(30) == rootFlowConfig->findProcessorByName("TailFile")->getPenalizationPeriod());
+  REQUIRE(30s == rootFlowConfig->findProcessorByName("TailFile")->getPenalizationPeriod());
   REQUIRE(1 * 1000 == rootFlowConfig->findProcessorByName("TailFile")->getYieldPeriodMsec());
   REQUIRE(0 == rootFlowConfig->findProcessorByName("TailFile")->getRunDurationNano());
 
diff --git a/libminifi/src/core/yaml/YamlConfiguration.cpp b/libminifi/src/core/yaml/YamlConfiguration.cpp
index d5d2e6e..1a4850b 100644
--- a/libminifi/src/core/yaml/YamlConfiguration.cpp
+++ b/libminifi/src/core/yaml/YamlConfiguration.cpp
@@ -764,8 +764,16 @@ void YamlConfiguration::parseSingleProperty(const std::string& propertyName, con
   core::Property myProp(propertyName, "", "");
   processor->getProperty(propertyName, myProp);
   const PropertyValue coercedValue = getValidatedProcessorPropertyForDefaultTypeInfo(myProp, propertyValueNode);
+  bool property_set = false;
+  try {
+    property_set = processor->setProperty(myProp, coercedValue);
+  } catch(const utils::internal::InvalidValueException&) {
+    auto component = std::dynamic_pointer_cast<core::CoreComponent>(processor);
+    logger_->log_error("Invalid value was set for property '%s' creating component '%s'", propertyName, component->getName());
+    throw;
+  }
   const std::string rawValueString = propertyValueNode.as<std::string>();
-  if (!processor->setProperty(myProp, coercedValue)) {
+  if (!property_set) {
     std::shared_ptr<core::Connectable> proc = std::dynamic_pointer_cast<core::Connectable>(processor);
     if (proc) {
       logger_->log_warn("Received property %s with value %s but is not one of the properties for %s. Attempting to add as dynamic property.", propertyName, rawValueString, proc->getName());