Repository: tower-rs/tower
Pull request #432 (2020-03-31 17:32:00)

2020: merge all the middleware
Tracking issue: #431


Patch:
diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index 9e9cd4f..b7816b5 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -46,24 +46,9 @@ jobs:
       matrix:
         crate:
           - tower
-          - tower-balance
-          - tower-buffer
-          - tower-discover
-          - tower-filter
-          - tower-hedge
           - tower-layer
-          - tower-limit
-          - tower-load
-          - tower-load-shed
-          - tower-make
-          - tower-ready-cache
-          - tower-reconnect
-          - tower-retry
           - tower-service
-          - tower-spawn-ready
           - tower-test
-          - tower-timeout
-          - tower-util
 
     steps:
       - name: Checkout code
@@ -94,10 +79,53 @@ jobs:
         uses: actions-rs/cargo@v1
         env:
           CI: 'True'
-          RUSTFLAGS: '-D warnings'
+          # RUSTFLAGS: '-D warnings'
         with:
           command: test
-          args: -p ${{ matrix.crate }} --verbose
+          args: -p ${{ matrix.crate }} --verbose --all-features
+
+  features:
+
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@v1
+      - name: Install rust toolchain
+        uses: actions-rs/toolchain@v1
+        with:
+          toolchain: nightly
+          override: true
+      - name: Patch
+        run: |
+          set -e
+          # Remove any existing patch statements
+          mv Cargo.toml Cargo.toml.bck
+          sed -n '/\[patch.crates-io\]/q;p' Cargo.toml.bck > Cargo.toml
+          # Patch all crates
+          cat .github/workflows/patch.toml >> Cargo.toml
+          # Print `Cargo.toml` for debugging
+          echo "~~~~ Cargo.toml ~~~~"
+          cat Cargo.toml
+          echo "~~~~~~~~~~~~~~~~~~~~"
+      - name: Install cargo-hack
+        uses: actions-rs/cargo@v1
+        with:
+          command: install
+          args: cargo-hack
+      - name: Run feature checks
+        uses: actions-rs/cargo@v1
+        env:
+          CI: 'True'
+        with:
+          command: hack
+          # Check each feature works properly
+          # * --each-feature
+          #   run for each feature which includes --no-default-features and default features of package
+          # * -Z avoid-dev-deps
+          #   build without dev-dependencies to avoid https://github.com/rust-lang/cargo/issues/4866
+          #   tracking-issue: https://github.com/rust-lang/cargo/issues/5133
+          args: check -p tower --each-feature -Z avoid-dev-deps
 
   rustfmt:
 
diff --git a/.github/workflows/patch.toml b/.github/workflows/patch.toml
index 54633ad..91f0b60 100644
--- a/.github/workflows/patch.toml
+++ b/.github/workflows/patch.toml
@@ -2,17 +2,6 @@
 # repository.
 [patch.crates-io]
 tower = { path = "tower" }
-tower-balance = { path = "tower-balance" }
-tower-buffer = { path = "tower-buffer" }
-tower-discover = { path = "tower-discover" }
-tower-filter = { path = "tower-filter" }
 tower-layer = { path = "tower-layer" }
-tower-limit = { path = "tower-limit" }
-tower-load-shed = { path = "tower-load-shed" }
-tower-reconnect = { path = "tower-reconnect" }
-tower-retry = { path = "tower-retry" }
 tower-service = { path = "tower-service" }
-tower-spawn-ready = { path = "tower-spawn-ready" }
 tower-test = { path = "tower-test" }
-tower-timeout = { path = "tower-timeout" }
-tower-util = { path = "tower-util" }
diff --git a/Cargo.toml b/Cargo.toml
index 6a82d11..b7d4757 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,22 +2,7 @@
 
 members = [
   "tower",
-  "tower-balance",
-  "tower-buffer",
-  "tower-discover",
-  "tower-filter",
-  "tower-hedge",
   "tower-layer",
-  "tower-limit",
-  "tower-load",
-  "tower-load-shed",
-  "tower-ready-cache",
-  "tower-reconnect",
-  "tower-retry",
   "tower-service",
-  "tower-spawn-ready",
   "tower-test",
-  "tower-timeout",
-  "tower-make",
-  "tower-util",
 ]
