From 35a8caa2acf595c610eb03a91b364f695e239846 Mon Sep 17 00:00:00 2001
From: Ian Chen <ichen@openrobotics.org>
Date: Wed, 3 Jan 2024 13:29:21 -0800
Subject: [PATCH 1/3] Update CI badges in README (#393)

---------

Signed-off-by: Ian Chen <ichen@openrobotics.org>
---
 README.md | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 7e12fac1..17c0f72f 100644
--- a/README.md
+++ b/README.md
@@ -9,10 +9,10 @@
 
 Build | Status
 -- | --
-Test coverage | [![codecov](https://codecov.io/gh/gazebosim/gz-fuel-tools/branch/main/graph/badge.svg)](https://codecov.io/gh/gazebosim/gz-fuel-tools/branch/main)
-Ubuntu Focal | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ignition_fuel-tools-ci-main-focal-amd64)](https://build.osrfoundation.org/job/ignition_fuel-tools-ci-main-focal-amd64)
-Homebrew      | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ignition_fuel-tools-ci-main-homebrew-amd64)](https://build.osrfoundation.org/job/ignition_fuel-tools-ci-main-homebrew-amd64)
-Windows       | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ign_fuel-tools-ci-win)](https://build.osrfoundation.org/job/ign_fuel-tools-ci-win/)
+Test coverage | [![codecov](https://codecov.io/gh/gazebosim/gz-fuel-tools/tree/gz-fuel-tools9/graph/badge.svg)](https://codecov.io/gh/gazebosim/gz-fuel-tools/tree/gz-fuel-tools9)
+Ubuntu Jammy  | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_fuel_tools-ci-gz-fuel-tools9-jammy-amd64)](https://build.osrfoundation.org/job/gz_fuel_tools-ci-gz-fuel-tools9-jammy-amd64)
+Homebrew      | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_fuel_tools-ci-gz-fuel-tools9-homebrew-amd64)](https://build.osrfoundation.org/job/gz_fuel_tools-ci-gz-fuel-tools9-homebrew-amd64)
+Windows       | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_fuel_tools-9-win)](https://build.osrfoundation.org/job/gz_fuel_tools-9-win/)
 
 Gazebo Fuel Tools is composed by a client library and command line tools for
 interacting with Gazebo Fuel servers.

From 93ec03d962c05b761e290304f28ed1ff739935cd Mon Sep 17 00:00:00 2001
From: Michael Carroll <mjcarroll@intrinsic.ai>
Date: Fri, 5 Jan 2024 12:36:28 -0600
Subject: [PATCH 2/3] Tidy nested namespaces (#396)

Signed-off-by: Michael Carroll <mjcarroll@intrinsic.ai>
---
 include/gz/fuel_tools/ClientConfig.hh         | 220 ++---
 include/gz/fuel_tools/CollectionIdentifier.hh | 157 ++-
 include/gz/fuel_tools/FuelClient.hh           | 902 +++++++++---------
 include/gz/fuel_tools/Helpers.hh              |  10 +-
 include/gz/fuel_tools/HttpMethod.hh           |  56 ++
 include/gz/fuel_tools/Interface.hh            |  75 +-
 include/gz/fuel_tools/JSONParser.hh           | 169 ++--
 include/gz/fuel_tools/Model.hh                | 139 ++-
 include/gz/fuel_tools/ModelIdentifier.hh      | 441 +++++----
 include/gz/fuel_tools/ModelIter.hh            |  77 +-
 include/gz/fuel_tools/RestClient.hh           | 163 ++--
 include/gz/fuel_tools/Result.hh               | 134 +--
 include/gz/fuel_tools/ResultType.hh           |  78 ++
 include/gz/fuel_tools/ServerConfig.hh         | 106 ++
 include/gz/fuel_tools/WorldIdentifier.hh      | 245 +++--
 include/gz/fuel_tools/WorldIter.hh            |  77 +-
 include/gz/fuel_tools/Zip.hh                  |  35 +-
 src/CMakeLists.txt                            |   2 +
 src/ClientConfig.cc                           | 136 +--
 src/ClientConfig_TEST.cc                      |  60 --
 src/CollectionIdentifier.cc                   |   7 +-
 src/FuelClient.cc                             |  32 +-
 src/Helpers.cc                                |   7 +-
 src/Interface.cc                              | 197 ++--
 src/JSONParser.cc                             |   8 +-
 src/LocalCache.cc                             |   8 +-
 src/LocalCache.hh                             | 147 ++-
 src/Model.cc                                  |   6 +-
 src/ModelIdentifier.cc                        |   8 +-
 src/ModelIter.cc                              |   6 +-
 src/ModelIterPrivate.hh                       | 281 +++---
 src/ModelPrivate.hh                           |  23 +-
 src/RestClient.cc                             |   9 +-
 src/Result.cc                                 |   9 +-
 src/ServerConfig.cc                           | 160 ++++
 src/ServerConfig_TEST.cc                      | 124 +++
 src/WorldIdentifier.cc                        |   7 +-
 src/WorldIter.cc                              |   5 +-
 src/WorldIterPrivate.hh                       | 201 ++--
 src/gz.cc                                     |   5 -
 40 files changed, 2337 insertions(+), 2195 deletions(-)
 create mode 100644 include/gz/fuel_tools/HttpMethod.hh
 create mode 100644 include/gz/fuel_tools/ResultType.hh
 create mode 100644 include/gz/fuel_tools/ServerConfig.hh
 create mode 100644 src/ServerConfig.cc
 create mode 100644 src/ServerConfig_TEST.cc

diff --git a/include/gz/fuel_tools/ClientConfig.hh b/include/gz/fuel_tools/ClientConfig.hh
index da7eb962..2fe4cbcd 100644
--- a/include/gz/fuel_tools/ClientConfig.hh
+++ b/include/gz/fuel_tools/ClientConfig.hh
@@ -25,6 +25,7 @@
 #include <gz/common/URI.hh>
 
 #include "gz/fuel_tools/Export.hh"
+#include "gz/fuel_tools/ServerConfig.hh"
 
 #ifdef _WIN32
 // Disable warning C4251 which is triggered by
@@ -33,153 +34,86 @@
 #pragma warning(disable: 4251)
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
+  /// \brief Forward Declaration
+  class ClientConfigPrivate;
+
+  /// \brief High level interface to Gazebo Fuel.
+  ///
+  class GZ_FUEL_TOOLS_VISIBLE ClientConfig
   {
-    /// \brief forward declaration
-    class ServerConfigPrivate;
-
-    /// \brief Forward Declaration
-    class ClientConfigPrivate;
-
-    /// \brief Describes options needed for a server.
-    class GZ_FUEL_TOOLS_VISIBLE ServerConfig
-    {
-      /// \brief Constructor.
-      public: ServerConfig();
-
-      /// \brief Copy constructor.
-      /// \param[in] _orig The server config to copy.
-      public: ServerConfig(const ServerConfig &_orig);
-
-      /// \brief Assignment operator overload.
-      /// \param[in] _orig The server config to copy.
-      public: ServerConfig &operator=(const ServerConfig &_orig);
-
-      /// \brief Destructor.
-      public: ~ServerConfig();
-
-      /// \brief Clear the server config. This will set all values to empty
-      /// strings, except the version string which will be set to its default
-      /// value.
-      public: void Clear();
-
-      /// \brief Get the URL to access the server.
-      /// \return The URL of this server.
-      public: common::URI Url() const;
-
-      /// \brief Set the URL of this server.
-      /// \param[in] _url URL of this server.
-      public: void SetUrl(const common::URI &_url);
-
-      /// \brief Get the API key to auth with the server.
-      /// \return The API key.
-      public: std::string ApiKey() const;
-
-      /// \brief Set the API key to auth with the server.
-      /// \param[in] _key The API key.
-      public: void SetApiKey(const std::string &_key);
-
-      /// \brief Get the protocol version used with this server.
-      /// \return The version. E.g.: "1.0".
-      public: std::string Version() const;
-
-      /// \brief Set the protocol version used with this server.
-      /// \param[in] _version The version. E.g.: "1.0".
-      public: void SetVersion(const std::string &_version);
-
-      /// \brief Returns all the server information as a string.
-      /// \param[in] _prefix Optional prefix for every line of the string.
-      /// \return Server information string
-      public: std::string AsString(const std::string &_prefix = "") const;
-
-      /// \brief Returns all the available model information as a string using
-      /// colors for better human parsing.
-      /// \param[in] _prefix Optional prefix for every line of the string.
-      /// \return Model information string
-      public: std::string AsPrettyString(const std::string &_prefix = "") const;
-
-      /// \brief PIMPL
-      private: std::unique_ptr<ServerConfigPrivate> dataPtr;
-    };
-
-    /// \brief High level interface to Gazebo Fuel.
-    ///
-    class GZ_FUEL_TOOLS_VISIBLE ClientConfig
-    {
-      /// \brief Constructor.
-      public: ClientConfig();
-
-      /// \brief Copy constructor.
-      /// \param[in] _copy ClientConfig to copy.
-      public: ClientConfig(const ClientConfig &_copy);
-
-      /// \brief Assignment operator overload.
-      /// \param[in] _copy ClientConfig to copy.
-      public: ClientConfig &operator=(const ClientConfig &_copy);
-
-      /// \brief Destructor.
-      public: ~ClientConfig();
-
-      /// \brief Clear the client config. This will set all values to empty
-      /// strings, except the user agent which will be set to its default
-      /// value.
-      public: void Clear();
-
-      /// \brief Set the user agent name.
-      /// \param[in] _agent User agent name.
-      public: void SetUserAgent(const std::string &_agent);
-
-      /// \brief Get the user agent name.
-      /// \return Name of the user agent.
-      public: const std::string &UserAgent() const;
-
-      /// \brief Load a YAML configuration file.
-      /// \param[in] _file Config file to load.
-      /// \return True if the configuration was loaded correctly.
-      /// \sa ConfigPath
-      public: bool LoadConfig(const std::string &_file);
-
-      /// \brief Get the location of the configuration file.
-      /// \return Path to the configuration file, which is set via
-      /// LoadConfig. The default return value is an empty string.
-      /// \sa LoadConfig
-      public: std::string ConfigPath() const;
-
-      /// \brief List of servers the client will connect to.
-      /// \return The list of servers.
-      public: std::vector<ServerConfig> Servers() const;
-
-      /// \brief List of servers the client will connect to.
-      /// \return The list of servers.
-      public: std::vector<ServerConfig> & MutableServers() const;
-
-      /// \brief Add a server to the list.
-      /// \param[in] _srv The server config.
-      public: void AddServer(const ServerConfig &_srv);
-
-      /// \brief Where are models and stuff stored locally?
-      /// \return The location where assets are stored locally.
-      public: std::string CacheLocation() const;
-
-      /// \brief Set where models and stuff are saved.
-      /// \param[in] _path path on disk where models are saved.
-      public: void SetCacheLocation(const std::string &_path);
-
-      /// \brief Returns all the client information as a string.
-      /// \param[in] _prefix Optional prefix for every line of the string.
-      /// \return Client information string
-      public: std::string AsString(const std::string &_prefix = "") const;
-
-      /// \brief PIMPL
-      private: std::unique_ptr<ClientConfigPrivate> dataPtr;
-    };
-  }
-}
+    /// \brief Constructor.
+    public: ClientConfig();
+
+    /// \brief Copy constructor.
+    /// \param[in] _copy ClientConfig to copy.
+    public: ClientConfig(const ClientConfig &_copy);
+
+    /// \brief Assignment operator overload.
+    /// \param[in] _copy ClientConfig to copy.
+    public: ClientConfig &operator=(const ClientConfig &_copy);
+
+    /// \brief Destructor.
+    public: ~ClientConfig();
+
+    /// \brief Clear the client config. This will set all values to empty
+    /// strings, except the user agent which will be set to its default
+    /// value.
+    public: void Clear();
+
+    /// \brief Set the user agent name.
+    /// \param[in] _agent User agent name.
+    public: void SetUserAgent(const std::string &_agent);
+
+    /// \brief Get the user agent name.
+    /// \return Name of the user agent.
+    public: const std::string &UserAgent() const;
+
+    /// \brief Load a YAML configuration file.
+    /// \param[in] _file Config file to load.
+    /// \return True if the configuration was loaded correctly.
+    /// \sa ConfigPath
+    public: bool LoadConfig(const std::string &_file);
+
+    /// \brief Get the location of the configuration file.
+    /// \return Path to the configuration file, which is set via
+    /// LoadConfig. The default return value is an empty string.
+    /// \sa LoadConfig
+    public: std::string ConfigPath() const;
+
+    /// \brief List of servers the client will connect to.
+    /// \return The list of servers.
+    public: std::vector<ServerConfig> Servers() const;
+
+    /// \brief List of servers the client will connect to.
+    /// \return The list of servers.
+    public: std::vector<ServerConfig> & MutableServers() const;
+
+    /// \brief Add a server to the list.
+    /// \param[in] _srv The server config.
+    public: void AddServer(const ServerConfig &_srv);
+
+    /// \brief Where are models and stuff stored locally?
+    /// \return The location where assets are stored locally.
+    public: std::string CacheLocation() const;
+
+    /// \brief Set where models and stuff are saved.
+    /// \param[in] _path path on disk where models are saved.
+    public: void SetCacheLocation(const std::string &_path);
+
+    /// \brief Returns all the client information as a string.
+    /// \param[in] _prefix Optional prefix for every line of the string.
+    /// \return Client information string
+    public: std::string AsString(const std::string &_prefix = "") const;
+
+    /// \brief PIMPL
+    private: std::unique_ptr<ClientConfigPrivate> dataPtr;
+  };
+}  // namespace gz::fuel_tools
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
-#endif
+#endif  // GZ_FUEL_TOOLS_CLIENTCONFIG_HH_
diff --git a/include/gz/fuel_tools/CollectionIdentifier.hh b/include/gz/fuel_tools/CollectionIdentifier.hh
index 5269734e..9e7d5cca 100644
--- a/include/gz/fuel_tools/CollectionIdentifier.hh
+++ b/include/gz/fuel_tools/CollectionIdentifier.hh
@@ -30,90 +30,87 @@
 #pragma warning(disable: 4251)
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
+  /// \brief Forward Declaration
+  class CollectionIdentifierPrivate;
+  class ServerConfig;
+
+  /// \brief Defines how to identify a collection
+  class GZ_FUEL_TOOLS_VISIBLE CollectionIdentifier
   {
-    /// \brief Forward Declaration
-    class CollectionIdentifierPrivate;
-    class ServerConfig;
-
-    /// \brief Defines how to identify a collection
-    class GZ_FUEL_TOOLS_VISIBLE CollectionIdentifier
-    {
-      /// \brief Constructor.
-      public: CollectionIdentifier();
-
-      /// \brief Copy Constructor.
-      /// \param[in] _orig CollectionIdentifier to copy.
-      public: CollectionIdentifier(const CollectionIdentifier &_orig);
-
-      /// \brief Destructor.
-      public: ~CollectionIdentifier();
-
-      /// \brief Assignment operator
-      /// \param[in] _orig CollectionIdentifier to copy.
-      /// \return Reference to this object.
-      public: CollectionIdentifier
-              &operator=(const CollectionIdentifier &_orig);
-
-        /// \brief Equality operator.
-        /// \param[in] _rhs CollectionIdentifier to compare.
-        /// \return True if the CollectionIdentifier names are equal.
-      public: bool operator==(const CollectionIdentifier &_rhs) const;
-
-      /// \brief Returns the collection name
-      /// \return Collection name.
-      public: std::string Name() const;
-
-      /// \brief Set the name of the collection.
-      /// \param[in] _name The name to set.
-      /// \return True if successful.
-      public: bool SetName(const std::string &_name);
-
-      /// \brief Returns owner to attribute collection to.
-      /// \return Owner name.
-      public: std::string Owner() const;
-
-      /// \brief Set the owner of the collection
-      /// \param[in] _name The name to set. Must be ascii and pass [-_a-z0-9]+
-      /// \return true if successful
-      public: bool SetOwner(const std::string &_name);
-
-      /// \brief Returns server information to retrieve collection from.
-      /// \return Server information.
-      public: ServerConfig &Server() const;
-
-      /// \brief Set the server from which this collection comes.
-      /// \param[in] _server The server to retrieve the collection from.
-      /// \return True if successful.
-      public: bool SetServer(const ServerConfig &_server);
-
-      /// \brief Returns a unique name for the collection.
-      /// \remarks this is Server/Owner/Name.
-      /// \return Unique collection name.
-      public: std::string UniqueName() const;
-
-      /// \brief Returns all the collection information as a string. Convenient
-      /// for debugging.
-      /// \param[in] _prefix Optional prefix for every line of the string.
-      /// \return Collection information string
-      public: std::string AsString(const std::string &_prefix = "") const;
-
-      /// \brief Returns all the available collection information as a string
-      /// using colors for better human parsing.
-      /// \param[in] _prefix Optional prefix for every line of the string.
-      /// \return Collection information string
-      public: std::string AsPrettyString(const std::string &_prefix = "") const;
-
-      /// \brief PIMPL
-      private: std::unique_ptr<CollectionIdentifierPrivate> dataPtr;
-    };
-  }
-}
+    /// \brief Constructor.
+    public: CollectionIdentifier();
+
+    /// \brief Copy Constructor.
+    /// \param[in] _orig CollectionIdentifier to copy.
+    public: CollectionIdentifier(const CollectionIdentifier &_orig);
+
+    /// \brief Destructor.
+    public: ~CollectionIdentifier();
+
+    /// \brief Assignment operator
+    /// \param[in] _orig CollectionIdentifier to copy.
+    /// \return Reference to this object.
+    public: CollectionIdentifier
+            &operator=(const CollectionIdentifier &_orig);
+
+      /// \brief Equality operator.
+      /// \param[in] _rhs CollectionIdentifier to compare.
+      /// \return True if the CollectionIdentifier names are equal.
+    public: bool operator==(const CollectionIdentifier &_rhs) const;
+
+    /// \brief Returns the collection name
+    /// \return Collection name.
+    public: std::string Name() const;
+
+    /// \brief Set the name of the collection.
+    /// \param[in] _name The name to set.
+    /// \return True if successful.
+    public: bool SetName(const std::string &_name);
+
+    /// \brief Returns owner to attribute collection to.
+    /// \return Owner name.
+    public: std::string Owner() const;
+
+    /// \brief Set the owner of the collection
+    /// \param[in] _name The name to set. Must be ascii and pass [-_a-z0-9]+
+    /// \return true if successful
+    public: bool SetOwner(const std::string &_name);
+
+    /// \brief Returns server information to retrieve collection from.
+    /// \return Server information.
+    public: ServerConfig &Server() const;
+
+    /// \brief Set the server from which this collection comes.
+    /// \param[in] _server The server to retrieve the collection from.
+    /// \return True if successful.
+    public: bool SetServer(const ServerConfig &_server);
+
+    /// \brief Returns a unique name for the collection.
+    /// \remarks this is Server/Owner/Name.
+    /// \return Unique collection name.
+    public: std::string UniqueName() const;
+
+    /// \brief Returns all the collection information as a string. Convenient
+    /// for debugging.
+    /// \param[in] _prefix Optional prefix for every line of the string.
+    /// \return Collection information string
+    public: std::string AsString(const std::string &_prefix = "") const;
+
+    /// \brief Returns all the available collection information as a string
+    /// using colors for better human parsing.
+    /// \param[in] _prefix Optional prefix for every line of the string.
+    /// \return Collection information string
+    public: std::string AsPrettyString(const std::string &_prefix = "") const;
+
+    /// \brief PIMPL
+    private: std::unique_ptr<CollectionIdentifierPrivate> dataPtr;
+  };
+}  // namespace gz::fuel_tools
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
-#endif
+#endif  // GZ_FUEL_TOOLS_COLLECTIONIDENTIFIER_HH_
diff --git a/include/gz/fuel_tools/FuelClient.hh b/include/gz/fuel_tools/FuelClient.hh
index 703d3032..d477cf6a 100644
--- a/include/gz/fuel_tools/FuelClient.hh
+++ b/include/gz/fuel_tools/FuelClient.hh
@@ -36,467 +36,465 @@
 #pragma warning(disable: 4251)
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
+  /// \brief Forward Declaration
+  class ClientConfig;
+  class CollectionIdentifier;
+  class FuelClientPrivate;
+  class LocalCache;
+  class ModelIdentifier;
+  class ServerConfig;
+  class WorldIdentifier;
+
+  /// \brief High level interface to Gazebo Fuel
+  class GZ_FUEL_TOOLS_VISIBLE FuelClient
   {
-    /// \brief Forward Declaration
-    class ClientConfig;
-    class CollectionIdentifier;
-    class FuelClientPrivate;
-    class LocalCache;
-    class ModelIdentifier;
-    class ServerConfig;
-
-    /// \brief High level interface to Gazebo Fuel
-    class GZ_FUEL_TOOLS_VISIBLE FuelClient
-    {
-      /// \brief Default constructor.
-      public: FuelClient();
-
-      /// \brief Constructor accepts server and auth configuration
-      /// \param[in] _config configuration about servers to connect to
-      /// \param[in] _rest A REST request.
-      /// \remarks the client saves a copy of the config passed into it
-      public: FuelClient(const ClientConfig &_config,
-                         const Rest &_rest = Rest());
-
-      /// \brief Destructor
-      public: ~FuelClient();
-
-      /// \brief Get a mutable reference to the client configuration.
-      /// \return Mutable reference to the client configuration.
-      public: ClientConfig &Config();
-
-      /// \brief Fetch the details of a model.
-      /// \param[in] _id a partially filled out identifier used to fetch models
-      /// \remarks Fulfills Get-One requirement
-      /// \param[out] _model The requested model
-      /// \return Result of the fetch operation.
-      public: Result ModelDetails(const ModelIdentifier &_id,
-                                  ModelIdentifier &_model) const;
-
-      /// \brief Fetch the details of a model.
-      /// \param[in] _id a partially filled out identifier used to fetch models
-      /// \remarks Fulfills Get-One requirement
-      /// \param[out] _model The requested model
-      /// \param[in] _headers Headers to set on the HTTP request.
-      /// \return Result of the fetch operation.
-      public: Result ModelDetails(const ModelIdentifier &_id,
-                  ModelIdentifier &_model,
-                  const std::vector<std::string> &_headers) const;
-
-
-      /// \brief Returns an iterator that can return names of models
-      /// \remarks Fulfills Get-All requirement
-      /// \remarks an iterator instead of a list of names is returned in case
-      ///          the model names api supports pagination in the future. The
-      ///          iterator may fetch more names if code continues to request
-      ///          it. The initial API appears to return all of the models, so
-      ///          right now this iterator stores a list of names internally.
-      /// \param[in] _server The server to request the operation.
-      /// \return A model iterator
-      public: ModelIter Models(const ServerConfig &_server);
-
-      /// \brief Returns an iterator that can return names of models
-      /// \remarks Fulfills Get-All requirement
-      /// \remarks an iterator instead of a list of names is returned in case
-      ///          the model names api supports pagination in the future. The
-      ///          iterator may fetch more names if code continues to request
-      ///          it. The initial API appears to return all of the models, so
-      ///          right now this iterator stores a list of names internally.
-      /// \param[in] _server The server to request the operation.
-      /// \return A model iterator
-      public: ModelIter Models(const ServerConfig &_server) const;
-
-      /// \brief Fetch the details of a world.
-      /// \param[in] _id a partially filled out identifier used to fetch worlds
-      /// \param[out] _world The requested world
-      /// \return Result of the fetch operation.
-      public: Result WorldDetails(const WorldIdentifier &_id,
-                                  WorldIdentifier &_world) const;
-
-      /// \brief Fetch the details of a world.
-      /// \param[in] _id a partially filled out identifier used to fetch worlds
-      /// \param[out] _world The requested world
-      /// \param[in] _headers Headers to set on the HTTP request.
-      /// \return Result of the fetch operation.
-      public: Result WorldDetails(const WorldIdentifier &_id,
-                                WorldIdentifier &_world,
-                                const std::vector<std::string> &_headers) const;
-
-      /// \brief Returns an iterator that can return information of worlds
-      /// \remarks An iterator instead of a list of names, to be able to
-      ///          handle pagination. The iterator may fetch more names if
-      ///          code continues to request it.
-      /// \param[in] _server The server to request the operation.
-      /// \return A world iterator
-      public: WorldIter Worlds(const ServerConfig &_server) const;
-
-      /// \brief Returns models matching a given identifying criteria
-      /// \param[in] _id a partially filled out identifier used to fetch models
-      /// \remarks Fulfills Get-One requirement
-      /// \remarks Model names are unique to the owner, so this API
-      ///          allows the possibility of getting multiple models with the
-      ///          same name if the owner is not specified.
-      /// \return An iterator of models with names matching the criteria
-      public: ModelIter Models(const ModelIdentifier &_id);
-
-      /// \brief Returns models matching a given identifying criteria
-      /// \param[in] _id a partially filled out identifier used to fetch models
-      /// \remarks Fulfills Get-One requirement
-      /// \remarks Model names are unique to the owner, so this API
-      ///          allows the possibility of getting multiple models with the
-      ///          same name if the owner is not specified.
-      /// \return An iterator of models with names matching the criteria
-      public: ModelIter Models(const ModelIdentifier &_id) const;
-
-      /// \brief Returns models matching a given identifying criteria
-      /// \param[in] _id a partially filled out identifier used to fetch models
-      /// \param[in] _checkCache Whether to check the cache.
-      /// \remarks Fulfills Get-One requirement
-      /// \remarks Model names are unique to the owner, so this API
-      ///          allows the possibility of getting multiple models with the
-      ///          same name if the owner is not specified.
-      /// \return An iterator of models with names matching the criteria
-      public: ModelIter Models(const ModelIdentifier &_id, bool _checkCache);
-
-      /// \brief Returns models matching a given identifying criteria
-      /// \param[in] _id a partially filled out identifier used to fetch models
-      /// \param[in] _checkCache Whether to check the cache.
-      /// \remarks Fulfills Get-One requirement
-      /// \remarks Model names are unique to the owner, so this API
-      ///          allows the possibility of getting multiple models with the
-      ///          same name if the owner is not specified.
-      /// \return An iterator of models with names matching the criteria
-      public: ModelIter Models(const ModelIdentifier &_id,
-                               bool _checkCache) const;
-
-       /// \brief Returns an iterator for the models found in a collection.
-       /// \param[in] _id a partially filled out identifier used to fetch a
-       /// collection.
-       /// \return An iterator of models in the collection.
-      public: ModelIter Models(const CollectionIdentifier &_id) const;
-
-      /// \brief Returns worlds matching a given identifying criteria
-      /// \param[in] _id A partially filled out identifier used to fetch worlds
-      /// \return An iterator of worlds with names matching the criteria
-      public: WorldIter Worlds(const WorldIdentifier &_id) const;
-
-      /// \brief Returns an iterator for the worlds found in a collection.
-      /// \param[in] _id a partially filled out identifier used to fetch a
-      /// collection.
-      /// \return An iterator of words in the collection.
-      public: WorldIter Worlds(const CollectionIdentifier &_id) const;
-
-      /// \brief Upload a directory as a new model
-      /// \param[in] _pathToModelDir a path to a directory containing a model
-      /// \param[in] _id An identifier to assign to this new model
-      /// \param[in] _headers Headers to set on the HTTP request.
-      /// \param[in] _private True to make the model private.
-      /// \return Result of the upload operation
-      public: Result UploadModel(const std::string &_pathToModelDir,
-                                 const ModelIdentifier &_id,
-                                 const std::vector<std::string> &_headers,
-                                 bool _private = false);
-
-      /// \brief Upload a directory as a new model
-      /// \param[in] _pathToModelDir a path to a directory containing a model
-      /// \param[in] _id An identifier to assign to this new model
-      /// \param[in] _headers Headers to set on the HTTP request.
-      /// \param[in] _private True to make the model private.
-      /// \param[in] _owner Name of the owner. Empty string indicates that
-      /// the owner is specified by the private token in the headers.
-      /// \return Result of the upload operation
-      public: Result UploadModel(const std::string &_pathToModelDir,
-                                 const ModelIdentifier &_id,
-                                 const std::vector<std::string> &_headers,
-                                 bool _private,
-                                 const std::string &_owner);
-
-      /// \brief Remove a resource, such as a model or world, from Gazebo Fuel
-      /// \param[in] _uri The full URI of the resource, e.g:
-      /// https://fuel.gazebosim.org/1.0/openrobotcs/model/my_model
-      /// \param[in] _headers Headers to set on the HTTP request.
-      /// \return Result of the delete operation
-      public: Result DeleteUrl(const gz::common::URI &_uri,
-                  const std::vector<std::string> &_headers);
-
-      /// \brief Download a model from Gazebo Fuel. This will override an
-      /// existing local copy of the model.
-      /// \param[in] _id The model identifier.
-      /// \return Result of the download operation
-      public: Result DownloadModel(const ModelIdentifier &_id);
-
-      /// \brief Download a model from Gazebo Fuel. This will override an
-      /// existing local copy of the model.
-      /// \param[in] _id The model identifier.
-      /// \param[in] _headers Headers to set on the HTTP request.
-      /// \return Result of the download operation
-      public: Result DownloadModel(const ModelIdentifier &_id,
-                  const std::vector<std::string> &_headers);
-
-      /// \brief Download a model from Gazebo Fuel. This will override an
-      /// existing local copy of the model.
-      /// \param[in] _id The model identifier.
-      /// \param[in] _headers Headers to set on the HTTP request.
-      /// \param[out] _dependencies List of models that this model depends on.
-      /// \return Result of the download operation
-      public: Result DownloadModel(const ModelIdentifier &_id,
-                  const std::vector<std::string> &_headers,
-                  std::vector<ModelIdentifier> &_dependencies);
-
-      /// \brief Retrieve the list of dependencies for a model.
-      /// \param[in] _id The model identifier.
-      /// \param[out] _dependencies The list of dependencies.
-      /// \return Result of the operation
-      public: Result ModelDependencies(const ModelIdentifier &_id,
-                  std::vector<ModelIdentifier> &_dependencies);
-
-      /// \brief Retrieve the list of dependencies for a list of models.
-      /// \param[in] _id The list of model identifiers.
-      /// \param[out] _dependencies The list of dependencies.
-      /// \return Result of the operation
-      public: Result ModelDependencies(
-                  const std::vector<ModelIdentifier> &_id,
-                  std::vector<ModelIdentifier> &_dependencies);
-
-      /// \brief Download a world from Gazebo Fuel. This will override an
-      /// existing local copy of the world.
-      /// \param[out] _id The world identifier, with local path updated.
-      /// \return Result of the download operation
-      public: Result DownloadWorld(WorldIdentifier &_id);
-
-      /// \brief Download a world from Gazebo Fuel. This will override an
-      /// existing local copy of the world.
-      /// \param[out] _id The world identifier, with local path updated.
-      /// \param[in] _headers Headers to set on the HTTP request.
-      /// \return Result of the download operation
-      public: Result DownloadWorld(WorldIdentifier &_id,
-                  const std::vector<std::string> &_headers);
-
-      /// \brief Download a model from Gazebo Fuel. This will override an
-      /// existing local copy of the model.
-      /// \param[in] _modelUrl The unique URL of the model to download.
-      /// E.g.: https://fuel.gazebosim.org/1.0/caguero/models/Beer
-      /// \param[out] _path Path where the model was downloaded.
-      /// \return Result of the download operation.
-      public: Result DownloadModel(const common::URI &_modelUrl,
-                                   std::string &_path);
-
-      /// \brief Download a world from Gazebo Fuel. This will override an
-      /// existing local copy of the world.
-      /// \param[in] _worldUrl The unique URL of the world to download.
-      /// E.g.: https://fuel.gazebosim.org/1.0/OpenRobotics/worlds/Empty
-      /// \param[out] _path Path where the world was downloaded.
-      /// \return Result of the download operation.
-      public: Result DownloadWorld(const common::URI &_worldUrl,
-                                   std::string &_path);
-
-      using ModelResult = std::tuple<ModelIdentifier, Result>;
-
-      /// \brief Download a list of models from Gazebo Fuel.
-      /// \param[in] _ids The list of model ids to download.
-      ///   This will also find all recursive dependencies of the models
-      /// \param[in] _jobs Number of parallel jobs to use to download models
-      /// \return Result of the download operation.
-      //    The resulting vector will be at least the size of the _ids input
-      //    vector, but may be larger depending on the number of depedencies
-      //    downloaded
-      public: std::vector<ModelResult> DownloadModels(
-                  const std::vector<ModelIdentifier> &_ids,
-                  size_t _jobs = 2);
-
-      /// \brief Download a list of mworlds from Gazebo Fuel.
-      /// \param[in] _ids The list of world ids to download.
-      /// \param[in] _jobs Number of parallel jobs to use to download worlds.
-      /// \return Result of the download operation.
-      public: Result DownloadWorlds(
-                  const std::vector<WorldIdentifier> &_ids,
-                  size_t _jobs = 2);
-
-      /// \brief Check if a model is already present in the local cache.
-      /// \param[in] _id The model identifier
-      /// \param[out] _path Local path where the model can be found.
-      /// \return FETCH_ERROR if not cached, FETCH_ALREADY_EXISTS if cached.
-      public: Result CachedModel(const ModelIdentifier &_id,
+    /// \brief Default constructor.
+    public: FuelClient();
+
+    /// \brief Constructor accepts server and auth configuration
+    /// \param[in] _config configuration about servers to connect to
+    /// \param[in] _rest A REST request.
+    /// \remarks the client saves a copy of the config passed into it
+    public: FuelClient(const ClientConfig &_config,
+                       const Rest &_rest = Rest());
+
+    /// \brief Destructor
+    public: ~FuelClient();
+
+    /// \brief Get a mutable reference to the client configuration.
+    /// \return Mutable reference to the client configuration.
+    public: ClientConfig &Config();
+
+    /// \brief Fetch the details of a model.
+    /// \param[in] _id a partially filled out identifier used to fetch models
+    /// \remarks Fulfills Get-One requirement
+    /// \param[out] _model The requested model
+    /// \return Result of the fetch operation.
+    public: Result ModelDetails(const ModelIdentifier &_id,
+                                ModelIdentifier &_model) const;
+
+    /// \brief Fetch the details of a model.
+    /// \param[in] _id a partially filled out identifier used to fetch models
+    /// \remarks Fulfills Get-One requirement
+    /// \param[out] _model The requested model
+    /// \param[in] _headers Headers to set on the HTTP request.
+    /// \return Result of the fetch operation.
+    public: Result ModelDetails(const ModelIdentifier &_id,
+                ModelIdentifier &_model,
+                const std::vector<std::string> &_headers) const;
+
+
+    /// \brief Returns an iterator that can return names of models
+    /// \remarks Fulfills Get-All requirement
+    /// \remarks an iterator instead of a list of names is returned in case
+    ///          the model names api supports pagination in the future. The
+    ///          iterator may fetch more names if code continues to request
+    ///          it. The initial API appears to return all of the models, so
+    ///          right now this iterator stores a list of names internally.
+    /// \param[in] _server The server to request the operation.
+    /// \return A model iterator
+    public: ModelIter Models(const ServerConfig &_server);
+
+    /// \brief Returns an iterator that can return names of models
+    /// \remarks Fulfills Get-All requirement
+    /// \remarks an iterator instead of a list of names is returned in case
+    ///          the model names api supports pagination in the future. The
+    ///          iterator may fetch more names if code continues to request
+    ///          it. The initial API appears to return all of the models, so
+    ///          right now this iterator stores a list of names internally.
+    /// \param[in] _server The server to request the operation.
+    /// \return A model iterator
+    public: ModelIter Models(const ServerConfig &_server) const;
+
+    /// \brief Fetch the details of a world.
+    /// \param[in] _id a partially filled out identifier used to fetch worlds
+    /// \param[out] _world The requested world
+    /// \return Result of the fetch operation.
+    public: Result WorldDetails(const WorldIdentifier &_id,
+                                WorldIdentifier &_world) const;
+
+    /// \brief Fetch the details of a world.
+    /// \param[in] _id a partially filled out identifier used to fetch worlds
+    /// \param[out] _world The requested world
+    /// \param[in] _headers Headers to set on the HTTP request.
+    /// \return Result of the fetch operation.
+    public: Result WorldDetails(const WorldIdentifier &_id,
+                              WorldIdentifier &_world,
+                              const std::vector<std::string> &_headers) const;
+
+    /// \brief Returns an iterator that can return information of worlds
+    /// \remarks An iterator instead of a list of names, to be able to
+    ///          handle pagination. The iterator may fetch more names if
+    ///          code continues to request it.
+    /// \param[in] _server The server to request the operation.
+    /// \return A world iterator
+    public: WorldIter Worlds(const ServerConfig &_server) const;
+
+    /// \brief Returns models matching a given identifying criteria
+    /// \param[in] _id a partially filled out identifier used to fetch models
+    /// \remarks Fulfills Get-One requirement
+    /// \remarks Model names are unique to the owner, so this API
+    ///          allows the possibility of getting multiple models with the
+    ///          same name if the owner is not specified.
+    /// \return An iterator of models with names matching the criteria
+    public: ModelIter Models(const ModelIdentifier &_id);
+
+    /// \brief Returns models matching a given identifying criteria
+    /// \param[in] _id a partially filled out identifier used to fetch models
+    /// \remarks Fulfills Get-One requirement
+    /// \remarks Model names are unique to the owner, so this API
+    ///          allows the possibility of getting multiple models with the
+    ///          same name if the owner is not specified.
+    /// \return An iterator of models with names matching the criteria
+    public: ModelIter Models(const ModelIdentifier &_id) const;
+
+    /// \brief Returns models matching a given identifying criteria
+    /// \param[in] _id a partially filled out identifier used to fetch models
+    /// \param[in] _checkCache Whether to check the cache.
+    /// \remarks Fulfills Get-One requirement
+    /// \remarks Model names are unique to the owner, so this API
+    ///          allows the possibility of getting multiple models with the
+    ///          same name if the owner is not specified.
+    /// \return An iterator of models with names matching the criteria
+    public: ModelIter Models(const ModelIdentifier &_id, bool _checkCache);
+
+    /// \brief Returns models matching a given identifying criteria
+    /// \param[in] _id a partially filled out identifier used to fetch models
+    /// \param[in] _checkCache Whether to check the cache.
+    /// \remarks Fulfills Get-One requirement
+    /// \remarks Model names are unique to the owner, so this API
+    ///          allows the possibility of getting multiple models with the
+    ///          same name if the owner is not specified.
+    /// \return An iterator of models with names matching the criteria
+    public: ModelIter Models(const ModelIdentifier &_id,
+                             bool _checkCache) const;
+
+     /// \brief Returns an iterator for the models found in a collection.
+     /// \param[in] _id a partially filled out identifier used to fetch a
+     /// collection.
+     /// \return An iterator of models in the collection.
+    public: ModelIter Models(const CollectionIdentifier &_id) const;
+
+    /// \brief Returns worlds matching a given identifying criteria
+    /// \param[in] _id A partially filled out identifier used to fetch worlds
+    /// \return An iterator of worlds with names matching the criteria
+    public: WorldIter Worlds(const WorldIdentifier &_id) const;
+
+    /// \brief Returns an iterator for the worlds found in a collection.
+    /// \param[in] _id a partially filled out identifier used to fetch a
+    /// collection.
+    /// \return An iterator of words in the collection.
+    public: WorldIter Worlds(const CollectionIdentifier &_id) const;
+
+    /// \brief Upload a directory as a new model
+    /// \param[in] _pathToModelDir a path to a directory containing a model
+    /// \param[in] _id An identifier to assign to this new model
+    /// \param[in] _headers Headers to set on the HTTP request.
+    /// \param[in] _private True to make the model private.
+    /// \return Result of the upload operation
+    public: Result UploadModel(const std::string &_pathToModelDir,
+                               const ModelIdentifier &_id,
+                               const std::vector<std::string> &_headers,
+                               bool _private = false);
+
+    /// \brief Upload a directory as a new model
+    /// \param[in] _pathToModelDir a path to a directory containing a model
+    /// \param[in] _id An identifier to assign to this new model
+    /// \param[in] _headers Headers to set on the HTTP request.
+    /// \param[in] _private True to make the model private.
+    /// \param[in] _owner Name of the owner. Empty string indicates that
+    /// the owner is specified by the private token in the headers.
+    /// \return Result of the upload operation
+    public: Result UploadModel(const std::string &_pathToModelDir,
+                               const ModelIdentifier &_id,
+                               const std::vector<std::string> &_headers,
+                               bool _private,
+                               const std::string &_owner);
+
+    /// \brief Remove a resource, such as a model or world, from Gazebo Fuel
+    /// \param[in] _uri The full URI of the resource, e.g:
+    /// https://fuel.gazebosim.org/1.0/openrobotcs/model/my_model
+    /// \param[in] _headers Headers to set on the HTTP request.
+    /// \return Result of the delete operation
+    public: Result DeleteUrl(const gz::common::URI &_uri,
+                const std::vector<std::string> &_headers);
+
+    /// \brief Download a model from Gazebo Fuel. This will override an
+    /// existing local copy of the model.
+    /// \param[in] _id The model identifier.
+    /// \return Result of the download operation
+    public: Result DownloadModel(const ModelIdentifier &_id);
+
+    /// \brief Download a model from Gazebo Fuel. This will override an
+    /// existing local copy of the model.
+    /// \param[in] _id The model identifier.
+    /// \param[in] _headers Headers to set on the HTTP request.
+    /// \return Result of the download operation
+    public: Result DownloadModel(const ModelIdentifier &_id,
+                const std::vector<std::string> &_headers);
+
+    /// \brief Download a model from Gazebo Fuel. This will override an
+    /// existing local copy of the model.
+    /// \param[in] _id The model identifier.
+    /// \param[in] _headers Headers to set on the HTTP request.
+    /// \param[out] _dependencies List of models that this model depends on.
+    /// \return Result of the download operation
+    public: Result DownloadModel(const ModelIdentifier &_id,
+                const std::vector<std::string> &_headers,
+                std::vector<ModelIdentifier> &_dependencies);
+
+    /// \brief Retrieve the list of dependencies for a model.
+    /// \param[in] _id The model identifier.
+    /// \param[out] _dependencies The list of dependencies.
+    /// \return Result of the operation
+    public: Result ModelDependencies(const ModelIdentifier &_id,
+                std::vector<ModelIdentifier> &_dependencies);
+
+    /// \brief Retrieve the list of dependencies for a list of models.
+    /// \param[in] _id The list of model identifiers.
+    /// \param[out] _dependencies The list of dependencies.
+    /// \return Result of the operation
+    public: Result ModelDependencies(
+                const std::vector<ModelIdentifier> &_id,
+                std::vector<ModelIdentifier> &_dependencies);
+
+    /// \brief Download a world from Gazebo Fuel. This will override an
+    /// existing local copy of the world.
+    /// \param[out] _id The world identifier, with local path updated.
+    /// \return Result of the download operation
+    public: Result DownloadWorld(WorldIdentifier &_id);
+
+    /// \brief Download a world from Gazebo Fuel. This will override an
+    /// existing local copy of the world.
+    /// \param[out] _id The world identifier, with local path updated.
+    /// \param[in] _headers Headers to set on the HTTP request.
+    /// \return Result of the download operation
+    public: Result DownloadWorld(WorldIdentifier &_id,
+                const std::vector<std::string> &_headers);
+
+    /// \brief Download a model from Gazebo Fuel. This will override an
+    /// existing local copy of the model.
+    /// \param[in] _modelUrl The unique URL of the model to download.
+    /// E.g.: https://fuel.gazebosim.org/1.0/caguero/models/Beer
+    /// \param[out] _path Path where the model was downloaded.
+    /// \return Result of the download operation.
+    public: Result DownloadModel(const common::URI &_modelUrl,
                                  std::string &_path);
 
-      /// \brief Check if a model is already present in the local cache.
-      /// \param[in] _modelUrl The unique URL of the model on a Fuel server.
-      /// E.g.: https://fuel.gazebosim.org/1.0/caguero/models/Beer
-      /// \param[out] _path Local path where the model can be found.
-      /// \return FETCH_ERROR if not cached, FETCH_ALREADY_EXISTS if cached.
-      public: Result CachedModel(const common::URI &_modelUrl,
+    /// \brief Download a world from Gazebo Fuel. This will override an
+    /// existing local copy of the world.
+    /// \param[in] _worldUrl The unique URL of the world to download.
+    /// E.g.: https://fuel.gazebosim.org/1.0/OpenRobotics/worlds/Empty
+    /// \param[out] _path Path where the world was downloaded.
+    /// \return Result of the download operation.
+    public: Result DownloadWorld(const common::URI &_worldUrl,
                                  std::string &_path);
 
-      /// \brief Check if a model exists in the cache.
-      /// \param[in] _modelUrl The unique URL of the world on a Fuel server.
-      /// E.g.: https://fuel.gazebosim.org/1.0/caguero/models/Beer
-      /// \return True if the model exists in the cache, false otherwise.
-      public: bool CachedModel(const common::URI &_modelUrl);
-
-      /// \brief Check if a world is already present in the local cache.
-      /// \param[in] _worldUrl The unique URL of the world on a Fuel server.
-      /// E.g.: https://fuel.gazebosim.org/1.0/OpenRobotics/worlds/Empty
-      /// \param[out] _path Local path where the world can be found.
-      /// \return FETCH_ERROR if not cached, FETCH_ALREADY_EXISTS if cached.
-      public: Result CachedWorld(const common::URI &_worldUrl,
-                                 std::string &_path);
+    using ModelResult = std::tuple<ModelIdentifier, Result>;
+
+    /// \brief Download a list of models from Gazebo Fuel.
+    /// \param[in] _ids The list of model ids to download.
+    ///   This will also find all recursive dependencies of the models
+    /// \param[in] _jobs Number of parallel jobs to use to download models
+    /// \return Result of the download operation.
+    //    The resulting vector will be at least the size of the _ids input
+    //    vector, but may be larger depending on the number of depedencies
+    //    downloaded
+    public: std::vector<ModelResult> DownloadModels(
+                const std::vector<ModelIdentifier> &_ids,
+                size_t _jobs = 2);
+
+    /// \brief Download a list of mworlds from Gazebo Fuel.
+    /// \param[in] _ids The list of world ids to download.
+    /// \param[in] _jobs Number of parallel jobs to use to download worlds.
+    /// \return Result of the download operation.
+    public: Result DownloadWorlds(
+                const std::vector<WorldIdentifier> &_ids,
+                size_t _jobs = 2);
+
+    /// \brief Check if a model is already present in the local cache.
+    /// \param[in] _id The model identifier
+    /// \param[out] _path Local path where the model can be found.
+    /// \return FETCH_ERROR if not cached, FETCH_ALREADY_EXISTS if cached.
+    public: Result CachedModel(const ModelIdentifier &_id,
+                               std::string &_path);
+
+    /// \brief Check if a model is already present in the local cache.
+    /// \param[in] _modelUrl The unique URL of the model on a Fuel server.
+    /// E.g.: https://fuel.gazebosim.org/1.0/caguero/models/Beer
+    /// \param[out] _path Local path where the model can be found.
+    /// \return FETCH_ERROR if not cached, FETCH_ALREADY_EXISTS if cached.
+    public: Result CachedModel(const common::URI &_modelUrl,
+                               std::string &_path);
+
+    /// \brief Check if a model exists in the cache.
+    /// \param[in] _modelUrl The unique URL of the world on a Fuel server.
+    /// E.g.: https://fuel.gazebosim.org/1.0/caguero/models/Beer
+    /// \return True if the model exists in the cache, false otherwise.
+    public: bool CachedModel(const common::URI &_modelUrl);
+
+    /// \brief Check if a world is already present in the local cache.
+    /// \param[in] _worldUrl The unique URL of the world on a Fuel server.
+    /// E.g.: https://fuel.gazebosim.org/1.0/OpenRobotics/worlds/Empty
+    /// \param[out] _path Local path where the world can be found.
+    /// \return FETCH_ERROR if not cached, FETCH_ALREADY_EXISTS if cached.
+    public: Result CachedWorld(const common::URI &_worldUrl,
+                               std::string &_path);
+
+    /// \brief Check if a world exists in the cache.
+    /// \param[in] _worldUrl The unique URL of the world on a Fuel server.
+    /// E.g.: https://fuel.gazebosim.org/1.0/OpenRobotics/worlds/Empty
+    /// \return True if the world exists in the cache, false otherwise.
+    public: bool CachedWorld(const common::URI &_worldUrl);
+
+    /// \brief Check if a file belonging to a model is already present in the
+    /// local cache.
+    /// \param[in] _fileUrl The unique URL of the file on a Fuel server. E.g.:
+    /// https://server.org/1.0/owner/models/model/files/meshes/mesh.dae
+    /// \param[out] _path Local path where the file can be found.
+    /// \return FETCH_ERROR if not cached, FETCH_ALREADY_EXISTS if cached.
+    public: Result CachedModelFile(const common::URI &_fileUrl,
+                                   std::string &_path);
+
+    /// \brief Check if a file belonging to a world is already present in the
+    /// local cache.
+    /// \param[in] _fileUrl The unique URL of the file on a Fuel server. E.g.:
+    /// https://server.org/1.0/owner/worlds/world/files/name.world
+    /// \param[out] _path Local path where the file can be found.
+    /// \return FETCH_ERROR if not cached, FETCH_ALREADY_EXISTS if cached.
+    public: Result CachedWorldFile(const common::URI &_fileUrl,
+                                   std::string &_path);
 
-      /// \brief Check if a world exists in the cache.
-      /// \param[in] _worldUrl The unique URL of the world on a Fuel server.
-      /// E.g.: https://fuel.gazebosim.org/1.0/OpenRobotics/worlds/Empty
-      /// \return True if the world exists in the cache, false otherwise.
-      public: bool CachedWorld(const common::URI &_worldUrl);
-
-      /// \brief Check if a file belonging to a model is already present in the
-      /// local cache.
-      /// \param[in] _fileUrl The unique URL of the file on a Fuel server. E.g.:
-      /// https://server.org/1.0/owner/models/model/files/meshes/mesh.dae
-      /// \param[out] _path Local path where the file can be found.
-      /// \return FETCH_ERROR if not cached, FETCH_ALREADY_EXISTS if cached.
-      public: Result CachedModelFile(const common::URI &_fileUrl,
-                                     std::string &_path);
-
-      /// \brief Check if a file belonging to a world is already present in the
-      /// local cache.
-      /// \param[in] _fileUrl The unique URL of the file on a Fuel server. E.g.:
-      /// https://server.org/1.0/owner/worlds/world/files/name.world
-      /// \param[out] _path Local path where the file can be found.
-      /// \return FETCH_ERROR if not cached, FETCH_ALREADY_EXISTS if cached.
-      public: Result CachedWorldFile(const common::URI &_fileUrl,
-                                     std::string &_path);
-
-      /// \brief Parse model identifier from model URL or unique name.
-      /// \param[in] _modelUrl The unique URL of a model. It may also be a
-      /// unique name, which is a URL without the server version.
-      /// \param[out] _id The model identifier. It may contain incomplete
-      /// information based on the passed URL and the current client
-      /// config.
-      /// The server version will be overridden if that server is in the config
-      /// file.
-      /// \return True if parsed successfully.
-      public: bool ParseModelUrl(const common::URI &_modelUrl,
-                                 ModelIdentifier &_id);
-
-      /// \brief Parse world identifier from world URL or unique name.
-      /// \param[in] _worldUrl The unique URL of a world. It may also be a
-      /// unique name, which is a URL without the server version.
-      /// \param[out] _id The world identifier. It may contain incomplete
-      /// information based on the passed URL and the current client
-      /// config.
-      /// The server version will be overridden if that server is in the config
-      /// file.
-      /// \return True if parsed successfully.
-      public: bool ParseWorldUrl(const common::URI &_worldUrl,
-                                 WorldIdentifier &_id);
-
-      /// \brief Parse model file identifier from model file URL.
-      /// \param[in] _modelFileUrl The unique URL of a model file. It may also
-      /// be a unique name, which is a URL without the server version.
-      /// \param[out] _id The model identifier. It may contain incomplete
-      /// information based on the passed URL and the current client
-      /// config.
-      /// \param[out] _filePath Path to the file from the model's root
-      /// directory, such as "meshes/mesh.dae" or "model.sdf".
-      /// \return True if parsed successfully.
-      public: bool ParseModelFileUrl(const common::URI &_modelFileUrl,
-                                     ModelIdentifier &_id,
-                                     std::string &_filePath);
-
-      /// \brief Parse world file identifier from world file URL.
-      /// \param[in] _worldFileUrl The unique URL of a world file. It may also
-      /// be a unique name, which is a URL without the server version.
-      /// \param[out] _id The world identifier. It may contain incomplete
-      /// information based on the passed URL and the current client
-      /// config.
-      /// \param[out] _filePath Path to the file from the world's root
-      /// directory, such as "name.world"
-      /// \return True if parsed successfully.
-      public: bool ParseWorldFileUrl(const common::URI &_worldFileUrl,
-                                     WorldIdentifier &_id,
-                                     std::string &_filePath);
-
-      /// \brief This function requests the available licenses from the
-      ///  Fuel server and stores this information locally.
-      ///
-      /// The UploadModel function can use this information to set
-      /// appropriate license information based on a model's metadata.pbtxt
-      /// file. If license information is not available, then the
-      /// UploadModel function will default to the
-      /// "Creative Commons - Public Domain" license.
-      /// \param[in] _server Information about the server that provides
-      /// license information.
-      public: void PopulateLicenses(const ServerConfig &_server);
-
-      /// \brief Update a model using a PATCH request.
-      ///
-      /// Model fields that are patched by this function:
-      ///   * private
-      ///
-      /// \param[in] _model The model to patch. The contents of this model
-      ///            will be sent in the PATCH request.
-      /// \param[in] _headers Headers to set on the HTTP request.
-      /// \return Result of the patch operation.
-      public: Result PatchModel(
-                  const gz::fuel_tools::ModelIdentifier &_model,
-                  const std::vector<std::string> &_headers);
-
-      /// \brief Update a model using a PATCH request.
-      ///
-      /// Model fields that are patched by this function:
-      ///   * private
-      ///   * Model files contained in _pathToModelDir.
-      ///   * Description, tags, license, and other attributes found in the
-      ///     metadata.pbtxt or model.config file.
-      ///
-      /// \param[in] _model The model to patch. The contents of this model
-      ///            will be sent in the PATCH request.
-      /// \param[in] _headers Headers to set on the HTTP request.
-      /// \param[in] _pathToModelDir a path to a directory containing a model.
-      /// \return Result of the patch operation.
-      public: Result PatchModel(
-                  const gz::fuel_tools::ModelIdentifier &_model,
-                  const std::vector<std::string> &_headers,
-                  const std::string &_pathToModelDir);
-
-      /// \brief Parse Collection identifer from URL.
-      /// \param[in] _url The unique URL of a collection. It may also be a
-      /// unique name, which is a URL without the server version.
-      /// \param[out] _id The collection identifier. It may contain incomplete
-      /// information based on the passed URL and the current client config.
-      /// The server version will be overridden if that server is in the config
-      /// file.
-      /// \return True if parsed successfully.
-      public: bool ParseCollectionUrl(const common::URI &_url,
-                                      CollectionIdentifier &_id);
-
-      /// \brief Update all models in local cache.
-      /// \param[in] _headers Headers to set on the HTTP request.
-      /// \return True if everything updated successfully.
-      public: bool UpdateModels(const std::vector<std::string> &_headers);
-
-      /// \brief Update all worlds in local cache.
-      /// \param[in] _headers Headers to set on the HTTP request.
-      /// \return True if everything updated successfully.
-      public: bool UpdateWorlds(const std::vector<std::string> &_headers);
-
-      /// \brief Checked if there is any header already specify
-      /// \param[in] _serverConfig Server configuration
-      /// \param[inout] _headers Vector with headers to check
-      private: void AddServerConfigParametersToHeaders(
-        const gz::fuel_tools::ServerConfig &_serverConfig,
-        std::vector<std::string> &_headers) const;
-
-      /// \brief PIMPL
-      private: std::unique_ptr<FuelClientPrivate> dataPtr;
-    };
-  }
-}
+    /// \brief Parse model identifier from model URL or unique name.
+    /// \param[in] _modelUrl The unique URL of a model. It may also be a
+    /// unique name, which is a URL without the server version.
+    /// \param[out] _id The model identifier. It may contain incomplete
+    /// information based on the passed URL and the current client
+    /// config.
+    /// The server version will be overridden if that server is in the config
+    /// file.
+    /// \return True if parsed successfully.
+    public: bool ParseModelUrl(const common::URI &_modelUrl,
+                               ModelIdentifier &_id);
+
+    /// \brief Parse world identifier from world URL or unique name.
+    /// \param[in] _worldUrl The unique URL of a world. It may also be a
+    /// unique name, which is a URL without the server version.
+    /// \param[out] _id The world identifier. It may contain incomplete
+    /// information based on the passed URL and the current client
+    /// config.
+    /// The server version will be overridden if that server is in the config
+    /// file.
+    /// \return True if parsed successfully.
+    public: bool ParseWorldUrl(const common::URI &_worldUrl,
+                               WorldIdentifier &_id);
+
+    /// \brief Parse model file identifier from model file URL.
+    /// \param[in] _modelFileUrl The unique URL of a model file. It may also
+    /// be a unique name, which is a URL without the server version.
+    /// \param[out] _id The model identifier. It may contain incomplete
+    /// information based on the passed URL and the current client
+    /// config.
+    /// \param[out] _filePath Path to the file from the model's root
+    /// directory, such as "meshes/mesh.dae" or "model.sdf".
+    /// \return True if parsed successfully.
+    public: bool ParseModelFileUrl(const common::URI &_modelFileUrl,
+                                   ModelIdentifier &_id,
+                                   std::string &_filePath);
+
+    /// \brief Parse world file identifier from world file URL.
+    /// \param[in] _worldFileUrl The unique URL of a world file. It may also
+    /// be a unique name, which is a URL without the server version.
+    /// \param[out] _id The world identifier. It may contain incomplete
+    /// information based on the passed URL and the current client
+    /// config.
+    /// \param[out] _filePath Path to the file from the world's root
+    /// directory, such as "name.world"
+    /// \return True if parsed successfully.
+    public: bool ParseWorldFileUrl(const common::URI &_worldFileUrl,
+                                   WorldIdentifier &_id,
+                                   std::string &_filePath);
+
+    /// \brief This function requests the available licenses from the
+    ///  Fuel server and stores this information locally.
+    ///
+    /// The UploadModel function can use this information to set
+    /// appropriate license information based on a model's metadata.pbtxt
+    /// file. If license information is not available, then the
+    /// UploadModel function will default to the
+    /// "Creative Commons - Public Domain" license.
+    /// \param[in] _server Information about the server that provides
+    /// license information.
+    public: void PopulateLicenses(const ServerConfig &_server);
+
+    /// \brief Update a model using a PATCH request.
+    ///
+    /// Model fields that are patched by this function:
+    ///   * private
+    ///
+    /// \param[in] _model The model to patch. The contents of this model
+    ///            will be sent in the PATCH request.
+    /// \param[in] _headers Headers to set on the HTTP request.
+    /// \return Result of the patch operation.
+    public: Result PatchModel(
+                const gz::fuel_tools::ModelIdentifier &_model,
+                const std::vector<std::string> &_headers);
+
+    /// \brief Update a model using a PATCH request.
+    ///
+    /// Model fields that are patched by this function:
+    ///   * private
+    ///   * Model files contained in _pathToModelDir.
+    ///   * Description, tags, license, and other attributes found in the
+    ///     metadata.pbtxt or model.config file.
+    ///
+    /// \param[in] _model The model to patch. The contents of this model
+    ///            will be sent in the PATCH request.
+    /// \param[in] _headers Headers to set on the HTTP request.
+    /// \param[in] _pathToModelDir a path to a directory containing a model.
+    /// \return Result of the patch operation.
+    public: Result PatchModel(
+                const gz::fuel_tools::ModelIdentifier &_model,
+                const std::vector<std::string> &_headers,
+                const std::string &_pathToModelDir);
+
+    /// \brief Parse Collection identifer from URL.
+    /// \param[in] _url The unique URL of a collection. It may also be a
+    /// unique name, which is a URL without the server version.
+    /// \param[out] _id The collection identifier. It may contain incomplete
+    /// information based on the passed URL and the current client config.
+    /// The server version will be overridden if that server is in the config
+    /// file.
+    /// \return True if parsed successfully.
+    public: bool ParseCollectionUrl(const common::URI &_url,
+                                    CollectionIdentifier &_id);
+
+    /// \brief Update all models in local cache.
+    /// \param[in] _headers Headers to set on the HTTP request.
+    /// \return True if everything updated successfully.
+    public: bool UpdateModels(const std::vector<std::string> &_headers);
+
+    /// \brief Update all worlds in local cache.
+    /// \param[in] _headers Headers to set on the HTTP request.
+    /// \return True if everything updated successfully.
+    public: bool UpdateWorlds(const std::vector<std::string> &_headers);
+
+    /// \brief Checked if there is any header already specify
+    /// \param[in] _serverConfig Server configuration
+    /// \param[inout] _headers Vector with headers to check
+    private: void AddServerConfigParametersToHeaders(
+      const gz::fuel_tools::ServerConfig &_serverConfig,
+      std::vector<std::string> &_headers) const;
+
+    /// \brief PIMPL
+    private: std::unique_ptr<FuelClientPrivate> dataPtr;
+  };
+}  // namespace gz::fuel_tools
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
-#endif
+#endif  // GZ_FUEL_TOOLS_FUELCLIENT_HH_
diff --git a/include/gz/fuel_tools/Helpers.hh b/include/gz/fuel_tools/Helpers.hh
index 96df74b9..1bcaf94c 100644
--- a/include/gz/fuel_tools/Helpers.hh
+++ b/include/gz/fuel_tools/Helpers.hh
@@ -35,9 +35,7 @@
   #define gz_strdup strdup
 #endif
 
-namespace gz
-{
-namespace fuel_tools
+namespace gz::fuel_tools
 {
 /// \brief Convert the authority portion of a URI to a string
 /// suitable to be used as a path on disk for all platforms.
@@ -60,8 +58,6 @@ std::string sanitizeAuthority(const std::string &_uriAuthority);
 /// \return String suitable to use in file paths
 GZ_FUEL_TOOLS_VISIBLE
 std::string uriToPath(const gz::common::URI &_uri);
-}
-}
+}  // namespace gz::fuel_tools
 
-// GZ_FUEL_TOOLS_HELPERS_HH_
-#endif
+#endif  // GZ_FUEL_TOOLS_HELPERS_HH_
diff --git a/include/gz/fuel_tools/HttpMethod.hh b/include/gz/fuel_tools/HttpMethod.hh
new file mode 100644
index 00000000..12d53b46
--- /dev/null
+++ b/include/gz/fuel_tools/HttpMethod.hh
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 Open Source Robotics Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+#ifndef GZ_FUEL_TOOLS_HTTPMETHOD_HH_
+#define GZ_FUEL_TOOLS_HTTPMETHOD_HH_
+
+#if defined(_WIN32) && defined(DELETE)
+// Windows defines "DELETE" as part of the Win32 "Standard Access Rights"
+// Since we aren't using that here, go ahead and undefine so that we can
+// use it as part of the HttpMethod enum class.
+// Ref: https://learn.microsoft.com/en-us/windows/win32/secauthz/standard-access-rights
+#undef DELETE
+#endif
+
+namespace gz::fuel_tools
+{
+  /// \brief the types of HTTP methods
+  enum class HttpMethod
+  {
+    /// \brief Get method.
+    GET,
+
+    /// \brief Post method.
+    POST,
+
+    /// \brief Delete method.
+    DELETE,
+
+    /// \brief Put method.
+    PUT,
+
+    /// \brief Patch method.
+    PATCH,
+
+    /// \brief Post form method.
+    POST_FORM,
+
+    /// \brief Patch form method.
+    PATCH_FORM
+  };
+}  // namespace gz::fuel_tools
+
+#endif  // GZ_FUEL_TOOLS_HTTPMETHOD_HH_
diff --git a/include/gz/fuel_tools/Interface.hh b/include/gz/fuel_tools/Interface.hh
index 10f5e410..66454c7e 100644
--- a/include/gz/fuel_tools/Interface.hh
+++ b/include/gz/fuel_tools/Interface.hh
@@ -22,46 +22,43 @@
 #include "gz/fuel_tools/Export.hh"
 #include "gz/fuel_tools/FuelClient.hh"
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
-  {
-    /// \brief Download the specified resource into the default configuration of
-    /// fuel tools. This will place the asset in ~/.gz/fuel.
-    /// \param[in] _uri URI to the asset.
-    /// \return Path to the downloaded asset. Empty on error.
-    GZ_FUEL_TOOLS_VISIBLE std::string fetchResource(
-        const std::string &_uri);
+  /// \brief Download the specified resource into the default configuration of
+  /// fuel tools. This will place the asset in ~/.gz/fuel.
+  /// \param[in] _uri URI to the asset.
+  /// \return Path to the downloaded asset. Empty on error.
+  GZ_FUEL_TOOLS_VISIBLE std::string fetchResource(
+      const std::string &_uri);
 
-    /// \brief Download the specified resource using the ClientConfig
-    /// contained in the FuelClient parameter.
-    /// \param[in] _uri URI to the asset.
-    /// \param[in] _client Custom FuelClient configuration.
-    /// \return Path to the downloaded asset. Empty on error.
-    GZ_FUEL_TOOLS_VISIBLE std::string fetchResourceWithClient(
-        const std::string &_uri, gz::fuel_tools::FuelClient &_client);
+  /// \brief Download the specified resource using the ClientConfig
+  /// contained in the FuelClient parameter.
+  /// \param[in] _uri URI to the asset.
+  /// \param[in] _client Custom FuelClient configuration.
+  /// \return Path to the downloaded asset. Empty on error.
+  GZ_FUEL_TOOLS_VISIBLE std::string fetchResourceWithClient(
+      const std::string &_uri, gz::fuel_tools::FuelClient &_client);
 
-    /// \brief Get the SDF file path for a model or world based on a directory
-    /// containing a Fuel model or world. Here is a typical use case:
-    ///
-    ///   1. Fetch a Fuel resource:
-    ///   `std::string resourcePath = fetchResource("https://...")`
-    ///   2. Get the SDF file for the resource:
-    ///   `std::string resourceSdf = sdfFromPath(resourcePath)`
-    ///   3. Parse the SDF file using libsdformat.
-    ///
-    /// This function will determine the SDF file according to the following:
-    ///   1. Check for a metadata.pbtxt file, and return the SDF file specified
-    /// within the metadata.pbtxt file.
-    ///   2. Check for a model.config file, and return the SDF file specified
-    /// withing the model.config file.
-    ///   3. Return the first file with an `.sdf` extension.
-    /// \param[in] _path Filesystem path to a Fuel model or world directory.
-    /// \return Full path to the model or world SDF file, or empty string if
-    /// the SDF file coult not be determined.
-    GZ_FUEL_TOOLS_VISIBLE std::string sdfFromPath(
-        const std::string &_path);
-  }
-}
+  /// \brief Get the SDF file path for a model or world based on a directory
+  /// containing a Fuel model or world. Here is a typical use case:
+  ///
+  ///   1. Fetch a Fuel resource:
+  ///   `std::string resourcePath = fetchResource("https://...")`
+  ///   2. Get the SDF file for the resource:
+  ///   `std::string resourceSdf = sdfFromPath(resourcePath)`
+  ///   3. Parse the SDF file using libsdformat.
+  ///
+  /// This function will determine the SDF file according to the following:
+  ///   1. Check for a metadata.pbtxt file, and return the SDF file specified
+  /// within the metadata.pbtxt file.
+  ///   2. Check for a model.config file, and return the SDF file specified
+  /// withing the model.config file.
+  ///   3. Return the first file with an `.sdf` extension.
+  /// \param[in] _path Filesystem path to a Fuel model or world directory.
+  /// \return Full path to the model or world SDF file, or empty string if
+  /// the SDF file coult not be determined.
+  GZ_FUEL_TOOLS_VISIBLE std::string sdfFromPath(
+      const std::string &_path);
+}  // namespace gz::fuel_tools
 