diff --git a/tower-balance/CHANGELOG.md b/tower-balance/CHANGELOG.md
deleted file mode 100644
index 1aa198f..0000000
--- a/tower-balance/CHANGELOG.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# 0.3.0 (December 4, 2019)
-
-- Update to `tower-service 0.3`
-- Update to `tower-ready-cache 0.3`
-- Update to `futures 0.3`
-
-# 0.3.0-alpha.2 (September 30, 2019)
-
-- Move to `futures-*-preview 0.3.0-alpha.19`
-- Move to `pin-project 0.4`
-
-# 0.3.0-alpha.1 (September 11, 2019)
-
-- Move to `std::future`
-
-# 0.1.0 (unreleased)
-
-- Initial release
diff --git a/tower-balance/Cargo.toml b/tower-balance/Cargo.toml
deleted file mode 100644
index ea41c9f..0000000
--- a/tower-balance/Cargo.toml
+++ /dev/null
@@ -1,53 +0,0 @@
-[package]
-name = "tower-balance"
-# When releasing to crates.io:
-# - Remove path dependencies
-# - Update html_root_url.
-# - Update doc url
-#   - Cargo.toml
-#   - README.md
-# - Update CHANGELOG.md.
-# - Create "v0.1.x" git tag.
-version = "0.3.0"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-balance/0.3.0"
-description = """
-Balance load across a set of uniform services.
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-
-[features]
-log = ["tracing/log"]
-default = ["log"]
-
-[dependencies]
-futures-util = { version = "0.3", default-features = false } 
-futures-core = { version = "0.3", default-features = false }
-pin-project = "0.4"
-indexmap = "1.0.2"
-tracing = "0.1"
-rand = { version = "0.7", features = ["small_rng"] } 
-tokio = { version = "0.2", features = ["sync", "time"] }
-tower-discover = { version = "0.3", path = "../tower-discover" }
-tower-layer = "0.3"
-tower-load = { version = "0.3", path = "../tower-load" }
-tower-service = "0.3"
-tower-ready-cache = { version = "0.3", path = "../tower-ready-cache" }
-tower-make = "0.3"
-slab = "0.4"
-
-[dev-dependencies]
-tracing-subscriber = "0.1.1"
-hdrhistogram = "6.0"
-quickcheck = { version = "0.6", default-features = false }
-tokio = { version = "0.2", features = ["macros", "stream"] }
-tokio-test = "0.2"
-tower-buffer = { version = "0.3", path = "../tower-buffer" }
-tower-limit = { version = "0.3", path = "../tower-limit" }
-tower-test = { version = "0.3", path = "../tower-test" }
-tower = { version = "0.3", path = "../tower" }
diff --git a/tower-balance/LICENSE b/tower-balance/LICENSE
deleted file mode 100644
index b980cac..0000000
--- a/tower-balance/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2019 Tower Contributors
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/tower-balance/README.md b/tower-balance/README.md
deleted file mode 100644
index 1ceb355..0000000
--- a/tower-balance/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Tower Balance
-
-Balance load across a set of uniform services.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
diff --git a/tower-balance/src/lib.rs b/tower-balance/src/lib.rs
deleted file mode 100644
index 2c0006f..0000000
--- a/tower-balance/src/lib.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-//! Load balancing middlewares.
-
-#![doc(html_root_url = "https://docs.rs/tower-balance/0.3.0")]
-#![warn(
-    missing_debug_implementations,
-    missing_docs,
-    rust_2018_idioms,
-    unreachable_pub
-)]
-#![allow(elided_lifetimes_in_paths)]
-
-pub mod error;
-pub mod p2c;
-pub mod pool;
diff --git a/tower-buffer/CHANGELOG.md b/tower-buffer/CHANGELOG.md
deleted file mode 100644
index 3876abc..0000000
--- a/tower-buffer/CHANGELOG.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# 0.3.0 (December 19, 2019)
-
-- Update to `tokio 0.2`
-- Update to `futures-core 0.3`
-- Update to `tower-service 0.3`
-- Update to `tower-layer 0.3`
-
-# 0.3.0-alpha.2 (September 30, 2019)
-
-- Move to `futures-*-preview 0.3.0-alpha.19`
-- Move to `pin-project 0.4`
-
-# 0.3.0-alpha.1b (September 13, 2019)
-
-- Remove `Stream` unused warning.
-
-# 0.3.0-alpha.1a (September 13, 2019)
-
-- Fix `poll_next` not exisitng.
-
-# 0.3.0-alpha.1 (September 11, 2019)
-
-- Move to `std::future`
-
-# 0.1.1 (July 19, 2019)
-
-- Add `tracing` support
-
-# 0.1.0 (April 26, 2019)
-
-- Initial release
diff --git a/tower-buffer/Cargo.toml b/tower-buffer/Cargo.toml
deleted file mode 100644
index c3d484a..0000000
--- a/tower-buffer/Cargo.toml
+++ /dev/null
@@ -1,39 +0,0 @@
-[package]
-name = "tower-buffer"
-# When releasing to crates.io:
-# - Remove path dependencies
-# - Update html_root_url.
-# - Update doc url
-#   - Cargo.toml
-#   - README.md
-# - Update CHANGELOG.md.
-# - Create "v0.1.x" git tag.
-version = "0.3.0"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-buffer/0.3.0"
-description = """
-Buffer requests before dispatching to a `Service`.
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-
-[features]
-log = ["tracing/log"]
-default = ["log"]
-
-[dependencies]
-futures-core = { version = "0.3", default-features = false }
-pin-project = "0.4"
-tower-service = "0.3"
-tower-layer = "0.3"
-tokio = { version = "0.2", features = ["rt-core", "sync"] }
-tracing = "0.1.2"
-
-[dev-dependencies]
-tower-test = { version = "0.3", path = "../tower-test" }
-tokio-test = { version = "0.2" }
-tokio = { version = "0.2", features = ["macros"] }
diff --git a/tower-buffer/LICENSE b/tower-buffer/LICENSE
deleted file mode 100644
index b980cac..0000000
--- a/tower-buffer/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2019 Tower Contributors
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/tower-buffer/README.md b/tower-buffer/README.md
deleted file mode 100644
index 3b3bfbd..0000000
--- a/tower-buffer/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Tower Buffer
-
-Buffer requests before dispatching to a `Service`.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
diff --git a/tower-discover/CHANGELOG.md b/tower-discover/CHANGELOG.md
deleted file mode 100644
index 0803b17..0000000
--- a/tower-discover/CHANGELOG.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# 0.3.0 (December 19, 2019)
-
-- Update to `tower-service 0.3`
-- Update to `futures-core 0.3`
-
-# 0.3.0-alpha.2 (September 30, 2019)
-
-- Move to `futures-*-preview 0.3.0-alpha.19`
-- Move to `pin-project 0.4`
-
-# 0.3.0-alpha.1 (September 11, 2019)
-
-- Move to `std::future`
-
-# 0.1.0 (April 26, 2019)
-
-- Initial release
diff --git a/tower-discover/Cargo.toml b/tower-discover/Cargo.toml
deleted file mode 100644
index 8eb226b..0000000
--- a/tower-discover/Cargo.toml
+++ /dev/null
@@ -1,27 +0,0 @@
-[package]
-name = "tower-discover"
-# When releasing to crates.io:
-# - Remove path dependencies
-# - Update html_root_url.
-# - Update doc url
-#   - Cargo.toml
-#   - README.md
-# - Update CHANGELOG.md.
-# - Create "v0.1.x" git tag.
-version = "0.3.0"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-discover/0.3.0"
-description = """
-Abstracts over service discovery strategies.
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-
-[dependencies]
-futures-core = { version = "0.3", default-features = false }
-tower-service = "0.3"
-pin-project = "0.4"
diff --git a/tower-discover/LICENSE b/tower-discover/LICENSE
deleted file mode 100644
index b980cac..0000000
--- a/tower-discover/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2019 Tower Contributors
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/tower-discover/README.md b/tower-discover/README.md
deleted file mode 100644
index 0b0e7fd..0000000
--- a/tower-discover/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Tower Discovery
-
-Abstracts over service discovery strategies.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
diff --git a/tower-filter/CHANGELOG.md b/tower-filter/CHANGELOG.md
deleted file mode 100644
index 4eb60cc..0000000
--- a/tower-filter/CHANGELOG.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# 0.3.0-alpha.2 (September 30, 2019)
-
-- Move to `futures-*-preview 0.3.0-alpha.19`
-- Move to `pin-project 0.4`
-
-# 0.3.0-alpha.1
-
-- Move to `std::future`
-
-# 0.1.0 (unreleased)
-
-- Initial release
diff --git a/tower-filter/Cargo.toml b/tower-filter/Cargo.toml
deleted file mode 100644
index 3469057..0000000
--- a/tower-filter/Cargo.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-[package]
-name = "tower-filter"
-# When releasing to crates.io:
-# - Remove path dependencies
-# - Update html_root_url.
-# - Update doc url
-#   - Cargo.toml
-#   - README.md
-# - Update CHANGELOG.md.
-# - Create "v0.1.x" git tag.
-version = "0.3.0"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-filter/0.3.0-alpha.2"
-description = """
-Conditionally allow requests to be dispatched to a service based on the result
-of a predicate.
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-publish = false
-
-[dependencies]
-tower-service = "0.3"
-tower-layer = "0.3"
-pin-project = "0.4"
-futures-core = { version = "0.3", default-features = false }
-
-[dev-dependencies]
-tower-test = { version = "0.3", path = "../tower-test" }
-futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
-tokio = { version = "0.2", features = ["macros", "sync"] }
diff --git a/tower-filter/LICENSE b/tower-filter/LICENSE
deleted file mode 100644
index b980cac..0000000
--- a/tower-filter/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2019 Tower Contributors
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/tower-filter/README.md b/tower-filter/README.md
deleted file mode 100644
index c862a19..0000000
--- a/tower-filter/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Tower Filter
-
-Conditionally allow requests to be dispatched to a service based on the result
-of a predicate.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
diff --git a/tower-hedge/CHANGELOG.md b/tower-hedge/CHANGELOG.md
deleted file mode 100644
index 362ff4f..0000000
--- a/tower-hedge/CHANGELOG.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# 0.3.0 (December 4, 2019)
-
-- Initial release
\ No newline at end of file
diff --git a/tower-hedge/Cargo.toml b/tower-hedge/Cargo.toml
deleted file mode 100644
index c6a84ed..0000000
--- a/tower-hedge/Cargo.toml
+++ /dev/null
@@ -1,20 +0,0 @@
-[package]
-name = "tower-hedge"
-version = "0.3.0"
-authors = ["Alex Leong <adlleong@gmail.com>"]
-edition = "2018"
-publish = false
-
-[dependencies]
-hdrhistogram = "6.0"
-log = "0.4.1"
-tower-service = "0.3"
-tower-filter = { version = "0.3", path = "../tower-filter" }
-tokio = { version = "0.2", features = ["time"] }
-futures-util = { version = "0.3", default-features = false }
-pin-project = "0.4"
-
-[dev-dependencies]
-tower-test = { version = "0.3", path = "../tower-test" }
-tokio-test = "0.2"
-tokio = { version = "0.2", features = ["macros", "test-util"] }
\ No newline at end of file
diff --git a/tower-hedge/README.md b/tower-hedge/README.md
deleted file mode 100644
index e69de29..0000000
diff --git a/tower-limit/CHANGELOG.md b/tower-limit/CHANGELOG.md
deleted file mode 100644
index cafba0f..0000000
--- a/tower-limit/CHANGELOG.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# 0.3.1 (March 25, 2020)
-
-- Implement `tower_load::Load` for `ConcurrentLimit` and `RateLimit`
-  (#429).
-
-# 0.3.0 (December 19, 2019)
-
-- Update to `futures 0.3`
-- Update to `tokio 0.2`
-
-# 0.3.0-alpha.2 (September 30, 2019)
-
-- Move to `futures-*-preview 0.3.0-alpha.19`
-- Move to `pin-project 0.4`
-
-# 0.3.0-alpha.1 (September 11, 2019)
-
-- Move to `std::future`
-
-# 0.1.0 (April 26, 2019)
-
-- Initial release
diff --git a/tower-limit/Cargo.toml b/tower-limit/Cargo.toml
deleted file mode 100644
index bf88054..0000000
--- a/tower-limit/Cargo.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-[package]
-name = "tower-limit"
-# When releasing to crates.io:
-# - Remove path dependencies
-# - Update html_root_url.
-# - Update doc url
-#   - Cargo.toml
-#   - README.md
-# - Update CHANGELOG.md.
-# - Create "v0.3.x" git tag.
-version = "0.3.1"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-limit/0.3.1"
-description = """
-Limit maximum request rate to a `Service`.
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-
-[dependencies]
-futures-core = { version = "0.3", default-features = false }
-tower-service = "0.3"
-tower-layer = "0.3"
-tower-load = "0.3"
-tokio = { version = "0.2", features = ["time"] }
-pin-project = "0.4"
-
-[dev-dependencies]
-tower-test = { version = "0.3", path = "../tower-test" }
-tokio-test = "0.2"
-tokio = { version = "0.2", features = ["macros", "test-util"] }
diff --git a/tower-limit/LICENSE b/tower-limit/LICENSE
deleted file mode 100644
index b980cac..0000000
--- a/tower-limit/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2019 Tower Contributors
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/tower-limit/README.md b/tower-limit/README.md
deleted file mode 100644
index 3cb2d63..0000000
--- a/tower-limit/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Tower Rate Limit
-
-Limit maximum request rate to a `Service`.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
diff --git a/tower-limit/src/lib.rs b/tower-limit/src/lib.rs
deleted file mode 100644
index 8611c2d..0000000
--- a/tower-limit/src/lib.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-#![doc(html_root_url = "https://docs.rs/tower-limit/0.3.1")]
-#![warn(
-    missing_debug_implementations,
-    missing_docs,
-    rust_2018_idioms,
-    unreachable_pub
-)]
-#![allow(elided_lifetimes_in_paths)]
-
-//! Tower middleware for limiting requests.
-
-pub mod concurrency;
-pub mod rate;
-
-pub use crate::{
-    concurrency::{ConcurrencyLimit, ConcurrencyLimitLayer},
-    rate::{RateLimit, RateLimitLayer},
-};
diff --git a/tower-load-shed/CHANGELOG.md b/tower-load-shed/CHANGELOG.md
deleted file mode 100644
index 7223835..0000000
--- a/tower-load-shed/CHANGELOG.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# 0.3.0 (December 4, 2019)
-
-- Update to `tower-service 0.3`
-- Update to `futures 0.3`
-
-# 0.3.0-alpha.2 (September 30, 2019)
-
-- Move to `futures-*-preview 0.3.0-alpha.19`
-- Move to `pin-project 0.4`
-
-# 0.3.0-alpha.1 (September 11, 2019)
-
-- Move to `std::future`
-
-# 0.1.0 (April 26, 2019)
-
-- Initial release
diff --git a/tower-load-shed/Cargo.toml b/tower-load-shed/Cargo.toml
deleted file mode 100644
index ee5ce3b..0000000
--- a/tower-load-shed/Cargo.toml
+++ /dev/null
@@ -1,34 +0,0 @@
-[package]
-name = "tower-load-shed"
-# When releasing to crates.io:
-# - Remove path dependencies
-# - Update html_root_url.
-# - Update doc url
-#   - Cargo.toml
-#   - README.md
-# - Update CHANGELOG.md.
-# - Create "v0.1.x" git tag.
-version = "0.3.0"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-load-shed/0.3.0"
-description = """
-Immediately reject requests if the inner service is not ready. This is also
-known as load-shedding.
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-
-[dependencies]
-tower-service = "0.3"
-tower-layer = "0.3"
-pin-project = "0.4"
-futures-core = { version = "0.3", default-features = false }
-
-[dev-dependencies]
-tokio-test = "0.2"
-tower-test = { version = "0.3", path = "../tower-test" }
-tokio = { version = "0.2", features = ["macros"] }
\ No newline at end of file
diff --git a/tower-load-shed/LICENSE b/tower-load-shed/LICENSE
deleted file mode 100644
index b980cac..0000000
--- a/tower-load-shed/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2019 Tower Contributors
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/tower-load-shed/README.md b/tower-load-shed/README.md
deleted file mode 100644
index 30440f6..0000000
--- a/tower-load-shed/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Tower Load Shed
-
-Immediately reject requests if the inner service is not ready. This is also
-known as load-shedding.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
diff --git a/tower-load/CHANGELOG.md b/tower-load/CHANGELOG.md
deleted file mode 100644
index 36f1352..0000000
--- a/tower-load/CHANGELOG.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# 0.3.0 (December 19, 2019)
-
-- Update to `tower-service 0.3`
-- Update to `tower-discover 0.3`
-
-# 0.3.0-alpha.2 (September 30, 2019)
-
-- Move to `futures-*-preview 0.3.0-alpha.19`
-- Move to `pin-project 0.4`
-
-# 0.3.0-alpha.1 (September 11, 2019)
-
-- Move to `std::future`
-
-# 0.1.0 (unreleased)
-
-- Initial release
diff --git a/tower-load/Cargo.toml b/tower-load/Cargo.toml
deleted file mode 100644
index 7b698aa..0000000
--- a/tower-load/Cargo.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-[package]
-name = "tower-load"
-# When releasing to crates.io:
-# - Remove path dependencies
-# - Update html_root_url.
-# - Update doc url
-#   - Cargo.toml
-#   - README.md
-# - Update CHANGELOG.md.
-# - Create "v0.1.x" git tag.
-version = "0.3.0"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-load/0.3.0-alpha.2"
-description = """
-Strategies for measuring the load of a service
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-
-[dependencies]
-futures-core = { version = "0.3", default-features = false }
-log = "0.4.1"
-tokio = { version = "0.2", features = ["time"] }
-tower-service = "0.3"
-tower-discover = { version = "0.3", path = "../tower-discover" }
-pin-project = "0.4"
-
-[dev-dependencies]
-tokio-test = "0.2"
-tokio = { version = "0.2", features = ["macros", "test-util" ] }
-futures-util = { version = "0.3", default-features = false }
diff --git a/tower-load/LICENSE b/tower-load/LICENSE
deleted file mode 100644
index b980cac..0000000
--- a/tower-load/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2019 Tower Contributors
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/tower-load/README.md b/tower-load/README.md
deleted file mode 100644
index f8c58a0..0000000
--- a/tower-load/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Tower Load
-
-Provides strategies for measuring a service's load.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
diff --git a/tower-make/CHANGELOG.md b/tower-make/CHANGELOG.md
deleted file mode 100644
index eab9485..0000000
--- a/tower-make/CHANGELOG.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# 0.3.0 (November 29, 2019)
-
-- Update `tokio` to `0.2`.
-- Rename `io` feature to `connect`.
-
-# 0.3.0-alpha.2a (September 30, 2019)
-
-- Update `tokio-io` to `alpha.6`
-- Update `tower-service` to `alpha.2`
-
-# 0.3.0-alpha.2 (September 20, 2019)
-
-- Update `tokio-io` to `alpha.5`
-
-# 0.3.0-alpha.1 (September 11, 2019)
-
-- Bump version to match all the other crates with `std::future`
-
-# 0.1.0-alpha.2 (August 30, 2019)
-
-- Update `tokio-io` to `alpha.4`
-
-
-# 0.1.0-alpha.1 (August 26, 2019)
-
-- Initial release
diff --git a/tower-make/Cargo.toml b/tower-make/Cargo.toml
deleted file mode 100644
index 3605090..0000000
--- a/tower-make/Cargo.toml
+++ /dev/null
@@ -1,21 +0,0 @@
-[package]
-name = "tower-make"
-version = "0.3.0"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-make/0.3.0"
-description = """
-Trait aliases for Services that produce specific types of Responses.
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-
-[features]
-connect = ["tokio"]
-
-[dependencies]
-tower-service = "0.3"
-tokio = { version = "0.2", optional = true }
diff --git a/tower-make/LICENSE b/tower-make/LICENSE
deleted file mode 100644
index b980cac..0000000
--- a/tower-make/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2019 Tower Contributors
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/tower-make/README.md b/tower-make/README.md
deleted file mode 100644
index 444af14..0000000
--- a/tower-make/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Tower Service Makers
-
-Trait aliases for Services that produce specific types of Responses.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
diff --git a/tower-make/src/lib.rs b/tower-make/src/lib.rs
deleted file mode 100644
index 5977f96..0000000
--- a/tower-make/src/lib.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-#![doc(html_root_url = "https://docs.rs/tower-make/0.3.0")]
-#![warn(
-    missing_debug_implementations,
-    missing_docs,
-    rust_2018_idioms,
-    unreachable_pub
-)]
-
-//! Trait aliases for Services that produce specific types of Responses.
-
-#[cfg(feature = "connect")]
-mod make_connection;
-mod make_service;
-
-#[cfg(feature = "connect")]
-pub use crate::make_connection::MakeConnection;
-pub use crate::make_service::MakeService;
-
-mod sealed {
-    pub trait Sealed<T> {}
-}
diff --git a/tower-ready-cache/CHANGELOG.md b/tower-ready-cache/CHANGELOG.md
deleted file mode 100644
index f5427f4..0000000
--- a/tower-ready-cache/CHANGELOG.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# 0.3.1 (February 24, 2020)
-
-- Fix spurious panic (#420).
-- Restore assertion from pre-`std::future::Future` (#418).
-- Fix documentation URLs to point to 0.3.
diff --git a/tower-ready-cache/Cargo.toml b/tower-ready-cache/Cargo.toml
deleted file mode 100644
index 533cf41..0000000
--- a/tower-ready-cache/Cargo.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-[package]
-name = "tower-ready-cache"
-# When releasing to crates.io:
-# - Remove path dependencies
-# - Update html_root_url.
-# - Update doc url
-#   - Cargo.toml
-#   - README.md
-# - Update CHANGELOG.md.
-# - Create "v0.1.x" git tag.
-version = "0.3.1"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-ready-cache/0.3.1"
-description = """
-Caches a set of services
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-
-[dependencies]
-futures-core = { version = "0.3", default-features = false }
-futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
-indexmap = "1.0.2"
-log = "0.4.1"
-tokio = { version = "0.2", features = ["sync"] } 
-tower-service = "0.3"
-
-[dev-dependencies]
-tower-test = { version = "0.3", path = "../tower-test" }
-tokio-test = "0.2"
-
diff --git a/tower-ready-cache/README.md b/tower-ready-cache/README.md
deleted file mode 100644
index 6c51f30..0000000
--- a/tower-ready-cache/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Tower Ready Cache 
-
-Provides a set of ready services.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
-
diff --git a/tower-ready-cache/src/lib.rs b/tower-ready-cache/src/lib.rs
deleted file mode 100644
index dec2a81..0000000
--- a/tower-ready-cache/src/lib.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//! A cache of services
-
-#![doc(html_root_url = "https://docs.rs/tower-ready-cache/0.3.1")]
-#![deny(missing_docs)]
-#![deny(rust_2018_idioms)]
-#![allow(elided_lifetimes_in_paths)]
-
-pub mod cache;
-pub mod error;
-
-pub use self::cache::ReadyCache;
diff --git a/tower-reconnect/CHANGELOG.md b/tower-reconnect/CHANGELOG.md
deleted file mode 100644
index 35d0999..0000000
--- a/tower-reconnect/CHANGELOG.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# 0.3.0 (December 19, 2019)
-
-- Update to `tower-service 0.3`
-
-# 0.3.0-alpha.2 (September 30, 2019)
-
-- Move to `futures-*-preview 0.3.0-alpha.19`
-- Move to `pin-project 0.4`
-
-# 0.3.0-alpha.1 (September 11, 2019)
-
-- Move to `std::future`
-
-# 0.1.0 (unreleased)
-
-- Initial release
diff --git a/tower-reconnect/Cargo.toml b/tower-reconnect/Cargo.toml
deleted file mode 100644
index 406565c..0000000
--- a/tower-reconnect/Cargo.toml
+++ /dev/null
@@ -1,28 +0,0 @@
-[package]
-name = "tower-reconnect"
-# When releasing to crates.io:
-# - Remove path dependencies
-# - Update html_root_url.
-# - Update doc url
-#   - Cargo.toml
-#   - README.md
-# - Update CHANGELOG.md.
-# - Create "v0.1.x" git tag.
-version = "0.3.0"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-reconnect/0.3.0-alpha.2"
-description = """
-Automatically recreate a new `Service` instance when an error is encountered.
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-
-[dependencies]
-log = "0.4.1"
-tower-service = "0.3"
-tower-make = "0.3"
-pin-project = "0.4"
diff --git a/tower-reconnect/LICENSE b/tower-reconnect/LICENSE
deleted file mode 100644
index b980cac..0000000
--- a/tower-reconnect/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2019 Tower Contributors
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/tower-reconnect/README.md b/tower-reconnect/README.md
deleted file mode 100644
index be0f5ac..0000000
--- a/tower-reconnect/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Tower Reconnect
-
-Automatically recreate a new `Service` instance when an error is encountered.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
diff --git a/tower-retry/CHANGELOG.md b/tower-retry/CHANGELOG.md
deleted file mode 100644
index fc569a8..0000000
--- a/tower-retry/CHANGELOG.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# 0.3.0 (December 4, 2019)
-
-- Update to `tower-service 0.3`
-- Update to `tower-layer 0.3`
-- Update to `tokio 0.2`
-- Update to `futures-core 0.3`
-
-# 0.3.0-alpha.2 (September 30, 2019)
-
-- Move to `futures-*-preview 0.3.0-alpha.19`
-- Move to `pin-project 0.4`
-
-# 0.3.0-alpha.1 (September 11, 2019)
-
-- Move to `std::future`
-
-# 0.1.0 (April 26, 2019)
-
-- Initial release
diff --git a/tower-retry/Cargo.toml b/tower-retry/Cargo.toml
deleted file mode 100644
index 71c48cc..0000000
--- a/tower-retry/Cargo.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-[package]
-name = "tower-retry"
-# When releasing to crates.io:
-# - Remove path dependencies
-# - Update html_root_url.
-# - Update doc url
-#   - Cargo.toml
-#   - README.md
-# - Update CHANGELOG.md.
-# - Create "v0.1.x" git tag.
-version = "0.3.0"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-retry/0.3.0"
-description = """
-Retry failed requests.
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-
-[dependencies]
-tower-service = "0.3"
-tower-layer = "0.3"
-tokio = { version = "0.2", features = ["time"] }
-pin-project = "0.4"
-futures-core = { version = "0.3", default-features = false }
-
-[dev-dependencies]
-tower-test = { version = "0.3", path = "../tower-test" }
-tokio = { version  = "0.2", features = ["macros", "test-util"] }
-tokio-test = "0.2"
-futures-util = { version = "0.3", default-features = false }
diff --git a/tower-retry/LICENSE b/tower-retry/LICENSE
deleted file mode 100644
index b980cac..0000000
--- a/tower-retry/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2019 Tower Contributors
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/tower-retry/README.md b/tower-retry/README.md
deleted file mode 100644
index 433d67f..0000000
--- a/tower-retry/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Tower Retry
-
-Retry failed requests.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
diff --git a/tower-spawn-ready/CHANGELOG.md b/tower-spawn-ready/CHANGELOG.md
deleted file mode 100644
index 6d9fa72..0000000
--- a/tower-spawn-ready/CHANGELOG.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# 0.3.0 (December 19, 2019)
-
-- Update to `tower-service 0.3`
-- Update to `tokio 0.2`
-- Remove `Executor` usage
-
-# 0.3.0-alpha.2 (September 30, 2019)
-
-- Move to `futures-*-preview 0.3.0-alpha.19`
-- Move to `pin-project 0.4`
-
-# 0.3.0-alpha.1 (September 11, 2019)
-
-- Move to `std::future`
-
-# 0.1.0 (unreleased)
diff --git a/tower-spawn-ready/Cargo.toml b/tower-spawn-ready/Cargo.toml
deleted file mode 100644
index 925b27f..0000000
--- a/tower-spawn-ready/Cargo.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-[package]
-name = "tower-spawn-ready"
-# When releasing to crates.io:
-# - Remove path dependencies
-# - Update html_root_url.
-# - Update doc url
-#   - Cargo.toml
-#   - README.md
-# - Update CHANGELOG.md.
-# - Create "v0.1.x" git tag.
-version = "0.3.0"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-spawn-ready/0.3.0-alpha.2"
-description = """
-Drives service readiness via a spawned task
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-
-[dependencies]
-futures-core = { version = "0.3", default-features = false }
-futures-util = { version = "0.3", default-features = false }
-pin-project = "0.4"
-tower-service = "0.3"
-tower-layer = "0.3"
-tokio = { version = "0.2", features = ["sync"] }
-
-[dev-dependencies]
-tower-test = { version = "0.3", path = "../tower-test" }
-tokio-test = "0.2"
-tokio = { version = "0.2", features = ["macros"] }
\ No newline at end of file
diff --git a/tower-spawn-ready/LICENSE b/tower-spawn-ready/LICENSE
deleted file mode 100644
index b980cac..0000000
--- a/tower-spawn-ready/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2019 Tower Contributors
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/tower-spawn-ready/README.md b/tower-spawn-ready/README.md
deleted file mode 100644
index 04d9505..0000000
--- a/tower-spawn-ready/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Tower Spawn Ready
-
-Spawn Ready ensures that its inner service is driven to readiness on an executor. Useful with pooling layers that may poll their inner service infrequently.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
diff --git a/tower-spawn-ready/src/lib.rs b/tower-spawn-ready/src/lib.rs
deleted file mode 100644
index 279a826..0000000
--- a/tower-spawn-ready/src/lib.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-#![doc(html_root_url = "https://docs.rs/tower-spawn-ready/0.3.0")]
-#![warn(
-    missing_debug_implementations,
-    missing_docs,
-    rust_2018_idioms,
-    unreachable_pub
-)]
-#![allow(elided_lifetimes_in_paths)]
-
-//! When an underlying service is not ready, drive it to readiness on a
-//! background task.
-
-pub mod future;
-mod layer;
-mod make;
-mod service;
-
-pub use crate::layer::SpawnReadyLayer;
-pub use crate::make::{MakeFuture, MakeSpawnReady};
-pub use crate::service::SpawnReady;
-
-/// Errors produced by `SpawnReady`.
-pub(crate) type Error = Box<dyn std::error::Error + Send + Sync>;
diff --git a/tower-timeout/CHANGELOG.md b/tower-timeout/CHANGELOG.md
deleted file mode 100644
index 6d06991..0000000
--- a/tower-timeout/CHANGELOG.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# 0.3.0 (December 1, 2019)
-
-- Update to `tower-service 0.3`
-
-# 0.3.0-alpha.2 (September 30, 2019)
-
-- Move to `futures-*-preview 0.3.0-alpha.19`
-- Move to `pin-project 0.4`
-
-# 0.3.0-alpha.1 (September 11, 2019)
-
-- Move to `std::future`
-
-# 0.1.1 (July 30th, 2019)
-
-- Add `Elapsed::new`
-
-# 0.1.0 (April 26, 2019)
-
-- Initial release
diff --git a/tower-timeout/Cargo.toml b/tower-timeout/Cargo.toml
deleted file mode 100644
index c501249..0000000
--- a/tower-timeout/Cargo.toml
+++ /dev/null
@@ -1,28 +0,0 @@
-[package]
-name = "tower-timeout"
-# When releasing to crates.io:
-# - Remove path dependencies
-# - Update html_root_url.
-# - Update doc url
-#   - Cargo.toml
-#   - README.md
-# - Update CHANGELOG.md.
-# - Create "v0.3.x" git tag.
-version = "0.3.0"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-timeout/0.3.0"
-description = """
-Apply a timeout to requests, ensuring completion within a fixed time duration.
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-
-[dependencies]
-tower-service = "0.3"
-tower-layer = "0.3"
-tokio = { version = "0.2", features = ["time"] }
-pin-project = "0.4"
diff --git a/tower-timeout/LICENSE b/tower-timeout/LICENSE
deleted file mode 100644
index b980cac..0000000
--- a/tower-timeout/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2019 Tower Contributors
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/tower-timeout/README.md b/tower-timeout/README.md
deleted file mode 100644
index 0e2e237..0000000
--- a/tower-timeout/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Tower Timeout
-
-Apply a timeout to requests, ensuring completion within a fixed time duration.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
diff --git a/tower-util/CHANGELOG.md b/tower-util/CHANGELOG.md
deleted file mode 100644
index 2bd2913..0000000
--- a/tower-util/CHANGELOG.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# 0.3.1 (March 23, 2020)
-
-- Adds `ReadyAnd` and `ServiceExt::ready_and`, which yield `&mut` to the
-  service when it is ready (#427).
-- Adds `ReadyOneshot` and `ServiceExt::ready_oneshot`, which yield the
-  service when it is ready (#427).
-- Updates `Ready` and `ServiceExt::ready` documentation to reflect that
-  they do not yield the service, just unit, when the service is ready
-  (#427).
-
-# 0.3.0 (December 19, 2019)
-
-- Update to `tower-serivce 0.3`
-- Update to `futures 0.3`
-- Update to `tokio 0.2`
-
-# 0.3.0-alpha.2 (September 30, 2019)
-
-- Move to `futures-*-preview 0.3.0-alpha.19`
-- Move to `pin-project 0.4`
-
-# 0.3.0-alpha.1 (September 11, 2019)
-
-- Move to `std::future`
-
-# 0.1.0 (April 26, 2019)
-
-- Initial release
diff --git a/tower-util/Cargo.toml b/tower-util/Cargo.toml
deleted file mode 100644
index 6fa4a41..0000000
--- a/tower-util/Cargo.toml
+++ /dev/null
@@ -1,41 +0,0 @@
-[package]
-
-name = "tower-util"
-# When releasing to crates.io:
-# - Remove path dependencies
-# - Update html_root_url.
-# - Update doc url
-#   - Cargo.toml
-#   - README.md
-# - Update CHANGELOG.md.
-# - Create "v0.3.x" git tag.
-version = "0.3.1"
-authors = ["Tower Maintainers <team@tower-rs.com>"]
-license = "MIT"
-readme = "README.md"
-repository = "https://github.com/tower-rs/tower"
-homepage = "https://github.com/tower-rs/tower"
-documentation = "https://docs.rs/tower-util/0.3.1"
-description = """
-Utilities for working with `Service`.
-"""
-categories = ["asynchronous", "network-programming"]
-edition = "2018"
-
-[features]
-default = ["call-all"]
-call-all = ["futures-util"]
-
-[dependencies]
-tower-service = "0.3"
-pin-project = "0.4"
-futures-core = { version = "0.3", default-features = false }
-
-# Optional
-
-futures-util = { version = "0.3", optional = true, default-features = false, features = ["alloc"] }
-
-[dev-dependencies]
-tokio-test = "0.2"
-tokio = { version = "0.2", features = ["stream", "sync", "macros"] }
-tower-test = { version = "0.3", path = "../tower-test" }
diff --git a/tower-util/LICENSE b/tower-util/LICENSE
deleted file mode 100644
index b980cac..0000000
--- a/tower-util/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2019 Tower Contributors
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/tower-util/README.md b/tower-util/README.md
deleted file mode 100644
index fbb9d3b..0000000
--- a/tower-util/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Tower Service Util
-
-Utilities for working with `Service`.
-
-## License
-
-This project is licensed under the [MIT license](LICENSE).
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Tower by you, shall be licensed as MIT, without any additional
-terms or conditions.
diff --git a/tower/CHANGELOG.md b/tower/CHANGELOG.md
index d18c994..e9751f0 100644
--- a/tower/CHANGELOG.md
+++ b/tower/CHANGELOG.md
@@ -1,3 +1,19 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+### Added
+
+### Changed
+
+ - All middleware `tower-*` crates were merged into `tower` and placed
+   behind feature flags.
+
+### Removed
+
 # 0.3.1 (January 17, 2020)
 
 - Allow opting out of tracing/log (#410).
diff --git a/tower/Cargo.toml b/tower/Cargo.toml
index f450f1f..b879326 100644
--- a/tower/Cargo.toml
+++ b/tower/Cargo.toml
@@ -7,7 +7,7 @@ name = "tower"
 #   - Cargo.toml
 #   - README.md
 # - Update CHANGELOG.md.
-# - Create "v0.1.x" git tag.
+# - Create "vX.X.X" git tag.
 version = "0.3.1"
 authors = ["Tower Maintainers <team@tower-rs.com>"]
 license = "MIT"
@@ -24,26 +24,45 @@ keywords = ["io", "async", "non-blocking", "futures", "service"]
 edition = "2018"
 
 [features]
-default = ["full", "log"]
-full = []
-log = ["tower-buffer/log"]
+default = ["log"]
+log = ["tracing/log"]
+balance = ["discover", "load", "ready-cache", "make", "rand", "slab"]
+buffer = ["tokio/sync", "tokio/rt-core"]
+discover = []
+filter = []
+hedge = ["filter", "futures-util", "hdrhistogram", "tokio/time"]
+limit = ["tokio/time"]
+load = ["discover", "tokio/time"]
+load-shed = []
+make = ["tokio/io-std"]
+ready-cache = ["futures-util", "indexmap", "tokio/sync"]
+reconnect = ["make", "tokio/io-std"]
+retry = ["tokio/time"]
+spawn-ready = ["futures-util", "tokio/sync", "tokio/rt-core"]
+timeout = ["tokio/time"]
+util = ["futures-util"]
 
 [dependencies]
-tower-buffer = { version = "0.3", path = "../tower-buffer", default-features = false }
-tower-discover = { version = "0.3", path = "../tower-discover" }
-tower-layer = "0.3"
-tower-limit = { version = "0.3", path = "../tower-limit" }
-tower-load-shed = { version = "0.3", path = "../tower-load-shed" }
-tower-retry = { version = "0.3", path = "../tower-retry" }
-tower-service = "0.3"
-tower-timeout = { version = "0.3", path = "../tower-timeout" }
-tower-util = { version = "0.3", path = "../tower-util", features = ["call-all"] }
-futures-core = { version = "0.3", default-features = false }
+futures-core = "0.3"
+pin-project = "0.4"
+tower-layer = { version = "0.3", path = "../tower-layer" }
+tower-service = { version = "0.3", path = "../tower-service" }
+tracing = "0.1.2"
+
+futures-util = { version = "0.3", default-features = false, features = ["alloc"], optional = true }
+hdrhistogram = { version = "6.0", optional = true }
+indexmap = { version = "1.0.2", optional = true }
+rand = { version = "0.7", features = ["small_rng"], optional = true }
+slab = { version = "0.4", optional = true }
+tokio = { version = "0.2", optional = true }
 
 [dev-dependencies]
+futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
+hdrhistogram = "6.0"
+quickcheck = { version = "0.6", default-features = false }
+tokio = { version = "0.2", features = ["macros", "stream", "sync", "test-util" ] }
+tokio-test = "0.2"
+tower-test = { version = "0.3", path = "../tower-test" }
+tracing-subscriber = "0.1.1"
 # env_logger = { version = "0.5.3", default-features = false }
-futures-util = { version = "0.3", default-features = false }
-tokio = { version = "0.2", features = ["macros"] }
 # log = "0.4.1"
-# # tokio = "0.2"
-tower-test = { version = "0.3", path = "../tower-test" }
diff --git a/tower-balance/src/error.rs b/tower/src/balance/error.rs
similarity index 100%
rename from tower-balance/src/error.rs
rename to tower/src/balance/error.rs
diff --git a/tower/src/balance/mod.rs b/tower/src/balance/mod.rs
new file mode 100644
index 0000000..21a3948
--- /dev/null
+++ b/tower/src/balance/mod.rs
@@ -0,0 +1,5 @@
+//! Load balancing middlewares.
+
+pub mod error;
+pub mod p2c;
+pub mod pool;
diff --git a/tower-balance/src/p2c/layer.rs b/tower/src/balance/p2c/layer.rs
similarity index 100%
rename from tower-balance/src/p2c/layer.rs
rename to tower/src/balance/p2c/layer.rs
diff --git a/tower-balance/src/p2c/make.rs b/tower/src/balance/p2c/make.rs
similarity index 97%
rename from tower-balance/src/p2c/make.rs
rename to tower/src/balance/p2c/make.rs
index 01d8f24..f8e8b93 100644
--- a/tower-balance/src/p2c/make.rs
+++ b/tower/src/balance/p2c/make.rs
@@ -1,5 +1,6 @@
+use super::super::error;
 use super::Balance;
-use crate::error;
+use crate::discover::Discover;
 use futures_core::ready;
 use pin_project::pin_project;
 use rand::{rngs::SmallRng, SeedableRng};
@@ -9,7 +10,6 @@ use std::{
     pin::Pin,
     task::{Context, Poll},
 };
-use tower_discover::Discover;
 use tower_service::Service;
 
 /// Makes `Balancer`s given an inner service that makes `Discover`s.
diff --git a/tower-balance/src/p2c/mod.rs b/tower/src/balance/p2c/mod.rs
similarity index 100%
rename from tower-balance/src/p2c/mod.rs
rename to tower/src/balance/p2c/mod.rs
diff --git a/tower-balance/src/p2c/service.rs b/tower/src/balance/p2c/service.rs
similarity index 98%
rename from tower-balance/src/p2c/service.rs
rename to tower/src/balance/p2c/service.rs
index a3723ea..cc2058e 100644
--- a/tower-balance/src/p2c/service.rs
+++ b/tower/src/balance/p2c/service.rs
@@ -1,4 +1,7 @@
-use crate::error;
+use super::super::error;
+use crate::discover::{Change, Discover};
+use crate::load::Load;
+use crate::ready_cache::{error::Failed, ReadyCache};
 use futures_core::ready;
 use futures_util::future::{self, TryFutureExt};
 use pin_project::pin_project;
@@ -11,9 +14,6 @@ use std::{
     task::{Context, Poll},
 };
 use tokio::sync::oneshot;
-use tower_discover::{Change, Discover};
-use tower_load::Load;
-use tower_ready_cache::{error::Failed, ReadyCache};
 use tower_service::Service;
 use tracing::{debug, trace};
 
diff --git a/tower-balance/src/pool/mod.rs b/tower/src/balance/pool/mod.rs
similarity index 99%
rename from tower-balance/src/pool/mod.rs
rename to tower/src/balance/pool/mod.rs
index 46efb14..b049d49 100644
--- a/tower-balance/src/pool/mod.rs
+++ b/tower/src/balance/pool/mod.rs
@@ -14,8 +14,11 @@
 //! added or removed.
 #![deny(missing_docs)]
 
+use super::error;
 use super::p2c::Balance;
-use crate::error;
+use crate::discover::{Change, Discover};
+use crate::load::Load;
+use crate::make::MakeService;
 use futures_core::ready;
 use pin_project::pin_project;
 use slab::Slab;
@@ -25,9 +28,6 @@ use std::{
     pin::Pin,
     task::{Context, Poll},
 };
-use tower_discover::{Change, Discover};
-use tower_load::Load;
-use tower_make::MakeService;
 use tower_service::Service;
 
 #[cfg(test)]
diff --git a/tower-buffer/src/error.rs b/tower/src/buffer/error.rs
similarity index 100%
rename from tower-buffer/src/error.rs
rename to tower/src/buffer/error.rs
diff --git a/tower-buffer/src/future.rs b/tower/src/buffer/future.rs
similarity index 99%
rename from tower-buffer/src/future.rs
rename to tower/src/buffer/future.rs
index 6fb8ecd..66f1995 100644
--- a/tower-buffer/src/future.rs
+++ b/tower/src/buffer/future.rs
@@ -1,6 +1,6 @@
 //! Future types
 
-use crate::{
+use super::{
     error::{Closed, Error},
     message,
 };
diff --git a/tower-buffer/src/layer.rs b/tower/src/buffer/layer.rs
similarity index 95%
rename from tower-buffer/src/layer.rs
rename to tower/src/buffer/layer.rs
index 7f19480..faa5fa6 100644
--- a/tower-buffer/src/layer.rs
+++ b/tower/src/buffer/layer.rs
@@ -1,4 +1,4 @@
-use crate::{error::Error, service::Buffer};
+use super::{error::Error, service::Buffer};
 use std::{fmt, marker::PhantomData};
 use tower_layer::Layer;
 use tower_service::Service;
diff --git a/tower-buffer/src/message.rs b/tower/src/buffer/message.rs
similarity index 92%
rename from tower-buffer/src/message.rs
rename to tower/src/buffer/message.rs
index 98e7744..6d13aa1 100644
--- a/tower-buffer/src/message.rs
+++ b/tower/src/buffer/message.rs
@@ -1,4 +1,4 @@
-use crate::error::ServiceError;
+use super::error::ServiceError;
 use tokio::sync::oneshot;
 
 /// Message sent over buffer
diff --git a/tower-buffer/src/lib.rs b/tower/src/buffer/mod.rs
similarity index 61%
rename from tower-buffer/src/lib.rs
rename to tower/src/buffer/mod.rs
index 24499d7..a7afe64 100644
--- a/tower-buffer/src/lib.rs
+++ b/tower/src/buffer/mod.rs
@@ -1,12 +1,3 @@
-#![doc(html_root_url = "https://docs.rs/tower-buffer/0.3.0")]
-#![warn(
-    missing_debug_implementations,
-    missing_docs,
-    rust_2018_idioms,
-    unreachable_pub
-)]
-#![allow(elided_lifetimes_in_paths)]
-
 //! Buffer requests when the inner service is out of capacity.
 //!
 //! Buffering works by spawning a new task that is dedicated to pulling requests
@@ -21,5 +12,5 @@ mod message;
 mod service;
 mod worker;
 
-pub use crate::layer::BufferLayer;
-pub use crate::service::Buffer;
+pub use self::layer::BufferLayer;
+pub use self::service::Buffer;
diff --git a/tower-buffer/src/service.rs b/tower/src/buffer/service.rs
similarity index 99%
rename from tower-buffer/src/service.rs
rename to tower/src/buffer/service.rs
index 3d55738..63227c4 100644
--- a/tower-buffer/src/service.rs
+++ b/tower/src/buffer/service.rs
@@ -1,4 +1,4 @@
-use crate::{
+use super::{
     error::Error,
     future::ResponseFuture,
     message::Message,
diff --git a/tower-buffer/src/worker.rs b/tower/src/buffer/worker.rs
similarity index 99%
rename from tower-buffer/src/worker.rs
rename to tower/src/buffer/worker.rs
index 94bee09..c0f82d3 100644
--- a/tower-buffer/src/worker.rs
+++ b/tower/src/buffer/worker.rs
@@ -1,4 +1,4 @@
-use crate::{
+use super::{
     error::{Closed, Error, ServiceError},
     message::Message,
 };
diff --git a/tower/src/builder/mod.rs b/tower/src/builder/mod.rs
index 7896e9e..ca72409 100644
--- a/tower/src/builder/mod.rs
+++ b/tower/src/builder/mod.rs
@@ -1,16 +1,8 @@
 //! Builder types to compose layers and services
 
-use crate::{
-    buffer::BufferLayer,
-    limit::{concurrency::ConcurrencyLimitLayer, rate::RateLimitLayer},
-    load_shed::LoadShedLayer,
-    retry::RetryLayer,
-    timeout::TimeoutLayer,
-};
-
 use tower_layer::{Identity, Layer, Stack};
 
-use std::{fmt, time::Duration};
+use std::fmt;
 
 /// Declaratively construct Service values.
 ///
@@ -37,8 +29,11 @@ use std::{fmt, time::Duration};
 /// `service` will be last to see the request.
 ///
 /// ```
+/// # // this (and other) doctest is ignored because we don't have a way
+/// # // to say that it should only be run with cfg(feature = "...")
 /// # use tower::Service;
 /// # use tower::builder::ServiceBuilder;
+/// #[cfg(all(feature = "buffer", feature = "limit"))]
 /// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
 /// ServiceBuilder::new()
 ///     .buffer(100)
@@ -57,6 +52,7 @@ use std::{fmt, time::Duration};
 /// ```
 /// # use tower::Service;
 /// # use tower::builder::ServiceBuilder;
+/// #[cfg(all(feature = "buffer", feature = "limit"))]
 /// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
 /// ServiceBuilder::new()
 ///     .concurrency_limit(10)
@@ -77,7 +73,9 @@ use std::{fmt, time::Duration};
 /// ```
 /// # use tower::Service;
 /// # use tower::builder::ServiceBuilder;
-/// # use tower_limit::concurrency::ConcurrencyLimitLayer;
+/// # #[cfg(feature = "limit")]
+/// # use tower::limit::concurrency::ConcurrencyLimitLayer;
+/// #[cfg(feature = "limit")]
 /// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
 /// ServiceBuilder::new()
 ///     .concurrency_limit(5)
@@ -93,6 +91,7 @@ use std::{fmt, time::Duration};
 /// # use tower::Service;
 /// # use tower::builder::ServiceBuilder;
 /// # use std::time::Duration;
+/// #[cfg(all(feature = "buffer", feature = "limit"))]
 /// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
 /// ServiceBuilder::new()
 ///     .buffer(5)
@@ -125,8 +124,12 @@ impl<L> ServiceBuilder<L> {
     }
 
     /// Buffer requests when when the next layer is out of capacity.
-    pub fn buffer<Request>(self, bound: usize) -> ServiceBuilder<Stack<BufferLayer<Request>, L>> {
-        self.layer(BufferLayer::new(bound))
+    #[cfg(feature = "buffer")]
+    pub fn buffer<Request>(
+        self,
+        bound: usize,
+    ) -> ServiceBuilder<Stack<crate::buffer::BufferLayer<Request>, L>> {
+        self.layer(crate::buffer::BufferLayer::new(bound))
     }
 
     /// Limit the max number of in-flight requests.
@@ -134,8 +137,12 @@ impl<L> ServiceBuilder<L> {
     /// A request is in-flight from the time the request is received until the
     /// response future completes. This includes the time spent in the next
     /// layers.
-    pub fn concurrency_limit(self, max: usize) -> ServiceBuilder<Stack<ConcurrencyLimitLayer, L>> {
-        self.layer(ConcurrencyLimitLayer::new(max))
+    #[cfg(feature = "limit")]
+    pub fn concurrency_limit(
+        self,
+        max: usize,
+    ) -> ServiceBuilder<Stack<crate::limit::ConcurrencyLimitLayer, L>> {
+        self.layer(crate::limit::ConcurrencyLimitLayer::new(max))
     }
 
     /// Drop requests when the next layer is unable to respond to requests.
@@ -146,13 +153,19 @@ impl<L> ServiceBuilder<L> {
     ///
     /// `load_shed` immediately responds with an error when the next layer is
     /// out of capacity.
-    pub fn load_shed(self) -> ServiceBuilder<Stack<LoadShedLayer, L>> {
-        self.layer(LoadShedLayer::new())
+    #[cfg(feature = "load-shed")]
+    pub fn load_shed(self) -> ServiceBuilder<Stack<crate::load_shed::LoadShedLayer, L>> {
+        self.layer(crate::load_shed::LoadShedLayer::new())
     }
 
     /// Limit requests to at most `num` per the given duration
-    pub fn rate_limit(self, num: u64, per: Duration) -> ServiceBuilder<Stack<RateLimitLayer, L>> {
-        self.layer(RateLimitLayer::new(num, per))
+    #[cfg(feature = "limit")]
+    pub fn rate_limit(
+        self,
+        num: u64,
+        per: std::time::Duration,
+    ) -> ServiceBuilder<Stack<crate::limit::RateLimitLayer, L>> {
+        self.layer(crate::limit::RateLimitLayer::new(num, per))
     }
 
     /// Retry failed requests.
@@ -160,16 +173,21 @@ impl<L> ServiceBuilder<L> {
     /// `policy` must implement [`Policy`].
     ///
     /// [`Policy`]: ../retry/trait.Policy.html
-    pub fn retry<P>(self, policy: P) -> ServiceBuilder<Stack<RetryLayer<P>, L>> {
-        self.layer(RetryLayer::new(policy))
+    #[cfg(feature = "retry")]
+    pub fn retry<P>(self, policy: P) -> ServiceBuilder<Stack<crate::retry::RetryLayer<P>, L>> {
+        self.layer(crate::retry::RetryLayer::new(policy))
     }
 
     /// Fail requests that take longer than `timeout`.
     ///
     /// If the next layer takes more than `timeout` to respond to a request,
     /// processing is terminated and an error is returned.
-    pub fn timeout(self, timeout: Duration) -> ServiceBuilder<Stack<TimeoutLayer, L>> {
-        self.layer(TimeoutLayer::new(timeout))
+    #[cfg(feature = "timeout")]
+    pub fn timeout(
+        self,
+        timeout: std::time::Duration,
+    ) -> ServiceBuilder<Stack<crate::timeout::TimeoutLayer, L>> {
+        self.layer(crate::timeout::TimeoutLayer::new(timeout))
     }
 
     /// Obtains the underlying `Layer` implementation.
diff --git a/tower-discover/src/error.rs b/tower/src/discover/error.rs
similarity index 100%
rename from tower-discover/src/error.rs
rename to tower/src/discover/error.rs
diff --git a/tower-discover/src/list.rs b/tower/src/discover/list.rs
similarity index 97%
rename from tower-discover/src/list.rs
rename to tower/src/discover/list.rs
index 2a0c80e..8f8beb1 100644
--- a/tower-discover/src/list.rs
+++ b/tower/src/discover/list.rs
@@ -1,4 +1,4 @@
-use crate::{error::Never, Change, Discover};
+use super::{error::Never, Change, Discover};
 use pin_project::pin_project;
 use std::iter::{Enumerate, IntoIterator};
 use std::{
diff --git a/tower-discover/src/lib.rs b/tower/src/discover/mod.rs
similarity index 90%
rename from tower-discover/src/lib.rs
rename to tower/src/discover/mod.rs
index 27d8fc3..0492297 100644
--- a/tower-discover/src/lib.rs
+++ b/tower/src/discover/mod.rs
@@ -1,12 +1,3 @@
-#![doc(html_root_url = "https://docs.rs/tower-discover/0.3.0")]
-#![warn(
-    missing_debug_implementations,
-    missing_docs,
-    rust_2018_idioms,
-    unreachable_pub
-)]
-#![allow(elided_lifetimes_in_paths)]
-
 //! # Tower service discovery
 //!
 //! Service discovery is the automatic detection of services available to the
@@ -18,7 +9,7 @@ mod error;
 mod list;
 mod stream;
 
-pub use crate::{list::ServiceList, stream::ServiceStream};
+pub use self::{list::ServiceList, stream::ServiceStream};
 
 use std::hash::Hash;
 use std::ops;
diff --git a/tower-discover/src/stream.rs b/tower/src/discover/stream.rs
similarity index 97%
rename from tower-discover/src/stream.rs
rename to tower/src/discover/stream.rs
index ea2f90e..488221a 100644
--- a/tower-discover/src/stream.rs
+++ b/tower/src/discover/stream.rs
@@ -1,4 +1,4 @@
-use crate::{Change, Discover};
+use super::{Change, Discover};
 use futures_core::{ready, TryStream};
 use pin_project::pin_project;
 use std::hash::Hash;
diff --git a/tower-filter/src/error.rs b/tower/src/filter/error.rs
similarity index 100%
rename from tower-filter/src/error.rs
rename to tower/src/filter/error.rs
diff --git a/tower-filter/src/future.rs b/tower/src/filter/future.rs
similarity index 98%
rename from tower-filter/src/future.rs
rename to tower/src/filter/future.rs
index 31a9655..1c07426 100644
--- a/tower-filter/src/future.rs
+++ b/tower/src/filter/future.rs
@@ -1,6 +1,6 @@
 //! Future types
 
-use crate::error::{self, Error};
+use super::error::{self, Error};
 use futures_core::ready;
 use pin_project::{pin_project, project};
 use std::{
diff --git a/tower-filter/src/layer.rs b/tower/src/filter/layer.rs
similarity index 96%
rename from tower-filter/src/layer.rs
rename to tower/src/filter/layer.rs
index a779b29..92f368e 100644
--- a/tower-filter/src/layer.rs
+++ b/tower/src/filter/layer.rs
@@ -1,4 +1,4 @@
-use crate::Filter;
+use super::Filter;
 use tower_layer::Layer;
 
 /// Conditionally dispatch requests to the inner service based on a predicate.
diff --git a/tower-filter/src/lib.rs b/tower/src/filter/mod.rs
similarity index 80%
rename from tower-filter/src/lib.rs
rename to tower/src/filter/mod.rs
index bffd21a..23d668b 100644
--- a/tower-filter/src/lib.rs
+++ b/tower/src/filter/mod.rs
@@ -1,12 +1,3 @@
-#![doc(html_root_url = "https://docs.rs/tower-filter/0.3.0-alpha.2")]
-#![warn(
-    missing_debug_implementations,
-    missing_docs,
-    rust_2018_idioms,
-    unreachable_pub
-)]
-#![allow(elided_lifetimes_in_paths)]
-
 //! Conditionally dispatch requests to the inner service based on the result of
 //! a predicate.
 
@@ -15,9 +6,9 @@ pub mod future;
 mod layer;
 mod predicate;
 
-pub use crate::{layer::FilterLayer, predicate::Predicate};
+pub use self::{layer::FilterLayer, predicate::Predicate};
 
-use crate::{error::Error, future::ResponseFuture};
+use self::{error::Error, future::ResponseFuture};
 use futures_core::ready;
 use std::task::{Context, Poll};
 use tower_service::Service;
diff --git a/tower-filter/src/predicate.rs b/tower/src/filter/predicate.rs
similarity index 96%
rename from tower-filter/src/predicate.rs
rename to tower/src/filter/predicate.rs
index 34d2e58..52b3936 100644
--- a/tower-filter/src/predicate.rs
+++ b/tower/src/filter/predicate.rs
@@ -1,4 +1,4 @@
-use crate::error::Error;
+use super::error::Error;
 use std::future::Future;
 
 /// Checks a request
diff --git a/tower-hedge/src/delay.rs b/tower/src/hedge/delay.rs
similarity index 100%
rename from tower-hedge/src/delay.rs
rename to tower/src/hedge/delay.rs
diff --git a/tower-hedge/src/latency.rs b/tower/src/hedge/latency.rs
similarity index 100%
rename from tower-hedge/src/latency.rs
rename to tower/src/hedge/latency.rs
diff --git a/tower-hedge/src/lib.rs b/tower/src/hedge/mod.rs
similarity index 96%
rename from tower-hedge/src/lib.rs
rename to tower/src/hedge/mod.rs
index bd78ba8..807ecd5 100644
--- a/tower-hedge/src/lib.rs
+++ b/tower/src/hedge/mod.rs
@@ -8,8 +8,8 @@
     unreachable_pub
 )]
 
+use crate::filter::Filter;
 use futures_util::future;
-use log::error;
 use pin_project::pin_project;
 use std::sync::{Arc, Mutex};
 use std::time::Duration;
@@ -17,7 +17,7 @@ use std::{
     pin::Pin,
     task::{Context, Poll},
 };
-use tower_filter::Filter;
+use tracing::error;
 
 mod delay;
 mod latency;
@@ -220,13 +220,13 @@ impl latency::Record for Histo {
     }
 }
 
-impl<P, Request> tower_filter::Predicate<Request> for PolicyPredicate<P>
+impl<P, Request> crate::filter::Predicate<Request> for PolicyPredicate<P>
 where
     P: Policy<Request>,
 {
     type Future = future::Either<
-        future::Ready<Result<(), tower_filter::error::Error>>,
-        future::Pending<Result<(), tower_filter::error::Error>>,
+        future::Ready<Result<(), crate::filter::error::Error>>,
+        future::Pending<Result<(), crate::filter::error::Error>>,
     >;
 
     fn check(&mut self, request: &Request) -> Self::Future {
diff --git a/tower-hedge/src/rotating_histogram.rs b/tower/src/hedge/rotating_histogram.rs
similarity index 99%
rename from tower-hedge/src/rotating_histogram.rs
rename to tower/src/hedge/rotating_histogram.rs
index 87f371b..79f6dc6 100644
--- a/tower-hedge/src/rotating_histogram.rs
+++ b/tower/src/hedge/rotating_histogram.rs
@@ -1,7 +1,7 @@
 use hdrhistogram::Histogram;
-use log::trace;
 use std::time::Duration;
 use tokio::time::Instant;
+use tracing::trace;
 
 /// This represents a "rotating" histogram which stores two histogram, one which
 /// should be read and one which should be written to.  Every period, the read
diff --git a/tower-hedge/src/select.rs b/tower/src/hedge/select.rs
similarity index 100%
rename from tower-hedge/src/select.rs
rename to tower/src/hedge/select.rs
diff --git a/tower/src/lib.rs b/tower/src/lib.rs
index 47b24ca..1ef9a60 100644
--- a/tower/src/lib.rs
+++ b/tower/src/lib.rs
@@ -1,38 +1,53 @@
 #![doc(html_root_url = "https://docs.rs/tower/0.3.1")]
-// Allows refining features in the future without breaking backwards
-// compatibility
-#![cfg(feature = "full")]
 #![warn(
     missing_debug_implementations,
     missing_docs,
     rust_2018_idioms,
     unreachable_pub
 )]
+#![allow(elided_lifetimes_in_paths)]
 
 //! `fn(Request) -> Future<Response>`
 //!
 //! Tower is a library of modular and reusable components for building
 //! robust networking clients and servers.
 
-#[doc(inline)]
-pub use tower_buffer as buffer;
-#[doc(inline)]
-pub use tower_discover as discover;
-#[doc(inline)]
-pub use tower_limit as limit;
-#[doc(inline)]
-pub use tower_load_shed as load_shed;
-#[doc(inline)]
-pub use tower_retry as retry;
-#[doc(inline)]
-pub use tower_timeout as timeout;
-// pub use tower_layer as layer;
-#[doc(inline)]
-pub use tower_layer as layer;
+#[cfg(feature = "balance")]
+pub mod balance;
+#[cfg(feature = "buffer")]
+pub mod buffer;
+#[cfg(feature = "discover")]
+pub mod discover;
+#[cfg(feature = "filter")]
+#[doc(hidden)] // not yet released
+pub mod filter;
+#[cfg(feature = "hedge")]
+#[doc(hidden)] // not yet released
+pub mod hedge;
+#[cfg(feature = "limit")]
+pub mod limit;
+#[cfg(feature = "load")]
+pub mod load;
+#[cfg(feature = "load-shed")]
+pub mod load_shed;
+#[cfg(feature = "make")]
+pub mod make;
+#[cfg(feature = "ready-cache")]
+pub mod ready_cache;
+#[cfg(feature = "reconnect")]
+pub mod reconnect;
+#[cfg(feature = "retry")]
+pub mod retry;
+#[cfg(feature = "spawn-ready")]
+pub mod spawn_ready;
+#[cfg(feature = "timeout")]
+pub mod timeout;
+#[cfg(feature = "util")]
+pub mod util;
 
 pub mod builder;
-pub mod util;
 
-pub use crate::{builder::ServiceBuilder, util::ServiceExt};
+#[cfg(feature = "util")]
+pub use self::util::{service_fn, ServiceExt};
+pub use crate::builder::ServiceBuilder;
 pub use tower_service::Service;
-pub use tower_util::service_fn;
diff --git a/tower-limit/src/concurrency/future.rs b/tower/src/limit/concurrency/future.rs
similarity index 100%
rename from tower-limit/src/concurrency/future.rs
rename to tower/src/limit/concurrency/future.rs
diff --git a/tower-limit/src/concurrency/layer.rs b/tower/src/limit/concurrency/layer.rs
similarity index 100%
rename from tower-limit/src/concurrency/layer.rs
rename to tower/src/limit/concurrency/layer.rs
diff --git a/tower-limit/src/concurrency/mod.rs b/tower/src/limit/concurrency/mod.rs
similarity index 100%
rename from tower-limit/src/concurrency/mod.rs
rename to tower/src/limit/concurrency/mod.rs
diff --git a/tower-limit/src/concurrency/never.rs b/tower/src/limit/concurrency/never.rs
similarity index 100%
rename from tower-limit/src/concurrency/never.rs
rename to tower/src/limit/concurrency/never.rs
diff --git a/tower-limit/src/concurrency/service.rs b/tower/src/limit/concurrency/service.rs
similarity index 96%
rename from tower-limit/src/concurrency/service.rs
rename to tower/src/limit/concurrency/service.rs
index bac2695..cf4ba4c 100644
--- a/tower-limit/src/concurrency/service.rs
+++ b/tower/src/limit/concurrency/service.rs
@@ -86,9 +86,10 @@ where
     }
 }
 
-impl<S> tower_load::Load for ConcurrencyLimit<S>
+#[cfg(feature = "load")]
+impl<S> crate::load::Load for ConcurrencyLimit<S>
 where
-    S: tower_load::Load,
+    S: crate::load::Load,
 {
     type Metric = S::Metric;
     fn load(&self) -> Self::Metric {
diff --git a/tower-limit/src/concurrency/sync/cell.rs b/tower/src/limit/concurrency/sync/cell.rs
similarity index 100%
rename from tower-limit/src/concurrency/sync/cell.rs
rename to tower/src/limit/concurrency/sync/cell.rs
diff --git a/tower-limit/src/concurrency/sync/mod.rs b/tower/src/limit/concurrency/sync/mod.rs
similarity index 100%
rename from tower-limit/src/concurrency/sync/mod.rs
rename to tower/src/limit/concurrency/sync/mod.rs
diff --git a/tower-limit/src/concurrency/sync/semaphore.rs b/tower/src/limit/concurrency/sync/semaphore.rs
similarity index 100%
rename from tower-limit/src/concurrency/sync/semaphore.rs
rename to tower/src/limit/concurrency/sync/semaphore.rs
diff --git a/tower-limit/src/concurrency/sync/waker.rs b/tower/src/limit/concurrency/sync/waker.rs
similarity index 100%
rename from tower-limit/src/concurrency/sync/waker.rs
rename to tower/src/limit/concurrency/sync/waker.rs
diff --git a/tower/src/limit/mod.rs b/tower/src/limit/mod.rs
new file mode 100644
index 0000000..9af07e1
--- /dev/null
+++ b/tower/src/limit/mod.rs
@@ -0,0 +1,9 @@
+//! Tower middleware for limiting requests.
+
+pub mod concurrency;
+pub mod rate;
+
+pub use self::{
+    concurrency::{ConcurrencyLimit, ConcurrencyLimitLayer},
+    rate::{RateLimit, RateLimitLayer},
+};
diff --git a/tower-limit/src/rate/layer.rs b/tower/src/limit/rate/layer.rs
similarity index 100%
rename from tower-limit/src/rate/layer.rs
rename to tower/src/limit/rate/layer.rs
diff --git a/tower-limit/src/rate/mod.rs b/tower/src/limit/rate/mod.rs
similarity index 100%
rename from tower-limit/src/rate/mod.rs
rename to tower/src/limit/rate/mod.rs
diff --git a/tower-limit/src/rate/rate.rs b/tower/src/limit/rate/rate.rs
similarity index 100%
rename from tower-limit/src/rate/rate.rs
rename to tower/src/limit/rate/rate.rs
diff --git a/tower-limit/src/rate/service.rs b/tower/src/limit/rate/service.rs
similarity index 96%
rename from tower-limit/src/rate/service.rs
rename to tower/src/limit/rate/service.rs
index 76d40b9..7e55ec8 100644
--- a/tower-limit/src/rate/service.rs
+++ b/tower/src/limit/rate/service.rs
@@ -109,9 +109,10 @@ where
     }
 }
 
-impl<S> tower_load::Load for RateLimit<S>
+#[cfg(feature = "load")]
+impl<S> crate::load::Load for RateLimit<S>
 where
-    S: tower_load::Load,
+    S: crate::load::Load,
 {
     type Metric = S::Metric;
     fn load(&self) -> Self::Metric {
diff --git a/tower-load/src/constant.rs b/tower/src/load/constant.rs
similarity index 96%
rename from tower-load/src/constant.rs
rename to tower/src/load/constant.rs
index 2481166..4d78af7 100644
--- a/tower-load/src/constant.rs
+++ b/tower/src/load/constant.rs
@@ -1,15 +1,15 @@
 //! A constant `Load` implementation. Primarily useful for testing.
 
+use crate::discover::{Change, Discover};
 use futures_core::ready;
 use pin_project::pin_project;
 use std::{
     pin::Pin,
     task::{Context, Poll},
 };
-use tower_discover::{Change, Discover};
 use tower_service::Service;
 
-use crate::Load;
+use super::Load;
 
 /// Wraps a type so that `Load::load` returns a constant value.
 #[pin_project]
diff --git a/tower-load/src/instrument.rs b/tower/src/load/instrument.rs
similarity index 100%
rename from tower-load/src/instrument.rs
rename to tower/src/load/instrument.rs
diff --git a/tower-load/src/lib.rs b/tower/src/load/mod.rs
similarity index 74%
rename from tower-load/src/lib.rs
rename to tower/src/load/mod.rs
index c951621..fdd1f19 100644
--- a/tower-load/src/lib.rs
+++ b/tower/src/load/mod.rs
@@ -1,14 +1,5 @@
 //! Abstractions and utilties for measuring a service's load.
 
-#![doc(html_root_url = "https://docs.rs/tower-load/0.3.0")]
-#![warn(
-    missing_debug_implementations,
-    missing_docs,
-    rust_2018_idioms,
-    unreachable_pub
-)]
-#![allow(elided_lifetimes_in_paths)]
-
 mod constant;
 mod instrument;
 pub mod peak_ewma;
diff --git a/tower-load/src/peak_ewma.rs b/tower/src/load/peak_ewma.rs
similarity index 99%
rename from tower-load/src/peak_ewma.rs
rename to tower/src/load/peak_ewma.rs
index 7e3bb85..6e16e8a 100644
--- a/tower-load/src/peak_ewma.rs
+++ b/tower/src/load/peak_ewma.rs
@@ -1,9 +1,9 @@
 //! A `Load` implementation that PeakEWMA on response latency.
 
+use super::Load;
 use super::{Instrument, InstrumentFuture, NoInstrument};
-use crate::Load;
+use crate::discover::{Change, Discover};
 use futures_core::ready;
-use log::trace;
 use pin_project::pin_project;
 use std::{
     pin::Pin,
@@ -14,8 +14,8 @@ use std::{
     time::Duration,
 };
 use tokio::time::Instant;
-use tower_discover::{Change, Discover};
 use tower_service::Service;
+use tracing::trace;
 
 /// Wraps an `S`-typed Service with Peak-EWMA load measurement.
 ///
diff --git a/tower-load/src/pending_requests.rs b/tower/src/load/pending_requests.rs
similarity index 98%
rename from tower-load/src/pending_requests.rs
rename to tower/src/load/pending_requests.rs
index e550f86..a881fa3 100644
--- a/tower-load/src/pending_requests.rs
+++ b/tower/src/load/pending_requests.rs
@@ -1,7 +1,8 @@
 //! A `Load` implementation that uses the count of in-flight requests.
 
+use super::Load;
 use super::{Instrument, InstrumentFuture, NoInstrument};
-use crate::Load;
+use crate::discover::{Change, Discover};
 use futures_core::ready;
 use pin_project::pin_project;
 use std::sync::Arc;
@@ -9,7 +10,6 @@ use std::{
     pin::Pin,
     task::{Context, Poll},
 };
-use tower_discover::{Change, Discover};
 use tower_service::Service;
 
 /// Expresses load based on the number of currently-pending requests.
diff --git a/tower-load-shed/src/error.rs b/tower/src/load_shed/error.rs
similarity index 100%
rename from tower-load-shed/src/error.rs
rename to tower/src/load_shed/error.rs
diff --git a/tower-load-shed/src/future.rs b/tower/src/load_shed/future.rs
similarity index 97%
rename from tower-load-shed/src/future.rs
rename to tower/src/load_shed/future.rs
index 331c495..ed3c339 100644
--- a/tower-load-shed/src/future.rs
+++ b/tower/src/load_shed/future.rs
@@ -8,7 +8,7 @@ use std::task::{Context, Poll};
 use futures_core::ready;
 use pin_project::{pin_project, project};
 
-use crate::error::{Error, Overloaded};
+use super::error::{Error, Overloaded};
 
 /// Future for the `LoadShed` service.
 #[pin_project]
diff --git a/tower-load-shed/src/layer.rs b/tower/src/load_shed/layer.rs
similarity index 96%
rename from tower-load-shed/src/layer.rs
rename to tower/src/load_shed/layer.rs
index 3a2f0fb..96aa2fd 100644
--- a/tower-load-shed/src/layer.rs
+++ b/tower/src/load_shed/layer.rs
@@ -1,7 +1,7 @@
 use std::fmt;
 use tower_layer::Layer;
 
-use crate::LoadShed;
+use super::LoadShed;
 
 /// A `tower-layer` to wrap services in `LoadShed` middleware.
 #[derive(Clone)]
diff --git a/tower-load-shed/src/lib.rs b/tower/src/load_shed/mod.rs
similarity index 86%
rename from tower-load-shed/src/lib.rs
rename to tower/src/load_shed/mod.rs
index 1a8cb2b..d1e405b 100644
--- a/tower-load-shed/src/lib.rs
+++ b/tower/src/load_shed/mod.rs
@@ -1,12 +1,3 @@
-#![doc(html_root_url = "https://docs.rs/tower-load-shed/0.3.0")]
-#![warn(
-    missing_debug_implementations,
-    missing_docs,
-    rust_2018_idioms,
-    unreachable_pub
-)]
-#![allow(elided_lifetimes_in_paths)]
-
 //! Tower middleware for shedding load when inner services aren't ready.
 
 use std::task::{Context, Poll};
@@ -16,9 +7,9 @@ pub mod error;
 pub mod future;
 mod layer;
 
-use crate::error::Error;
-use crate::future::ResponseFuture;
-pub use crate::layer::LoadShedLayer;
+use self::error::Error;
+use self::future::ResponseFuture;
+pub use self::layer::LoadShedLayer;
 
 /// A `Service` that sheds load when the inner service isn't ready.
 #[derive(Debug)]
diff --git a/tower-make/src/make_connection.rs b/tower/src/make/make_connection.rs
similarity index 98%
rename from tower-make/src/make_connection.rs
rename to tower/src/make/make_connection.rs
index 03b8313..bd50a41 100644
--- a/tower-make/src/make_connection.rs
+++ b/tower/src/make/make_connection.rs
@@ -1,4 +1,4 @@
-use crate::sealed::Sealed;
+use super::sealed::Sealed;
 use std::future::Future;
 use std::task::{Context, Poll};
 use tokio::io::{AsyncRead, AsyncWrite};
diff --git a/tower-make/src/make_service.rs b/tower/src/make/make_service.rs
similarity index 98%
rename from tower-make/src/make_service.rs
rename to tower/src/make/make_service.rs
index 4df56d7..96fa4bc 100644
--- a/tower-make/src/make_service.rs
+++ b/tower/src/make/make_service.rs
@@ -1,4 +1,4 @@
-use crate::sealed::Sealed;
+use super::sealed::Sealed;
 use std::future::Future;
 use std::task::{Context, Poll};
 use tower_service::Service;
diff --git a/tower/src/make/mod.rs b/tower/src/make/mod.rs
new file mode 100644
index 0000000..d0a841b
--- /dev/null
+++ b/tower/src/make/mod.rs
@@ -0,0 +1,11 @@
+//! Trait aliases for Services that produce specific types of Responses.
+
+mod make_connection;
+mod make_service;
+
+pub use self::make_connection::MakeConnection;
+pub use self::make_service::MakeService;
+
+mod sealed {
+    pub trait Sealed<T> {}
+}
diff --git a/tower-ready-cache/src/cache.rs b/tower/src/ready_cache/cache.rs
similarity index 99%
rename from tower-ready-cache/src/cache.rs
rename to tower/src/ready_cache/cache.rs
index a32ced4..3218423 100644
--- a/tower-ready-cache/src/cache.rs
+++ b/tower/src/ready_cache/cache.rs
@@ -1,17 +1,17 @@
 //! A cache of services.
 
-use crate::error;
+use super::error;
 use futures_core::Stream;
 use futures_util::stream::FuturesUnordered;
 pub use indexmap::Equivalent;
 use indexmap::IndexMap;
-use log::{debug, trace};
 use std::future::Future;
 use std::hash::Hash;
 use std::pin::Pin;
 use std::task::{Context, Poll};
 use tokio::sync::oneshot;
 use tower_service::Service;
+use tracing::{debug, trace};
 
 /// Drives readiness over a set of services.
 ///
diff --git a/tower-ready-cache/src/error.rs b/tower/src/ready_cache/error.rs
similarity index 100%
rename from tower-ready-cache/src/error.rs
rename to tower/src/ready_cache/error.rs
diff --git a/tower/src/ready_cache/mod.rs b/tower/src/ready_cache/mod.rs
new file mode 100644
index 0000000..ebf85ab
--- /dev/null
+++ b/tower/src/ready_cache/mod.rs
@@ -0,0 +1,6 @@
+//! A cache of services
+
+pub mod cache;
+pub mod error;
+
+pub use self::cache::ReadyCache;
diff --git a/tower-reconnect/src/future.rs b/tower/src/reconnect/future.rs
similarity index 97%
rename from tower-reconnect/src/future.rs
rename to tower/src/reconnect/future.rs
index e12a795..b1d2c74 100644
--- a/tower-reconnect/src/future.rs
+++ b/tower/src/reconnect/future.rs
@@ -1,4 +1,4 @@
-use crate::Error;
+use super::Error;
 use pin_project::pin_project;
 use std::{
     future::Future,
diff --git a/tower-reconnect/src/lib.rs b/tower/src/reconnect/mod.rs
similarity index 94%
rename from tower-reconnect/src/lib.rs
rename to tower/src/reconnect/mod.rs
index 2717c54..2464ee4 100644
--- a/tower-reconnect/src/lib.rs
+++ b/tower/src/reconnect/mod.rs
@@ -1,20 +1,15 @@
-#![doc(html_root_url = "https://docs.rs/tower-reconnect/0.3.0")]
-#![warn(missing_debug_implementations, rust_2018_idioms, unreachable_pub)]
-#![allow(missing_docs)] // TODO
-#![allow(elided_lifetimes_in_paths)]
-
 pub mod future;
 
-use crate::future::ResponseFuture;
-use log::trace;
+use self::future::ResponseFuture;
+use crate::make::MakeService;
 use std::fmt;
 use std::{
     future::Future,
     pin::Pin,
     task::{Context, Poll},
 };
-use tower_make::MakeService;
 use tower_service::Service;
+use tracing::trace;
 
 /// Reconnect to failed services.
 pub struct Reconnect<M, Target>
diff --git a/tower-retry/src/budget.rs b/tower/src/retry/budget.rs
similarity index 100%
rename from tower-retry/src/budget.rs
rename to tower/src/retry/budget.rs
diff --git a/tower-retry/src/future.rs b/tower/src/retry/future.rs
similarity index 99%
rename from tower-retry/src/future.rs
rename to tower/src/retry/future.rs
index a60a85b..77377c5 100644
--- a/tower-retry/src/future.rs
+++ b/tower/src/retry/future.rs
@@ -1,6 +1,6 @@
 //! Future types
 
-use crate::{Policy, Retry};
+use super::{Policy, Retry};
 use futures_core::ready;
 use pin_project::{pin_project, project};
 use std::future::Future;
diff --git a/tower-retry/src/layer.rs b/tower/src/retry/layer.rs
similarity index 96%
rename from tower-retry/src/layer.rs
rename to tower/src/retry/layer.rs
index eb9e2b5..a5be368 100644
--- a/tower-retry/src/layer.rs
+++ b/tower/src/retry/layer.rs
@@ -1,4 +1,4 @@
-use crate::Retry;
+use super::Retry;
 use tower_layer::Layer;
 
 /// Retry requests based on a policy
diff --git a/tower-retry/src/lib.rs b/tower/src/retry/mod.rs
similarity index 82%
rename from tower-retry/src/lib.rs
rename to tower/src/retry/mod.rs
index c35618e..e369dbb 100644
--- a/tower-retry/src/lib.rs
+++ b/tower/src/retry/mod.rs
@@ -1,12 +1,3 @@
-#![doc(html_root_url = "https://docs.rs/tower-retry/0.3.0")]
-#![warn(
-    missing_debug_implementations,
-    missing_docs,
-    rust_2018_idioms,
-    unreachable_pub
-)]
-#![allow(elided_lifetimes_in_paths)]
-
 //! Tower middleware for retrying "failed" requests.
 
 pub mod budget;
@@ -14,10 +5,10 @@ pub mod future;
 mod layer;
 mod policy;
 
-pub use crate::layer::RetryLayer;
-pub use crate::policy::Policy;
+pub use self::layer::RetryLayer;
+pub use self::policy::Policy;
 
-use crate::future::ResponseFuture;
+use self::future::ResponseFuture;
 use pin_project::pin_project;
 use std::task::{Context, Poll};
 use tower_service::Service;
diff --git a/tower-retry/src/never.rs b/tower/src/retry/never.rs
similarity index 100%
rename from tower-retry/src/never.rs
rename to tower/src/retry/never.rs
diff --git a/tower-retry/src/policy.rs b/tower/src/retry/policy.rs
similarity index 98%
rename from tower-retry/src/policy.rs
rename to tower/src/retry/policy.rs
index 6f4c16d..cedf880 100644
--- a/tower-retry/src/policy.rs
+++ b/tower/src/retry/policy.rs
@@ -5,7 +5,7 @@ use std::future::Future;
 /// # Example
 ///
 /// ```
-/// use tower_retry::Policy;
+/// use tower::retry::Policy;
 /// use futures_util::future;
 ///
 /// type Req = String;
diff --git a/tower-spawn-ready/src/future.rs b/tower/src/spawn_ready/future.rs
similarity index 98%
rename from tower-spawn-ready/src/future.rs
rename to tower/src/spawn_ready/future.rs
index 676058d..741792d 100644
--- a/tower-spawn-ready/src/future.rs
+++ b/tower/src/spawn_ready/future.rs
@@ -1,6 +1,6 @@
 //! Background readiness types
 
-use crate::Error;
+use super::Error;
 use futures_core::ready;
 use pin_project::pin_project;
 use std::marker::PhantomData;
diff --git a/tower-spawn-ready/src/layer.rs b/tower/src/spawn_ready/layer.rs
similarity index 94%
rename from tower-spawn-ready/src/layer.rs
rename to tower/src/spawn_ready/layer.rs
index ceddf9c..5e1185d 100644
--- a/tower-spawn-ready/src/layer.rs
+++ b/tower/src/spawn_ready/layer.rs
@@ -1,4 +1,4 @@
-use crate::MakeSpawnReady;
+use super::MakeSpawnReady;
 use tower_layer::Layer;
 
 /// Spawns tasks to drive its inner service to readiness.
diff --git a/tower-spawn-ready/src/make.rs b/tower/src/spawn_ready/make.rs
similarity index 98%
rename from tower-spawn-ready/src/make.rs
rename to tower/src/spawn_ready/make.rs
index 6e6f859..0a413ef 100644
--- a/tower-spawn-ready/src/make.rs
+++ b/tower/src/spawn_ready/make.rs
@@ -1,4 +1,4 @@
-use crate::SpawnReady;
+use super::SpawnReady;
 use futures_core::ready;
 use pin_project::pin_project;
 use std::{
diff --git a/tower/src/spawn_ready/mod.rs b/tower/src/spawn_ready/mod.rs
new file mode 100644
index 0000000..c005696
--- /dev/null
+++ b/tower/src/spawn_ready/mod.rs
@@ -0,0 +1,14 @@
+//! When an underlying service is not ready, drive it to readiness on a
+//! background task.
+
+pub mod future;
+mod layer;
+mod make;
+mod service;
+
+pub use self::layer::SpawnReadyLayer;
+pub use self::make::{MakeFuture, MakeSpawnReady};
+pub use self::service::SpawnReady;
+
+/// Errors produced by `SpawnReady`.
+pub(crate) type Error = Box<dyn std::error::Error + Send + Sync>;
diff --git a/tower-spawn-ready/src/service.rs b/tower/src/spawn_ready/service.rs
similarity index 97%
rename from tower-spawn-ready/src/service.rs
rename to tower/src/spawn_ready/service.rs
index 63ac8c9..362069e 100644
--- a/tower-spawn-ready/src/service.rs
+++ b/tower/src/spawn_ready/service.rs
@@ -1,4 +1,4 @@
-use crate::{future::background_ready, Error};
+use super::{future::background_ready, Error};
 use futures_core::ready;
 use futures_util::future::{MapErr, TryFutureExt};
 use std::{
diff --git a/tower-timeout/src/error.rs b/tower/src/timeout/error.rs
similarity index 100%
rename from tower-timeout/src/error.rs
rename to tower/src/timeout/error.rs
diff --git a/tower-timeout/src/future.rs b/tower/src/timeout/future.rs
similarity index 96%
rename from tower-timeout/src/future.rs
rename to tower/src/timeout/future.rs
index fb86300..64200c8 100644
--- a/tower-timeout/src/future.rs
+++ b/tower/src/timeout/future.rs
@@ -1,6 +1,6 @@
 //! Future types
 
-use crate::error::{Elapsed, Error};
+use super::error::{Elapsed, Error};
 use pin_project::pin_project;
 use std::{
     future::Future,
diff --git a/tower-timeout/src/layer.rs b/tower/src/timeout/layer.rs
similarity index 96%
rename from tower-timeout/src/layer.rs
rename to tower/src/timeout/layer.rs
index e165ce1..71970ec 100644
--- a/tower-timeout/src/layer.rs
+++ b/tower/src/timeout/layer.rs
@@ -1,4 +1,4 @@
-use crate::Timeout;
+use super::Timeout;
 use std::time::Duration;
 use tower_layer::Layer;
 
diff --git a/tower-timeout/src/lib.rs b/tower/src/timeout/mod.rs
similarity index 83%
rename from tower-timeout/src/lib.rs
rename to tower/src/timeout/mod.rs
index b5458f9..463755d 100644
--- a/tower-timeout/src/lib.rs
+++ b/tower/src/timeout/mod.rs
@@ -1,11 +1,3 @@
-#![doc(html_root_url = "https://docs.rs/tower-timeout/0.3.0")]
-#![warn(
-    missing_debug_implementations,
-    missing_docs,
-    rust_2018_idioms,
-    unreachable_pub
-)]
-
 //! Tower middleware that applies a timeout to requests.
 //!
 //! If the response does not complete within the specified timeout, the response
@@ -15,9 +7,9 @@ pub mod error;
 pub mod future;
 mod layer;
 
-pub use crate::layer::TimeoutLayer;
+pub use self::layer::TimeoutLayer;
 
-use crate::{error::Error, future::ResponseFuture};
+use self::{error::Error, future::ResponseFuture};
 use std::task::{Context, Poll};
 use std::time::Duration;
 use tower_service::Service;
diff --git a/tower-timeout/src/never.rs b/tower/src/timeout/never.rs
similarity index 100%
rename from tower-timeout/src/never.rs
rename to tower/src/timeout/never.rs
diff --git a/tower/src/util.rs b/tower/src/util.rs
deleted file mode 100644
index 87cf6c8..0000000
--- a/tower/src/util.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//! Combinators for working with `Service`s
-
-pub use tower_util::{
-    BoxService, CallAll, CallAllUnordered, Either, Oneshot, Optional, Ready, ServiceExt,
-    UnsyncBoxService,
-};
diff --git a/tower-util/src/boxed/mod.rs b/tower/src/util/boxed/mod.rs
similarity index 96%
rename from tower-util/src/boxed/mod.rs
rename to tower/src/util/boxed/mod.rs
index 5fb9faf..dc339b3 100644
--- a/tower-util/src/boxed/mod.rs
+++ b/tower/src/util/boxed/mod.rs
@@ -16,7 +16,7 @@
 //! ```
 //! use futures_util::future::ready;
 //! # use tower_service::Service;
-//! # use tower_util::{BoxService, service_fn};
+//! # use tower::util::{BoxService, service_fn};
 //! // Respond to requests using a closure, but closures cannot be named...
 //! # pub fn main() {
 //! let svc = service_fn(|mut request: String| {
diff --git a/tower-util/src/boxed/sync.rs b/tower/src/util/boxed/sync.rs
similarity index 100%
rename from tower-util/src/boxed/sync.rs
rename to tower/src/util/boxed/sync.rs
diff --git a/tower-util/src/boxed/unsync.rs b/tower/src/util/boxed/unsync.rs
similarity index 100%
rename from tower-util/src/boxed/unsync.rs
rename to tower/src/util/boxed/unsync.rs
diff --git a/tower-util/src/call_all/common.rs b/tower/src/util/call_all/common.rs
similarity index 100%
rename from tower-util/src/call_all/common.rs
rename to tower/src/util/call_all/common.rs
diff --git a/tower-util/src/call_all/mod.rs b/tower/src/util/call_all/mod.rs
similarity index 100%
rename from tower-util/src/call_all/mod.rs
rename to tower/src/util/call_all/mod.rs
diff --git a/tower-util/src/call_all/ordered.rs b/tower/src/util/call_all/ordered.rs
similarity index 99%
rename from tower-util/src/call_all/ordered.rs
rename to tower/src/util/call_all/ordered.rs
index b3374eb..f0e05bf 100644
--- a/tower-util/src/call_all/ordered.rs
+++ b/tower/src/util/call_all/ordered.rs
@@ -23,7 +23,7 @@ use tower_service::Service;
 /// use futures_util::future::{ready, Ready};
 /// use futures_util::StreamExt;
 /// use tower_service::Service;
-/// use tower_util::ServiceExt;
+/// use tower::util::ServiceExt;
 /// use tokio::prelude::*;
 ///
 /// // First, we need to have a Service to process our requests.
diff --git a/tower-util/src/call_all/unordered.rs b/tower/src/util/call_all/unordered.rs
similarity index 100%
rename from tower-util/src/call_all/unordered.rs
rename to tower/src/util/call_all/unordered.rs
diff --git a/tower-util/src/either.rs b/tower/src/util/either.rs
similarity index 100%
rename from tower-util/src/either.rs
rename to tower/src/util/either.rs
diff --git a/tower-util/src/lib.rs b/tower/src/util/mod.rs
similarity index 82%
rename from tower-util/src/lib.rs
rename to tower/src/util/mod.rs
index 30b505e..7c642a7 100644
--- a/tower-util/src/lib.rs
+++ b/tower/src/util/mod.rs
@@ -1,16 +1,6 @@
-#![doc(html_root_url = "https://docs.rs/tower-util/0.3.1")]
-#![warn(
-    missing_debug_implementations,
-    missing_docs,
-    rust_2018_idioms,
-    unreachable_pub
-)]
-#![allow(elided_lifetimes_in_paths)]
-
 //! Various utility types and functions that are generally with Tower.
 
 mod boxed;
-#[cfg(feature = "call-all")]
 mod call_all;
 mod either;
 mod oneshot;
@@ -18,7 +8,7 @@ mod optional;
 mod ready;
 mod service_fn;
 
-pub use crate::{
+pub use self::{
     boxed::{BoxService, UnsyncBoxService},
     either::Either,
     oneshot::Oneshot,
@@ -27,8 +17,7 @@ pub use crate::{
     service_fn::{service_fn, ServiceFn},
 };
 
-#[cfg(feature = "call-all")]
-pub use crate::call_all::{CallAll, CallAllUnordered};
+pub use self::call_all::{CallAll, CallAllUnordered};
 
 #[doc(hidden)]
 pub type Error = Box<dyn std::error::Error + Send + Sync>;
@@ -36,13 +25,13 @@ pub type Error = Box<dyn std::error::Error + Send + Sync>;
 pub mod error {
     //! Error types
 
-    pub use crate::optional::error as optional;
+    pub use super::optional::error as optional;
 }
 
 pub mod future {
     //! Future types
 
-    pub use crate::optional::future as optional;
+    pub use super::optional::future as optional;
 }
 
 /// An extension trait for `Service`s that provides a variety of convenient
@@ -86,7 +75,6 @@ pub trait ServiceExt<Request>: tower_service::Service<Request> {
     ///
     /// This is essentially `Stream<Item = Request>` + `Self` => `Stream<Item = Response>`. See the
     /// documentation for [`CallAll`](struct.CallAll.html) for details.
-    #[cfg(feature = "call-all")]
     fn call_all<S>(self, reqs: S) -> CallAll<Self, S>
     where
         Self: Sized,


Test patch:
diff --git a/tower-test/Cargo.toml b/tower-test/Cargo.toml
index e812179..18412a5 100644
--- a/tower-test/Cargo.toml
+++ b/tower-test/Cargo.toml
@@ -24,10 +24,10 @@ edition = "2018"
 [dependencies]
 futures-util = { version = "0.3", default-features = false }
 tokio = { version = "0.2", features = ["sync"]}
-tower-layer = "0.3"
+tower-layer = { version = "0.3", path = "../tower-layer" }
 tokio-test = "0.2"
-tower-service = "0.3"
+tower-service = { version = "0.3", path = "../tower-service" }
 pin-project = "0.4"
 
 [dev-dependencies]
-tokio = { version = "0.2", features = ["macros"] }
\ No newline at end of file
+tokio = { version = "0.2", features = ["macros"] }
diff --git a/tower-balance/src/p2c/test.rs b/tower/src/balance/p2c/test.rs
similarity index 98%
rename from tower-balance/src/p2c/test.rs
rename to tower/src/balance/p2c/test.rs
index b1eb39a..437b912 100644
--- a/tower-balance/src/p2c/test.rs
+++ b/tower/src/balance/p2c/test.rs
@@ -1,8 +1,8 @@
+use crate::discover::ServiceList;
+use crate::load;
 use futures_util::pin_mut;
 use std::task::Poll;
 use tokio_test::{assert_pending, assert_ready, assert_ready_ok, task};
-use tower_discover::ServiceList;
-use tower_load as load;
 use tower_test::{assert_request_eq, mock};
 
 use super::*;
diff --git a/tower-balance/src/pool/test.rs b/tower/src/balance/pool/test.rs
similarity index 99%
rename from tower-balance/src/pool/test.rs
rename to tower/src/balance/pool/test.rs
index f9f6eac..6861b25 100644
--- a/tower-balance/src/pool/test.rs
+++ b/tower/src/balance/pool/test.rs
@@ -1,6 +1,6 @@
+use crate::load;
 use futures_util::pin_mut;
 use tokio_test::{assert_pending, assert_ready, assert_ready_ok, task};
-use tower_load as load;
 use tower_test::{assert_request_eq, mock};
 
 use super::*;
diff --git a/tower-util/src/oneshot.rs b/tower/src/util/oneshot.rs
similarity index 100%
rename from tower-util/src/oneshot.rs
rename to tower/src/util/oneshot.rs
diff --git a/tower-util/src/optional/error.rs b/tower/src/util/optional/error.rs
similarity index 100%
rename from tower-util/src/optional/error.rs
rename to tower/src/util/optional/error.rs
diff --git a/tower-util/src/optional/future.rs b/tower/src/util/optional/future.rs
similarity index 100%
rename from tower-util/src/optional/future.rs
rename to tower/src/util/optional/future.rs
diff --git a/tower-util/src/optional/mod.rs b/tower/src/util/optional/mod.rs
similarity index 100%
rename from tower-util/src/optional/mod.rs
rename to tower/src/util/optional/mod.rs
diff --git a/tower-util/src/ready.rs b/tower/src/util/ready.rs
similarity index 100%
rename from tower-util/src/ready.rs
rename to tower/src/util/ready.rs
diff --git a/tower-util/src/service_fn.rs b/tower/src/util/service_fn.rs
similarity index 100%
rename from tower-util/src/service_fn.rs
rename to tower/src/util/service_fn.rs
diff --git a/tower-balance/tests/p2c.rs b/tower/tests/balance/main.rs
similarity index 97%
rename from tower-balance/tests/p2c.rs
rename to tower/tests/balance/main.rs
index d0c9718..d43ab9d 100644
--- a/tower-balance/tests/p2c.rs
+++ b/tower/tests/balance/main.rs
@@ -1,8 +1,10 @@
+#![cfg(feature = "balance")]
+
 use std::future::Future;
 use std::task::{Context, Poll};
 use tokio_test::{assert_pending, assert_ready, task};
-use tower_balance::p2c::Balance;
-use tower_discover::{Change, ServiceStream};
+use tower::balance::p2c::Balance;
+use tower::discover::{Change, ServiceStream};
 use tower_service::Service;
 use tower_test::mock;
 
@@ -21,7 +23,7 @@ impl Service<Req> for Mock {
     }
 }
 
-impl tower_load::Load for Mock {
+impl tower::load::Load for Mock {
     type Metric = usize;
     fn load(&self) -> Self::Metric {
         rand::random()
diff --git a/tower-buffer/tests/buffer.rs b/tower/tests/buffer/main.rs
similarity index 98%
rename from tower-buffer/tests/buffer.rs
rename to tower/tests/buffer/main.rs
index f26c3a9..5fa32c5 100644
--- a/tower-buffer/tests/buffer.rs
+++ b/tower/tests/buffer/main.rs
@@ -1,6 +1,8 @@
+#![cfg(feature = "buffer")]
+
 use std::thread;
 use tokio_test::{assert_pending, assert_ready, assert_ready_err, assert_ready_ok, task};
-use tower_buffer::{error, Buffer};
+use tower::buffer::{error, Buffer};
 use tower_test::{assert_request_eq, mock};
 
 fn let_worker_work() {
diff --git a/tower/tests/builder.rs b/tower/tests/builder.rs
index de12b39..a922001 100644
--- a/tower/tests/builder.rs
+++ b/tower/tests/builder.rs
@@ -1,10 +1,12 @@
+#![cfg(all(feature = "buffer", feature = "limit", feature = "retry"))]
+
 use futures_util::{future::Ready, pin_mut};
 use std::time::Duration;
+use tower::buffer::BufferLayer;
 use tower::builder::ServiceBuilder;
+use tower::limit::{concurrency::ConcurrencyLimitLayer, rate::RateLimitLayer};
+use tower::retry::{Policy, RetryLayer};
 use tower::util::ServiceExt;
-use tower_buffer::BufferLayer;
-use tower_limit::{concurrency::ConcurrencyLimitLayer, rate::RateLimitLayer};
-use tower_retry::{Policy, RetryLayer};
 use tower_service::*;
 use tower_test::{assert_request_eq, mock};
 
diff --git a/tower-filter/tests/filter.rs b/tower/tests/filter/main.rs
similarity index 95%
rename from tower-filter/tests/filter.rs
rename to tower/tests/filter/main.rs
index 240ed6f..6274125 100644
--- a/tower-filter/tests/filter.rs
+++ b/tower/tests/filter/main.rs
@@ -1,6 +1,8 @@
+#![cfg(feature = "filter")]
+
 use futures_util::{future::poll_fn, pin_mut};
 use std::future::Future;
-use tower_filter::{error::Error, Filter};
+use tower::filter::{error::Error, Filter};
 use tower_service::Service;
 use tower_test::{assert_request_eq, mock};
 
diff --git a/tower-hedge/tests/hedge.rs b/tower/tests/hedge/main.rs
similarity index 97%
rename from tower-hedge/tests/hedge.rs
rename to tower/tests/hedge/main.rs
index f33c615..a4e2867 100644
--- a/tower-hedge/tests/hedge.rs
+++ b/tower/tests/hedge/main.rs
@@ -1,7 +1,9 @@
+#![cfg(feature = "hedge")]
+
 use std::time::Duration;
 use tokio::time;
 use tokio_test::{assert_pending, assert_ready, assert_ready_ok, task};
-use tower_hedge::{Hedge, Policy};
+use tower::hedge::{Hedge, Policy};
 use tower_test::{assert_request_eq, mock};
 
 #[tokio::test]
@@ -143,7 +145,7 @@ static NOT_CLONABLE: &'static str = "NOT_CLONABLE";
 #[derive(Clone)]
 struct TestPolicy;
 
-impl tower_hedge::Policy<Req> for TestPolicy {
+impl tower::hedge::Policy<Req> for TestPolicy {
     fn can_retry(&self, req: &Req) -> bool {
         *req != NOT_RETRYABLE
     }
diff --git a/tower-limit/tests/concurrency.rs b/tower/tests/limit/concurrency.rs
similarity index 98%
rename from tower-limit/tests/concurrency.rs
rename to tower/tests/limit/concurrency.rs
index 8027d98..7e2ba4f 100644
--- a/tower-limit/tests/concurrency.rs
+++ b/tower/tests/limit/concurrency.rs
@@ -1,5 +1,5 @@
 use tokio_test::{assert_pending, assert_ready, assert_ready_ok};
-use tower_limit::concurrency::ConcurrencyLimitLayer;
+use tower::limit::concurrency::ConcurrencyLimitLayer;
 use tower_test::{assert_request_eq, mock};
 
 #[tokio::test]
diff --git a/tower/tests/limit/main.rs b/tower/tests/limit/main.rs
new file mode 100644
index 0000000..f80d68b
--- /dev/null
+++ b/tower/tests/limit/main.rs
@@ -0,0 +1,4 @@
+#![cfg(feature = "limit")]
+
+mod concurrency;
+mod rate;
diff --git a/tower-limit/tests/rate.rs b/tower/tests/limit/rate.rs
similarity index 95%
rename from tower-limit/tests/rate.rs
rename to tower/tests/limit/rate.rs
index 49b9fc6..e608651 100644
--- a/tower-limit/tests/rate.rs
+++ b/tower/tests/limit/rate.rs
@@ -1,7 +1,7 @@
 use std::time::Duration;
 use tokio::time;
 use tokio_test::{assert_pending, assert_ready, assert_ready_ok};
-use tower_limit::rate::RateLimitLayer;
+use tower::limit::rate::RateLimitLayer;
 use tower_test::{assert_request_eq, mock};
 
 #[tokio::test]
diff --git a/tower-load-shed/tests/load-shed.rs b/tower/tests/load_shed/main.rs
similarity index 86%
rename from tower-load-shed/tests/load-shed.rs
rename to tower/tests/load_shed/main.rs
index de92418..6bad7ab 100644
--- a/tower-load-shed/tests/load-shed.rs
+++ b/tower/tests/load_shed/main.rs
@@ -1,5 +1,7 @@
+#![cfg(feature = "load-shed")]
+
 use tokio_test::{assert_ready_err, assert_ready_ok, task};
-use tower_load_shed::LoadShedLayer;
+use tower::load_shed::LoadShedLayer;
 use tower_test::{assert_request_eq, mock};
 
 #[tokio::test]
@@ -27,5 +29,5 @@ async fn when_not_ready() {
     let mut fut = task::spawn(service.call("hello"));
 
     let err = assert_ready_err!(fut.poll());
-    assert!(err.is::<tower_load_shed::error::Overloaded>());
+    assert!(err.is::<tower::load_shed::error::Overloaded>());
 }
diff --git a/tower-ready-cache/tests/ready_cache.rs b/tower/tests/ready_cache/main.rs
similarity index 98%
rename from tower-ready-cache/tests/ready_cache.rs
rename to tower/tests/ready_cache/main.rs
index 93a2105..4578e4e 100644
--- a/tower-ready-cache/tests/ready_cache.rs
+++ b/tower/tests/ready_cache/main.rs
@@ -1,5 +1,7 @@
+#![cfg(feature = "ready-cache")]
+
 use tokio_test::{assert_pending, assert_ready, task};
-use tower_ready_cache::ReadyCache;
+use tower::ready_cache::ReadyCache;
 use tower_test::mock;
 
 type Req = &'static str;
diff --git a/tower-retry/tests/retry.rs b/tower/tests/retry/main.rs
similarity index 96%
rename from tower-retry/tests/retry.rs
rename to tower/tests/retry/main.rs
index be45ed9..ae97fc5 100644
--- a/tower-retry/tests/retry.rs
+++ b/tower/tests/retry/main.rs
@@ -1,6 +1,8 @@
+#![cfg(feature = "retry")]
+
 use futures_util::future;
 use tokio_test::{assert_pending, assert_ready_err, assert_ready_ok, task};
-use tower_retry::Policy;
+use tower::retry::Policy;
 use tower_test::{assert_request_eq, mock};
 
 #[tokio::test]
@@ -155,7 +157,7 @@ impl Policy<Req, Res, Error> for CannotClone {
 
 fn new_service<P: Policy<Req, Res, Error> + Clone>(
     policy: P,
-) -> (mock::Spawn<tower_retry::Retry<P, Mock>>, Handle) {
-    let retry = tower_retry::RetryLayer::new(policy);
+) -> (mock::Spawn<tower::retry::Retry<P, Mock>>, Handle) {
+    let retry = tower::retry::RetryLayer::new(policy);
     mock::spawn_layer(retry)
 }
diff --git a/tower-spawn-ready/tests/spawn_ready.rs b/tower/tests/spawn_ready/main.rs
similarity index 92%
rename from tower-spawn-ready/tests/spawn_ready.rs
rename to tower/tests/spawn_ready/main.rs
index bef3bef..db28e39 100644
--- a/tower-spawn-ready/tests/spawn_ready.rs
+++ b/tower/tests/spawn_ready/main.rs
@@ -1,6 +1,8 @@
+#![cfg(feature = "spawn-ready")]
+
 use std::{thread, time::Duration};
 use tokio_test::{assert_pending, assert_ready, assert_ready_err, assert_ready_ok};
-use tower_spawn_ready::SpawnReadyLayer;
+use tower::spawn_ready::SpawnReadyLayer;
 use tower_test::mock;
 
 #[tokio::test]
diff --git a/tower-util/tests/call_all.rs b/tower/tests/util/call_all.rs
similarity index 99%
rename from tower-util/tests/call_all.rs
rename to tower/tests/util/call_all.rs
index 0b056d2..5964f9d 100644
--- a/tower-util/tests/call_all.rs
+++ b/tower/tests/util/call_all.rs
@@ -6,9 +6,9 @@ use futures_util::{
 use std::task::{Context, Poll};
 use std::{cell::Cell, rc::Rc};
 use tokio_test::{assert_pending, assert_ready, task};
+use tower::util::ServiceExt;
 use tower_service::*;
 use tower_test::{assert_request_eq, mock};
-use tower_util::ServiceExt;
 
 type Error = Box<dyn std::error::Error + Send + Sync>;
 
diff --git a/tower/tests/util/main.rs b/tower/tests/util/main.rs
new file mode 100644
index 0000000..28a2932
--- /dev/null
+++ b/tower/tests/util/main.rs
@@ -0,0 +1,4 @@
+#![cfg(feature = "util")]
+
+mod call_all;
+mod service_fn;
diff --git a/tower-util/tests/service_fn.rs b/tower/tests/util/service_fn.rs
similarity index 89%
rename from tower-util/tests/service_fn.rs
rename to tower/tests/util/service_fn.rs
index 3a5a5ab..d024159 100644
--- a/tower-util/tests/service_fn.rs
+++ b/tower/tests/util/service_fn.rs
@@ -1,6 +1,6 @@
 use futures_util::future::ready;
+use tower::util::service_fn;
 use tower_service::Service;
-use tower_util::service_fn;
 
 #[tokio::test]
 async fn simple() {