-#endif
+#endif  // GZ_FUEL_TOOLS_INTERFACE_HH_
diff --git a/include/gz/fuel_tools/JSONParser.hh b/include/gz/fuel_tools/JSONParser.hh
index 86f71e22..02e051bb 100644
--- a/include/gz/fuel_tools/JSONParser.hh
+++ b/include/gz/fuel_tools/JSONParser.hh
@@ -33,91 +33,88 @@ namespace Json
   class Value;
 }
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
-  {
-    class ServerConfig;
-
-    /// \brief A helper class for making REST requests.
-    class GZ_FUEL_TOOLS_VISIBLE JSONParser
-    {
-      /// \brief Parse a model JSON string and return a model identifier
-      /// \param[in] _json JSON string containing a model.
-      /// \param[in] _server The server sending the JSON.
-      /// This information is populated into some fields of the model.
-      /// \return a model identifier
-      public: static ModelIdentifier ParseModel(
-                  const std::string &_json,
-                  const ServerConfig &_server);
-
-      /// \brief Parse a world JSON string and return a world identifier
-      /// \param[in] _json JSON string containing a world.
-      /// \param[in] _server The server sending the JSON.
-      /// This information is populated into some fields of the world.
-      /// \return A world identifier
-      public: static WorldIdentifier ParseWorld(
-                  const std::string &_json,
-                  const ServerConfig &_server);
-
-      /// \brief Parse a model array JSON string and return a model iterator
-      /// \param[in] _json JSON string containing an array of models
-      /// \param[in] _server The server sending the JSON.
-      /// This information is populated into some fields of the models.
-      /// \return vector of model identifiers
-      public: static std::vector<ModelIdentifier> ParseModels(
-                  const std::string &_json,
-                  const ServerConfig &_server);
-
-      /// \brief Parse a world array JSON string and return a world iterator
-      /// \param[in] _json JSON string containing an array of worlds
-      /// \param[in] _server The server sending the JSON.
-      /// This information is populated into some fields of the worlds.
-      /// \return vector of world identifiers
-      public: static std::vector<WorldIdentifier> ParseWorlds(
-                  const std::string &_json,
-                  const ServerConfig &_server);
-
-      /// \brief Build a model iterator from a JSON string
-      /// \param[in] _modelIt A model iterator containing only one model
-      /// \return A JSON string representing a single model
-      public: static std::string BuildModel(ModelIter _modelIt);
-
-      /// \brief Build a world iterator from a JSON string
-      /// \param[in] _worldIt A world iterator containing only one world
-      /// \return A JSON string representing a single world
-      public: static std::string BuildWorld(WorldIter _worldIt);
-
-      /// \brief Parse a license array JSON string and return a map of
-      /// licenses.
-      /// \param[in] _json JSON string containing an array of models
-      /// \param[out] _licenses License information where the keys are license
-      /// names and values are license id's on the Fuel server.
-      /// \return True on success, false otherwise.
-      public: static bool ParseLicenses(const std::string &_json,
-                  std::map<std::string, unsigned int> &_licenses);
-
-      /// \brief Parse a json object as a model.
-      /// \param[in] _json JSON object containing a single model
-      /// \param[out] _model a model identifier after parsing the JSON
-      /// \return True if the parsing succeed or false otherwise
-      private: static bool ParseModelImpl(
-                  const Json::Value &_json, ModelIdentifier &_model);
-
-      /// \brief Parse a JSON object as a world.
-      /// \param[in] _json JSON object containing a single world
-      /// \param[out] _world a world identifier after parsing the JSON
-      /// \return True if the parsing succeed or false otherwise
-      private: static bool ParseWorldImpl(
-                  const Json::Value &_json, WorldIdentifier &_world);
-
-      /// \brief Parse the list of tags contained in a model.
-      /// \param[in] _json JSON representation of the model.
-      /// \return The list of tags.
-      private: static std::vector<std::string> ParseTags(
-                  const Json::Value &_json);
-    };
-  }
-}
+  class ServerConfig;
 
-#endif
+  /// \brief A helper class for making REST requests.
+  class GZ_FUEL_TOOLS_VISIBLE JSONParser
+  {
+    /// \brief Parse a model JSON string and return a model identifier
+    /// \param[in] _json JSON string containing a model.
+    /// \param[in] _server The server sending the JSON.
+    /// This information is populated into some fields of the model.
+    /// \return a model identifier
+    public: static ModelIdentifier ParseModel(
+                const std::string &_json,
+                const ServerConfig &_server);
+
+    /// \brief Parse a world JSON string and return a world identifier
+    /// \param[in] _json JSON string containing a world.
+    /// \param[in] _server The server sending the JSON.
+    /// This information is populated into some fields of the world.
+    /// \return A world identifier
+    public: static WorldIdentifier ParseWorld(
+                const std::string &_json,
+                const ServerConfig &_server);
+
+    /// \brief Parse a model array JSON string and return a model iterator
+    /// \param[in] _json JSON string containing an array of models
+    /// \param[in] _server The server sending the JSON.
+    /// This information is populated into some fields of the models.
+    /// \return vector of model identifiers
+    public: static std::vector<ModelIdentifier> ParseModels(
+                const std::string &_json,
+                const ServerConfig &_server);
+
+    /// \brief Parse a world array JSON string and return a world iterator
+    /// \param[in] _json JSON string containing an array of worlds
+    /// \param[in] _server The server sending the JSON.
+    /// This information is populated into some fields of the worlds.
+    /// \return vector of world identifiers
+    public: static std::vector<WorldIdentifier> ParseWorlds(
+                const std::string &_json,
+                const ServerConfig &_server);
+
+    /// \brief Build a model iterator from a JSON string
+    /// \param[in] _modelIt A model iterator containing only one model
+    /// \return A JSON string representing a single model
+    public: static std::string BuildModel(ModelIter _modelIt);
+
+    /// \brief Build a world iterator from a JSON string
+    /// \param[in] _worldIt A world iterator containing only one world
+    /// \return A JSON string representing a single world
+    public: static std::string BuildWorld(WorldIter _worldIt);
+
+    /// \brief Parse a license array JSON string and return a map of
+    /// licenses.
+    /// \param[in] _json JSON string containing an array of models
+    /// \param[out] _licenses License information where the keys are license
+    /// names and values are license id's on the Fuel server.
+    /// \return True on success, false otherwise.
+    public: static bool ParseLicenses(const std::string &_json,
+                std::map<std::string, unsigned int> &_licenses);
+
+    /// \brief Parse a json object as a model.
+    /// \param[in] _json JSON object containing a single model
+    /// \param[out] _model a model identifier after parsing the JSON
+    /// \return True if the parsing succeed or false otherwise
+    private: static bool ParseModelImpl(
+                const Json::Value &_json, ModelIdentifier &_model);
+
+    /// \brief Parse a JSON object as a world.
+    /// \param[in] _json JSON object containing a single world
+    /// \param[out] _world a world identifier after parsing the JSON
+    /// \return True if the parsing succeed or false otherwise
+    private: static bool ParseWorldImpl(
+                const Json::Value &_json, WorldIdentifier &_world);
+
+    /// \brief Parse the list of tags contained in a model.
+    /// \param[in] _json JSON representation of the model.
+    /// \return The list of tags.
+    private: static std::vector<std::string> ParseTags(
+                const Json::Value &_json);
+  };
+}  // namespace gz::fuel_tools
+
+#endif  // GZ_FUEL_TOOLS_JSONPARSER_HH_
diff --git a/include/gz/fuel_tools/Model.hh b/include/gz/fuel_tools/Model.hh
index 9f918a3a..a2ef929c 100644
--- a/include/gz/fuel_tools/Model.hh
+++ b/include/gz/fuel_tools/Model.hh
@@ -32,89 +32,86 @@
 #pragma warning(disable: 4251)
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
-  {
-    /// \brief Forward Declaration
-    class ModelPrivate;
-
-    /// \brief Forward declaration
-    class ModelIter;
-
-    /// \brief Forward declaration
-    class ModelIterPrivate;
-
-    /// \brief forward declaration
-    class LocalCache;
-
-    /// \brief forward declaration
-    class LocalCachePrivate;
-
-    /// \brief Forward declaration
-    class IterIds;
+  /// \brief Forward Declaration
+  class ModelPrivate;
 
-    /// \brief Forward declaration
-    class IterRESTIds;
+  /// \brief Forward declaration
+  class ModelIter;
 
-    /// \brief Forward declaration
-    class IterRestIds;
+  /// \brief Forward declaration
+  class ModelIterPrivate;
 
-    /// \brief Forward declaration
-    class ModelIterTest;
+  /// \brief forward declaration
+  class LocalCache;
 
-    /// \brief Defines how to identify a model.
-    class GZ_FUEL_TOOLS_VISIBLE Model
-    {
-      friend IterIds;
-      friend IterRESTIds;
-      friend IterRestIds;
-      friend ModelIter;
-      friend ModelIterPrivate;
-      friend ModelIterTest;
-      friend LocalCache;
-      friend LocalCachePrivate;
+  /// \brief forward declaration
+  class LocalCachePrivate;
 
-      /// \brief Default constructor
-      public: Model();
+  /// \brief Forward declaration
+  class IterIds;
 
-      /// \brief Copy constructor
-      /// \param[in] _orig Model to copy.
-      public: Model(const Model &_orig) = default;
+  /// \brief Forward declaration
+  class IterRESTIds;
 
-      /// \brief Protected constructor
-      /// \param[in] _dPtr Model private data to copy.
-      protected: explicit Model(std::shared_ptr<ModelPrivate> _dptr);
+  /// \brief Forward declaration
+  class IterRestIds;
 
-      /// \brief Returns false if model was constructed via Model()
-      public: operator bool() const;
+  /// \brief Forward declaration
+  class ModelIterTest;
 
-      /// \brief Returns false if model was constructed via Model().
-      /// \return False if model was constructed via Model().
-      public: operator bool();
-
-      /// \brief Returns information identifying the model.
-      /// \return Information that can identify the model.
-      public: ModelIdentifier Identification() const;
-
-      /// \brief Make sure this model is in the local cache
-      /// \remarks this downloads the model and saves it locally if necessary
-      /// \returns The result of fetching
-      public: Result Fetch() const;
-
-      /// \brief Returns a path to the model on disk if it is already
-      /// cached.
-      /// \returns path, or empty string if the model is not cached.
-      public: std::string PathToModel() const;
-
-      /// \brief PIMPL
-      private: std::shared_ptr<ModelPrivate> dataPtr;
-    };
-  }
-}
+  /// \brief Defines how to identify a model.
+  class GZ_FUEL_TOOLS_VISIBLE Model
+  {
+    friend IterIds;
+    friend IterRESTIds;
+    friend IterRestIds;
+    friend ModelIter;
+    friend ModelIterPrivate;
+    friend ModelIterTest;
+    friend LocalCache;
+    friend LocalCachePrivate;
+
+    /// \brief Default constructor
+    public: Model();
+
+    /// \brief Copy constructor
+    /// \param[in] _orig Model to copy.
+    public: Model(const Model &_orig) = default;
+
+    /// \brief Protected constructor
+    /// \param[in] _dPtr Model private data to copy.
+    protected: explicit Model(std::shared_ptr<ModelPrivate> _dptr);
+
+    /// \brief Returns false if model was constructed via Model()
+    public: operator bool() const;
+
+    /// \brief Returns false if model was constructed via Model().
+    /// \return False if model was constructed via Model().
+    public: operator bool();
+
+    /// \brief Returns information identifying the model.
+    /// \return Information that can identify the model.
+    public: ModelIdentifier Identification() const;
+
+    /// \brief Make sure this model is in the local cache
+    /// \remarks this downloads the model and saves it locally if necessary
+    /// \returns The result of fetching
+    public: Result Fetch() const;
+
+    /// \brief Returns a path to the model on disk if it is already
+    /// cached.
+    /// \returns path, or empty string if the model is not cached.
+    public: std::string PathToModel() const;
+
+    /// \brief PIMPL
+    private: std::shared_ptr<ModelPrivate> dataPtr;
+  };
+}  // namespace gz::fuel_tools
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
-#endif
+#endif  // GZ_FUEL_TOOLS_MODEL_HH_
diff --git a/include/gz/fuel_tools/ModelIdentifier.hh b/include/gz/fuel_tools/ModelIdentifier.hh
index b126c7f5..70eb9d2a 100644
--- a/include/gz/fuel_tools/ModelIdentifier.hh
+++ b/include/gz/fuel_tools/ModelIdentifier.hh
@@ -33,232 +33,229 @@
 #pragma warning(disable: 4251)
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
+  /// \brief Forward Declaration
+  class ModelIdentifierPrivate;
+  class ServerConfig;
+
+  /// \brief Defines how to identify a model
+  class GZ_FUEL_TOOLS_VISIBLE ModelIdentifier
   {
-    /// \brief Forward Declaration
-    class ModelIdentifierPrivate;
-    class ServerConfig;
-
-    /// \brief Defines how to identify a model
-    class GZ_FUEL_TOOLS_VISIBLE ModelIdentifier
-    {
-      /// \brief Constructor.
-      public: ModelIdentifier();
-
-      /// \brief Copy Constructor.
-      /// \param[in] _orig ModelIdentifier to copy.
-      public: ModelIdentifier(const ModelIdentifier &_orig);
-
-      /// \brief Destructor.
-      public: ~ModelIdentifier();
-
-      /// \brief Assignment operator
-      /// \param[in] _orig ModelIdentifier to copy.
-      /// \return Reference to this object.
-      public: ModelIdentifier &operator=(const ModelIdentifier &_orig);
-
-      /// \brief Equality operator.
-      /// \param[in] _rhs ModelIdentifier to compare.
-      /// \return True if the ModelIdentifier names are equal.
-      public: bool operator==(const ModelIdentifier &_rhs) const;
-
-      /// \brief Inequality operator.
-      /// \param[in] _rhs ModelIdentifier to compare.
-      /// \return True if the ModelIdentifier names are not equal.
-      public: bool operator!=(const ModelIdentifier &_rhs) const;
-
-      /// \brief Returns just the last part of the model name.
-      /// \return Model name.
-      public: std::string Name() const;
-
-      /// \brief Returns owner to attribute model to.
-      /// \return Owner name.
-      public: std::string Owner() const;
-
-      /// \brief Returns server information to retrieve model from.
-      /// \return Server information.
-      public: ServerConfig &Server() const;
-
-      /// \brief Returns a unique name for the model.
-      /// \remarks this is Server/Owner/Name.
-      /// \return Unique model name.
-      public: std::string UniqueName() const;
-
-      /// \brief set the name of the model.
-      /// \param[in] _name The name to set. Must be ascii and pass [-_a-z0-9]+.
-      /// \return true if successful.
-      public: bool SetName(const std::string &_name);
-
-      /// \brief Set the owner of the model
-      /// \param[in] _name The name to set. Must be ascii and pass [-_a-z0-9]+
-      /// \return true if successful
-      public: bool SetOwner(const std::string &_name);
-
-      /// \brief Set the server from which this model comes.
-      /// \param[in] _server The server to retrieve the model from.
-      /// \return True if successful.
-      public: bool SetServer(const ServerConfig &_server);
-
-      /// \brief Returns the description of the model.
-      /// \return Model description.
-      public: std::string Description() const;
-
-      /// \brief Returns the file size of the model in bytes.
-      /// \return Model file size in bytes.
-      public: unsigned int FileSize() const;
-
-      /// \brief Returns the upload date of the model.
-      /// \return Model upload date.
-      public: std::time_t UploadDate() const;
-
-      /// \brief Returns the modify date of the model.
-      /// \return Model modify date.
-      public: std::time_t ModifyDate() const;
-
-      /// \brief Returns the number of "likes" for the model.
-      /// \return Number of "likes".
-      public: uint32_t LikeCount() const;
-
-      /// \brief Returns the number of downloads for the model.
-      /// \return Number of downloads.
-      public: uint32_t DownloadCount() const;
-
-      /// \brief Returns the license name.
-      /// \return License name.
-      public: std::string LicenseName() const;
-
-      /// \brief Returns the license URL.
-      /// \return License URL.
-      public: std::string LicenseUrl() const;
-
-      /// \brief Returns the license image URL.
-      /// \return License image URL.
-      public: std::string LicenseImageUrl() const;
-
-      /// \brief Returns the collection of tags.
-      /// \return The collection of tags.
-      public: std::vector<std::string> Tags() const;
-
-      /// \brief Returns the privacy setting of the model.
-      /// \return True if the model is private, false if the model is
-      /// public.
-      public: bool Private() const;
-
-      /// \brief Set the privacy setting of the model.
-      /// \param[in] True indicates the model is private, false indicates the
-      /// model is public.
-      public: void SetPrivate(bool _private) const;
-
-      /// \brief Set the description of the model.
-      /// \param[in] _desc The description
-      /// \return True if successful.
-      public: bool SetDescription(const std::string &_desc);
-
-      /// \brief Set the file size of the model in bytes.
-      /// \param[in] _filesize The model's file size in bytes.
-      /// \return True if successful.
-      public: bool SetFileSize(const unsigned int _filesize);
-
-      /// \brief Set the upload date.
-      /// \param[in] _date Upload date.
-      /// \return True if successful.
-      public: bool SetUploadDate(const std::time_t &_date);
-
-      /// \brief Set the modify date
-      /// \return True if successful
-      public: bool SetModifyDate(const std::time_t &_date);
-
-      /// \brief Set the number of "likes" of the model.
-      /// \param[in] _likes Number of "likes".
-      /// \return True if successful.
-      public: bool SetLikeCount(const uint32_t _likes);
-
-      /// \brief Set the number of downloads of the model.
-      /// \param[in] _downloads Number of downloads.
-      /// \return True if successful.
-      public: bool SetDownloadCount(const uint32_t _downloads);
-
-      /// \brief Set the license name of the model.
-      /// \param[in] _name The name.
-      /// \return True if successful.
-      public: bool SetLicenseName(const std::string &_name);
-
-      /// \brief Set the license URL of the model.
-      /// \param[in] _url The URL.
-      /// \return True if successful.
-      public: bool SetLicenseUrl(const std::string &_url);
-
-      /// \brief Set the license image URL of the model.
-      /// \param[in] _url The URL.
-      /// \return True if successful.
-      public: bool SetLicenseImageUrl(const std::string &_url);
-
-      /// \brief Set the list of tags of the model.
-      /// \param[in] _tags The tags.
-      /// \return True if successful.
-      public: bool SetTags(const std::vector<std::string> &_tags);
-
-      /// \brief Returns the model's version as a number. Versions are integers
-      /// counting from 1. Version zero means the tip.
-      /// \return Model's version.
-      /// \sa VersionStr
-      /// \sa SetVersion
-      public: unsigned int Version() const;
-
-      /// \brief Returns the model's version as a string. Versions are integers
-      /// counting from 1. The strings "tip" or "" mean the latest version.
-      /// \return Model's version.
-      /// \sa Version
-      /// \sa SetVersionStr
-      public: std::string VersionStr() const;
-
-      /// \brief Set the model's version. Versions are integers counting from
-      /// 1.
-      /// \param[in] _version The model's version
-      /// \return True if successful.
-      /// \sa Version
-      /// \sa SetVersionStr
-      public: bool SetVersion(const unsigned int _version);
-
-      /// \brief Set the model's version. Versions are integers counting from
-      /// 1 or "tip" for the latest version.
-      /// \param[in] _version The model's version
-      /// \return True if successful.
-      /// \sa VersionStr
-      /// \sa SetVersion
-      public: bool SetVersionStr(const std::string &_version);
-
-      // /// \brief returns a SHA 2 256 hash of the model
-      // /// \remarks fulfills versioning requirement
-      // public: std::array<std::uint8_t, 32> SHA_256() const;
-
-      // /// \brief Sets the SHA 2 256 hash of the model
-      // /// \param[in] _hash a 256 bit SHA 2 hash
-      // /// \returns true if successful
-      // public: bool SHA_256(const std::array<std::uint8_t, 32> &_hash);
-
-      /// \brief Returns all the model information as a string. Convenient for
-      /// debugging.
-      /// \param[in] _prefix Optional prefix for every line of the string.
-      /// \return Model information string
-      public: std::string AsString(const std::string &_prefix = "") const;
-
-      /// \brief Returns all the available model information as a string using
-      /// colors for better human parsing.
-      /// \param[in] _prefix Optional prefix for every line of the string.
-      /// \return Model information string
-      public: std::string AsPrettyString(const std::string &_prefix = "") const;
-
-      /// \brief PIMPL
-      private: std::unique_ptr<ModelIdentifierPrivate> dataPtr;
-    };
-  }
-}
+    /// \brief Constructor.
+    public: ModelIdentifier();
+
+    /// \brief Copy Constructor.
+    /// \param[in] _orig ModelIdentifier to copy.
+    public: ModelIdentifier(const ModelIdentifier &_orig);
+
+    /// \brief Destructor.
+    public: ~ModelIdentifier();
+
+    /// \brief Assignment operator
+    /// \param[in] _orig ModelIdentifier to copy.
+    /// \return Reference to this object.
+    public: ModelIdentifier &operator=(const ModelIdentifier &_orig);
+
+    /// \brief Equality operator.
+    /// \param[in] _rhs ModelIdentifier to compare.
+    /// \return True if the ModelIdentifier names are equal.
+    public: bool operator==(const ModelIdentifier &_rhs) const;
+
+    /// \brief Inequality operator.
+    /// \param[in] _rhs ModelIdentifier to compare.
+    /// \return True if the ModelIdentifier names are not equal.
+    public: bool operator!=(const ModelIdentifier &_rhs) const;
+
+    /// \brief Returns just the last part of the model name.
+    /// \return Model name.
+    public: std::string Name() const;
+
+    /// \brief Returns owner to attribute model to.
+    /// \return Owner name.
+    public: std::string Owner() const;
+
+    /// \brief Returns server information to retrieve model from.
+    /// \return Server information.
+    public: ServerConfig &Server() const;
+
+    /// \brief Returns a unique name for the model.
+    /// \remarks this is Server/Owner/Name.
+    /// \return Unique model name.
+    public: std::string UniqueName() const;
+
+    /// \brief set the name of the model.
+    /// \param[in] _name The name to set. Must be ascii and pass [-_a-z0-9]+.
+    /// \return true if successful.
+    public: bool SetName(const std::string &_name);
+
+    /// \brief Set the owner of the model
+    /// \param[in] _name The name to set. Must be ascii and pass [-_a-z0-9]+
+    /// \return true if successful
+    public: bool SetOwner(const std::string &_name);
+
+    /// \brief Set the server from which this model comes.
+    /// \param[in] _server The server to retrieve the model from.
+    /// \return True if successful.
+    public: bool SetServer(const ServerConfig &_server);
+
+    /// \brief Returns the description of the model.
+    /// \return Model description.
+    public: std::string Description() const;
+
+    /// \brief Returns the file size of the model in bytes.
+    /// \return Model file size in bytes.
+    public: unsigned int FileSize() const;
+
+    /// \brief Returns the upload date of the model.
+    /// \return Model upload date.
+    public: std::time_t UploadDate() const;
+
+    /// \brief Returns the modify date of the model.
+    /// \return Model modify date.
+    public: std::time_t ModifyDate() const;
+
+    /// \brief Returns the number of "likes" for the model.
+    /// \return Number of "likes".
+    public: uint32_t LikeCount() const;
+
+    /// \brief Returns the number of downloads for the model.
+    /// \return Number of downloads.
+    public: uint32_t DownloadCount() const;
+
+    /// \brief Returns the license name.
+    /// \return License name.
+    public: std::string LicenseName() const;
+
+    /// \brief Returns the license URL.
+    /// \return License URL.
+    public: std::string LicenseUrl() const;
+
+    /// \brief Returns the license image URL.
+    /// \return License image URL.
+    public: std::string LicenseImageUrl() const;
+
+    /// \brief Returns the collection of tags.
+    /// \return The collection of tags.
+    public: std::vector<std::string> Tags() const;
+
+    /// \brief Returns the privacy setting of the model.
+    /// \return True if the model is private, false if the model is
+    /// public.
+    public: bool Private() const;
+
+    /// \brief Set the privacy setting of the model.
+    /// \param[in] True indicates the model is private, false indicates the
+    /// model is public.
+    public: void SetPrivate(bool _private) const;
+
+    /// \brief Set the description of the model.
+    /// \param[in] _desc The description
+    /// \return True if successful.
+    public: bool SetDescription(const std::string &_desc);
+
+    /// \brief Set the file size of the model in bytes.
+    /// \param[in] _filesize The model's file size in bytes.
+    /// \return True if successful.
+    public: bool SetFileSize(const unsigned int _filesize);
+
+    /// \brief Set the upload date.
+    /// \param[in] _date Upload date.
+    /// \return True if successful.
+    public: bool SetUploadDate(const std::time_t &_date);
+
+    /// \brief Set the modify date
+    /// \return True if successful
+    public: bool SetModifyDate(const std::time_t &_date);
+
+    /// \brief Set the number of "likes" of the model.
+    /// \param[in] _likes Number of "likes".
+    /// \return True if successful.
+    public: bool SetLikeCount(const uint32_t _likes);
+
+    /// \brief Set the number of downloads of the model.
+    /// \param[in] _downloads Number of downloads.
+    /// \return True if successful.
+    public: bool SetDownloadCount(const uint32_t _downloads);
+
+    /// \brief Set the license name of the model.
+    /// \param[in] _name The name.
+    /// \return True if successful.
+    public: bool SetLicenseName(const std::string &_name);
+
+    /// \brief Set the license URL of the model.
+    /// \param[in] _url The URL.
+    /// \return True if successful.
+    public: bool SetLicenseUrl(const std::string &_url);
+
+    /// \brief Set the license image URL of the model.
+    /// \param[in] _url The URL.
+    /// \return True if successful.
+    public: bool SetLicenseImageUrl(const std::string &_url);
+
+    /// \brief Set the list of tags of the model.
+    /// \param[in] _tags The tags.
+    /// \return True if successful.
+    public: bool SetTags(const std::vector<std::string> &_tags);
+
+    /// \brief Returns the model's version as a number. Versions are integers
+    /// counting from 1. Version zero means the tip.
+    /// \return Model's version.
+    /// \sa VersionStr
+    /// \sa SetVersion
+    public: unsigned int Version() const;
+
+    /// \brief Returns the model's version as a string. Versions are integers
+    /// counting from 1. The strings "tip" or "" mean the latest version.
+    /// \return Model's version.
+    /// \sa Version
+    /// \sa SetVersionStr
+    public: std::string VersionStr() const;
+
+    /// \brief Set the model's version. Versions are integers counting from
+    /// 1.
+    /// \param[in] _version The model's version
+    /// \return True if successful.
+    /// \sa Version
+    /// \sa SetVersionStr
+    public: bool SetVersion(const unsigned int _version);
+
+    /// \brief Set the model's version. Versions are integers counting from
+    /// 1 or "tip" for the latest version.
+    /// \param[in] _version The model's version
+    /// \return True if successful.
+    /// \sa VersionStr
+    /// \sa SetVersion
+    public: bool SetVersionStr(const std::string &_version);
+
+    // /// \brief returns a SHA 2 256 hash of the model
+    // /// \remarks fulfills versioning requirement
+    // public: std::array<std::uint8_t, 32> SHA_256() const;
+
+    // /// \brief Sets the SHA 2 256 hash of the model
+    // /// \param[in] _hash a 256 bit SHA 2 hash
+    // /// \returns true if successful
+    // public: bool SHA_256(const std::array<std::uint8_t, 32> &_hash);
+
+    /// \brief Returns all the model information as a string. Convenient for
+    /// debugging.
+    /// \param[in] _prefix Optional prefix for every line of the string.
+    /// \return Model information string
+    public: std::string AsString(const std::string &_prefix = "") const;
+
+    /// \brief Returns all the available model information as a string using
+    /// colors for better human parsing.
+    /// \param[in] _prefix Optional prefix for every line of the string.
+    /// \return Model information string
+    public: std::string AsPrettyString(const std::string &_prefix = "") const;
+
+    /// \brief PIMPL
+    private: std::unique_ptr<ModelIdentifierPrivate> dataPtr;
+  };
+}  // namespace gz::fuel_tools
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
-#endif
+#endif  // GZ_FUEL_TOOLS_MODELIDENTIFIER_HH_
diff --git a/include/gz/fuel_tools/ModelIter.hh b/include/gz/fuel_tools/ModelIter.hh
index e623293e..d68c3813 100644
--- a/include/gz/fuel_tools/ModelIter.hh
+++ b/include/gz/fuel_tools/ModelIter.hh
@@ -30,59 +30,56 @@
 #pragma warning(disable: 4251)
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
-  {
-    /// \brief forward declaration
-    class FuelClient;
-    class ModelIterPrivate;
-    class ModelIterFactory;
+  /// \brief forward declaration
+  class FuelClient;
+  class ModelIterPrivate;
+  class ModelIterFactory;
 
-    /// \brief class for iterating through models
-    class GZ_FUEL_TOOLS_VISIBLE ModelIter
-    {
-      friend ModelIterFactory;
+  /// \brief class for iterating through models
+  class GZ_FUEL_TOOLS_VISIBLE ModelIter
+  {
+    friend ModelIterFactory;
 
-      /// \brief Construct an iterator with the data it needs to function
-      /// \param[in] _dptr Pointer to private data to copy
-      protected: explicit ModelIter(std::unique_ptr<ModelIterPrivate> _dptr);
+    /// \brief Construct an iterator with the data it needs to function
+    /// \param[in] _dptr Pointer to private data to copy
+    protected: explicit ModelIter(std::unique_ptr<ModelIterPrivate> _dptr);
 
-      /// \brief Move constructor
-      /// \param[in] _old Iter to move
-      public: ModelIter(ModelIter && _old);
+    /// \brief Move constructor
+    /// \param[in] _old Iter to move
+    public: ModelIter(ModelIter && _old);
 
-      /// \brief Default destructor.
-      public: ~ModelIter();
+    /// \brief Default destructor.
+    public: ~ModelIter();
 
-      /// \brief Conversion operator
-      /// \return false once the iterator is one past the end of the models
-      public: operator bool();
+    /// \brief Conversion operator
+    /// \return false once the iterator is one past the end of the models
+    public: operator bool();
 
-      /// \brief Conversion operator
-      /// \return false once the iterator is one past the end of the models
-      public: operator bool() const;
+    /// \brief Conversion operator
+    /// \return false once the iterator is one past the end of the models
+    public: operator bool() const;
 
-      /// \brief Prefix increment
-      /// \return Next iteration
-      public: ModelIter &operator++();
+    /// \brief Prefix increment
+    /// \return Next iteration
+    public: ModelIter &operator++();
 
-      /// \brief Dereference operator
-      /// \return Reference
-      public: Model &operator*();
+    /// \brief Dereference operator
+    /// \return Reference
+    public: Model &operator*();
 
-      /// \brief -> operator
-      /// \return Internal world identifier
-      public: Model *operator->();
+    /// \brief -> operator
+    /// \return Internal world identifier
+    public: Model *operator->();
 
-      /// \brief Private data pointer.
-      private: std::unique_ptr<ModelIterPrivate> dataPtr;
-    };
-  }
-}
+    /// \brief Private data pointer.
+    private: std::unique_ptr<ModelIterPrivate> dataPtr;
+  };
+}  // namespace gz::fuel_tools
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
-#endif
+#endif  // GZ_FUEL_TOOLS_MODELITER_HH_
diff --git a/include/gz/fuel_tools/RestClient.hh b/include/gz/fuel_tools/RestClient.hh
index ad63625a..30500996 100644
--- a/include/gz/fuel_tools/RestClient.hh
+++ b/include/gz/fuel_tools/RestClient.hh
@@ -23,117 +23,88 @@
 #include <vector>
 
 #include "gz/fuel_tools/Export.hh"
+#include "gz/fuel_tools/HttpMethod.hh"
 
 #ifdef _WIN32
 // Disable warning C4251 which is triggered by
 // std::string
 #pragma warning(push)
 #pragma warning(disable: 4251)
-// TODO(jrivero): rename the DELETE method which is a reserved word in Windows
-#undef DELETE
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
+  /// \brief Stores a response to a RESTful request
+  struct GZ_FUEL_TOOLS_VISIBLE RestResponse
   {
-    /// \brief Stores a response to a RESTful request
-    struct GZ_FUEL_TOOLS_VISIBLE RestResponse
-    {
-      /// \brief The returned status code. E.g.: 200
-      // cppcheck-suppress unusedStructMember
-      public: int statusCode = 0;
+    /// \brief The returned status code. E.g.: 200
+    // cppcheck-suppress unusedStructMember
+    public: int statusCode = 0;
 
-      /// \brief The data received.
-      public: std::string data = "";
+    /// \brief The data received.
+    public: std::string data = "";
 
-      /// \brief Map of headers where the key is the header type.
-      /// For example, a raw header of the form "Content-Type: json" would
-      /// use "Content-Type" as a key and "json" as the key's data.
-      public: std::map<std::string, std::string> headers;
-    };
+    /// \brief Map of headers where the key is the header type.
+    /// For example, a raw header of the form "Content-Type: json" would
+    /// use "Content-Type" as a key and "json" as the key's data.
+    public: std::map<std::string, std::string> headers;
+  };
 
-    /// \brief the types of HTTP methods
-    enum class HttpMethod
-    {
-      /// \brief Get method.
-      GET,
-
-      /// \brief Post method.
-      POST,
-
-      /// \brief Delete method.
-      DELETE,
-
-      /// \brief Put method.
-      PUT,
-
-      /// \brief Patch method.
-      PATCH,
-
-      /// \brief Post form method.
-      POST_FORM,
-
-      /// \brief Patch form method.
-      PATCH_FORM
-    };
-
-    /// \brief A helper class for making REST requests.
-    class GZ_FUEL_TOOLS_VISIBLE Rest
-    {
-      /// \brief Default constructor.
-      public: Rest() = default;
-
-      /// \brief Trigger a REST request.
-      /// \param[in] _method The HTTP method. Use all uppercase letters.
-      ///            E.g.: "GET"
-      /// \param[in] _url The url to request.
-      ///            E.g.: "http://localhost:8000/"
-      /// \param[in] _version The protocol version.
-      ///            E.g.: "1.0"
-      /// \param[in] _path The path to request.
-      ///            E.g.: "collection"
-      /// \param[in] _queryStrings All the query strings to be requested.
-      ///            E.g.: {"sort=name", "sortdir=1"}
-      /// \param[in] _headers All the headers to be included in the HTTP request
-      ///            E.g.: {"Accept: application/json"}
-      /// \param[in] _data Data to be included in the HTTP request.
-      /// \param[in] _form Multi-part / form data to be used with
-      /// Method::POST_FORM. Files can be transferred by using a value of
-      /// "@<local_file_path>;<upload_filename>". For example, to transfer the
-      /// local file "/tmp/test.txt" and upload the file as "changed.txt"
-      /// in a form with the field name "file", then insert
-      /// the following key-value pair into the _form parameter:
-      /// `{"file", "@/tmp/test.txt;changed.txt"}`. The ";<upload_filename>"
-      /// portion is optional. If this part is absent, then the basename of
-      /// provided "<local_file_path>" is used. For example,
-      /// "@/tmp/text.txt" will be uploaded as "text.txt".
-      public: virtual RestResponse Request(const HttpMethod _method,
-          const std::string &_url,
-          const std::string &_version,
-          const std::string &_path,
-          const std::vector<std::string> &_queryStrings,
-          const std::vector<std::string> &_headers,
-          const std::string &_data,
-          const std::multimap<std::string, std::string> &_form =
-          std::multimap<std::string, std::string>()) const;
-
-      /// \brief Set the user agent name.
-      /// \param[in] _agent User agent name.
-      public: void SetUserAgent(const std::string &_agent);
-
-      /// \brief Get the user agent name.
-      /// \return Name of the user agent.
-      public: const std::string &UserAgent() const;
-
-      /// \brief The user agent name.
-      private: std::string userAgent;
-    };
-  }
-}
+  /// \brief A helper class for making REST requests.
+  class GZ_FUEL_TOOLS_VISIBLE Rest
+  {
+    /// \brief Default constructor.
+    public: Rest() = default;
+
+    /// \brief Trigger a REST request.
+    /// \param[in] _method The HTTP method. Use all uppercase letters.
+    ///            E.g.: "GET"
+    /// \param[in] _url The url to request.
+    ///            E.g.: "http://localhost:8000/"
+    /// \param[in] _version The protocol version.
+    ///            E.g.: "1.0"
+    /// \param[in] _path The path to request.
+    ///            E.g.: "collection"
+    /// \param[in] _queryStrings All the query strings to be requested.
+    ///            E.g.: {"sort=name", "sortdir=1"}
+    /// \param[in] _headers All the headers to be included in the HTTP request
+    ///            E.g.: {"Accept: application/json"}
+    /// \param[in] _data Data to be included in the HTTP request.
+    /// \param[in] _form Multi-part / form data to be used with
+    /// Method::POST_FORM. Files can be transferred by using a value of
+    /// "@<local_file_path>;<upload_filename>". For example, to transfer the
+    /// local file "/tmp/test.txt" and upload the file as "changed.txt"
+    /// in a form with the field name "file", then insert
+    /// the following key-value pair into the _form parameter:
+    /// `{"file", "@/tmp/test.txt;changed.txt"}`. The ";<upload_filename>"
+    /// portion is optional. If this part is absent, then the basename of
+    /// provided "<local_file_path>" is used. For example,
+    /// "@/tmp/text.txt" will be uploaded as "text.txt".
+    public: virtual RestResponse Request(const HttpMethod _method,
+        const std::string &_url,
+        const std::string &_version,
+        const std::string &_path,
+        const std::vector<std::string> &_queryStrings,
+        const std::vector<std::string> &_headers,
+        const std::string &_data,
+        const std::multimap<std::string, std::string> &_form =
+        std::multimap<std::string, std::string>()) const;
+
+    /// \brief Set the user agent name.
+    /// \param[in] _agent User agent name.
+    public: void SetUserAgent(const std::string &_agent);
+
+    /// \brief Get the user agent name.
+    /// \return Name of the user agent.
+    public: const std::string &UserAgent() const;
+
+    /// \brief The user agent name.
+    private: std::string userAgent;
+  };
+}  // namespace gz::fuel_tools
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
-#endif
+#endif  // GZ_FUEL_TOOLS_RESTCLIENT_HH_
diff --git a/include/gz/fuel_tools/Result.hh b/include/gz/fuel_tools/Result.hh
index 54c084e2..d5d6bdd7 100644
--- a/include/gz/fuel_tools/Result.hh
+++ b/include/gz/fuel_tools/Result.hh
@@ -22,120 +22,70 @@
 #include <string>
 
 #include "gz/fuel_tools/Export.hh"
+#include "gz/fuel_tools/ResultType.hh"
 
 #ifdef _WIN32
 // Disable warning C4251 which is triggered by
 // std::unique_ptr
 #pragma warning(push)
 #pragma warning(disable: 4251)
-// TODO(jrivero): rename the DELETE method which is a reserved word in Windows
-#undef DELETE
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
-  {
-    // forward declaration
-    class ResultPrivate;
-    class Model;
-
-    /// Result type.
-    enum class ResultType
-    {
-      /// \brief Uninitialized type.
-      UNKNOWN = 0,
-
-      /// \brief Delete successful.
-      DELETE,
-
-      /// \brief Model not found.
-      DELETE_NOT_FOUND,
-
-      /// \brief Delete failed. Other errors.
-      /// \sa ReadableResult
-      DELETE_ERROR,
-
-      /// \brief Fetch successful.
-      FETCH,
-
-      /// \brief Model already exists.
-      FETCH_ALREADY_EXISTS,
-
-      /// \brief Model not found.
-      FETCH_NOT_FOUND,
+  // forward declaration
+  class ResultPrivate;
+  class Model;
 
-      /// \brief Fetch failed. Other errors.
-      /// \sa ReadableResult
-      FETCH_ERROR,
-
-      /// \brief Upload successful.
-      UPLOAD,
-
-      /// \brief Model already exists.
-      UPLOAD_ALREADY_EXISTS,
-
-      /// \brief Upload failed. Other errors.
-      /// \sa ReadableResult
-      UPLOAD_ERROR,
-
-      /// \brief Patch failed.
-      PATCH_ERROR,
-
-      /// \brief Patch successful.
-      PATCH,
-    };
-
-    /// \brief Class describing a result of an operation.
-    class GZ_FUEL_TOOLS_VISIBLE Result
-    {
-      /// \brief Default constructor
-      public: Result();
+  /// \brief Class describing a result of an operation.
+  class GZ_FUEL_TOOLS_VISIBLE Result
+  {
+    /// \brief Default constructor
+    public: Result();
 
-      /// \brief Destructor.
-      public: virtual ~Result();
+    /// \brief Destructor.
+    public: virtual ~Result();
 
-      /// \brief Constructor
-      /// \param[in] _type Result type
-      public: explicit Result(const ResultType _type);
+    /// \brief Constructor
+    /// \param[in] _type Result type
+    public: explicit Result(const ResultType _type);
 
-      /// \brief Copy constructor.
-      /// \param[in] _result Result to copy.
-      public: Result(const Result &_result);
+    /// \brief Copy constructor.
+    /// \param[in] _result Result to copy.
+    public: Result(const Result &_result);
 
-      /// \brief Move constructor
-      /// \param[in] _result Result to move.
-      public: Result(Result &&_result) noexcept;  // NOLINT
+    /// \brief Move constructor
+    /// \param[in] _result Result to move.
+    public: Result(Result &&_result) noexcept;  // NOLINT
 
-      /// \brief Copy assignment operator.
-      /// \param[in] _result Result to copy.
-      public: Result &operator=(const Result &_result);
+    /// \brief Copy assignment operator.
+    /// \param[in] _result Result to copy.
+    public: Result &operator=(const Result &_result);
 
-      /// \brief Move assignment operator.
-      /// \param[in] _result Result component to move.
-      /// \return Reference to this.
-      public: Result &operator=(Result &&_result) noexcept;  // NOLINT
+    /// \brief Move assignment operator.
+    /// \param[in] _result Result component to move.
+    /// \return Reference to this.
+    public: Result &operator=(Result &&_result) noexcept;  // NOLINT
 
-      /// \brief Get the type of result
-      /// \return The type of result.
-      public: ResultType Type() const;
+    /// \brief Get the type of result
+    /// \return The type of result.
+    public: ResultType Type() const;
 
-      /// \brief Operator bool returns true if operation was successful.
-      /// \return True if the operation was successful.
-      public: virtual operator bool() const;
+    /// \brief Operator bool returns true if operation was successful.
+    /// \return True if the operation was successful.
+    public: virtual operator bool() const;
 
-      /// \brief Get human readable result string.
-      /// \return The result string.
-      public: virtual std::string ReadableResult() const;
+    /// \brief Get human readable result string.
+    /// \return The result string.
+    public: virtual std::string ReadableResult() const;
 
-      /// brief Pointer to private data
-      private: std::unique_ptr<ResultPrivate> dataPtr;
-    };
-  }
-}
+    /// brief Pointer to private data
+    private: std::unique_ptr<ResultPrivate> dataPtr;
+  };
+}  // namespace gz::fuel_tools
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
-#endif
+#endif  // GZ_FUEL_TOOLS_RESULT_HH_
diff --git a/include/gz/fuel_tools/ResultType.hh b/include/gz/fuel_tools/ResultType.hh
new file mode 100644
index 00000000..59ffb39e
--- /dev/null
+++ b/include/gz/fuel_tools/ResultType.hh
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024 Open Source Robotics Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+#ifndef GZ_FUEL_TOOLS_RESULTTYPE_HH_
+#define GZ_FUEL_TOOLS_RESULTTYPE_HH_
+
+#if defined(_WIN32) && defined(DELETE)
+// Windows defines "DELETE" as part of the Win32 "Standard Access Rights"
+// Since we aren't using that here, go ahead and undefine so that we can
+// use it as part of the ResultType enum class.
+// Ref: https://learn.microsoft.com/en-us/windows/win32/secauthz/standard-access-rights
+#undef DELETE
+#endif
+
+namespace gz::fuel_tools
+{
+  /// Result type.
+  enum class ResultType
+  {
+    /// \brief Uninitialized type.
+    UNKNOWN = 0,
+
+    /// \brief Delete successful.
+    DELETE,
+
+    /// \brief Model not found.
+    DELETE_NOT_FOUND,
+
+    /// \brief Delete failed. Other errors.
+    /// \sa ReadableResult
+    DELETE_ERROR,
+
+    /// \brief Fetch successful.
+    FETCH,
+
+    /// \brief Model already exists.
+    FETCH_ALREADY_EXISTS,
+
+    /// \brief Model not found.
+    FETCH_NOT_FOUND,
+
+    /// \brief Fetch failed. Other errors.
+    /// \sa ReadableResult
+    FETCH_ERROR,
+
+    /// \brief Upload successful.
+    UPLOAD,
+
+    /// \brief Model already exists.
+    UPLOAD_ALREADY_EXISTS,
+
+    /// \brief Upload failed. Other errors.
+    /// \sa ReadableResult
+    UPLOAD_ERROR,
+
+    /// \brief Patch failed.
+    PATCH_ERROR,
+
+    /// \brief Patch successful.
+    PATCH,
+  };
+}  // namespace gz::fuel_tools
+
+#endif  // GZ_FUEL_TOOLS_RESULTTYPE_HH_
diff --git a/include/gz/fuel_tools/ServerConfig.hh b/include/gz/fuel_tools/ServerConfig.hh
new file mode 100644
index 00000000..613d2639
--- /dev/null
+++ b/include/gz/fuel_tools/ServerConfig.hh
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2024 Open Source Robotics Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+#ifndef GZ_FUEL_TOOLS_SERVERCONFIG_HH_
+#define GZ_FUEL_TOOLS_SERVERCONFIG_HH_
+
+#include <memory>
+#include <string>
+
+#include <gz/common/URI.hh>
+
+#include "gz/fuel_tools/Export.hh"
+
+#ifdef _WIN32
+// Disable warning C4251 which is triggered by
+// std::unique_ptr
+#pragma warning(push)
+#pragma warning(disable: 4251)
+#endif
+
+namespace gz::fuel_tools
+{
+  /// \brief forward declaration
+  class ServerConfigPrivate;
+
+  /// \brief Describes options needed for a server.
+  class GZ_FUEL_TOOLS_VISIBLE ServerConfig
+  {
+    /// \brief Constructor.
+    public: ServerConfig();
+
+    /// \brief Copy constructor.
+    /// \param[in] _orig The server config to copy.
+    public: ServerConfig(const ServerConfig &_orig);
+
+    /// \brief Assignment operator overload.
+    /// \param[in] _orig The server config to copy.
+    public: ServerConfig &operator=(const ServerConfig &_orig);
+
+    /// \brief Destructor.
+    public: ~ServerConfig();
+
+    /// \brief Clear the server config. This will set all values to empty
+    /// strings, except the version string which will be set to its default
+    /// value.
+    public: void Clear();
+
+    /// \brief Get the URL to access the server.
+    /// \return The URL of this server.
+    public: common::URI Url() const;
+
+    /// \brief Set the URL of this server.
+    /// \param[in] _url URL of this server.
+    public: void SetUrl(const common::URI &_url);
+
+    /// \brief Get the API key to auth with the server.
+    /// \return The API key.
+    public: std::string ApiKey() const;
+
+    /// \brief Set the API key to auth with the server.
+    /// \param[in] _key The API key.
+    public: void SetApiKey(const std::string &_key);
+
+    /// \brief Get the protocol version used with this server.
+    /// \return The version. E.g.: "1.0".
+    public: std::string Version() const;
+
+    /// \brief Set the protocol version used with this server.
+    /// \param[in] _version The version. E.g.: "1.0".
+    public: void SetVersion(const std::string &_version);
+
+    /// \brief Returns all the server information as a string.
+    /// \param[in] _prefix Optional prefix for every line of the string.
+    /// \return Server information string
+    public: std::string AsString(const std::string &_prefix = "") const;
+
+    /// \brief Returns all the available model information as a string using
+    /// colors for better human parsing.
+    /// \param[in] _prefix Optional prefix for every line of the string.
+    /// \return Model information string
+    public: std::string AsPrettyString(const std::string &_prefix = "") const;
+
+    /// \brief PIMPL
+    private: std::unique_ptr<ServerConfigPrivate> dataPtr;
+  };
+}  // namespace gz::fuel_tools
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif  // GZ_FUEL_TOOLS_SERVERCONFIG_HH_
diff --git a/include/gz/fuel_tools/WorldIdentifier.hh b/include/gz/fuel_tools/WorldIdentifier.hh
index d4579248..9be30374 100644
--- a/include/gz/fuel_tools/WorldIdentifier.hh
+++ b/include/gz/fuel_tools/WorldIdentifier.hh
@@ -30,134 +30,131 @@
 #pragma warning(disable: 4251)
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
+  /// \brief Forward Declaration
+  class WorldIdentifierPrivate;
+  class ServerConfig;
+
+  /// \brief Defines how to identify a world
+  class GZ_FUEL_TOOLS_VISIBLE WorldIdentifier
   {
-    /// \brief Forward Declaration
-    class WorldIdentifierPrivate;
-    class ServerConfig;
-
-    /// \brief Defines how to identify a world
-    class GZ_FUEL_TOOLS_VISIBLE WorldIdentifier
-    {
-      /// \brief Constructor.
-      public: WorldIdentifier();
-
-      /// \brief Copy Constructor.
-      /// \param[in] _orig WorldIdentifier to copy.
-      public: WorldIdentifier(const WorldIdentifier &_orig);
-
-      /// \brief Destructor.
-      public: ~WorldIdentifier();
-
-      /// \brief Assignment operator
-      /// \param[in] _orig WorldIdentifier to copy.
-      /// \return Reference to this object.
-      public: WorldIdentifier &operator=(const WorldIdentifier &_orig);
-
-      /// \brief Equality operator.
-      /// \param[in] _rhs WorldIdentifier to compare.
-      /// \return True if the WorldIdentifier names are equal.
-      public: bool operator==(const WorldIdentifier &_rhs) const;
-
-      /// \brief Returns the world name
-      /// \return World name.
-      public: std::string Name() const;
-
-      /// \brief Set the name of the world.
-      /// \param[in] _name The name to set.
-      /// \return True if successful.
-      public: bool SetName(const std::string &_name);
-
-      /// \brief Returns owner to attribute world to.
-      /// \return Owner name.
-      public: std::string Owner() const;
-
-      /// \brief Set the owner of the world
-      /// \param[in] _name The name to set. Must be ascii and pass [-_a-z0-9]+
-      /// \return true if successful
-      public: bool SetOwner(const std::string &_name);
-
-      /// \brief Returns server information to retrieve world from.
-      /// \return Server information.
-      public: ServerConfig &Server() const;
-
-      /// \brief Set the server from which this world comes.
-      /// \param[in] _server The server to retrieve the world from.
-      /// \return True if successful.
-      public: bool SetServer(const ServerConfig &_server);
-
-      /// \brief Returns the world's version as a number. Versions are integers
-      /// counting from 1. Version zero means the tip.
-      /// \return World's version.
-      /// \sa VersionStr
-      /// \sa SetVersion
-      public: unsigned int Version() const;
-
-      /// \brief Returns the world's version as a string. Versions are integers
-      /// counting from 1. The strings "tip" or "" mean the latest version.
-      /// \return World's version.
-      /// \sa Version
-      /// \sa SetVersionStr
-      public: std::string VersionStr() const;
-
-      /// \brief Set the world's version. Versions are integers counting from
-      /// 1.
-      /// \param[in] _version The world's version
-      /// \return True if successful.
-      /// \sa Version
-      /// \sa SetVersionStr
-      public: bool SetVersion(const unsigned int _version);
-
-      /// \brief Set the world's version. Versions are integers counting from
-      /// 1 or "tip" for the latest version.
-      /// \param[in] _version The world's version
-      /// \return True if successful.
-      /// \sa VersionStr
-      /// \sa SetVersion
-      public: bool SetVersionStr(const std::string &_version);
-
-      /// \brief Returns a path to the world on disk if it is already cached
-      /// \returns Path, or empty string if the path has not been set
-      /// \sa SetLocalPath
-      public: std::string LocalPath() const;
-
-      /// \brief Sets the path of the world in the local cache.
-      /// \param[in] Local path to world.
-      /// \sa LocalPath
-      public: bool SetLocalPath(const std::string &_path);
-
-      /// \brief Returns a unique name for the world.
-      /// \remarks this is Server/Owner/Name.
-      /// \return Unique world name.
-      public: std::string UniqueName() const;
-
-      // /// \brief Sets the SHA 2 256 hash of the world
-      // /// \param[in] _hash a 256 bit SHA 2 hash
-      // /// \returns true if successful
-      // public: bool SHA_256(const std::array<std::uint8_t, 32> &_hash);
-
-      /// \brief Returns all the world information as a string. Convenient for
-      /// debugging.
-      /// \param[in] _prefix Optional prefix for every line of the string.
-      /// \return World information string
-      public: std::string AsString(const std::string &_prefix = "") const;
-
-      /// \brief Returns all the available world information as a string using
-      /// colors for better human parsing.
-      /// \param[in] _prefix Optional prefix for every line of the string.
-      /// \return World information string
-      public: std::string AsPrettyString(const std::string &_prefix = "") const;
-
-      /// \brief PIMPL
-      private: std::unique_ptr<WorldIdentifierPrivate> dataPtr;
-    };
-  }
-}
+    /// \brief Constructor.
+    public: WorldIdentifier();
+
+    /// \brief Copy Constructor.
+    /// \param[in] _orig WorldIdentifier to copy.
+    public: WorldIdentifier(const WorldIdentifier &_orig);
+
+    /// \brief Destructor.
+    public: ~WorldIdentifier();
+
+    /// \brief Assignment operator
+    /// \param[in] _orig WorldIdentifier to copy.
+    /// \return Reference to this object.
+    public: WorldIdentifier &operator=(const WorldIdentifier &_orig);
+
+    /// \brief Equality operator.
+    /// \param[in] _rhs WorldIdentifier to compare.
+    /// \return True if the WorldIdentifier names are equal.
+    public: bool operator==(const WorldIdentifier &_rhs) const;
+
+    /// \brief Returns the world name
+    /// \return World name.
+    public: std::string Name() const;
+
+    /// \brief Set the name of the world.
+    /// \param[in] _name The name to set.
+    /// \return True if successful.
+    public: bool SetName(const std::string &_name);
+
+    /// \brief Returns owner to attribute world to.
+    /// \return Owner name.
+    public: std::string Owner() const;
+
+    /// \brief Set the owner of the world
+    /// \param[in] _name The name to set. Must be ascii and pass [-_a-z0-9]+
+    /// \return true if successful
+    public: bool SetOwner(const std::string &_name);
+
+    /// \brief Returns server information to retrieve world from.
+    /// \return Server information.
+    public: ServerConfig &Server() const;
+
+    /// \brief Set the server from which this world comes.
+    /// \param[in] _server The server to retrieve the world from.
+    /// \return True if successful.
+    public: bool SetServer(const ServerConfig &_server);
+
+    /// \brief Returns the world's version as a number. Versions are integers
+    /// counting from 1. Version zero means the tip.
+    /// \return World's version.
+    /// \sa VersionStr
+    /// \sa SetVersion
+    public: unsigned int Version() const;
+
+    /// \brief Returns the world's version as a string. Versions are integers
+    /// counting from 1. The strings "tip" or "" mean the latest version.
+    /// \return World's version.
+    /// \sa Version
+    /// \sa SetVersionStr
+    public: std::string VersionStr() const;
+
+    /// \brief Set the world's version. Versions are integers counting from
+    /// 1.
+    /// \param[in] _version The world's version
+    /// \return True if successful.
+    /// \sa Version
+    /// \sa SetVersionStr
+    public: bool SetVersion(const unsigned int _version);
+
+    /// \brief Set the world's version. Versions are integers counting from
+    /// 1 or "tip" for the latest version.
+    /// \param[in] _version The world's version
+    /// \return True if successful.
+    /// \sa VersionStr
+    /// \sa SetVersion
+    public: bool SetVersionStr(const std::string &_version);
+
+    /// \brief Returns a path to the world on disk if it is already cached
+    /// \returns Path, or empty string if the path has not been set
+    /// \sa SetLocalPath
+    public: std::string LocalPath() const;
+
+    /// \brief Sets the path of the world in the local cache.
+    /// \param[in] Local path to world.
+    /// \sa LocalPath
+    public: bool SetLocalPath(const std::string &_path);
+
+    /// \brief Returns a unique name for the world.
+    /// \remarks this is Server/Owner/Name.
+    /// \return Unique world name.
+    public: std::string UniqueName() const;
+
+    // /// \brief Sets the SHA 2 256 hash of the world
+    // /// \param[in] _hash a 256 bit SHA 2 hash
+    // /// \returns true if successful
+    // public: bool SHA_256(const std::array<std::uint8_t, 32> &_hash);
+
+    /// \brief Returns all the world information as a string. Convenient for
+    /// debugging.
+    /// \param[in] _prefix Optional prefix for every line of the string.
+    /// \return World information string
+    public: std::string AsString(const std::string &_prefix = "") const;
+
+    /// \brief Returns all the available world information as a string using
+    /// colors for better human parsing.
+    /// \param[in] _prefix Optional prefix for every line of the string.
+    /// \return World information string
+    public: std::string AsPrettyString(const std::string &_prefix = "") const;
+
+    /// \brief PIMPL
+    private: std::unique_ptr<WorldIdentifierPrivate> dataPtr;
+  };
+}  // namespace gz::fuel_tools
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
-#endif
+#endif  // GZ_FUEL_TOOLS_WORLDIDENTIFIER_HH_
diff --git a/include/gz/fuel_tools/WorldIter.hh b/include/gz/fuel_tools/WorldIter.hh
index 95bd9aa3..bfd7e5c5 100644
--- a/include/gz/fuel_tools/WorldIter.hh
+++ b/include/gz/fuel_tools/WorldIter.hh
@@ -29,59 +29,56 @@
 #pragma warning(disable: 4251)
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
-  {
-    /// \brief Forward declarations
-    class WorldIdentifier;
-    class WorldIterPrivate;
-    class WorldIterFactory;
+  /// \brief Forward declarations
+  class WorldIdentifier;
+  class WorldIterPrivate;
+  class WorldIterFactory;
 
-    /// \brief class for iterating through worlds
-    class GZ_FUEL_TOOLS_VISIBLE WorldIter
-    {
-      friend WorldIterFactory;
+  /// \brief class for iterating through worlds
+  class GZ_FUEL_TOOLS_VISIBLE WorldIter
+  {
+    friend WorldIterFactory;
 
-      /// \brief Construct an iterator with the data it needs to function
-      /// \param[in] _dptr Pointer to private data to copy
-      protected: explicit WorldIter(std::unique_ptr<WorldIterPrivate> _dptr);
+    /// \brief Construct an iterator with the data it needs to function
+    /// \param[in] _dptr Pointer to private data to copy
+    protected: explicit WorldIter(std::unique_ptr<WorldIterPrivate> _dptr);
 
-      /// \brief Move constructor
-      /// \param[in] _old Iter to move
-      public: WorldIter(WorldIter && _old);
+    /// \brief Move constructor
+    /// \param[in] _old Iter to move
+    public: WorldIter(WorldIter && _old);
 
-      /// \brief Default destructor.
-      public: ~WorldIter();
+    /// \brief Default destructor.
+    public: ~WorldIter();
 
-      /// \brief Conversion operator
-      /// \return False once the iterator is one past the end of the worlds
-      public: operator bool() const;
+    /// \brief Conversion operator
+    /// \return False once the iterator is one past the end of the worlds
+    public: operator bool() const;
 
-      /// \brief Conversion operator
-      /// \return Internal world identifier.
-      public: operator WorldIdentifier() const;
+    /// \brief Conversion operator
+    /// \return Internal world identifier.
+    public: operator WorldIdentifier() const;
 
-      /// \brief Prefix increment
-      /// \return Next iteration
-      public: WorldIter &operator++();
+    /// \brief Prefix increment
+    /// \return Next iteration
+    public: WorldIter &operator++();
 
-      /// \brief -> operator
-      /// \return Internal world identifier
-      public: WorldIdentifier *operator->();
+    /// \brief -> operator
+    /// \return Internal world identifier
+    public: WorldIdentifier *operator->();
 
-      /// \brief Derefence operator
-      /// \return Internal world identifier
-      public: WorldIdentifier &operator*();
+    /// \brief Derefence operator
+    /// \return Internal world identifier
+    public: WorldIdentifier &operator*();
 
-      /// \brief Private data pointer.
-      private: std::unique_ptr<WorldIterPrivate> dataPtr;
-    };
-  }
-}
+    /// \brief Private data pointer.
+    private: std::unique_ptr<WorldIterPrivate> dataPtr;
+  };
+}  // namespace gz::fuel_tools
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
-#endif
+#endif  // GZ_FUEL_TOOLS_WORLDITER_HH_
diff --git a/include/gz/fuel_tools/Zip.hh b/include/gz/fuel_tools/Zip.hh
index 63eb795e..8098dea0 100644
--- a/include/gz/fuel_tools/Zip.hh
+++ b/include/gz/fuel_tools/Zip.hh
@@ -23,26 +23,23 @@
 
 #include "gz/fuel_tools/Export.hh"
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
+  /// \brief A helper class for making REST requests.
+  class GZ_FUEL_TOOLS_VISIBLE Zip
   {
-    /// \brief A helper class for making REST requests.
-    class GZ_FUEL_TOOLS_VISIBLE Zip
-    {
-      /// \brief Compress a file or directory
-      /// \param[in] _src Path to file or directory to compress
-      /// \param[in] _dst Output compressed file path
-      public: static bool Compress(const std::string &_src,
-          const std::string &_dst);
+    /// \brief Compress a file or directory
+    /// \param[in] _src Path to file or directory to compress
+    /// \param[in] _dst Output compressed file path
+    public: static bool Compress(const std::string &_src,
+        const std::string &_dst);
 
-      /// \brief Extract a compressed file
-      /// \param[in] _src Path to compressed file
-      /// \param[in] _dst Output extracted file path
-      public: static bool Extract(const std::string &_src,
-          const std::string &_dst);
-    };
-  }
-}
+    /// \brief Extract a compressed file
+    /// \param[in] _src Path to compressed file
+    /// \param[in] _dst Output extracted file path
+    public: static bool Extract(const std::string &_src,
+        const std::string &_dst);
+  };
+}  // namespace gz::fuel_tools
 
-#endif
+#endif  // GZ_FUEL_TOOLS_ZIP_HH_
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c2ec97ac..2748e73f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -12,6 +12,7 @@ set (sources
   ModelIter.cc
   RestClient.cc
   Result.cc
+  ServerConfig.cc
   Zip.cc
   WorldIdentifier.cc
   WorldIter.cc
@@ -31,6 +32,7 @@ set (gtest_sources
   Model_TEST.cc
   RestClient_TEST.cc
   Result_TEST.cc
+  ServerConfig_TEST.cc
   WorldIdentifier_TEST.cc
   WorldIter_TEST.cc
   Zip_TEST.cc
diff --git a/src/ClientConfig.cc b/src/ClientConfig.cc
index 02ba8a13..dd9b7466 100644
--- a/src/ClientConfig.cc
+++ b/src/ClientConfig.cc
@@ -28,12 +28,11 @@
 #include "gz/fuel_tools/ClientConfig.hh"
 #include "gz/fuel_tools/config.hh"
 
-using namespace gz;
-using namespace fuel_tools;
-
+namespace gz::fuel_tools
+{
 //////////////////////////////////////////////////
 /// \brief Private data class
-class gz::fuel_tools::ClientConfigPrivate
+class ClientConfigPrivate
 {
   /// \brief Constructor.
   public: ClientConfigPrivate()
@@ -70,134 +69,6 @@ class gz::fuel_tools::ClientConfigPrivate
           "GazeboFuelTools-" GZ_FUEL_TOOLS_VERSION_FULL;
 };
 
-//////////////////////////////////////////////////
-/// \brief Private data class
-class gz::fuel_tools::ServerConfigPrivate
-{
-  /// \brief Clear values.
-  public: void Clear()
-          {
-            this->url.Clear();
-            this->key = "";
-            this->version = "1.0";
-          }
-
-  /// \brief URL to reach server
-  public: common::URI url{"https://fuel.gazebosim.org", true};
-
-  /// \brief A key to auth with the server
-  public: std::string key = "";
-
-  /// \brief The protocol version used when talking with this server.
-  public: std::string version = "1.0";
-};
-
-//////////////////////////////////////////////////
-ServerConfig::ServerConfig()
-  : dataPtr (new ServerConfigPrivate)
-{
-}
-
-//////////////////////////////////////////////////
-ServerConfig::ServerConfig(const ServerConfig &_orig)
-  : dataPtr(new ServerConfigPrivate)
-{
-  *(this->dataPtr) = *(_orig.dataPtr);
-}
-
-//////////////////////////////////////////////////
-void ServerConfig::Clear()
-{
-  this->dataPtr->Clear();
-}
-
-//////////////////////////////////////////////////
-ServerConfig &ServerConfig::operator=(const ServerConfig &_orig)
-{
-  *(this->dataPtr) = *(_orig.dataPtr);
-  return *this;
-}
-
-//////////////////////////////////////////////////
-ServerConfig::~ServerConfig()
-{
-}
-
-//////////////////////////////////////////////////
-common::URI ServerConfig::Url() const
-{
-  return this->dataPtr->url;
-}
-
-//////////////////////////////////////////////////
-void ServerConfig::SetUrl(const common::URI &_url)
-{
-  this->dataPtr->url = _url;
-}
-
-//////////////////////////////////////////////////
-std::string ServerConfig::ApiKey() const
-{
-  return this->dataPtr->key;
-}
-
-//////////////////////////////////////////////////
-void ServerConfig::SetApiKey(const std::string &_key)
-{
-  this->dataPtr->key = _key;
-}
-
-//////////////////////////////////////////////////
-std::string ServerConfig::Version() const
-{
-  return this->dataPtr->version;
-}
-
-//////////////////////////////////////////////////
-void ServerConfig::SetVersion(const std::string &_version)
-{
-  this->dataPtr->version = _version;
-}
-
-//////////////////////////////////////////////////
-std::string ServerConfig::AsString(const std::string &_prefix) const
-{
-  std::stringstream out;
-  out << _prefix << "URL: " << this->Url().Str() << std::endl
-      << _prefix << "Version: " << this->Version() << std::endl
-      << _prefix << "API key: " << this->ApiKey() << std::endl;
-  return out.str();
-}
-
-//////////////////////////////////////////////////
-std::string ServerConfig::AsPrettyString(const std::string &_prefix) const
-{
-  std::string prop = "\033[96m\033[1m";
-  std::string value = "\033[37m";
-  std::string reset = "\033[0m";
-
-  std::stringstream out;
-
-  if (this->Url().Valid())
-  {
-    out << _prefix << prop << "URL: " << reset
-        << value << this->Url().Str() << reset << std::endl;
-  }
-
-  if (!this->Version().empty())
-  {
-    out << _prefix << prop << "Version: " << reset
-        << value << this->Version() << reset << std::endl;
-  }
-
-  if (!this->ApiKey().empty())
-  {
-    out << _prefix << prop << "API key: " << reset
-        << value << this->ApiKey() << reset << std::endl;
-  }
-  return out.str();
-}
-
 //////////////////////////////////////////////////
 ClientConfig::ClientConfig() : dataPtr(new ClientConfigPrivate)
 {
@@ -527,3 +398,4 @@ std::string ClientConfig::AsString(const std::string &_prefix) const
 
   return out.str();
 }
+}  // namespace gz::fuel_tools
diff --git a/src/ClientConfig_TEST.cc b/src/ClientConfig_TEST.cc
index facd548e..6a071db3 100644
--- a/src/ClientConfig_TEST.cc
+++ b/src/ClientConfig_TEST.cc
@@ -65,8 +65,6 @@ class ClientConfigTest: public ::testing::Test
   public: std::shared_ptr<gz::common::TempDirectory> tempDir;
 };
 
-class ServerConfigTest: public ClientConfigTest {};
-
 /////////////////////////////////////////////////
 /// \brief Initially only the default server in config
 TEST_F(ClientConfigTest, InitiallyDefaultServers)
@@ -261,19 +259,6 @@ TEST_F(ClientConfigTest, UserAgent)
   EXPECT_EQ("my_user_agent", config.UserAgent());
 }
 
-/////////////////////////////////////////////////
-TEST_F(ServerConfigTest, ApiKey)
-{
-  ServerConfig config;
-  EXPECT_TRUE(config.ApiKey().empty());
-
-  config.SetApiKey("my_api_key");
-  EXPECT_EQ("my_api_key", config.ApiKey());
-
-  config.SetApiKey("my_other_api_key");
-  EXPECT_EQ("my_other_api_key", config.ApiKey());
-}
-
 /////////////////////////////////////////////////
 TEST_F(ClientConfigTest, AsString)
 {
@@ -364,48 +349,3 @@ TEST_F(ClientConfigTest, AsPrettyString)
     EXPECT_NE(str.find("ABCD"), std::string::npos);
   }
 }
-
-/////////////////////////////////////////////////
-TEST_F(ServerConfigTest, Url)
-{
-  // Invalid URL string
-  {
-    ServerConfig srv;
-    srv.SetUrl(common::URI("asdf"));
-    EXPECT_TRUE(srv.Url().Str().empty());
-  }
-
-  // Valid URL
-  {
-    ServerConfig srv;
-    srv.SetUrl(common::URI("http://banana:8080"));
-    EXPECT_EQ("http://banana:8080", srv.Url().Str());
-    EXPECT_EQ("http", srv.Url().Scheme());
-    EXPECT_EQ("banana:8080", srv.Url().Path().Str());
-    EXPECT_FALSE(srv.Url().Authority());
-  }
-
-  // Trailing /
-  {
-    ServerConfig srv;
-    srv.SetUrl(common::URI("http://banana:8080"));
-    EXPECT_EQ("http://banana:8080", srv.Url().Str());
-    EXPECT_EQ("http", srv.Url().Scheme());
-    EXPECT_EQ("banana:8080", srv.Url().Path().Str());
-    EXPECT_FALSE(srv.Url().Authority());
-  }
-
-  // Set from URI
-  {
-    auto url = common::URI();
-    url.SetScheme("http");
-    url.Path() = common::URIPath("banana:8080");
-
-    ServerConfig srv;
-    srv.SetUrl(url);
-    EXPECT_EQ("http://banana:8080", srv.Url().Str());
-    EXPECT_EQ("http", srv.Url().Scheme());
-    EXPECT_EQ("banana:8080", srv.Url().Path().Str());
-    EXPECT_FALSE(srv.Url().Authority());
-  }
-}
diff --git a/src/CollectionIdentifier.cc b/src/CollectionIdentifier.cc
index 73fc4dc6..949e4be6 100644
--- a/src/CollectionIdentifier.cc
+++ b/src/CollectionIdentifier.cc
@@ -24,10 +24,10 @@
 #include "gz/fuel_tools/ClientConfig.hh"
 #include "gz/fuel_tools/CollectionIdentifier.hh"
 
-using namespace gz;
-using namespace fuel_tools;
 
-class gz::fuel_tools::CollectionIdentifierPrivate
+namespace gz::fuel_tools
+{
+class CollectionIdentifierPrivate
 {
   /// \brief a name given to this collection by a user
   public: std::string name;
@@ -156,3 +156,4 @@ std::string CollectionIdentifier::AsPrettyString(
       << this->Server().AsPrettyString(_prefix + "  ");
   return out.str();
 }
+}  // namespace gz::fuel_tools
diff --git a/src/FuelClient.cc b/src/FuelClient.cc
index 28e5bf47..55da2d32 100644
--- a/src/FuelClient.cc
+++ b/src/FuelClient.cc
@@ -48,16 +48,28 @@
 #include "gz/fuel_tools/ModelIdentifier.hh"
 #include "gz/fuel_tools/RestClient.hh"
 #include "gz/fuel_tools/WorldIdentifier.hh"
+#include "gz/fuel_tools/WorldIter.hh"
 
 #include "LocalCache.hh"
 #include "ModelIterPrivate.hh"
 #include "WorldIterPrivate.hh"
 
-using namespace gz;
-using namespace fuel_tools;
+namespace std
+{
+  template<> struct hash<gz::fuel_tools::ModelIdentifier>
+  {
+    std::size_t operator()(
+      const gz::fuel_tools::ModelIdentifier &_id) const noexcept
+    {
+      return std::hash<std::string>{}(_id.AsString());
+    }
+  };
+}  // namespace std
 
+namespace gz::fuel_tools
+{
 /// \brief Private Implementation
-class gz::fuel_tools::FuelClientPrivate
+class FuelClientPrivate
 {
   /// \brief A model URL,
   /// E.g.: https://fuel.gazebosim.org/1.0/caguero/models/Beer/2
@@ -893,18 +905,6 @@ Result FuelClient::DownloadWorld(WorldIdentifier &_id,
   return Result(ResultType::FETCH);
 }
 
-//////////////////////////////////////////////////
-namespace std
-{
-  template<> struct hash<ModelIdentifier>
-  {
-    std::size_t operator()(const ModelIdentifier &_id) const noexcept
-    {
-      return std::hash<std::string>{}(_id.AsString());
-    }
-  };
-}
-
 //////////////////////////////////////////////////
 std::vector<FuelClient::ModelResult> FuelClient::DownloadModels(
     const std::vector<ModelIdentifier> &_ids,
@@ -2008,3 +2008,5 @@ void FuelClientPrivate::ZipFromResponse(const RestResponse &_resp,
     _zip = std::move(_resp.data);
   }
 }
+}  // namespace gz::fuel_tools
+
diff --git a/src/Helpers.cc b/src/Helpers.cc
index e9be8d35..4934faa7 100644
--- a/src/Helpers.cc
+++ b/src/Helpers.cc
@@ -19,8 +19,10 @@
 
 #include "gz/fuel_tools/Helpers.hh"
 
+namespace gz::fuel_tools
+{
 //////////////////////////////////////////////////
-std::string gz::fuel_tools::sanitizeAuthority(const std::string &_uriAuthority)
+std::string sanitizeAuthority(const std::string &_uriAuthority)
 {
   // Take an authority of the form userinfo@host:port and turn it into a valid
   // subset of characters for a path.
@@ -30,7 +32,7 @@ std::string gz::fuel_tools::sanitizeAuthority(const std::string &_uriAuthority)
 }
 
 //////////////////////////////////////////////////
-std::string gz::fuel_tools::uriToPath(const common::URI &_uri)
+std::string uriToPath(const common::URI &_uri)
 {
   auto path = _uri.Path().Str();
   if (_uri.Path().IsAbsolute())
@@ -63,3 +65,4 @@ std::string gz::fuel_tools::uriToPath(const common::URI &_uri)
 
   return common::joinPaths(authority, path);
 }
+}  // namespace gz::fuel_tools
diff --git a/src/Interface.cc b/src/Interface.cc
index c1c9412a..828109a9 100644
--- a/src/Interface.cc
+++ b/src/Interface.cc
@@ -31,124 +31,121 @@
 #include "gz/fuel_tools/Interface.hh"
 #include "gz/fuel_tools/WorldIdentifier.hh"
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
+  //////////////////////////////////////////////
+  std::string fetchResource(const std::string &_uri)
   {
-    //////////////////////////////////////////////
-    std::string fetchResource(const std::string &_uri)
+    gz::fuel_tools::FuelClient client;
+    return fetchResourceWithClient(_uri, client);
+  }
+
+  //////////////////////////////////////////////
+  std::string fetchResourceWithClient(const std::string &_uri,
+      gz::fuel_tools::FuelClient &_client)
+  {
+    std::string result;
+
+    gz::fuel_tools::ModelIdentifier model;
+    gz::fuel_tools::WorldIdentifier world;
+    std::string fileUrl;
+    gz::common::URI uri(_uri);
+    // Download the model, if it is a model URI
+    if (_client.ParseModelUrl(uri, model) &&
+        !_client.CachedModel(uri, result))
     {
-      gz::fuel_tools::FuelClient client;
-      return fetchResourceWithClient(_uri, client);
+      _client.DownloadModel(uri, result);
     }
-
-    //////////////////////////////////////////////
-    std::string fetchResourceWithClient(const std::string &_uri,
-        gz::fuel_tools::FuelClient &_client)
+    // Download the model, if it's a model file URI
+    else if (_client.ParseModelFileUrl(uri, model, fileUrl) &&
+        !_client.CachedModelFile(uri, result))
     {
-      std::string result;
-
-      gz::fuel_tools::ModelIdentifier model;
-      gz::fuel_tools::WorldIdentifier world;
-      std::string fileUrl;
-      gz::common::URI uri(_uri);
-      // Download the model, if it is a model URI
-      if (_client.ParseModelUrl(uri, model) &&
-          !_client.CachedModel(uri, result))
-      {
-        _client.DownloadModel(uri, result);
-      }
-      // Download the model, if it's a model file URI
-      else if (_client.ParseModelFileUrl(uri, model, fileUrl) &&
-          !_client.CachedModelFile(uri, result))
-      {
-        auto modelUri = _uri.substr(0,
-            _uri.find("files", model.UniqueName().size())-1);
-        _client.DownloadModel(common::URI(modelUri), result);
-        result = common::joinPaths(result, fileUrl);
-      }
-      // Download the world, if it is a world URI
-      else if (_client.ParseWorldUrl(uri, world) &&
-               !_client.CachedWorld(uri, result))
-      {
-        _client.DownloadWorld(uri, result);
-      }
-      // Download the world, if it's a world file URI
-      else if (_client.ParseWorldFileUrl(uri, world, fileUrl) &&
-          !_client.CachedWorldFile(uri, result))
-      {
-        auto worldUri = _uri.substr(0,
-            _uri.find("files", world.UniqueName().size())-1);
-        _client.DownloadWorld(common::URI(worldUri), result);
-        result = common::joinPaths(result, fileUrl);
-
-      }
+      auto modelUri = _uri.substr(0,
+          _uri.find("files", model.UniqueName().size())-1);
+      _client.DownloadModel(common::URI(modelUri), result);
+      result = common::joinPaths(result, fileUrl);
+    }
+    // Download the world, if it is a world URI
+    else if (_client.ParseWorldUrl(uri, world) &&
+             !_client.CachedWorld(uri, result))
+    {
+      _client.DownloadWorld(uri, result);
+    }
+    // Download the world, if it's a world file URI
+    else if (_client.ParseWorldFileUrl(uri, world, fileUrl) &&
+        !_client.CachedWorldFile(uri, result))
+    {
+      auto worldUri = _uri.substr(0,
+          _uri.find("files", world.UniqueName().size())-1);
+      _client.DownloadWorld(common::URI(worldUri), result);
+      result = common::joinPaths(result, fileUrl);
 
-      return result;
     }
 
-    //////////////////////////////////////////////
-    std::string sdfFromPath(const std::string &_path)
-    {
-      gz::msgs::FuelMetadata meta;
-      std::string metadataPath =
-        gz::common::joinPaths(_path, "metadata.pbtxt");
-      std::string modelConfigPath =
-        gz::common::joinPaths(_path, "model.config");
+    return result;
+  }
 
-      bool foundMetadataPath = gz::common::exists(metadataPath);
-      bool foundModelConfigPath = gz::common::exists(modelConfigPath);
+  //////////////////////////////////////////////
+  std::string sdfFromPath(const std::string &_path)
+  {
+    gz::msgs::FuelMetadata meta;
+    std::string metadataPath =
+      gz::common::joinPaths(_path, "metadata.pbtxt");
+    std::string modelConfigPath =
+      gz::common::joinPaths(_path, "model.config");
 
-      // Use the metadata.pbtxt or model.config first.
-      if (foundMetadataPath || foundModelConfigPath)
-      {
-        std::string modelPath =
-          (foundMetadataPath) ? metadataPath : modelConfigPath;
+    bool foundMetadataPath = gz::common::exists(metadataPath);
+    bool foundModelConfigPath = gz::common::exists(modelConfigPath);
 
-        // Read the pbtxt or config file.
-        std::ifstream inputFile(modelPath);
-        std::string inputStr((std::istreambuf_iterator<char>(inputFile)),
-            std::istreambuf_iterator<char>());
+    // Use the metadata.pbtxt or model.config first.
+    if (foundMetadataPath || foundModelConfigPath)
+    {
+      std::string modelPath =
+        (foundMetadataPath) ? metadataPath : modelConfigPath;
 
-        if (foundMetadataPath)
-        {
-          // Parse the file into the fuel metadata message
-          google::protobuf::TextFormat::ParseFromString(inputStr, &meta);
-        }
-        else
-        {
-          if (!gz::msgs::ConvertFuelMetadata(inputStr, meta))
-            return "";
-        }
+      // Read the pbtxt or config file.
+      std::ifstream inputFile(modelPath);
+      std::string inputStr((std::istreambuf_iterator<char>(inputFile)),
+          std::istreambuf_iterator<char>());
 
-        if (meta.has_model())
-          return gz::common::joinPaths(_path, meta.model().file());
-        else if (meta.has_world())
-          return gz::common::joinPaths(_path, meta.world().file());
-        return "";
+      if (foundMetadataPath)
+      {
+        // Parse the file into the fuel metadata message
+        google::protobuf::TextFormat::ParseFromString(inputStr, &meta);
       }
+      else
+      {
+        if (!gz::msgs::ConvertFuelMetadata(inputStr, meta))
+          return "";
+      }
+
+      if (meta.has_model())
+        return gz::common::joinPaths(_path, meta.model().file());
+      else if (meta.has_world())
+        return gz::common::joinPaths(_path, meta.world().file());
+      return "";
+    }
 
-      // Otherwise, use the first ".sdf" file found in the given path.
-      common::DirIter dirIter(_path);
-      common::DirIter end;
-      while (dirIter != end)
+    // Otherwise, use the first ".sdf" file found in the given path.
+    common::DirIter dirIter(_path);
+    common::DirIter end;
+    while (dirIter != end)
+    {
+      if (common::isFile(*dirIter))
       {
-        if (common::isFile(*dirIter))
+        std::string basename = gz::common::basename(*dirIter);
+        // Just some safety checks.
+        if (!basename.empty() && basename.find(".sdf") != std::string::npos)
         {
-          std::string basename = gz::common::basename(*dirIter);
-          // Just some safety checks.
-          if (!basename.empty() && basename.find(".sdf") != std::string::npos)
-          {
-            std::string extension = basename.substr(
-                basename.find_last_of('.') + 1);
-            if (extension == "sdf")
-              return *dirIter;
-          }
+          std::string extension = basename.substr(
+              basename.find_last_of('.') + 1);
+          if (extension == "sdf")
+            return *dirIter;
         }
-        ++dirIter;
       }
-
-      return "";
+      ++dirIter;
     }
+
+    return "";
   }
-}
+}  // namespace gz::fuel_tools
diff --git a/src/JSONParser.cc b/src/JSONParser.cc
index daec0e19..04a45213 100644
--- a/src/JSONParser.cc
+++ b/src/JSONParser.cc
@@ -22,9 +22,7 @@
 
 #include "gz/fuel_tools/ClientConfig.hh"
 #include "gz/fuel_tools/JSONParser.hh"
-
-using namespace gz;
-using namespace fuel_tools;
+#include "gz/fuel_tools/WorldIter.hh"
 
 #if defined(_WIN32) && !defined(timegm)
   #define timegm _mkgmtime
@@ -33,6 +31,9 @@ using namespace fuel_tools;
 #define GZ_JSON_HAVE_EXCEPTIONS ((JSONCPP_VERSION_MAJOR < 1 && \
       JSONCPP_VERSION_MINOR < 10) ||  JSON_USE_EXCEPTION == 0)
 
+namespace gz::fuel_tools
+{
+
 /////////////////////////////////////////////////
 std::time_t ParseDateTime(const std::string &_datetime)
 {
@@ -388,3 +389,4 @@ bool JSONParser::ParseLicenses(const std::string &_json,
 
   return true;
 }
+}  // namespace gz::fuel_tools
diff --git a/src/LocalCache.cc b/src/LocalCache.cc
index 481da466..8a758bdf 100644
--- a/src/LocalCache.cc
+++ b/src/LocalCache.cc
@@ -43,10 +43,9 @@
 #include "WorldIterPrivate.hh"
 #include "LocalCache.hh"
 
-using namespace gz;
-using namespace fuel_tools;
-
-class gz::fuel_tools::LocalCachePrivate
+namespace gz::fuel_tools
+{
+class LocalCachePrivate
 {
   /// \brief return all models in a given directory
   /// \param[in] _path A directory for the local server cache
@@ -786,3 +785,4 @@ bool LocalCache::SaveWorld(
 
   return true;
 }
+}  // namespace gz::fuel_tools
diff --git a/src/LocalCache.hh b/src/LocalCache.hh
index aff4ac1b..c7e42451 100644
--- a/src/LocalCache.hh
+++ b/src/LocalCache.hh
@@ -33,85 +33,82 @@
 #pragma warning(disable: 4251)
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
+  /// \brief Forward declaration
+  class ClientConfig;
+  class LocalCachePrivate;
+  class ModelIdentifier;
+
+  /// \brief Class for managing stuff in the local cache
+  class GZ_FUEL_TOOLS_VISIBLE LocalCache
   {
-    /// \brief Forward declaration
-    class ClientConfig;
-    class LocalCachePrivate;
-    class ModelIdentifier;
-
-    /// \brief Class for managing stuff in the local cache
-    class GZ_FUEL_TOOLS_VISIBLE LocalCache
-    {
-      /// \brief Constructor
-      /// \param[in] _config The configuration for the client
-      public: explicit LocalCache(const ClientConfig *_config);
-
-      /// \brief destructor
-      public: virtual ~LocalCache();
-
-      /// \brief Get all models in offline cache
-      /// \return Model iterator
-      public: virtual ModelIter AllModels();
-
-      /// \brief Get all worlds in offline cache
-      /// \return World iterator
-      public: virtual WorldIter AllWorlds() const;
-
-      /// \brief Get the first model matching all fields on an id.
-      /// \param[in] _id An id with ServerUrl, Owner, and Name all set
-      /// \return A model which matches all of _id's parameters.
-      public: virtual Model MatchingModel(const ModelIdentifier &_id);
-
-      /// \brief Get the first world matching all fields on an id.
-      /// \param[in] _id An id with ServerUrl, Owner, and Name all set
-      /// \return A world which matches all of _id's parameters.
-      public: virtual bool MatchingWorld(WorldIdentifier &_id) const;
-
-      /// \brief Get all models partially matching an ID
-      /// \param[in] _id An id with at least one of ServerURL, Owner, and Name
-      /// \return An iterator with all models that match all fields that are
-      /// set on _id.
-      public: virtual ModelIter MatchingModels(const ModelIdentifier &_id);
-
-      /// \brief Get all worlds partially matching an ID
-      /// \param[in] _id An id with at least one of ServerUrl, Owner, and Name
-      /// \return An iterator with all worlds that match all fields that are
-      /// set on _id.
-      public: virtual WorldIter MatchingWorlds(
-          const WorldIdentifier &_id) const;
-
-      /// \brief Add a model from packed data to the local cache
-      /// \param[in] _id A completely populated ID
-      /// \param[in] _data Compressed content of the model
-      /// \param[in] _overwrite Overwrite model if already exists.
-      /// \returns True if the model was successfully added to the local cache,
-      /// and the model contains a model.config file.
-      public: virtual bool SaveModel(
-          const ModelIdentifier &_id,
-          const std::string &_data,
-          const bool _overwrite);
-
-      /// \brief Add a world from packed data to the local cache
-      /// \param[out] _id A completely populated ID
-      /// \param[in] _data Compressed content of the world
-      /// \param[in] _overwrite Overwrite world if already exists.
-      /// \returns True if the world was successfully added to the local cache
-      public: virtual bool SaveWorld(
-          WorldIdentifier &_id,
-          const std::string &_data,
-          const bool _overwrite);
-
-      /// \brief Internal data.
-      private: std::shared_ptr<LocalCachePrivate> dataPtr;
-    };
-  }
-}
+    /// \brief Constructor
+    /// \param[in] _config The configuration for the client
+    public: explicit LocalCache(const ClientConfig *_config);
+
+    /// \brief destructor
+    public: virtual ~LocalCache();
+
+    /// \brief Get all models in offline cache
+    /// \return Model iterator
+    public: virtual ModelIter AllModels();
+
+    /// \brief Get all worlds in offline cache
+    /// \return World iterator
+    public: virtual WorldIter AllWorlds() const;
+
+    /// \brief Get the first model matching all fields on an id.
+    /// \param[in] _id An id with ServerUrl, Owner, and Name all set
+    /// \return A model which matches all of _id's parameters.
+    public: virtual Model MatchingModel(const ModelIdentifier &_id);
+
+    /// \brief Get the first world matching all fields on an id.
+    /// \param[in] _id An id with ServerUrl, Owner, and Name all set
+    /// \return A world which matches all of _id's parameters.
+    public: virtual bool MatchingWorld(WorldIdentifier &_id) const;
+
+    /// \brief Get all models partially matching an ID
+    /// \param[in] _id An id with at least one of ServerURL, Owner, and Name
+    /// \return An iterator with all models that match all fields that are
+    /// set on _id.
+    public: virtual ModelIter MatchingModels(const ModelIdentifier &_id);
+
+    /// \brief Get all worlds partially matching an ID
+    /// \param[in] _id An id with at least one of ServerUrl, Owner, and Name
+    /// \return An iterator with all worlds that match all fields that are
+    /// set on _id.
+    public: virtual WorldIter MatchingWorlds(
+        const WorldIdentifier &_id) const;
+
+    /// \brief Add a model from packed data to the local cache
+    /// \param[in] _id A completely populated ID
+    /// \param[in] _data Compressed content of the model
+    /// \param[in] _overwrite Overwrite model if already exists.
+    /// \returns True if the model was successfully added to the local cache,
+    /// and the model contains a model.config file.
+    public: virtual bool SaveModel(
+        const ModelIdentifier &_id,
+        const std::string &_data,
+        const bool _overwrite);
+
+    /// \brief Add a world from packed data to the local cache
+    /// \param[out] _id A completely populated ID
+    /// \param[in] _data Compressed content of the world
+    /// \param[in] _overwrite Overwrite world if already exists.
+    /// \returns True if the world was successfully added to the local cache
+    public: virtual bool SaveWorld(
+        WorldIdentifier &_id,
+        const std::string &_data,
+        const bool _overwrite);
+
+    /// \brief Internal data.
+    private: std::shared_ptr<LocalCachePrivate> dataPtr;
+  };
+}  // namespace gz::fuel_tools
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
-#endif
+#endif  // GZ_FUEL_TOOLS_LOCALCACHE_HH_
diff --git a/src/Model.cc b/src/Model.cc
index 90f85560..3368cc7c 100644
--- a/src/Model.cc
+++ b/src/Model.cc
@@ -24,9 +24,8 @@
 
 #include "ModelPrivate.hh"
 
-using namespace gz;
-using namespace fuel_tools;
-
+namespace gz::fuel_tools
+{
 //////////////////////////////////////////////////
 Model::Model() : dataPtr(nullptr)
 {
@@ -86,3 +85,4 @@ std::string Model::PathToModel() const
   }
   return "";
 }
+}  // namespace gz::fuel_tools
diff --git a/src/ModelIdentifier.cc b/src/ModelIdentifier.cc
index 39c536e0..1eb42ede 100644
--- a/src/ModelIdentifier.cc
+++ b/src/ModelIdentifier.cc
@@ -27,10 +27,9 @@
 #include "gz/fuel_tools/ClientConfig.hh"
 #include "gz/fuel_tools/ModelIdentifier.hh"
 
-using namespace gz;
-using namespace fuel_tools;
-
-class gz::fuel_tools::ModelIdentifierPrivate
+namespace gz::fuel_tools
+{
+class ModelIdentifierPrivate
 {
   /// \brief returns true if name follows rules
   /// \param[in] _name Name to validate
@@ -510,3 +509,4 @@ void ModelIdentifier::SetPrivate(bool _private) const
 {
   this->dataPtr->privacy = _private;
 }
+}  // namespace gz::fuel_tools
diff --git a/src/ModelIter.cc b/src/ModelIter.cc
index c9db28b3..00f5a62d 100644
--- a/src/ModelIter.cc
+++ b/src/ModelIter.cc
@@ -31,9 +31,8 @@
 #include "ModelIterPrivate.hh"
 #include "ModelPrivate.hh"
 
-using namespace gz;
-using namespace fuel_tools;
-
+namespace gz::fuel_tools
+{
 //////////////////////////////////////////////////
 ModelIter ModelIterFactory::Create(const std::vector<ModelIdentifier> &_ids)
 {
@@ -264,3 +263,4 @@ Model *ModelIter::operator->()
 {
   return &(this->dataPtr->model);
 }
+}  // namespace gz::fuel_tools
diff --git a/src/ModelIterPrivate.hh b/src/ModelIterPrivate.hh
index 0f6787f0..cc93909e 100644
--- a/src/ModelIterPrivate.hh
+++ b/src/ModelIterPrivate.hh
@@ -18,10 +18,10 @@
 #ifndef GZ_FUEL_TOOLS_MODELITERPRIVATE_HH_
 #define GZ_FUEL_TOOLS_MODELITERPRIVATE_HH_
 
+#include <cstddef>
 #include <string>
 #include <vector>
 
-#include "gz/fuel_tools/ClientConfig.hh"
 #include "gz/fuel_tools/Model.hh"
 #include "gz/fuel_tools/ModelIdentifier.hh"
 #include "gz/fuel_tools/RestClient.hh"
@@ -33,155 +33,152 @@
 #pragma warning(disable: 4251)
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
+  /// \brief forward declaration
+  class ModelIter;
+
+  /// \brief Private class, do not include or instantiate
+  class GZ_FUEL_TOOLS_VISIBLE ModelIterFactory
+  {
+    /// \brief Create a model iterator from a vector of model identifiers
+    /// \param[in] _ids Model identifiers
+    /// \return Model iterator
+    public: static ModelIter Create(const std::vector<ModelIdentifier> &_ids);
+
+    /// \brief Create a model iterator from a vector of models
+    /// \param[in] _ids Models
+    /// \return Model iterator
+    public: static ModelIter Create(const std::vector<Model> &_models);
+
+    /// \brief Create a model iter that will make Rest api calls
+    /// \param[in] _rest a Rest request
+    /// \param[in] _server The server to request the operation
+    /// \param[in] _api The path to request
+    public: static ModelIter Create(const Rest &_rest,
+                                    const ServerConfig &_server,
+                                    const std::string &_api);
+
+    /// \brief Create a model iterator that is empty
+    /// \return An empty iterator
+    public: static ModelIter Create();
+  };
+
+  /// \brief Private class, do not include or instantiate
+  class GZ_FUEL_TOOLS_VISIBLE ModelIterPrivate
+  {
+    /// \brief Destructor
+    public: virtual ~ModelIterPrivate();
+
+    /// \brief Advance iterator to next model
+    public: virtual void Next() = 0;
+
+    /// \brief True if this iterator has reach the end
+    /// \return True if reached end.
+    public: virtual bool HasReachedEnd() = 0;
+
+    /// \brief Current model for returning references
+    public: Model model;
+  };
+
+  /// \brief class for iterating through model ids where all are known
+  ///        in advance
+  class GZ_FUEL_TOOLS_VISIBLE IterIds : public ModelIterPrivate
   {
-    /// \brief forward declaration
-    class ModelIter;
-
-    /// \brief Private class, do not include or instantiate
-    class GZ_FUEL_TOOLS_VISIBLE ModelIterFactory
-    {
-      /// \brief Create a model iterator from a vector of model identifiers
-      /// \param[in] _ids Model identifiers
-      /// \return Model iterator
-      public: static ModelIter Create(const std::vector<ModelIdentifier> &_ids);
-
-      /// \brief Create a model iterator from a vector of models
-      /// \param[in] _ids Models
-      /// \return Model iterator
-      public: static ModelIter Create(const std::vector<Model> &_models);
-
-      /// \brief Create a model iter that will make Rest api calls
-      /// \param[in] _rest a Rest request
-      /// \param[in] _server The server to request the operation
-      /// \param[in] _api The path to request
-      public: static ModelIter Create(const Rest &_rest,
-                                      const ServerConfig &_server,
-                                      const std::string &_api);
-
-      /// \brief Create a model iterator that is empty
-      /// \return An empty iterator
-      public: static ModelIter Create();
-    };
-
-    /// \brief Private class, do not include or instantiate
-    class GZ_FUEL_TOOLS_VISIBLE ModelIterPrivate
-    {
-      /// \brief Destructor
-      public: virtual ~ModelIterPrivate();
-
-      /// \brief Advance iterator to next model
-      public: virtual void Next() = 0;
-
-      /// \brief True if this iterator has reach the end
-      /// \return True if reached end.
-      public: virtual bool HasReachedEnd() = 0;
-
-      /// \brief Current model for returning references
-      public: Model model;
-    };
-
-    /// \brief class for iterating through model ids where all are known
-    ///        in advance
-    class GZ_FUEL_TOOLS_VISIBLE IterIds : public ModelIterPrivate
-    {
-      /// \brief Constructor
-      public: explicit IterIds(std::vector<ModelIdentifier> _ids);
-
-      /// \brief Destructor
-      public: virtual ~IterIds();
-
-      // Documentation inherited
-      public: virtual void Next() override;
-
-      // Documentation inherited
-      public: virtual bool HasReachedEnd() override;
-
-      /// \brief Model identifiers that have been requested
-      protected: std::vector<ModelIdentifier> ids;
-
-      /// \brief Where the current iterator is in the list of ids
-      protected: std::vector<ModelIdentifier>::iterator idIter;
-    };
-
-    /// \brief class for iterating through model ids where all are known
-    ///        in advance
-    class GZ_FUEL_TOOLS_VISIBLE IterModels: public ModelIterPrivate
-    {
-      /// \brief Constructor
-      public: explicit IterModels(std::vector<Model> _models);
-
-      /// \brief Destructor
-      public: virtual ~IterModels();
-
-      // Documentation inherited
-      public: virtual void Next() override;
-
-      // Documentation inherited
-      public: virtual bool HasReachedEnd() override;
-
-      /// \brief Models to iterator through
-      protected: std::vector<Model> models;
-
-      /// \brief Where the current iterator is in the list of models
-      protected: std::vector<Model>::iterator modelIter;
-    };
-
-    /// \brief class for iterating through model ids from a rest API
-    class GZ_FUEL_TOOLS_HIDDEN IterRestIds: public ModelIterPrivate
-    {
-      /// \brief constructor
-      public: IterRestIds(const Rest &_rest,
-                          const ServerConfig &_server,
-                          const std::string &_api);
-
-      /// \brief destructor
-      public: virtual ~IterRestIds();
-
-      /// \brief Advance iterator to next model.
-      public: virtual void Next() override;
-
-      /// \brief True if this iterator has reach the end.
-      /// \return True if iterator has reached the end.
-      public: virtual bool HasReachedEnd() override;
-
-      /// \brief Client configuration
-      public: ServerConfig config;
-
-      /// \brief RESTful client
-      public: Rest rest;
-
-      /// \brief The API (path) of the RESTful requests
-      public: const std::string api;
-
-      /// \brief Make a RESTful request for the given page
-      /// \param[in] _page Page number to request
-      /// \return Response from the request
-      protected: RestResponse MakeRestRequest(std::size_t _page);
+    /// \brief Constructor
+    public: explicit IterIds(std::vector<ModelIdentifier> _ids);
+
+    /// \brief Destructor
+    public: virtual ~IterIds();
+
+    // Documentation inherited
+    public: virtual void Next() override;
+
+    // Documentation inherited
+    public: virtual bool HasReachedEnd() override;
+
+    /// \brief Model identifiers that have been requested
+    protected: std::vector<ModelIdentifier> ids;
+
+    /// \brief Where the current iterator is in the list of ids
+    protected: std::vector<ModelIdentifier>::iterator idIter;
+  };
+
+  /// \brief class for iterating through model ids where all are known
+  ///        in advance
+  class GZ_FUEL_TOOLS_VISIBLE IterModels: public ModelIterPrivate
+  {
+    /// \brief Constructor
+    public: explicit IterModels(std::vector<Model> _models);
+
+    /// \brief Destructor
+    public: virtual ~IterModels();
 
-      /// \brief Parse model identifiers from a RESTful response
-      /// \param[in] _resp RESTful response
-      /// \return A vector of identifiers extracted from the response.
-      protected: std::vector<ModelIdentifier> ParseIdsFromResponse(
-          const RestResponse &_resp);
+    // Documentation inherited
+    public: virtual void Next() override;
 
-      /// \brief Model identifiers in the current page
-      protected: std::vector<ModelIdentifier> ids;
+    // Documentation inherited
+    public: virtual bool HasReachedEnd() override;
 
-      /// \brief Where the current iterator is in the list of ids
-      protected: std::vector<ModelIdentifier>::iterator idIter;
+    /// \brief Models to iterator through
+    protected: std::vector<Model> models;
 
-      /// \brief Keep track of page number for pagination of response data from
-      /// server.
-      protected: std::size_t currentPage{0};
-    };
-  }
-}
+    /// \brief Where the current iterator is in the list of models
+    protected: std::vector<Model>::iterator modelIter;
+  };
+
+  /// \brief class for iterating through model ids from a rest API
+  class GZ_FUEL_TOOLS_HIDDEN IterRestIds: public ModelIterPrivate
+  {
+    /// \brief constructor
+    public: IterRestIds(const Rest &_rest,
+                        const ServerConfig &_server,
+                        const std::string &_api);
+
+    /// \brief destructor
+    public: virtual ~IterRestIds();
+
+    /// \brief Advance iterator to next model.
+    public: virtual void Next() override;
+
+    /// \brief True if this iterator has reach the end.
+    /// \return True if iterator has reached the end.
+    public: virtual bool HasReachedEnd() override;
+
+    /// \brief Client configuration
+    public: ServerConfig config;
+
+    /// \brief RESTful client
+    public: Rest rest;
+
+    /// \brief The API (path) of the RESTful requests
+    public: const std::string api;
+
+    /// \brief Make a RESTful request for the given page
+    /// \param[in] _page Page number to request
+    /// \return Response from the request
+    protected: RestResponse MakeRestRequest(std::size_t _page);
+
+    /// \brief Parse model identifiers from a RESTful response
+    /// \param[in] _resp RESTful response
+    /// \return A vector of identifiers extracted from the response.
+    protected: std::vector<ModelIdentifier> ParseIdsFromResponse(
+        const RestResponse &_resp);
+
+    /// \brief Model identifiers in the current page
+    protected: std::vector<ModelIdentifier> ids;
+
+    /// \brief Where the current iterator is in the list of ids
+    protected: std::vector<ModelIdentifier>::iterator idIter;
+
+    /// \brief Keep track of page number for pagination of response data from
+    /// server.
+    protected: std::size_t currentPage{0};
+  };
+}  // namespace gz::fuel_tools
 
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
-#endif
+#endif  // GZ_FUEL_TOOLS_MODELITERPRIVATE_HH_
diff --git a/src/ModelPrivate.hh b/src/ModelPrivate.hh
index 6c8c656b..c474e69f 100644
--- a/src/ModelPrivate.hh
+++ b/src/ModelPrivate.hh
@@ -30,24 +30,19 @@
 #pragma warning(disable: 4251)
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
+  /// \brief Private class, do not use
+  class GZ_FUEL_TOOLS_VISIBLE ModelPrivate
   {
-    /// \brief Private class, do not use
-    class GZ_FUEL_TOOLS_VISIBLE ModelPrivate
-    {
-      /// \brief How this model is ID'd
-      public: ModelIdentifier id;
+    /// \brief How this model is ID'd
+    public: ModelIdentifier id;
 
-      /// \brief Where this model is on disk
-      public: std::string pathOnDisk;
-    };
-  }
+    /// \brief Where this model is on disk
+    public: std::string pathOnDisk;
+  };
 }
-
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
-
-#endif
+#endif  // GZ_FUEL_TOOLS_MODELPRIVATE_HH_
diff --git a/src/RestClient.cc b/src/RestClient.cc
index 26e45578..222f0c8f 100644
--- a/src/RestClient.cc
+++ b/src/RestClient.cc
@@ -16,10 +16,6 @@
 */
 
 #include <curl/curl.h>
-#ifdef _WIN32
-// DELETE is defined in winnt.h and causes a problem with HttpMethod::DELETE
-#undef DELETE
-#endif
 
 #include <cstring>
 #include <iostream>
@@ -30,8 +26,8 @@
 
 #include "gz/fuel_tools/RestClient.hh"
 
-using namespace gz;
-using namespace fuel_tools;
+namespace gz::fuel_tools
+{
 
 // List of known file extensions and associated mime type.
 static const std::map<std::string, std::string> kContentTypes =
@@ -387,3 +383,4 @@ const std::string &Rest::UserAgent() const
 {
   return this->userAgent;
 }
+}  // namespace gz::fuel_tools
diff --git a/src/Result.cc b/src/Result.cc
index 0ccfd59d..9c816331 100644
--- a/src/Result.cc
+++ b/src/Result.cc
@@ -17,12 +17,10 @@
 
 #include "gz/fuel_tools/Result.hh"
 
-namespace ignft = gz::fuel_tools;
-using namespace gz;
-using namespace ignft;
-
+namespace gz::fuel_tools
+{
 
-class ignft::ResultPrivate
+class ResultPrivate
 {
   /// \brief a type of result
   public: ResultType type = ResultType::UNKNOWN;
@@ -119,3 +117,4 @@ std::string Result::ReadableResult() const
       return "Unknown result";
   }
 }
+}  // namespace gz::fuel_tools
diff --git a/src/ServerConfig.cc b/src/ServerConfig.cc
new file mode 100644
index 00000000..e11f8ace
--- /dev/null
+++ b/src/ServerConfig.cc
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2024 Open Source Robotics Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+#include <yaml.h>
+#include <cstdio>
+#include <sstream>
+#include <stack>
+#include <string>
+#include <vector>
+
+#include <gz/common/Console.hh>
+#include <gz/common/Filesystem.hh>
+#include <gz/common/Util.hh>
+
+#include "gz/fuel_tools/ServerConfig.hh"
+
+namespace gz::fuel_tools
+{
+//////////////////////////////////////////////////
+/// \brief Private data class
+class ServerConfigPrivate
+{
+  /// \brief Clear values.
+  public: void Clear()
+          {
+            this->url.Clear();
+            this->key = "";
+            this->version = "1.0";
+          }
+
+  /// \brief URL to reach server
+  public: common::URI url{"https://fuel.gazebosim.org", true};
+
+  /// \brief A key to auth with the server
+  public: std::string key = "";
+
+  /// \brief The protocol version used when talking with this server.
+  public: std::string version = "1.0";
+};
+
+//////////////////////////////////////////////////
+ServerConfig::ServerConfig()
+  : dataPtr (new ServerConfigPrivate)
+{
+}
+
+//////////////////////////////////////////////////
+ServerConfig::ServerConfig(const ServerConfig &_orig)
+  : dataPtr(new ServerConfigPrivate)
+{
+  *(this->dataPtr) = *(_orig.dataPtr);
+}
+
+//////////////////////////////////////////////////
+void ServerConfig::Clear()
+{
+  this->dataPtr->Clear();
+}
+
+//////////////////////////////////////////////////
+ServerConfig &ServerConfig::operator=(const ServerConfig &_orig)
+{
+  *(this->dataPtr) = *(_orig.dataPtr);
+  return *this;
+}
+
+//////////////////////////////////////////////////
+ServerConfig::~ServerConfig()
+{
+}
+
+//////////////////////////////////////////////////
+common::URI ServerConfig::Url() const
+{
+  return this->dataPtr->url;
+}
+
+//////////////////////////////////////////////////
+void ServerConfig::SetUrl(const common::URI &_url)
+{
+  this->dataPtr->url = _url;
+}
+
+//////////////////////////////////////////////////
+std::string ServerConfig::ApiKey() const
+{
+  return this->dataPtr->key;
+}
+
+//////////////////////////////////////////////////
+void ServerConfig::SetApiKey(const std::string &_key)
+{
+  this->dataPtr->key = _key;
+}
+
+//////////////////////////////////////////////////
+std::string ServerConfig::Version() const
+{
+  return this->dataPtr->version;
+}
+
+//////////////////////////////////////////////////
+void ServerConfig::SetVersion(const std::string &_version)
+{
+  this->dataPtr->version = _version;
+}
+
+//////////////////////////////////////////////////
+std::string ServerConfig::AsString(const std::string &_prefix) const
+{
+  std::stringstream out;
+  out << _prefix << "URL: " << this->Url().Str() << std::endl
+      << _prefix << "Version: " << this->Version() << std::endl
+      << _prefix << "API key: " << this->ApiKey() << std::endl;
+  return out.str();
+}
+
+//////////////////////////////////////////////////
+std::string ServerConfig::AsPrettyString(const std::string &_prefix) const
+{
+  std::string prop = "\033[96m\033[1m";
+  std::string value = "\033[37m";
+  std::string reset = "\033[0m";
+
+  std::stringstream out;
+
+  if (this->Url().Valid())
+  {
+    out << _prefix << prop << "URL: " << reset
+        << value << this->Url().Str() << reset << std::endl;
+  }
+
+  if (!this->Version().empty())
+  {
+    out << _prefix << prop << "Version: " << reset
+        << value << this->Version() << reset << std::endl;
+  }
+
+  if (!this->ApiKey().empty())
+  {
+    out << _prefix << prop << "API key: " << reset
+        << value << this->ApiKey() << reset << std::endl;
+  }
+  return out.str();
+}
+}  // namespace gz::fuel_tools
diff --git a/src/ServerConfig_TEST.cc b/src/ServerConfig_TEST.cc
new file mode 100644
index 00000000..26b3160d
--- /dev/null
+++ b/src/ServerConfig_TEST.cc
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2024 Open Source Robotics Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+#include <gtest/gtest.h>
+#include <fstream>
+#include <string>
+#include <gz/common/Console.hh>
+#include <gz/common/Filesystem.hh>
+#include <gz/common/TempDirectory.hh>
+#include <gz/common/testing/TestPaths.hh>
+#include <gz/common/Util.hh>
+
+#include "gz/fuel_tools/config.hh"
+#include "gz/fuel_tools/ClientConfig.hh"
+
+using namespace gz;
+using namespace fuel_tools;
+
+/////////////////////////////////////////////////
+/// \brief Get home directory.
+/// \return Home directory or empty string if home wasn't found.
+/// \ToDo: Move this function to gz::common::Filesystem
+std::string homePath()
+{
+  std::string homePath;
+#ifndef _WIN32
+  gz::common::env("HOME", homePath);
+#else
+  gz::common::env("USERPROFILE", homePath);
+#endif
+  return homePath;
+}
+
+/////////////////////////////////////////////////
+class ServerConfigTest: public ::testing::Test
+{
+  public: void SetUp() override
+  {
+    gz::common::Console::SetVerbosity(4);
+    tempDir = gz::common::testing::MakeTestTempDirectory();
+    ASSERT_TRUE(tempDir->Valid()) << tempDir->Path();
+
+    gz::common::chdir(tempDir->Path());
+  }
+
+  public: std::string cachePath()
+  {
+    return this->tempDir->Path();
+  }
+
+  public: std::shared_ptr<gz::common::TempDirectory> tempDir;
+};
+
+/////////////////////////////////////////////////
+TEST_F(ServerConfigTest, ApiKey)
+{
+  ServerConfig config;
+  EXPECT_TRUE(config.ApiKey().empty());
+
+  config.SetApiKey("my_api_key");
+  EXPECT_EQ("my_api_key", config.ApiKey());
+
+  config.SetApiKey("my_other_api_key");
+  EXPECT_EQ("my_other_api_key", config.ApiKey());
+}
+
+/////////////////////////////////////////////////
+TEST_F(ServerConfigTest, Url)
+{
+  // Invalid URL string
+  {
+    ServerConfig srv;
+    srv.SetUrl(common::URI("asdf"));
+    EXPECT_TRUE(srv.Url().Str().empty());
+  }
+
+  // Valid URL
+  {
+    ServerConfig srv;
+    srv.SetUrl(common::URI("http://banana:8080"));
+    EXPECT_EQ("http://banana:8080", srv.Url().Str());
+    EXPECT_EQ("http", srv.Url().Scheme());
+    EXPECT_EQ("banana:8080", srv.Url().Path().Str());
+    EXPECT_FALSE(srv.Url().Authority());
+  }
+
+  // Trailing /
+  {
+    ServerConfig srv;
+    srv.SetUrl(common::URI("http://banana:8080"));
+    EXPECT_EQ("http://banana:8080", srv.Url().Str());
+    EXPECT_EQ("http", srv.Url().Scheme());
+    EXPECT_EQ("banana:8080", srv.Url().Path().Str());
+    EXPECT_FALSE(srv.Url().Authority());
+  }
+
+  // Set from URI
+  {
+    auto url = common::URI();
+    url.SetScheme("http");
+    url.Path() = common::URIPath("banana:8080");
+
+    ServerConfig srv;
+    srv.SetUrl(url);
+    EXPECT_EQ("http://banana:8080", srv.Url().Str());
+    EXPECT_EQ("http", srv.Url().Scheme());
+    EXPECT_EQ("banana:8080", srv.Url().Path().Str());
+    EXPECT_FALSE(srv.Url().Authority());
+  }
+}
diff --git a/src/WorldIdentifier.cc b/src/WorldIdentifier.cc
index 6af8c802..fd07e8fd 100644
--- a/src/WorldIdentifier.cc
+++ b/src/WorldIdentifier.cc
@@ -27,10 +27,10 @@
 #include "gz/fuel_tools/Helpers.hh"
 #include "gz/fuel_tools/WorldIdentifier.hh"
 
-using namespace gz;
-using namespace fuel_tools;
 
-class gz::fuel_tools::WorldIdentifierPrivate
+namespace gz::fuel_tools
+{
+class WorldIdentifierPrivate
 {
   /// \brief a name given to this world by a user
   public: std::string name;
@@ -229,3 +229,4 @@ std::string WorldIdentifier::AsPrettyString(const std::string &_prefix) const
       << this->Server().AsPrettyString(_prefix + "  ");
   return out.str();
 }
+}  // namespace gz::fuel_tools
diff --git a/src/WorldIter.cc b/src/WorldIter.cc
index 1374bfc8..1fdca4d2 100644
--- a/src/WorldIter.cc
+++ b/src/WorldIter.cc
@@ -29,8 +29,8 @@
 
 #include "WorldIterPrivate.hh"
 
-using namespace gz;
-using namespace fuel_tools;
+namespace gz::fuel_tools
+{
 
 //////////////////////////////////////////////////
 WorldIter WorldIterFactory::Create(const std::vector<WorldIdentifier> &_ids)
@@ -241,3 +241,4 @@ WorldIter::operator WorldIdentifier() const
 {
   return this->dataPtr->worldId;
 }
+}  // namespace gz::fuel_tools
diff --git a/src/WorldIterPrivate.hh b/src/WorldIterPrivate.hh
index c2f42ff8..f55485fb 100644
--- a/src/WorldIterPrivate.hh
+++ b/src/WorldIterPrivate.hh
@@ -32,112 +32,107 @@
 #pragma warning(disable: 4251)
 #endif
 
-namespace gz
+namespace gz::fuel_tools
 {
-  namespace fuel_tools
+  /// \brief forward declaration
+  class WorldIter;
+
+  /// \brief Private class, do not include or instantiate
+  class GZ_FUEL_TOOLS_VISIBLE WorldIterFactory
+  {
+    /// \brief Create a world iterator from a vector of world identifiers
+    /// \param[in] _ids World identifiers
+    /// \return World iterator
+    public: static WorldIter Create(const std::vector<WorldIdentifier> &_ids);
+
+    /// \brief Create a world iter that will make REST api calls
+    /// \param[in] _rest a REST request
+    /// \param[in] _server The server to request the operation
+    /// \param[in] _path The path to request
+    /// \return World iterator
+    public: static WorldIter Create(const Rest &_rest,
+                                    const ServerConfig &_server,
+                                    const std::string &_path);
+
+    /// \brief Create a world iterator that is empty
+    /// \return An empty iterator
+    public: static WorldIter Create();
+  };
+
+  /// \brief Private class, do not include or instantiate
+  class GZ_FUEL_TOOLS_VISIBLE WorldIterPrivate
+  {
+    /// \brief Destructor
+    public: virtual ~WorldIterPrivate();
+
+    /// \brief Advance iterator to next world
+    public: virtual void Next() = 0;
+
+    /// \brief True if this iterator has reach the end
+    /// \return True if reached end.
+    public: virtual bool HasReachedEnd() = 0;
+
+    /// \brief Current world for returning references
+    public: WorldIdentifier worldId;
+  };
+
+  /// \brief Class for iterating through world ids
+  class GZ_FUEL_TOOLS_VISIBLE WorldIterIds : public WorldIterPrivate
+  {
+    /// \brief Constructor
+    /// \param[in] _ids Vector of ids
+    public: explicit WorldIterIds(std::vector<WorldIdentifier> _ids);
+
+    /// \brief Destructor
+    public: virtual ~WorldIterIds();
+
+    // Documentation inherited
+    public: virtual void Next() override;
+
+    // Documentation inherited
+    public: virtual bool HasReachedEnd() override;
+
+    /// \brief World identifiers that have been requested
+    protected: std::vector<WorldIdentifier> ids;
+
+    /// \brief Where the current iterator is in the list of ids
+    protected: std::vector<WorldIdentifier>::iterator idIter;
+  };
+
+  /// \brief class for iterating through world ids from a rest API
+  class GZ_FUEL_TOOLS_VISIBLE WorldIterRestIds: public WorldIterPrivate
   {
-    /// \brief forward declaration
-    class WorldIter;
-
-    /// \brief Private class, do not include or instantiate
-    class GZ_FUEL_TOOLS_VISIBLE WorldIterFactory
-    {
-      /// \brief Create a world iterator from a vector of world identifiers
-      /// \param[in] _ids World identifiers
-      /// \return World iterator
-      public: static WorldIter Create(const std::vector<WorldIdentifier> &_ids);
-
-      /// \brief Create a world iter that will make REST api calls
-      /// \param[in] _rest a REST request
-      /// \param[in] _server The server to request the operation
-      /// \param[in] _path The path to request
-      /// \return World iterator
-      public: static WorldIter Create(const Rest &_rest,
-                                      const ServerConfig &_server,
-                                      const std::string &_path);
-
-      /// \brief Create a world iterator that is empty
-      /// \return An empty iterator
-      public: static WorldIter Create();
-    };
-
-    /// \brief Private class, do not include or instantiate
-    class GZ_FUEL_TOOLS_VISIBLE WorldIterPrivate
-    {
-      /// \brief Destructor
-      public: virtual ~WorldIterPrivate();
-
-      /// \brief Advance iterator to next world
-      public: virtual void Next() = 0;
-
-      /// \brief True if this iterator has reach the end
-      /// \return True if reached end.
-      public: virtual bool HasReachedEnd() = 0;
-
-      /// \brief Current world for returning references
-      public: WorldIdentifier worldId;
-    };
-
-    /// \brief Class for iterating through world ids
-    class GZ_FUEL_TOOLS_VISIBLE WorldIterIds : public WorldIterPrivate
-    {
-      /// \brief Constructor
-      /// \param[in] _ids Vector of ids
-      public: explicit WorldIterIds(std::vector<WorldIdentifier> _ids);
-
-      /// \brief Destructor
-      public: virtual ~WorldIterIds();
-
-      // Documentation inherited
-      public: virtual void Next() override;
-
-      // Documentation inherited
-      public: virtual bool HasReachedEnd() override;
-
-      /// \brief World identifiers that have been requested
-      protected: std::vector<WorldIdentifier> ids;
-
-      /// \brief Where the current iterator is in the list of ids
-      protected: std::vector<WorldIdentifier>::iterator idIter;
-    };
-
-    /// \brief class for iterating through world ids from a rest API
-    class GZ_FUEL_TOOLS_VISIBLE WorldIterRestIds: public WorldIterPrivate
-    {
-      /// \brief Constructor
-      /// \param[in] _rest REST client
-      /// \param[in] _server Server configuration
-      /// \param[in] _path The path to request
-      public: WorldIterRestIds(const Rest &_rest,
-                               const ServerConfig &_server,
-                               const std::string &_path);
-
-      /// \brief Destructor
-      public: virtual ~WorldIterRestIds();
-
-      // Documentation inherited
-      public: virtual void Next() override;
-
-      // Documentation inherited
-      public: virtual bool HasReachedEnd() override;
-
-      /// \brief Server configuration
-      public: ServerConfig config;
-
-      /// \brief RESTful client
-      public: Rest rest;
-
-      /// \brief World identifiers in the current page
-      protected: std::vector<WorldIdentifier> ids;
-
-      /// \brief Where the current iterator is in the list of ids
-      protected: std::vector<WorldIdentifier>::iterator idIter;
-    };
-  }
-}
+    /// \brief Constructor
+    /// \param[in] _rest REST client
+    /// \param[in] _server Server configuration
+    /// \param[in] _path The path to request
+    public: WorldIterRestIds(const Rest &_rest,
+                             const ServerConfig &_server,
+                             const std::string &_path);
+
+    /// \brief Destructor
+    public: virtual ~WorldIterRestIds();
+
+    // Documentation inherited
+    public: virtual void Next() override;
+
+    // Documentation inherited
+    public: virtual bool HasReachedEnd() override;
 
+    /// \brief Server configuration
+    public: ServerConfig config;
+
+    /// \brief RESTful client
+    public: Rest rest;
+
+    /// \brief World identifiers in the current page
+    protected: std::vector<WorldIdentifier> ids;
+
+    /// \brief Where the current iterator is in the list of ids
+    protected: std::vector<WorldIdentifier>::iterator idIter;
+  };
+}  // namespace gz::fuel_tools
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
-
-#endif
+#endif  // GZ_FUEL_TOOLS_WORLDITERPRIVATE_HH_
diff --git a/src/gz.cc b/src/gz.cc
index f7841413..cb2e2b19 100644
--- a/src/gz.cc
+++ b/src/gz.cc
@@ -34,11 +34,6 @@
 #include <gz/msgs/fuel_metadata.pb.h>
 #include <gz/msgs/Utility.hh>
 
-#ifdef _WIN32
-// DELETE is defined in winnt.h and causes a problem with REST::DELETE
-#undef DELETE
-#endif
-
 #include <algorithm>
 #include <chrono>
 #include <deque>

From 010494280c5c2f360e52f23ee7212550c49764b5 Mon Sep 17 00:00:00 2001
From: Michael Carroll <mjcarroll@intrinsic.ai>
Date: Fri, 5 Jan 2024 22:21:08 +0000
Subject: [PATCH 3/3] Update badges to main

Signed-off-by: Michael Carroll <mjcarroll@intrinsic.ai>
---
 README.md | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 17c0f72f..9cef36db 100644
--- a/README.md
+++ b/README.md
@@ -9,10 +9,10 @@
 
 Build | Status
 -- | --
-Test coverage | [![codecov](https://codecov.io/gh/gazebosim/gz-fuel-tools/tree/gz-fuel-tools9/graph/badge.svg)](https://codecov.io/gh/gazebosim/gz-fuel-tools/tree/gz-fuel-tools9)
-Ubuntu Jammy  | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_fuel_tools-ci-gz-fuel-tools9-jammy-amd64)](https://build.osrfoundation.org/job/gz_fuel_tools-ci-gz-fuel-tools9-jammy-amd64)
-Homebrew      | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_fuel_tools-ci-gz-fuel-tools9-homebrew-amd64)](https://build.osrfoundation.org/job/gz_fuel_tools-ci-gz-fuel-tools9-homebrew-amd64)
-Windows       | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_fuel_tools-9-win)](https://build.osrfoundation.org/job/gz_fuel_tools-9-win/)
+Test coverage | [![codecov](https://codecov.io/gh/gazebosim/gz-fuel-tools/tree/main/graph/badge.svg)](https://codecov.io/gh/gazebosim/gz-fuel-tools/tree/main)
+Ubuntu Jammy  | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_fuel_tools-ci-main-jammy-amd64)](https://build.osrfoundation.org/job/gz_fuel_tools-ci-main-jammy-amd64)
+Homebrew      | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_fuel_tools-ci-main-homebrew-amd64)](https://build.osrfoundation.org/job/gz_fuel_tools-ci-main-homebrew-amd64)
+Windows       | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=gz_fuel_tools-main-win)](https://build.osrfoundation.org/job/gz_fuel_tools-main-win/)
 
 Gazebo Fuel Tools is composed by a client library and command line tools for
 interacting with Gazebo Fuel servers.