Repository: conan-io/conan

Issue:
MSBuild should allow "do not adjust PlatformToolset" with an argument
Hey,

In https://github.com/conan-io/conan/pull/4250 the default behavior of VisualStudio's toolset selection was changed to compile the whole solution using the same toolset (the `/p:PlatformToolset` is always set - see discussion here https://github.com/conan-io/conan/pull/4250#pullrequestreview-193994771).

This change prevents using two different toolsets in the same solution. In my case building a driver using the `WindowsKernelModeDriver10.0` (which is not even a valid option right now) toolset and user mode library using the `v141` toolset.

I will be happy to write the code if this behavior change is accepted.

Discussion:

Patch:
diff --git a/conans/client/build/msbuild.py b/conans/client/build/msbuild.py
index 4123d2a1e..2e7edebb7 100644
--- a/conans/client/build/msbuild.py
+++ b/conans/client/build/msbuild.py
@@ -104,7 +104,8 @@ class MSBuild(object):
 
         build_type = build_type or self._settings.get_safe("build_type")
         arch = arch or self._settings.get_safe("arch")
-        toolset = toolset or tools.msvs_toolset(self._settings)
+        if toolset is None:  # False value to skip adjusting
+            toolset = tools.msvs_toolset(self._settings)
         verbosity = os.getenv("CONAN_MSBUILD_VERBOSITY") or verbosity or "minimal"
         if not build_type:
             raise ConanException("Cannot build_sln_command, build_type not defined")
diff --git a/conans/client/cache/cache.py b/conans/client/cache/cache.py
index a7d5afb33..317153e0e 100644
--- a/conans/client/cache/cache.py
+++ b/conans/client/cache/cache.py
@@ -93,39 +93,10 @@ class ClientCache(object):
         """
         return self.package_layout(ref).base_folder()
 
-    def export(self, ref):
-        return self.package_layout(ref).export()
-
-    def export_sources(self, ref, short_paths=False):
-        return self.package_layout(ref, short_paths).export_sources()
-
-    def source(self, ref, short_paths=False):
-        return self.package_layout(ref, short_paths).source()
-
-    def conanfile(self, ref):
-        return self.package_layout(ref).conanfile()
-
-    def builds(self, ref):
-        return self.package_layout(ref).builds()
-
-    def build(self, pref, short_paths=False):
-        return self.package_layout(pref.ref, short_paths).build(pref)
-
-    def system_reqs(self, ref):
-        return self.package_layout(ref).system_reqs()
-
-    def system_reqs_package(self, pref):
-        return self.package_layout(pref.ref).system_reqs_package(pref)
-
-    def packages(self, ref):
-        return self.package_layout(ref).packages()
-
     def package(self, pref, short_paths=False):
+        # TODO: This is deprecated, only used in testing
         return self.package_layout(pref.ref, short_paths).package(pref)
 
-    def scm_folder(self, ref):
-        return self.package_layout(ref).scm_folder()
-
     def installed_as_editable(self, ref):
         return isinstance(self.package_layout(ref), PackageEditableLayout)
 
@@ -171,14 +142,6 @@ class ClientCache(object):
             self._no_lock = self.config.cache_no_locks
         return self._no_lock
 
-    def conanfile_write_lock(self, ref):
-        layout = self.package_layout(ref)
-        return layout.conanfile_write_lock(self._output)
-
-    def package_lock(self, pref):
-        layout = self.package_layout(pref.ref)
-        return layout.package_lock(pref)
-
     @property
     def put_headers_path(self):
         return join(self.conan_folder, PUT_HEADERS)
diff --git a/conans/client/cmd/copy.py b/conans/client/cmd/copy.py
index 37845bd0d..52d1264d3 100644
--- a/conans/client/cmd/copy.py
+++ b/conans/client/cmd/copy.py
@@ -8,7 +8,7 @@ from conans.util.files import rmdir
 
 
 def _prepare_sources(cache, ref, remote_manager, loader, remotes):
-    conan_file_path = cache.conanfile(ref)
+    conan_file_path = cache.package_layout(ref).conanfile()
     conanfile = loader.load_class(conan_file_path)
     complete_recipe_sources(remote_manager, cache, conanfile, ref, remotes)
     return conanfile.short_paths
@@ -18,7 +18,7 @@ def _get_package_ids(cache, ref, package_ids):
     if not package_ids:
         return []
     if package_ids is True:
-        packages = cache.packages(ref)
+        packages = cache.package_layout(ref).packages()
         if os.path.exists(packages):
             package_ids = os.listdir(packages)
         else:
@@ -33,25 +33,28 @@ def cmd_copy(ref, user_channel, package_ids, cache, user_io, remote_manager, loa
     """
     # It is important to get the revision early, so "complete_recipe_sources" can
     # get the right revision sources, not latest
-    src_metadata = cache.package_layout(ref).load_metadata()
+    layout = cache.package_layout(ref)
+    src_metadata = layout.load_metadata()
     ref = ref.copy_with_rev(src_metadata.recipe.revision)
     short_paths = _prepare_sources(cache, ref, remote_manager, loader, remotes)
     package_ids = _get_package_ids(cache, ref, package_ids)
     package_copy(ref, user_channel, package_ids, cache, user_io, short_paths, force)
 
 
-def package_copy(src_ref, user_channel, package_ids, paths, user_io, short_paths=False, force=False):
+def package_copy(src_ref, user_channel, package_ids, cache, user_io, short_paths=False, force=False):
     dest_ref = ConanFileReference.loads("%s/%s@%s" % (src_ref.name,
                                                       src_ref.version,
                                                       user_channel))
     # Generate metadata
-    src_metadata = paths.package_layout(src_ref).load_metadata()
+    src_layout = cache.package_layout(src_ref, short_paths)
+    src_metadata = src_layout.load_metadata()
+    dst_layout = cache.package_layout(dest_ref, short_paths)
 
     # Copy export
-    export_origin = paths.export(src_ref)
+    export_origin = src_layout.export()
     if not os.path.exists(export_origin):
         raise ConanException("'%s' doesn't exist" % str(src_ref))
-    export_dest = paths.export(dest_ref)
+    export_dest = dst_layout.export()
     if os.path.exists(export_dest):
         if not force and not user_io.request_boolean("'%s' already exist. Override?"
                                                      % str(dest_ref)):
@@ -60,8 +63,8 @@ def package_copy(src_ref, user_channel, package_ids, paths, user_io, short_paths
     shutil.copytree(export_origin, export_dest, symlinks=True)
     user_io.out.info("Copied %s to %s" % (str(src_ref), str(dest_ref)))
 
-    export_sources_origin = paths.export_sources(src_ref, short_paths)
-    export_sources_dest = paths.export_sources(dest_ref, short_paths)
+    export_sources_origin = src_layout.export_sources()
+    export_sources_dest = dst_layout.export_sources()
     if os.path.exists(export_sources_dest):
         rmdir(export_sources_dest)
     shutil.copytree(export_sources_origin, export_sources_dest, symlinks=True)
@@ -72,8 +75,8 @@ def package_copy(src_ref, user_channel, package_ids, paths, user_io, short_paths
     for package_id in package_ids:
         pref_origin = PackageReference(src_ref, package_id)
         pref_dest = PackageReference(dest_ref, package_id)
-        package_path_origin = paths.package(pref_origin, short_paths)
-        package_path_dest = paths.package(pref_dest, short_paths)
+        package_path_origin = src_layout.package(pref_origin)
+        package_path_dest = dst_layout.package(pref_dest)
         if os.path.exists(package_path_dest):
             if not force and not user_io.request_boolean("Package '%s' already exist."
                                                          " Override?" % str(package_id)):
@@ -85,7 +88,7 @@ def package_copy(src_ref, user_channel, package_ids, paths, user_io, short_paths
         user_io.out.info("Copied %s to %s" % (str(package_id), str(dest_ref)))
 
     # Generate the metadata
-    with paths.package_layout(dest_ref).update_metadata() as metadata:
+    with dst_layout.update_metadata() as metadata:
         metadata.recipe.revision = src_metadata.recipe.revision
         for package_id, (revision, recipe_revision) in package_revisions.items():
             metadata.packages[package_id].revision = revision
diff --git a/conans/client/cmd/download.py b/conans/client/cmd/download.py
index 760c0eaf1..e5dd92f85 100644
--- a/conans/client/cmd/download.py
+++ b/conans/client/cmd/download.py
@@ -15,7 +15,7 @@ def download(ref, package_ids, remote, recipe, remote_manager,
     with cache.package_layout(ref).update_metadata() as metadata:
         metadata.recipe.remote = remote.name
 
-    conan_file_path = cache.conanfile(ref)
+    conan_file_path = cache.package_layout(ref).conanfile()
     conanfile = loader.load_class(conan_file_path)
 
     if not recipe:  # Not only the recipe
@@ -41,6 +41,6 @@ def _download_binaries(conanfile, ref, package_ids, cache, remote_manager, remot
 
     for package_id in package_ids:
         pref = PackageReference(ref, package_id)
-        package_folder = cache.package(pref, short_paths=short_paths)
+        package_folder = cache.package_layout(pref.ref, short_paths=short_paths).package(pref)
         output.info("Downloading %s" % str(pref))
         remote_manager.get_package(pref, package_folder, remote, output, recorder)
diff --git a/conans/client/cmd/export_pkg.py b/conans/client/cmd/export_pkg.py
index cf3421bda..c7fcea98e 100644
--- a/conans/client/cmd/export_pkg.py
+++ b/conans/client/cmd/export_pkg.py
@@ -3,17 +3,17 @@ import os
 from conans.client import packager
 from conans.client.graph.graph_manager import load_deps_info
 from conans.errors import ConanException
+from conans.model.conan_file import get_env_context_manager
 from conans.model.manifest import FileTreeManifest
 from conans.model.ref import PackageReference
 from conans.util.files import rmdir
-from conans.model.conan_file import get_env_context_manager
 
 
 def export_pkg(cache, graph_manager, hook_manager, recorder, output,
                ref, source_folder, build_folder, package_folder, install_folder,
                graph_info, force, remotes):
 
-    conan_file_path = cache.conanfile(ref)
+    conan_file_path = cache.package_layout(ref).conanfile()
     if not os.path.exists(conan_file_path):
         raise ConanException("Package recipe '%s' does not exist" % str(ref))
 
@@ -33,7 +33,8 @@ def export_pkg(cache, graph_manager, hook_manager, recorder, output,
     package_id = nodes[0].package_id
     output.info("Packaging to %s" % package_id)
     pref = PackageReference(ref, package_id)
-    dest_package_folder = cache.package(pref, short_paths=conanfile.short_paths)
+    layout = cache.package_layout(ref, short_paths=conanfile.short_paths)
+    dest_package_folder = layout.package(pref)
 
     if os.path.exists(dest_package_folder):
         if force:
@@ -42,7 +43,7 @@ def export_pkg(cache, graph_manager, hook_manager, recorder, output,
             raise ConanException("Package already exists. Please use --force, -f to "
                                  "overwrite it")
 
-    recipe_hash = cache.package_layout(ref).recipe_manifest().summary_hash
+    recipe_hash = layout.recipe_manifest().summary_hash
     conanfile.info.recipe_hash = recipe_hash
     conanfile.develop = True
     if package_folder:
@@ -57,7 +58,7 @@ def export_pkg(cache, graph_manager, hook_manager, recorder, output,
     readed_manifest = FileTreeManifest.load(dest_package_folder)
     pref = PackageReference(pref.ref, pref.id, readed_manifest.summary_hash)
     output.info("Package revision %s" % pref.revision)
-    with cache.package_layout(ref).update_metadata() as metadata:
+    with layout.update_metadata() as metadata:
         metadata.packages[package_id].revision = pref.revision
         metadata.packages[package_id].recipe_revision = metadata.recipe.revision
 
diff --git a/conans/client/cmd/uploader.py b/conans/client/cmd/uploader.py
index a156abd5b..820d4bcb7 100644
--- a/conans/client/cmd/uploader.py
+++ b/conans/client/cmd/uploader.py
@@ -129,7 +129,7 @@ class CmdUpload(object):
                 upload = self._user_io.request_boolean(msg)
             if upload:
                 try:
-                    conanfile_path = self._cache.conanfile(ref)
+                    conanfile_path = self._cache.package_layout(ref).conanfile()
                     conanfile = self._loader.load_class(conanfile_path)
                 except NotFoundException:
                     raise NotFoundException(("There is no local conanfile exported as %s" %
@@ -178,7 +178,7 @@ class CmdUpload(object):
         """ Uploads the recipes and binaries identified by ref
         """
         assert (ref.revision is not None), "Cannot upload a recipe without RREV"
-        conanfile_path = self._cache.conanfile(ref)
+        conanfile_path = self._cache.package_layout(ref).conanfile()
         # FIXME: I think it makes no sense to specify a remote to "pre_upload"
         # FIXME: because the recipe can have one and the package a different one
         self._hook_manager.execute("pre_upload", conanfile_path=conanfile_path,
@@ -211,7 +211,7 @@ class CmdUpload(object):
         if remote.name != current_remote_name:
             complete_recipe_sources(self._remote_manager, self._cache, conanfile, ref, remotes)
 
-        conanfile_path = self._cache.conanfile(ref)
+        conanfile_path = self._cache.package_layout(ref).conanfile()
         self._hook_manager.execute("pre_upload_recipe", conanfile_path=conanfile_path,
                                    reference=ref, remote=remote)
 
@@ -253,7 +253,7 @@ class CmdUpload(object):
         assert (pref.revision is not None), "Cannot upload a package without PREV"
         assert (pref.ref.revision is not None), "Cannot upload a package without RREV"
 
-        conanfile_path = self._cache.conanfile(pref.ref)
+        conanfile_path = self._cache.package_layout(pref.ref).conanfile()
         self._hook_manager.execute("pre_upload_package", conanfile_path=conanfile_path,
                                    reference=pref.ref,
                                    package_id=pref.id,
@@ -288,7 +288,7 @@ class CmdUpload(object):
         return pref
 
     def _compress_recipe_files(self, ref):
-        export_folder = self._cache.export(ref)
+        export_folder = self._cache.package_layout(ref).export()
 
         for f in (EXPORT_TGZ_NAME, EXPORT_SOURCES_TGZ_NAME):
             tgz_path = os.path.join(export_folder, f)
@@ -300,7 +300,7 @@ class CmdUpload(object):
         files, symlinks = gather_files(export_folder)
         if CONANFILE not in files or CONAN_MANIFEST not in files:
             raise ConanException("Cannot upload corrupted recipe '%s'" % str(ref))
-        export_src_folder = self._cache.export_sources(ref, short_paths=None)
+        export_src_folder = self._cache.package_layout(ref).export_sources()
         src_files, src_symlinks = gather_files(export_src_folder)
         the_files = _compress_recipe_files(files, symlinks, src_files, src_symlinks, export_folder,
                                            self._user_io.out)
@@ -310,7 +310,7 @@ class CmdUpload(object):
 
         t1 = time.time()
         # existing package, will use short paths if defined
-        package_folder = self._cache.package(pref, short_paths=None)
+        package_folder = self._cache.package_layout(pref.ref, short_paths=None).package(pref)
 
         if is_dirty(package_folder):
             raise ConanException("Package %s is corrupted, aborting upload.\n"
@@ -445,7 +445,7 @@ class CmdUpload(object):
             self._user_io.out.info(local_manifest)
             difference = remote_recipe_manifest.difference(local_manifest)
             if "conanfile.py" in difference:
-                contents = load(os.path.join(self._cache.export(ref), "conanfile.py"))
+                contents = load(self._cache.package_layout(ref).conanfile())
                 endlines = "\\r\\n" if "\r\n" in contents else "\\n"
                 self._user_io.out.info("Local 'conanfile.py' using '%s' line-ends" % endlines)
                 remote_contents = self._remote_manager.get_recipe_path(ref, path="conanfile.py",
diff --git a/conans/client/graph/graph_binaries.py b/conans/client/graph/graph_binaries.py
index e48d1b6a4..7f830a38d 100644
--- a/conans/client/graph/graph_binaries.py
+++ b/conans/client/graph/graph_binaries.py
@@ -60,10 +60,11 @@ class GraphBinariesAnalyzer(object):
             node.prev = None
             return
 
-        package_folder = self._cache.package(pref, short_paths=conanfile.short_paths)
+        package_folder = self._cache.package_layout(pref.ref,
+                                                    short_paths=conanfile.short_paths).package(pref)
 
         # Check if dirty, to remove it
-        with self._cache.package_lock(pref):
+        with self._cache.package_layout(pref.ref).package_lock(pref):
             assert node.recipe != RECIPE_EDITABLE, "Editable package shouldn't reach this code"
             if is_dirty(package_folder):
                 output.warn("Package is corrupted, removing folder: %s" % package_folder)
diff --git a/conans/client/graph/proxy.py b/conans/client/graph/proxy.py
index cd74b95c6..955f29bf8 100644
--- a/conans/client/graph/proxy.py
+++ b/conans/client/graph/proxy.py
@@ -23,13 +23,13 @@ class ConanProxy(object):
 
     def get_recipe(self, ref, check_updates, update, remotes, recorder):
         if self._cache.installed_as_editable(ref):
-            conanfile_path = self._cache.conanfile(ref)
+            conanfile_path = self._cache.package_layout(ref).conanfile()
             status = RECIPE_EDITABLE
             # TODO: log_recipe_got_from_editable(reference)
             # TODO: recorder.recipe_fetched_as_editable(reference)
             return conanfile_path, status, None, ref
 
-        with self._cache.conanfile_write_lock(ref):
+        with self._cache.package_layout(ref).conanfile_write_lock(self._out):
             result = self._get_recipe(ref, check_updates, update, remotes, recorder)
             conanfile_path, status, remote, new_ref = result
 
@@ -42,7 +42,7 @@ class ConanProxy(object):
     def _get_recipe(self, ref, check_updates, update, remotes, recorder):
         output = ScopedOutput(str(ref), self._out)
         # check if it is in disk
-        conanfile_path = self._cache.conanfile(ref)
+        conanfile_path = self._cache.package_layout(ref).conanfile()
 
         # NOT in disk, must be retrieved from remotes
         if not os.path.exists(conanfile_path):
@@ -85,7 +85,7 @@ class ConanProxy(object):
             ref = ref.copy_with_rev(cur_revision)
             return conanfile_path, status, selected_remote, ref
 
-        export = self._cache.export(ref)
+        export = self._cache.package_layout(ref).export()
         read_manifest = FileTreeManifest.load(export)
         if upstream_manifest != read_manifest:
             if upstream_manifest.time > read_manifest.time:
diff --git a/conans/client/installer.py b/conans/client/installer.py
index e5016248c..e5e329a2d 100644
--- a/conans/client/installer.py
+++ b/conans/client/installer.py
@@ -77,17 +77,12 @@ class _PackageBuilder(object):
         return build_folder, skip_build
 
     def _prepare_sources(self, conanfile, pref, package_layout, conanfile_path, source_folder,
-                         build_folder, package_folder, remotes):
+                         build_folder, remotes):
         export_folder = package_layout.export()
         export_source_folder = package_layout.export_sources()
 
         complete_recipe_sources(self._remote_manager, self._cache, conanfile, pref.ref, remotes)
-        try:
-            rmdir(build_folder)
-            rmdir(package_folder)
-        except OSError as e:
-            raise ConanException("%s\n\nCouldn't remove folder, might be busy or open\n"
-                                 "Close any app using it, and retry" % str(e))
+        _remove_folder_raising(build_folder)
 
         config_source(export_folder, export_source_folder, source_folder,
                       conanfile, self._output, conanfile_path, pref.ref,
@@ -140,6 +135,7 @@ class _PackageBuilder(object):
 
     def _package(self, conanfile, pref, package_layout, conanfile_path, build_folder,
                  package_folder):
+
         # FIXME: Is weak to assign here the recipe_hash
         manifest = package_layout.recipe_manifest()
         conanfile.info.recipe_hash = manifest.summary_hash
@@ -190,10 +186,11 @@ class _PackageBuilder(object):
             with package_layout.conanfile_write_lock(self._output):
                 set_dirty(build_folder)
                 self._prepare_sources(conanfile, pref, package_layout, conanfile_path, source_folder,
-                                      build_folder, package_folder, remotes)
+                                      build_folder, remotes)
 
         # BUILD & PACKAGE
         with package_layout.conanfile_read_lock(self._output):
+            _remove_folder_raising(package_folder)
             mkdir(build_folder)
             os.chdir(build_folder)
             self._output.info('Building your package in %s' % build_folder)
@@ -227,6 +224,14 @@ class _PackageBuilder(object):
             return node.pref
 
 
+def _remove_folder_raising(folder):
+    try:
+        rmdir(folder)
+    except OSError as e:
+        raise ConanException("%s\n\nCouldn't remove folder, might be busy or open\n"
+                             "Close any app using it, and retry" % str(e))
+
+
 def _handle_system_requirements(conan_file, pref, cache, out):
     """ check first the system_reqs/system_requirements.txt existence, if not existing
     check package/sha1/
@@ -236,8 +241,9 @@ def _handle_system_requirements(conan_file, pref, cache, out):
     if "system_requirements" not in type(conan_file).__dict__:
         return
 
-    system_reqs_path = cache.system_reqs(pref.ref)
-    system_reqs_package_path = cache.system_reqs_package(pref)
+    package_layout = cache.package_layout(pref.ref)
+    system_reqs_path = package_layout.system_reqs()
+    system_reqs_package_path = package_layout.system_reqs_package(pref)
     if os.path.exists(system_reqs_path) or os.path.exists(system_reqs_package_path):
         return
 
@@ -372,9 +378,9 @@ class BinaryInstaller(object):
 
         conan_file = node.conanfile
         output = conan_file.output
-        package_folder = self._cache.package(pref, conan_file.short_paths)
+        package_folder = self._cache.package_layout(pref.ref, conan_file.short_paths).package(pref)
 
-        with self._cache.package_lock(pref):
+        with self._cache.package_layout(pref.ref).package_lock(pref):
             if pref not in processed_package_references:
                 processed_package_references.add(pref)
                 if node.binary == BINARY_BUILD:
diff --git a/conans/client/manifest_manager.py b/conans/client/manifest_manager.py
index 58dd0a44a..4db935277 100644
--- a/conans/client/manifest_manager.py
+++ b/conans/client/manifest_manager.py
@@ -27,8 +27,9 @@ class ManifestManager(object):
 
     def _handle_recipe(self, node, verify, interactive):
         ref = node.ref
-        export = self._cache.export(ref)
-        exports_sources_folder = self._cache.export_sources(ref)
+        layout = self._cache.package_layout(ref)
+        export = layout.export()
+        exports_sources_folder = layout.export_sources()
         read_manifest = FileTreeManifest.load(export)
         expected_manifest = FileTreeManifest.create(export, exports_sources_folder)
         self._check_not_corrupted(ref, read_manifest, expected_manifest)
@@ -38,7 +39,7 @@ class ManifestManager(object):
     def _handle_package(self, node, verify, interactive):
         ref = node.ref
         pref = PackageReference(ref, node.package_id)
-        package_folder = self._cache.package(pref)
+        package_folder = self._cache.package_layout(pref.ref).package(pref)
         read_manifest = FileTreeManifest.load(package_folder)
         expected_manifest = FileTreeManifest.create(package_folder)
         self._check_not_corrupted(pref, read_manifest, expected_manifest)
diff --git a/conans/client/remote_manager.py b/conans/client/remote_manager.py
index 9230ef5ab..701495bc0 100644
--- a/conans/client/remote_manager.py
+++ b/conans/client/remote_manager.py
@@ -77,7 +77,7 @@ class RemoteManager(object):
         returns (dict relative_filepath:abs_path , remote_name)"""
 
         self._hook_manager.execute("pre_download_recipe", reference=ref, remote=remote)
-        dest_folder = self._cache.export(ref)
+        dest_folder = self._cache.package_layout(ref).export()
         rmdir(dest_folder)
 
         ref = self._resolve_latest_ref(ref, remote)
@@ -125,7 +125,7 @@ class RemoteManager(object):
 
     def get_package(self, pref, dest_folder, remote, output, recorder):
 
-        conanfile_path = self._cache.conanfile(pref.ref)
+        conanfile_path = self._cache.package_layout(pref.ref).conanfile()
         self._hook_manager.execute("pre_download_package", conanfile_path=conanfile_path,
                                    reference=pref.ref, package_id=pref.id, remote=remote)
         output.info("Retrieving package %s from remote '%s' " % (pref.id, remote.name))
diff --git a/conans/client/source.py b/conans/client/source.py
index 3d7c527b9..988c0c4f8 100644
--- a/conans/client/source.py
+++ b/conans/client/source.py
@@ -17,7 +17,7 @@ def complete_recipe_sources(remote_manager, cache, conanfile, ref, remotes):
     occassions, conan needs to get them too, like if uploading to a server, to keep the recipes
     complete
     """
-    sources_folder = cache.export_sources(ref, conanfile.short_paths)
+    sources_folder = cache.package_layout(ref, conanfile.short_paths).export_sources()
     if os.path.exists(sources_folder):
         return None
 
@@ -34,7 +34,7 @@ def complete_recipe_sources(remote_manager, cache, conanfile, ref, remotes):
         raise ConanException("Error while trying to get recipe sources for %s. "
                              "No remote defined" % str(ref))
 
-    export_path = cache.export(ref)
+    export_path = cache.package_layout(ref).export()
     remote_manager.get_recipe_sources(ref, export_path, sources_folder, current_remote)
 
 
@@ -102,7 +102,7 @@ def config_source(export_folder, export_source_folder, src_folder, conanfile, ou
             if raise_error or isinstance(e_rm, KeyboardInterrupt):
                 raise ConanException("Unable to remove source folder")
 
-    sources_pointer = cache.scm_folder(reference)
+    sources_pointer = cache.package_layout(reference).scm_folder()
     local_sources_path = load(sources_pointer) if os.path.exists(sources_pointer) else None
     if is_dirty(src_folder):
         output.warn("Trying to remove corrupted source folder")
diff --git a/conans/model/settings.py b/conans/model/settings.py
index c94fd59a3..3d55f9b3f 100644
--- a/conans/model/settings.py
+++ b/conans/model/settings.py
@@ -29,6 +29,7 @@ class SettingsItem(object):
     """ represents a setting value and its child info, which could be:
     - A range of valid values: [Debug, Release] (for settings.compiler.runtime of VS)
     - "ANY", as string to accept any value
+    - List ["None", "ANY"] to accept None or any value
     - A dict {subsetting: definition}, e.g. {version: [], runtime: []} for VS
     """
     def __init__(self, definition, name):
@@ -87,11 +88,14 @@ class SettingsItem(object):
     def __str__(self):
         return str(self._value)
 
+    def _not_any(self):
+        return self._definition != "ANY" and "ANY" not in self._definition
+
     def __eq__(self, other):
         if other is None:
             return self._value is None
         other = str(other)
-        if self._definition != "ANY" and other not in self.values_range:
+        if self._not_any() and other not in self.values_range:
             raise ConanException(bad_value_msg(self._name, other, self.values_range))
         return other == self.__str__()
 
@@ -114,10 +118,13 @@ class SettingsItem(object):
             v = str(v)
             if isinstance(self._definition, dict):
                 self._definition.pop(v, None)
-            elif self._definition != "ANY":
-                if v in self._definition:
-                    self._definition.remove(v)
-        if self._value is not None and self._value not in self._definition:
+            elif self._definition == "ANY":
+                if v == "ANY":
+                    self._definition = []
+            elif v in self._definition:
+                self._definition.remove(v)
+
+        if self._value is not None and self._value not in self._definition and self._not_any():
             raise ConanException(bad_value_msg(self._name, self._value, self.values_range))
 
     def _get_child(self, item):
@@ -154,7 +161,7 @@ class SettingsItem(object):
     @value.setter
     def value(self, v):
         v = str(v)
-        if self._definition != "ANY" and v not in self._definition:
+        if self._not_any() and v not in self.values_range:
             raise ConanException(bad_value_msg(self._name, v, self.values_range))
         self._value = v
 
@@ -180,7 +187,6 @@ class SettingsItem(object):
     def validate(self):
         if self._value is None and "None" not in self._definition:
             raise undefined_value(self._name)
-
         if isinstance(self._definition, dict):
             key = "None" if self._value is None else self._value
             self._definition[key].validate()


Test patch:
diff --git a/conans/test/functional/build_helpers/autotools_environment_test.py b/conans/test/functional/build_helpers/autotools_environment_test.py
index 076823c36..c6462eb5d 100644
--- a/conans/test/functional/build_helpers/autotools_environment_test.py
+++ b/conans/test/functional/build_helpers/autotools_environment_test.py
@@ -158,7 +158,7 @@ class HelloConan(ConanFile):
         self.assertNotIn("PKG_CONFIG_PATH=", client.out)
 
         ref = ConanFileReference.loads("Hello/1.2.1@conan/testing")
-        builds_folder = client.cache.builds(ref)
+        builds_folder = client.cache.package_layout(ref).builds()
         bf = os.path.join(builds_folder, os.listdir(builds_folder)[0])
 
         client.save({CONANFILE: conanfile % ("'pkg_config'", "")})
diff --git a/conans/test/functional/build_helpers/msbuild_test.py b/conans/test/functional/build_helpers/msbuild_test.py
index 8a0923770..62a062f87 100644
--- a/conans/test/functional/build_helpers/msbuild_test.py
+++ b/conans/test/functional/build_helpers/msbuild_test.py
@@ -91,7 +91,7 @@ class HelloConan(ConanFile):
         self.assertIn("Packaged 1 '.exe' file: MyProject.exe", client.out)
         full_ref = "Hello/1.2.1@lasote/stable:b786e9ece960c3a76378ca4d5b0d0e922f4cedc1"
         pref = PackageReference.loads(full_ref)
-        build_folder = client.cache.build(pref)
+        build_folder = client.cache.package_layout(pref.ref).build(pref)
         self.assertTrue(os.path.exists(os.path.join(build_folder, "mp.props")))
 
     @unittest.skipUnless(platform.system() == "Windows", "Requires MSBuild")
diff --git a/conans/test/functional/command/copy_packages_test.py b/conans/test/functional/command/copy_packages_test.py
index abf351b2c..5a406c9c3 100644
--- a/conans/test/functional/command/copy_packages_test.py
+++ b/conans/test/functional/command/copy_packages_test.py
@@ -23,13 +23,13 @@ class Pkg(ConanFile):
 
         # Copy all packages
         client.run("copy Hello0/0.1@lasote/stable pepe/testing --all")
-        pkgdir = client.cache.packages(ConanFileReference.loads("Hello0/0.1@pepe/testing"))
+        pkgdir = client.cache.package_layout(ConanFileReference.loads("Hello0/0.1@pepe/testing")).packages()
         packages = os.listdir(pkgdir)
         self.assertEqual(len(packages), 3)
 
         # Copy just one
         client.run("copy Hello0/0.1@lasote/stable pepe/stable -p %s" % packages[0])
-        pkgdir = client.cache.packages(ConanFileReference.loads("Hello0/0.1@pepe/stable"))
+        pkgdir = client.cache.package_layout(ConanFileReference.loads("Hello0/0.1@pepe/stable")).packages()
         packages = os.listdir(pkgdir)
         self.assertEqual(len(packages), 1)
 
@@ -40,7 +40,7 @@ class Pkg(ConanFile):
 
         # Copy only recipe
         client.run("copy Hello0/0.1@lasote/stable pepe/alpha")
-        pkgdir = client.cache.packages(ConanFileReference.loads("Hello0/0.1@pepe/alpha"))
+        pkgdir = client.cache.package_layout(ConanFileReference.loads("Hello0/0.1@pepe/alpha")).packages()
         self.assertFalse(os.path.exists(pkgdir))
 
     @parameterized.expand([(True, ), (False,)])
@@ -76,9 +76,9 @@ class Pkg(ConanFile):
         self.assertIn("Downloading conan_sources.tgz", client2.out)
 
         ref = ConanFileReference.loads("pkg/0.1@lasote/stable")
-        conanfile = load(client2.cache.conanfile(ref))
+        conanfile = load(client2.cache.package_layout(ref).conanfile())
         self.assertNotIn("# Recipe revision 2", conanfile)
-        data = load(os.path.join(client2.cache.export_sources(ref), "myfile.txt"))
+        data = load(os.path.join(client2.cache.package_layout(ref).export_sources(), "myfile.txt"))
         # With revisions, it work, it fetches the correct one
         if revision_enabled:
             self.assertIn("my data!", data)
diff --git a/conans/test/functional/command/create_test.py b/conans/test/functional/command/create_test.py
index 0d9a59cca..229b93950 100644
--- a/conans/test/functional/command/create_test.py
+++ b/conans/test/functional/command/create_test.py
@@ -1,10 +1,12 @@
 import os
+import textwrap
 import unittest
 
 from parameterized.parameterized import parameterized
 
 from conans.client import tools
-from conans.test.utils.tools import TestClient
+from conans.model.ref import ConanFileReference, PackageReference
+from conans.test.utils.tools import TestClient, NO_SETTINGS_PACKAGE_ID
 from conans.util.files import load
 
 
@@ -68,29 +70,34 @@ class HelloTestConan(ConanFile):
     @parameterized.expand([(True, ), (False, )])
     def keep_build_test(self, with_test):
         client = TestClient()
-        conanfile = """from conans import ConanFile
-class MyPkg(ConanFile):
-    exports_sources = "*.h"
-    def source(self):
-        self.output.info("mysource!!")
-    def build(self):
-        self.output.info("mybuild!!")
-    def package(self):
-        self.output.info("mypackage!!")
-        self.copy("*.h")
-"""
+        conanfile = textwrap.dedent("""
+            from conans import ConanFile
+            
+            class MyPkg(ConanFile):
+                exports_sources = "*.h"
+                def source(self):
+                    self.output.info("mysource!!")
+                def build(self):
+                    self.output.info("mybuild!!")
+                def package(self):
+                    self.output.info("mypackage!!")
+                    self.copy("*.h")
+            """)
         if with_test:
-            client.save({"conanfile.py": conanfile,
-                         "header.h": ""})
-        else:
-            test_conanfile = """from conans import ConanFile
-class MyPkg(ConanFile):
-    def test(self):
-        pass
-"""
+            test_conanfile = textwrap.dedent("""
+            from conans import ConanFile
+
+            class MyPkg(ConanFile):
+                def test(self):
+                    pass
+            """)
             client.save({"conanfile.py": conanfile,
                          "header.h": "",
                          "test_package/conanfile.py": test_conanfile})
+        else:
+            client.save({"conanfile.py": conanfile,
+                         "header.h": ""})
+
         client.run("create . Pkg/0.1@lasote/testing")
         self.assertIn("Pkg/0.1@lasote/testing: mysource!!", client.out)
         self.assertIn("Pkg/0.1@lasote/testing: mybuild!!", client.out)
@@ -135,6 +142,36 @@ class MyPkg(ConanFile):
         client.run("create . Pkg/0.1@lasote/testing --keep-build", assert_error=True)
         self.assertIn("ERROR: --keep-build specified, but build folder not found", client.out)
 
+    def keep_build_package_folder_test(self):
+        """
+        Package folder should be deleted always before a new conan create command, even with
+        --keep-build
+        """
+        client = TestClient()
+        conanfile = textwrap.dedent("""
+            from conans import ConanFile
+
+            class MyPkg(ConanFile):
+                exports_sources = "*.h", "*.cpp"
+                def package(self):
+                    self.copy("*.h")
+            """)
+        client.save({"conanfile.py": conanfile,
+                     "header.h": "",
+                     "source.cpp": ""})
+        client.run("create . pkg/0.1@danimtb/testing")
+        ref = ConanFileReference("pkg", "0.1", "danimtb", "testing")
+        pref = PackageReference(ref, NO_SETTINGS_PACKAGE_ID)
+        package_files = os.listdir(client.cache.package(pref))
+        self.assertIn("header.h", package_files)
+        self.assertNotIn("source.cpp", package_files)
+        client.save({"conanfile.py": conanfile.replace("self.copy(\"*.h\")",
+                                                       "self.copy(\"*.cpp\")")})
+        client.run("create . pkg/0.1@danimtb/testing -kb")
+        package_files = os.listdir(client.cache.package(pref))
+        self.assertNotIn("header.h", package_files)
+        self.assertIn("source.cpp", package_files)
+
     def create_test(self):
         client = TestClient()
         client.save({"conanfile.py": """from conans import ConanFile
@@ -454,3 +491,24 @@ class TestConanLib(ConanFile):
         self.assertTrue(os.path.exists(os.path.join(client.current_folder, "test_package",
                                                     "build_folder")))
         self.assertFalse(os.path.exists(default_build_dir))
+
+    def package_folder_build_error_test(self):
+        """
+        Check package folder is not created if the build step fails
+        """
+        client = TestClient()
+        conanfile = textwrap.dedent("""
+        from conans import ConanFile
+
+        class MyPkg(ConanFile):
+
+            def build(self):
+                raise ConanException("Build error")
+        """)
+        client.save({"conanfile.py": conanfile})
+        ref = ConanFileReference("pkg", "0.1", "danimtb", "testing")
+        pref = PackageReference(ref, NO_SETTINGS_PACKAGE_ID, None)
+        client.run("create . %s" % ref.full_repr(), assert_error=True)
+        self.assertIn("Build error", client.out)
+        package_folder = client.cache.package(pref)
+        self.assertFalse(os.path.exists(package_folder))
diff --git a/conans/test/functional/command/download_test.py b/conans/test/functional/command/download_test.py
index e16dc6157..20d7925d2 100644
--- a/conans/test/functional/command/download_test.py
+++ b/conans/test/functional/command/download_test.py
@@ -31,21 +31,21 @@ class Pkg(ConanFile):
                      "file.h": "myfile.h"})
         client.run("create . lasote/stable")
         ref = ConanFileReference.loads("pkg/0.1@lasote/stable")
-        self.assertTrue(os.path.exists(client.cache.conanfile(ref)))
+        self.assertTrue(os.path.exists(client.cache.package_layout(ref).conanfile()))
         conan = client.cache.base_folder(ref)
         self.assertTrue(os.path.exists(os.path.join(conan, "package")))
         client.run("upload pkg/0.1@lasote/stable --all")
         client.run("remove pkg/0.1@lasote/stable -f")
-        self.assertFalse(os.path.exists(client.cache.export(ref)))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).export()))
         client.run("download pkg/0.1@lasote/stable --recipe")
 
         self.assertIn("Downloading conanfile.py", client.out)
         self.assertNotIn("Downloading conan_sources.tgz", client.out)
         self.assertNotIn("Downloading conan_package.tgz", client.out)
-        export = client.cache.export(ref)
+        export = client.cache.package_layout(ref).export()
         self.assertTrue(os.path.exists(os.path.join(export, "conanfile.py")))
         self.assertEqual(conanfile, load(os.path.join(export, "conanfile.py")))
-        source = client.cache.export_sources(ref)
+        source = client.cache.package_layout(ref).export_sources()
         self.assertFalse(os.path.exists(os.path.join(source, "file.h")))
         conan = client.cache.base_folder(ref)
         self.assertFalse(os.path.exists(os.path.join(conan, "package")))
@@ -70,15 +70,15 @@ class Pkg(ConanFile):
         client.run("export . lasote/stable")
 
         ref = ConanFileReference.loads("pkg/0.1@lasote/stable")
-        self.assertTrue(os.path.exists(client.cache.conanfile(ref)))
+        self.assertTrue(os.path.exists(client.cache.package_layout(ref).conanfile()))
 
         client.run("upload pkg/0.1@lasote/stable")
         client.run("remove pkg/0.1@lasote/stable -f")
-        self.assertFalse(os.path.exists(client.cache.export(ref)))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).export()))
 
         client.run("download pkg/0.1@lasote/stable")
         self.assertIn("Downloading conan_sources.tgz", client.out)
-        source = client.cache.export_sources(ref)
+        source = client.cache.package_layout(ref).export_sources()
         self.assertEqual("myfile.h", load(os.path.join(source, "file.h")))
         self.assertEqual("C++code", load(os.path.join(source, "otherfile.cpp")))
 
@@ -96,17 +96,17 @@ class Pkg(ConanFile):
         client.run("export . lasote/stable")
 
         ref = ConanFileReference.loads("pkg/0.1@lasote/stable")
-        self.assertTrue(os.path.exists(client.cache.conanfile(ref)))
+        self.assertTrue(os.path.exists(client.cache.package_layout(ref).conanfile()))
 
         client.run("upload pkg/0.1@lasote/stable")
         client.run("remove pkg/0.1@lasote/stable -f")
-        self.assertFalse(os.path.exists(client.cache.export(ref)))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).export()))
 
         client.run("download pkg/0.1@lasote/stable")
         # Check 'No remote binary packages found' warning
         self.assertTrue("WARN: No remote binary packages found in remote", client.out)
         # Check at least conanfile.py is downloaded
-        self.assertTrue(os.path.exists(client.cache.conanfile(ref)))
+        self.assertTrue(os.path.exists(client.cache.package_layout(ref).conanfile()))
 
     def download_reference_with_packages_test(self):
         server = TestServer()
@@ -124,21 +124,21 @@ class Pkg(ConanFile):
         client.run("create . lasote/stable")
 
         ref = ConanFileReference.loads("pkg/0.1@lasote/stable")
-        self.assertTrue(os.path.exists(client.cache.conanfile(ref)))
+        self.assertTrue(os.path.exists(client.cache.package_layout(ref).conanfile()))
 
         package_folder = os.path.join(client.cache.base_folder(ref), "package",
-                                      os.listdir(client.cache.packages(ref))[0])
+                                      os.listdir(client.cache.package_layout(ref).packages())[0])
 
         client.run("upload pkg/0.1@lasote/stable --all")
         client.run("remove pkg/0.1@lasote/stable -f")
-        self.assertFalse(os.path.exists(client.cache.export(ref)))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).export()))
 
         client.run("download pkg/0.1@lasote/stable")
 
         # Check not 'No remote binary packages found' warning
         self.assertNotIn("WARN: No remote binary packages found in remote", client.out)
         # Check at conanfile.py is downloaded
-        self.assertTrue(os.path.exists(client.cache.conanfile(ref)))
+        self.assertTrue(os.path.exists(client.cache.package_layout(ref).conanfile()))
         # Check package folder created
         self.assertTrue(os.path.exists(package_folder))
 
diff --git a/conans/test/functional/command/export_dirty_test.py b/conans/test/functional/command/export_dirty_test.py
index b26e03991..9244d188e 100644
--- a/conans/test/functional/command/export_dirty_test.py
+++ b/conans/test/functional/command/export_dirty_test.py
@@ -25,7 +25,8 @@ class Pkg(ConanFile):
         self.assertIn("ERROR: pkg/1.0@user/channel: Error in source() method, line 6", client.out)
         ref = ConanFileReference.loads("pkg/1.0@user/channel")
         # Check that we can debug and see the folder
-        self.assertEqual(load(os.path.join(client.cache.source(ref), "somefile.txt")),
+        self.assertEqual(load(os.path.join(client.cache.package_layout(ref).source(),
+                                           "somefile.txt")),
                          "hello world!!!")
         client.run("create . pkg/1.0@user/channel", assert_error=True)
         self.assertIn("pkg/1.0@user/channel: Source folder is corrupted, forcing removal",
@@ -35,7 +36,7 @@ class Pkg(ConanFile):
         self.assertIn("pkg/1.0@user/channel: Source folder is corrupted, forcing removal",
                       client.out)
         # Check that it is empty
-        self.assertEqual(os.listdir(os.path.join(client.cache.source(ref))), [])
+        self.assertEqual(os.listdir(os.path.join(client.cache.package_layout(ref).source())), [])
 
 
 class ExportDirtyTest(unittest.TestCase):
@@ -54,7 +55,7 @@ class ExportDirtyTest(unittest.TestCase):
         self.client.run("export . lasote/stable")
         self.client.run("install Hello0/0.1@lasote/stable --build")
         ref = ConanFileReference.loads("Hello0/0.1@lasote/stable")
-        source_path = self.client.cache.source(ref)
+        source_path = self.client.cache.package_layout(ref).source()
         file_open = os.path.join(source_path, "main.cpp")
 
         self.f = open(file_open, 'wb')
diff --git a/conans/test/functional/command/export_path_test.py b/conans/test/functional/command/export_path_test.py
index e4648fd6e..e3912ad8d 100644
--- a/conans/test/functional/command/export_path_test.py
+++ b/conans/test/functional/command/export_path_test.py
@@ -18,8 +18,8 @@ class ExportPathTest(unittest.TestCase):
         ref = ConanFileReference("Hello0", "0.1", "lasote", "stable")
         client.save(files, path=source_folder)
         client.run("export source lasote/stable")
-        reg_path = client.cache.export(ref)
-        manif = FileTreeManifest.load(client.cache.export(ref))
+        reg_path = client.cache.package_layout(ref).export()
+        manif = FileTreeManifest.load(client.cache.package_layout(ref).export())
 
         self.assertIn('%s: A new conanfile.py version was exported' % str(ref),
                       client.user_io.out)
@@ -47,8 +47,8 @@ class ExportPathTest(unittest.TestCase):
         ref = ConanFileReference("Hello0", "0.1", "lasote", "stable")
         client.save(files, path=source_folder)
         client.run("export ../source lasote/stable")
-        reg_path = client.cache.export(ref)
-        manif = FileTreeManifest.load(client.cache.export(ref))
+        reg_path = client.cache.package_layout(ref).export()
+        manif = FileTreeManifest.load(client.cache.package_layout(ref).export())
 
         self.assertIn('%s: A new conanfile.py version was exported' % str(ref),
                       client.user_io.out)
@@ -79,8 +79,8 @@ class ExportPathTest(unittest.TestCase):
 
         client.save({"conanfile.py": conanfile})
         client.run("export . lasote/stable")
-        reg_path = client.cache.export(ref)
-        manif = FileTreeManifest.load(client.cache.export(ref))
+        reg_path = client.cache.package_layout(ref).export()
+        manif = FileTreeManifest.load(client.cache.package_layout(ref).export())
 
         self.assertIn('%s: A new conanfile.py version was exported' % str(ref),
                       client.user_io.out)
@@ -116,8 +116,8 @@ class ExportPathTest(unittest.TestCase):
 
         client.save({"conanfile.py": conanfile}, path=conanfile_folder)
         client.run("export ../conan lasote/stable")
-        reg_path = client.cache.export(ref)
-        manif = FileTreeManifest.load(client.cache.export(ref))
+        reg_path = client.cache.package_layout(ref).export()
+        manif = FileTreeManifest.load(client.cache.package_layout(ref).export())
 
         self.assertIn('%s: A new conanfile.py version was exported' % str(ref),
                       client.user_io.out)
diff --git a/conans/test/functional/command/export_pkg_test.py b/conans/test/functional/command/export_pkg_test.py
index 32654bd50..4608f7fc0 100644
--- a/conans/test/functional/command/export_pkg_test.py
+++ b/conans/test/functional/command/export_pkg_test.py
@@ -109,7 +109,7 @@ class HelloPythonConan(ConanFile):
         self.assertIn("Hello/0.1@lasote/stable: Packaged 1 '.h' file: myfile.h", client.out)
         self.assertNotIn("No files in this package!", client.out)
         ref = ConanFileReference.loads("Hello/0.1@lasote/stable")
-        pkg_folder = client.cache.packages(ref)
+        pkg_folder = client.cache.package_layout(ref).packages()
         folders = os.listdir(pkg_folder)
         pkg_folder = os.path.join(pkg_folder, folders[0])
         conaninfo = load(os.path.join(pkg_folder, "conaninfo.txt"))
diff --git a/conans/test/functional/command/export_test.py b/conans/test/functional/command/export_test.py
index 14646bd28..30d110df2 100644
--- a/conans/test/functional/command/export_test.py
+++ b/conans/test/functional/command/export_test.py
@@ -77,8 +77,8 @@ class TestConan(ConanFile):
     exports_sources = "file2.txt"
 """
         ref = ConanFileReference.loads("Hello/1.2@lasote/stable")
-        export_path = client.cache.export(ref)
-        export_src_path = client.cache.export_sources(ref)
+        export_path = client.cache.package_layout(ref).export()
+        export_src_path = client.cache.package_layout(ref).export_sources()
 
         files = {CONANFILE: conanfile,
                  "file1.txt": "",
@@ -140,7 +140,7 @@ class TestConan(ConanFile):
             client.current_folder = os.path.join(client.current_folder, "recipe")
             client.run("export . lasote/stable")
             ref = ConanFileReference("Hello", "1.2", "lasote", "stable")
-            export_path = client.cache.export(ref)
+            export_path = client.cache.package_layout(ref).export()
             content = load(os.path.join(export_path, "sibling/file.txt"))
             self.assertEqual("Hello World!", content)
 
@@ -160,7 +160,7 @@ class TestConan(ConanFile):
         client.current_folder = os.path.join(client.current_folder, "recipe")
         client.run("export . lasote/stable")
         ref = ConanFileReference("Hello", "1.2", "lasote", "stable")
-        export_path = client.cache.export(ref)
+        export_path = client.cache.package_layout(ref).export()
         content = load(os.path.join(export_path, "file.txt"))
         self.assertEqual("Hello World!", content)
 
@@ -182,7 +182,7 @@ class TestConan(ConanFile):
         client.current_folder = os.path.join(client.current_folder, "recipe")
         client.run("export . lasote/stable")
         ref = ConanFileReference("Hello", "1.2", "lasote", "stable")
-        export_path = client.cache.export_sources(ref)
+        export_path = client.cache.package_layout(ref).export_sources()
         self.assertEqual(sorted(['file.txt', 'file.cpp', 'file.h']),
                          sorted(os.listdir(export_path)))
 
@@ -201,7 +201,7 @@ class TestConan(ConanFile):
         self.assertIn("Hello/1.2@lasote/stable: A new conanfile.py version was exported",
                       client.user_io.out)
         ref = ConanFileReference("Hello", "1.2", "lasote", "stable")
-        export_path = client.cache.export(ref)
+        export_path = client.cache.package_layout(ref).export()
         conanfile = load(os.path.join(export_path, "conanfile.py"))
         self.assertIn('name = "Hello"', conanfile)
         manifest = load(os.path.join(export_path, "conanmanifest.txt"))
@@ -225,8 +225,8 @@ class TestConan(ConanFile):
                      "file_temp.cpp": ""})
         client.run("export . lasote/stable")
         ref = ConanFileReference("Hello", "1.2", "lasote", "stable")
-        export_path = client.cache.export(ref)
-        exports_sources_path = client.cache.export_sources(ref)
+        export_path = client.cache.package_layout(ref).export()
+        exports_sources_path = client.cache.package_layout(ref).export_sources()
         self.assertTrue(os.path.exists(os.path.join(export_path, "file.txt")))
         self.assertFalse(os.path.exists(os.path.join(export_path, "file1.txt")))
         self.assertTrue(os.path.exists(os.path.join(exports_sources_path, "file.cpp")))
@@ -248,7 +248,7 @@ class TestConan(ConanFile):
                      "other/sub/file2.txt": ""})
         client.run("export . lasote/stable")
         ref = ConanFileReference("Hello", "1.2", "lasote", "stable")
-        export_path = client.cache.export(ref)
+        export_path = client.cache.package_layout(ref).export()
         self.assertTrue(os.path.exists(os.path.join(export_path, "file.txt")))
         self.assertFalse(os.path.exists(os.path.join(export_path, "any/temp/file1.txt")))
         self.assertTrue(os.path.exists(os.path.join(export_path, "other/sub/file2.txt")))
@@ -266,8 +266,8 @@ class ExportTest(unittest.TestCase):
     def test_basic(self):
         """ simple registration of a new conans
         """
-        reg_path = self.conan.cache.export(self.ref)
-        manif = FileTreeManifest.load(self.conan.cache.export(self.ref))
+        reg_path = self.conan.cache.package_layout(self.ref).export()
+        manif = FileTreeManifest.load(self.conan.cache.package_layout(self.ref).export())
 
         self.assertIn('%s: A new conanfile.py version was exported' % str(self.ref),
                       self.conan.user_io.out)
@@ -303,7 +303,8 @@ class OpenSSLConan(ConanFile):
 """
         save(os.path.join(self.conan.current_folder, CONANFILE), content)
         self.conan.run("export . lasote/stable")
-        reg_path = self.conan.cache.export(ConanFileReference.loads('openssl/2.0.1@lasote/stable'))
+        ref = ConanFileReference.loads('openssl/2.0.1@lasote/stable')
+        reg_path = self.conan.cache.package_layout(ref).export()
         self.assertEqual(sorted(os.listdir(reg_path)),
                          [CONANFILE, CONAN_MANIFEST])
 
@@ -317,7 +318,6 @@ class OpenSSLConan(ConanFile):
 """
         save(os.path.join(self.conan.current_folder, CONANFILE), content)
         self.conan.run("export . lasote/stable")
-        reg_path = self.conan.cache.export(ConanFileReference.loads('openssl/2.0.1@lasote/stable'))
         self.assertEqual(sorted(os.listdir(reg_path)),
                          ['CMakeLists.txt', CONANFILE, CONAN_MANIFEST,
                           'helloHello0.h'])
@@ -333,7 +333,6 @@ class OpenSSLConan(ConanFile):
 """
         save(os.path.join(self.conan.current_folder, CONANFILE), content)
         self.conan.run("export . lasote/stable")
-        reg_path = self.conan.cache.export(ConanFileReference.loads('openssl/2.0.1@lasote/stable'))
         self.assertEqual(sorted(os.listdir(reg_path)),
                          ['CMakeLists.txt', CONANFILE, CONAN_MANIFEST, 'helloHello0.h'])
 
@@ -345,8 +344,8 @@ class OpenSSLConan(ConanFile):
         files2 = cpp_hello_conan_files("Hello0", "0.1")
         conan2.save(files2)
         conan2.run("export . lasote/stable")
-        reg_path2 = conan2.cache.export(self.ref)
-        digest2 = FileTreeManifest.load(conan2.cache.export(self.ref))
+        reg_path2 = conan2.cache.package_layout(self.ref).export()
+        digest2 = FileTreeManifest.load(conan2.cache.package_layout(self.ref).export())
 
         self.assertNotIn('A new Conan version was exported', conan2.user_io.out)
         self.assertNotIn('Cleaning the old builds ...', conan2.user_io.out)
@@ -382,8 +381,8 @@ class OpenSSLConan(ConanFile):
         conan2.save(files2)
         conan2.run("export . lasote/stable")
 
-        reg_path3 = conan2.cache.export(self.ref)
-        digest3 = FileTreeManifest.load(conan2.cache.export(self.ref))
+        reg_path3 = conan2.cache.package_layout(self.ref).export()
+        digest3 = FileTreeManifest.load(conan2.cache.package_layout(self.ref).export())
 
         self.assertIn('%s: A new conanfile.py version was exported' % str(self.ref),
                       self.conan.user_io.out)
@@ -406,8 +405,8 @@ class OpenSSLConan(ConanFile):
         #    self.assertFalse(os.path.exists(f))
 
     def _create_packages_and_builds(self):
-        reg_builds = self.conan.cache.builds(self.ref)
-        reg_packs = self.conan.cache.packages(self.ref)
+        reg_builds = self.conan.cache.package_layout(self.ref).builds()
+        reg_packs = self.conan.cache.package_layout(self.ref).packages()
 
         folders = [os.path.join(reg_builds, '342525g4f52f35f'),
                    os.path.join(reg_builds, 'ew9o8asdf908asdf80'),
@@ -426,7 +425,7 @@ class OpenSSLConan(ConanFile):
 class ExportMetadataTest(unittest.TestCase):
     conanfile = textwrap.dedent("""
         from conans import ConanFile
-        
+
         class Lib(ConanFile):
             revision_mode = "{revision_mode}"
     """)
diff --git a/conans/test/functional/command/info_folders_test.py b/conans/test/functional/command/info_folders_test.py
index dcb3a0e1c..ae1099e3a 100644
--- a/conans/test/functional/command/info_folders_test.py
+++ b/conans/test/functional/command/info_folders_test.py
@@ -137,9 +137,9 @@ class InfoFoldersTest(unittest.TestCase):
             ref = ConanFileReference.loads(self.reference1)
             id_ = re.search('ID:\s*([a-z0-9]*)', str(client.user_io.out)).group(1)
             pref = PackageReference(ref, id_)
-            for path in (client.cache.source(ref, True),
-                         client.cache.build(pref, True),
-                         client.cache.package(pref, True)):
+            for path in (client.cache.package_layout(ref, True).source(),
+                         client.cache.package_layout(ref, True).build(pref),
+                         client.cache.package_layout(ref, True).package(pref)):
                 self.assertFalse(os.path.exists(path))
                 self.assertTrue(os.path.exists(os.path.dirname(path)))
 
diff --git a/conans/test/functional/command/remove_test.py b/conans/test/functional/command/remove_test.py
index 199bdd1ef..75383c682 100644
--- a/conans/test/functional/command/remove_test.py
+++ b/conans/test/functional/command/remove_test.py
@@ -158,7 +158,7 @@ class RemoveTest(unittest.TestCase):
                 files["%s/%s/%s/%s" % (folder, PACKAGES_FOLDER, pack_id, CONANINFO)] = conaninfo % str(i) + "905eefe3570dd09a8453b30b9272bb44"
                 files["%s/%s/%s/%s" % (folder, PACKAGES_FOLDER, pack_id, CONAN_MANIFEST)] = ""
             files["%s/metadata.json" % folder] = fake_metadata.dumps()
-            exports_sources_dir = client.cache.export_sources(ref)
+            exports_sources_dir = client.cache.package_layout(ref).export_sources()
             os.makedirs(exports_sources_dir)
 
         client.save(files, client.cache.store)
diff --git a/conans/test/functional/command/search_test.py b/conans/test/functional/command/search_test.py
index d0e6cf720..e289cd585 100644
--- a/conans/test/functional/command/search_test.py
+++ b/conans/test/functional/command/search_test.py
@@ -260,54 +260,54 @@ helloTest/1.4.10@myuser/stable""".format(remote)
     def search_partial_match_test(self):
         self.client.run("search Hello")
         self.assertEqual("Existing package recipes:\n\n"
-                          "Hello/1.4.10@myuser/testing\n"
-                          "Hello/1.4.11@myuser/testing\n"
-                          "Hello/1.4.12@myuser/testing\n", self.client.out)
+                         "Hello/1.4.10@myuser/testing\n"
+                         "Hello/1.4.11@myuser/testing\n"
+                         "Hello/1.4.12@myuser/testing\n", self.client.out)
 
         self.client.run("search hello")
         self.assertEqual("Existing package recipes:\n\n"
-                          "Hello/1.4.10@myuser/testing\n"
-                          "Hello/1.4.11@myuser/testing\n"
-                          "Hello/1.4.12@myuser/testing\n", self.client.out)
+                         "Hello/1.4.10@myuser/testing\n"
+                         "Hello/1.4.11@myuser/testing\n"
+                         "Hello/1.4.12@myuser/testing\n", self.client.out)
 
         self.client.run("search Hello --case-sensitive")
         self.assertEqual("Existing package recipes:\n\n"
-                          "Hello/1.4.10@myuser/testing\n"
-                          "Hello/1.4.11@myuser/testing\n"
-                          "Hello/1.4.12@myuser/testing\n", self.client.out)
+                         "Hello/1.4.10@myuser/testing\n"
+                         "Hello/1.4.11@myuser/testing\n"
+                         "Hello/1.4.12@myuser/testing\n", self.client.out)
 
         self.client.run("search Hel")
         self.assertEqual("There are no packages matching the 'Hel' pattern\n", self.client.out)
 
         self.client.run("search Hello/")
         self.assertEqual("Existing package recipes:\n\n"
-                          "Hello/1.4.10@myuser/testing\n"
-                          "Hello/1.4.11@myuser/testing\n"
-                          "Hello/1.4.12@myuser/testing\n", self.client.out)
+                         "Hello/1.4.10@myuser/testing\n"
+                         "Hello/1.4.11@myuser/testing\n"
+                         "Hello/1.4.12@myuser/testing\n", self.client.out)
 
         self.client.run("search Hello/1.4.10")
         self.assertEqual("Existing package recipes:\n\n"
-                          "Hello/1.4.10@myuser/testing\n", self.client.out)
+                         "Hello/1.4.10@myuser/testing\n", self.client.out)
 
         self.client.run("search Hello/1.4")
         self.assertEqual("There are no packages matching the 'Hello/1.4' pattern\n",
-                          self.client.out)
+                         self.client.out)
 
         self.client.run("search Hello/1.4.10@")
         self.assertEqual("Existing package recipes:\n\n"
-                          "Hello/1.4.10@myuser/testing\n", self.client.out)
+                         "Hello/1.4.10@myuser/testing\n", self.client.out)
 
         self.client.run("search Hello/1.4.10@myuser")
         self.assertEqual("Existing package recipes:\n\n"
-                          "Hello/1.4.10@myuser/testing\n", self.client.out)
+                         "Hello/1.4.10@myuser/testing\n", self.client.out)
 
         self.client.run("search Hello/1.4.10@fen")
         self.assertEqual("There are no packages matching the 'Hello/1.4.10@fen' pattern\n",
-                          self.client.out)
+                         self.client.out)
 
         self.client.run("search Hello/1.4.10@myuser/")
         self.assertEqual("Existing package recipes:\n\n"
-                          "Hello/1.4.10@myuser/testing\n", self.client.out)
+                         "Hello/1.4.10@myuser/testing\n", self.client.out)
 
         self.client.run("search Hello/1.4.10@myuser/test", assert_error=True)
         self.assertEqual("ERROR: Recipe not found: 'Hello/1.4.10@myuser/test'\n", self.client.out)
@@ -315,9 +315,9 @@ helloTest/1.4.10@myuser/stable""".format(remote)
     def search_raw_test(self):
         self.client.run("search Hello* --raw")
         self.assertEqual("Hello/1.4.10@myuser/testing\n"
-                          "Hello/1.4.11@myuser/testing\n"
-                          "Hello/1.4.12@myuser/testing\n"
-                          "helloTest/1.4.10@myuser/stable\n", self.client.out)
+                         "Hello/1.4.11@myuser/testing\n"
+                         "Hello/1.4.12@myuser/testing\n"
+                         "helloTest/1.4.10@myuser/stable\n", self.client.out)
 
     def search_html_table_test(self):
         self.client.run("search Hello/1.4.10@myuser/testing --table=table.html")
@@ -510,21 +510,21 @@ helloTest/1.4.10@myuser/stable""".format(remote)
         # test in remote with search capabilities
         test_cases(remote="search_able")
 
-    def _copy_to_server(self, client_store_path, server_store):
-        subdirs = list_folder_subdirs(basedir=client_store_path.store, level=4)
+    def _copy_to_server(self, cache, server_store):
+        subdirs = list_folder_subdirs(basedir=cache.store, level=4)
         refs = [ConanFileReference(*folder.split("/"), revision=DEFAULT_REVISION_V1)
                 for folder in subdirs]
         for ref in refs:
-            origin_path = client_store_path.export(ref)
+            origin_path = cache.package_layout(ref).export()
             dest_path = server_store.export(ref)
             shutil.copytree(origin_path, dest_path)
             server_store.update_last_revision(ref)
-            packages = client_store_path.packages(ref)
+            packages = cache.package_layout(ref).packages()
             if not os.path.exists(packages):
                 continue
             for package in os.listdir(packages):
                 pref = PackageReference(ref, package, DEFAULT_REVISION_V1)
-                origin_path = client_store_path.package(pref)
+                origin_path = cache.package_layout(ref).package(pref)
                 dest_path = server_store.package(pref)
                 shutil.copytree(origin_path, dest_path)
                 server_store.update_last_package_revision(pref)
@@ -1376,4 +1376,3 @@ class SearchRemoteAllTestCase(unittest.TestCase):
         self.assertIn("all: http://fake", self.client.out)
         self.client.run("search -r {} {}".format(self.remote_name, self.reference))
         self.assertIn("Existing recipe in remote 'all':", self.client.out)  # Searching in 'all'
-
diff --git a/conans/test/functional/command/upload_complete_test.py b/conans/test/functional/command/upload_complete_test.py
index 4239642af..18f77f5d4 100644
--- a/conans/test/functional/command/upload_complete_test.py
+++ b/conans/test/functional/command/upload_complete_test.py
@@ -77,7 +77,7 @@ class UploadTest(unittest.TestCase):
         self.ref = ConanFileReference.loads("Hello/1.2.1@frodo/stable#%s" %
                                             DEFAULT_REVISION_V1)
         self.pref = PackageReference(self.ref, "myfakeid", DEFAULT_REVISION_V1)
-        reg_folder = self.client.cache.export(self.ref)
+        reg_folder = self.client.cache.package_layout(self.ref).export()
 
         self.client.run('upload %s' % str(self.ref), assert_error=True)
         self.assertIn("ERROR: Recipe not found: '%s'" % str(self.ref), self.client.out)
@@ -95,7 +95,7 @@ class UploadTest(unittest.TestCase):
                           "my_lib/debug/libd.a": "//copy",
                           "my_data/readme.txt": "//copy",
                           "my_bin/executable": "//copy"}, path=reg_folder)
-        mkdir(self.client.cache.export_sources(self.ref))
+        mkdir(self.client.cache.package_layout(self.ref).export_sources())
         manifest = FileTreeManifest.create(reg_folder)
         manifest.time = '123123123'
         manifest.save(reg_folder)
@@ -103,7 +103,7 @@ class UploadTest(unittest.TestCase):
 
         self.server_pack_folder = self.test_server.server_store.package(self.pref)
 
-        package_folder = self.client.cache.package(self.pref)
+        package_folder = self.client.cache.package_layout(self.ref).package(self.pref)
         save(os.path.join(package_folder, "include", "lib1.h"), "//header")
         save(os.path.join(package_folder, "lib", "my_lib", "libd.a"), "//lib")
         save(os.path.join(package_folder, "res", "shares", "readme.txt"),
@@ -118,8 +118,7 @@ class UploadTest(unittest.TestCase):
                  os.stat(os.path.join(package_folder, "bin", "my_bin", "executable")).st_mode |
                  stat.S_IRWXU)
 
-        package_path = self.client.cache.package(self.pref)
-        expected_manifest = FileTreeManifest.create(package_path)
+        expected_manifest = FileTreeManifest.create(package_folder)
         expected_manifest.save(package_folder)
 
         self.server_reg_folder = self.test_server.server_store.export(self.ref)
@@ -131,7 +130,7 @@ class UploadTest(unittest.TestCase):
         self.client.save(files)
         self.client.run("export . frodo/stable")
         ref = ConanFileReference.loads("Hello0/1.2.1@frodo/stable")
-        os.unlink(os.path.join(self.client.cache.export(ref), CONAN_MANIFEST))
+        os.unlink(os.path.join(self.client.cache.package_layout(ref).export(), CONAN_MANIFEST))
         with six.assertRaisesRegex(self, Exception, "Command failed"):
             self.client.run("upload %s" % str(ref))
 
@@ -374,7 +373,7 @@ class TestConan(ConanFile):
         old_digest = self.client.cache.package_layout(self.ref).recipe_manifest()
         old_digest.file_sums["new_file"] = "012345"
         fake_digest = FileTreeManifest(2, old_digest.file_sums)
-        fake_digest.save(self.client.cache.export(self.ref))
+        fake_digest.save(self.client.cache.package_layout(self.ref).export())
 
         self.client.run('upload %s' % str(self.ref), assert_error=True)
         self.assertIn("Remote recipe is newer than local recipe", self.client.user_io.out)
diff --git a/conans/test/functional/command/upload_test.py b/conans/test/functional/command/upload_test.py
index a066548b4..c049e7f2f 100644
--- a/conans/test/functional/command/upload_test.py
+++ b/conans/test/functional/command/upload_test.py
@@ -145,7 +145,7 @@ class UploadTest(unittest.TestCase):
             client.run("upload * --confirm", assert_error=True)
             self.assertIn("ERROR: Error gzopen conan_sources.tgz", client.out)
 
-            export_folder = client.cache.export(ref)
+            export_folder = client.cache.package_layout(ref).export()
             tgz = os.path.join(export_folder, EXPORT_SOURCES_TGZ_NAME)
             self.assertTrue(os.path.exists(tgz))
             self.assertTrue(is_dirty(tgz))
@@ -192,7 +192,7 @@ class UploadTest(unittest.TestCase):
                      "include/hello.h": ""})
         client.run("create . frodo/stable")
         ref = ConanFileReference.loads("Hello0/1.2.1@frodo/stable")
-        packages_folder = client.cache.packages(ref)
+        packages_folder = client.cache.package_layout(ref).packages()
         pkg_id = os.listdir(packages_folder)[0]
         package_folder = os.path.join(packages_folder, pkg_id)
         save(os.path.join(package_folder, "added.txt"), "")
@@ -220,7 +220,7 @@ class UploadTest(unittest.TestCase):
         ref = ConanFileReference.loads("Hello0/1.2.1@frodo/stable")
         manifest = client2.cache.package_layout(ref).recipe_manifest()
         manifest.time += 10
-        manifest.save(client2.cache.export(ref))
+        manifest.save(client2.cache.package_layout(ref).export())
         client2.run("upload Hello0/1.2.1@frodo/stable")
         self.assertIn("Uploading conanmanifest.txt", client2.user_io.out)
         self.assertIn("Uploaded conan recipe 'Hello0/1.2.1@frodo/stable' to 'default'",
@@ -254,7 +254,7 @@ class UploadTest(unittest.TestCase):
         ref = ConanFileReference.loads("Hello0/1.2.1@frodo/stable")
         manifest = client2.cache.package_layout(ref).recipe_manifest()
         manifest.time += 10
-        manifest.save(client2.cache.export(ref))
+        manifest.save(client2.cache.package_layout(ref).export())
         client2.run("upload Hello0/1.2.1@frodo/stable")
         self.assertNotIn("Uploading conanmanifest.txt", client2.out)
         self.assertNotIn("Uploaded conan recipe 'Hello0/1.2.1@frodo/stable' to 'default'",
diff --git a/conans/test/functional/conanfile/no_copy_source_test.py b/conans/test/functional/conanfile/no_copy_source_test.py
index c70297452..b3462816c 100644
--- a/conans/test/functional/conanfile/no_copy_source_test.py
+++ b/conans/test/functional/conanfile/no_copy_source_test.py
@@ -35,11 +35,11 @@ class ConanFileToolsTest(ConanFile):
         self.assertIn("Source files: myfile.h contents", client.user_io.out)
         ref = ConanFileReference.loads("Pkg/0.1@lasote/testing")
 
-        builds = client.cache.builds(ref)
+        builds = client.cache.package_layout(ref).builds()
         pid = os.listdir(builds)[0]
         build_folder = os.path.join(builds, pid)
         self.assertNotIn("file.h", os.listdir(build_folder))
-        packages = client.cache.packages(ref)
+        packages = client.cache.package_layout(ref).packages()
         package_folder = os.path.join(packages, pid)
         self.assertIn("file.h", os.listdir(package_folder))
         self.assertIn("myartifact.lib", os.listdir(package_folder))
@@ -66,7 +66,7 @@ class ConanFileToolsTest(ConanFile):
         client.run("create . lasote/testing --build")
         ref = ConanFileReference.loads("Pkg/0.1@lasote/testing")
 
-        packages = client.cache.packages(ref)
+        packages = client.cache.package_layout(ref).packages()
         pid = os.listdir(packages)[0]
         package_folder = os.path.join(packages, pid, "include")
         self.assertIn("header.h", os.listdir(package_folder))
@@ -76,7 +76,7 @@ class ConanFileToolsTest(ConanFile):
         client.run("create . lasote/testing --build")
         ref = ConanFileReference.loads("Pkg/0.1@lasote/testing")
 
-        packages = client.cache.packages(ref)
+        packages = client.cache.package_layout(ref).packages()
         pid = os.listdir(packages)[0]
         package_folder = os.path.join(packages, pid, "include")
         self.assertIn("header.h", os.listdir(package_folder))
\ No newline at end of file
diff --git a/conans/test/functional/environment/apply_environment_test.py b/conans/test/functional/environment/apply_environment_test.py
index 26701c956..a61ef5a45 100644
--- a/conans/test/functional/environment/apply_environment_test.py
+++ b/conans/test/functional/environment/apply_environment_test.py
@@ -776,7 +776,7 @@ class LibConan(ConanFile):
 
         def load_conaninfo(lib):
             # Read the LIB_A conaninfo
-            packages_path = client.cache.packages(ConanFileReference.loads("LIB_%s/1.0@lasote/stable" % lib))
+            packages_path = client.cache.package_layout(ConanFileReference.loads("LIB_%s/1.0@lasote/stable" % lib)).packages()
             package_path = os.path.join(packages_path, os.listdir(packages_path)[0])
             info = ConanInfo.loads(load(os.path.join(package_path, CONANINFO)))
             return info
diff --git a/conans/test/functional/generators/xcode_gcc_vs_test.py b/conans/test/functional/generators/xcode_gcc_vs_test.py
index e88445b56..c3ee2f114 100644
--- a/conans/test/functional/generators/xcode_gcc_vs_test.py
+++ b/conans/test/functional/generators/xcode_gcc_vs_test.py
@@ -76,7 +76,7 @@ xcode
         lib_dirs = linker.getElementsByTagName("AdditionalLibraryDirectories")[0].firstChild.data
         libs = linker.getElementsByTagName("AdditionalDependencies")[0].firstChild.data
 
-        package_id = os.listdir(client.cache.packages(ref))[0]
+        package_id = os.listdir(client.cache.package_layout(ref).packages())[0]
         pref = PackageReference(ref, package_id)
         package_path = client.cache.package(pref)
 
diff --git a/conans/test/functional/graph/graph_manager_base.py b/conans/test/functional/graph/graph_manager_base.py
index b8b5aabae..f2d354755 100644
--- a/conans/test/functional/graph/graph_manager_base.py
+++ b/conans/test/functional/graph/graph_manager_base.py
@@ -46,11 +46,11 @@ class GraphManagerTest(unittest.TestCase):
         if isinstance(test_conanfile, TestConanFile):
             test_conanfile.info = True
         ref = ConanFileReference.loads(reference)
-        save(self.cache.conanfile(ref), str(test_conanfile))
+        save(self.cache.package_layout(ref).conanfile(), str(test_conanfile))
         with self.cache.package_layout(ref).update_metadata() as metadata:
             metadata.recipe.revision = revision or "123"
-        manifest = FileTreeManifest.create(self.cache.export(ref))
-        manifest.save(self.cache.export(ref))
+        manifest = FileTreeManifest.create(self.cache.package_layout(ref).export())
+        manifest.save(self.cache.package_layout(ref).export())
 
     def build_graph(self, content, profile_build_requires=None, ref=None, create_ref=None):
         path = temp_folder()
diff --git a/conans/test/functional/graph/transitive_deps_test.py b/conans/test/functional/graph/transitive_deps_test.py
index 2a59107f4..36811f057 100644
--- a/conans/test/functional/graph/transitive_deps_test.py
+++ b/conans/test/functional/graph/transitive_deps_test.py
@@ -41,7 +41,7 @@ class TransitiveDepsTest(unittest.TestCase):
         pref_c = PackageReference.loads(
             "CCCC/1.0@user/channel:aef99e6ca67e3d2da47927c4ec1ec7129129943f")
         self.assertIn("{} - Build".format(pref_c), self.t.out)
-        build_folder = self.t.cache.build(pref=pref_c)
+        build_folder = self.t.cache.package_layout(pref_c.ref).build(pref_c)
 
         # It contains information about AAAA
         conanbuildinfo = load(os.path.join(build_folder, "conanbuildinfo.cmake"))
diff --git a/conans/test/functional/old/conan_trace_file_test.py b/conans/test/functional/old/conan_trace_file_test.py
index a480926a8..1e6f624e7 100644
--- a/conans/test/functional/old/conan_trace_file_test.py
+++ b/conans/test/functional/old/conan_trace_file_test.py
@@ -50,8 +50,8 @@ class HelloConan(ConanFile):
             client.run("user lasote -p mypass -r default")
             client.run("export . lasote/stable")
             client.run("install %s --build missing" % str(ref))
-            package_dir = client.cache.packages(
-                ConanFileReference.loads("Hello0/0.1@lasote/stable"))
+            package_dir = client.cache.package_layout(
+                ConanFileReference.loads("Hello0/0.1@lasote/stable")).packages()
             package_dir = os.path.join(package_dir, os.listdir(package_dir)[0])
             log_file_packaged_ = os.path.join(package_dir, RUN_LOG_NAME)
             return log_file_packaged_, client.user_io.out
diff --git a/conans/test/functional/old/create_package_test.py b/conans/test/functional/old/create_package_test.py
index 0a625428d..a850764f9 100644
--- a/conans/test/functional/old/create_package_test.py
+++ b/conans/test/functional/old/create_package_test.py
@@ -44,7 +44,7 @@ class ExporterTest(unittest.TestCase):
         files = hello_source_files()
 
         ref = ConanFileReference.loads("Hello/1.2.1@frodo/stable")
-        reg_folder = client.cache.export(ref)
+        reg_folder = client.cache.package_layout(ref).export()
 
         client.save(files, path=reg_folder)
         client.save({CONANFILE: myconan1,
@@ -71,8 +71,8 @@ class ExporterTest(unittest.TestCase):
 
         conanfile_path = os.path.join(reg_folder, CONANFILE)
         pref = PackageReference(ref, "myfakeid")
-        build_folder = client.cache.build(pref)
-        package_folder = client.cache.package(pref)
+        build_folder = client.cache.package_layout(pref.ref).build(pref)
+        package_folder = client.cache.package_layout(pref.ref).package(pref)
         install_folder = os.path.join(build_folder, "infos")
 
         shutil.copytree(reg_folder, build_folder)
diff --git a/conans/test/functional/old/package_copier_test.py b/conans/test/functional/old/package_copier_test.py
index 5a3b9658c..8ed485962 100644
--- a/conans/test/functional/old/package_copier_test.py
+++ b/conans/test/functional/old/package_copier_test.py
@@ -65,7 +65,7 @@ class PackageCopierTest(unittest.TestCase):
         output._stream.truncate(0)  # Reset output
         package_copy(ref, "lasote/stable", ["0101001", "2222222"], paths,
                      user_io=userio, force=False)
-        conanfile_content = load(os.path.join(paths.export(new_ref), "conanfile.py"))
+        conanfile_content = load(paths.package_layout(new_ref).conanfile())
         self.assertEqual(conanfile_content, "new content")
         package_content = load(os.path.join(paths.package(PackageReference(new_ref, "0101001")),
                                             "package.lib"))
@@ -80,7 +80,7 @@ class PackageCopierTest(unittest.TestCase):
         self._create_package(ref, "2222222", paths, "newlib22")
         package_copy(ref, "lasote/stable", ["0101001", "2222222"], paths,
                      user_io=userio, force=False)
-        conanfile_content = load(os.path.join(paths.export(new_ref), "conanfile.py"))
+        conanfile_content = load(paths.package_layout(new_ref).conanfile())
         self.assertEqual(conanfile_content, "new content")  # Not content22
         pref = PackageReference(new_ref, "0101001")
         package_content = load(os.path.join(paths.package(pref), "package.lib"))
@@ -109,7 +109,7 @@ class PackageCopierTest(unittest.TestCase):
         self._assert_package_doesnt_exists(new_ref, "2222222", paths)
 
     def _assert_conanfile_exists(self, reference, paths):
-        self.assertTrue(os.path.exists(paths.conanfile(reference)))
+        self.assertTrue(os.path.exists(paths.package_layout(reference).conanfile()))
 
     def _assert_package_exists(self, ref, package_id, paths):
         pref = PackageReference(ref, package_id)
@@ -120,11 +120,11 @@ class PackageCopierTest(unittest.TestCase):
         self.assertFalse(os.path.exists(os.path.join(paths.package(pref), "package.lib")))
 
     def _create_conanfile(self, ref, paths, content="default_content"):
-        origin_reg = paths.export(ref)
+        origin_reg = paths.package_layout(ref).export()
         mkdir(origin_reg)
         save(os.path.join(origin_reg, "conanfile.py"), content)
-        save(os.path.join(paths.base_folder(ref), "metadata.json"), PackageMetadata().dumps())
-        mkdir(paths.export_sources(ref))
+        save(paths.package_layout(ref).package_metadata(), PackageMetadata().dumps())
+        mkdir(paths.package_layout(ref).export_sources())
 
     def _create_package(self, ref, package_id, paths, content="default_content"):
         pref = PackageReference(ref, package_id)
diff --git a/conans/test/functional/old/path_limit_test.py b/conans/test/functional/old/path_limit_test.py
index 288fed7df..053563a58 100644
--- a/conans/test/functional/old/path_limit_test.py
+++ b/conans/test/functional/old/path_limit_test.py
@@ -97,7 +97,7 @@ class PathLengthLimitTest(unittest.TestCase):
             client2 = TestClient(servers=servers, users={"default": [("lasote", "mypass")]})
             client2.run("%s lib/0.1@lasote/channel" % command)
             ref = ConanFileReference.loads("lib/0.1@lasote/channel")
-            export_folder = client2.cache.export(ref)
+            export_folder = client2.cache.package_layout(ref).export()
             export_files = os.listdir(export_folder)
             self.assertNotIn('conan_export.tgz', export_files)
             pref = PackageReference.loads("lib/0.1@lasote/channel:" + NO_SETTINGS_PACKAGE_ID)
@@ -119,7 +119,7 @@ class PathLengthLimitTest(unittest.TestCase):
         client.save(files)
         client.run("export . user/channel")
         ref = ConanFileReference.loads("lib/0.1@user/channel")
-        source_folder = client.cache.export_sources(ref)
+        source_folder = client.cache.package_layout(ref, False).export_sources()
         if platform.system() == "Windows":
             source_folder = load(os.path.join(source_folder, ".conan_link"))
         self.assertTrue(os.path.exists(source_folder))
@@ -175,15 +175,15 @@ class PathLengthLimitTest(unittest.TestCase):
         self.assertEqual("Hello2 extra path length", file2)
         if platform.system() == "Windows":
             ref = ConanFileReference.loads("lib/0.1@user/channel")
-            source_folder = client.cache.source(ref)
+            source_folder = client.cache.package_layout(ref, False).source()
             link_source = load(os.path.join(source_folder, ".conan_link"))
             self.assertTrue(os.path.exists(link_source))
 
-            build_folder = client.cache.build(pref)
+            build_folder = client.cache.package_layout(ref, False).build(pref)
             link_build = load(os.path.join(build_folder, ".conan_link"))
             self.assertTrue(os.path.exists(link_build))
 
-            package_folder = client.cache.package(pref)
+            package_folder = client.cache.package_layout(ref, False).package(pref)
             link_package = load(os.path.join(package_folder, ".conan_link"))
             self.assertTrue(os.path.exists(link_package))
 
@@ -211,9 +211,9 @@ class ConanLib(ConanFile):
 
         if platform.system() == "Windows":
             ref = ConanFileReference.loads("lib/0.1@user/channel")
-            source_folder = client.cache.source(ref)
-            build_folder = client.cache.build(pref)
-            package_folder = client.cache.package(pref)
+            source_folder = client.cache.package_layout(ref, False).source()
+            build_folder = client.cache.package_layout(ref, False).build(pref)
+            package_folder = client.cache.package_layout(ref, False).package(pref)
             link_source = os.path.join(source_folder, ".conan_link")
             link_build = os.path.join(build_folder, ".conan_link")
             link_package = os.path.join(package_folder, ".conan_link")
diff --git a/conans/test/functional/old/paths_test.py b/conans/test/functional/old/paths_test.py
index a15f183fb..354ae896b 100644
--- a/conans/test/functional/old/paths_test.py
+++ b/conans/test/functional/old/paths_test.py
@@ -37,12 +37,13 @@ class PathsTest(unittest.TestCase):
         expected_base = os.path.join(folder, ".conan", "data",
                                      os.path.sep.join(["opencv", "2.4.10",
                                                        "lasote", "testing"]))
-        self.assertEqual(paths.base_folder(ref), expected_base)
-        self.assertEqual(paths.export(ref),
+        layout = paths.package_layout(ref)
+        self.assertEqual(layout.base_folder(), expected_base)
+        self.assertEqual(layout.export(),
                          os.path.join(expected_base, EXPORT_FOLDER))
-        self.assertEqual(paths.build(pref),
+        self.assertEqual(layout.build(pref),
                          os.path.join(expected_base, BUILD_FOLDER,  "456fa678eae68"))
-        self.assertEqual(paths.package(pref),
+        self.assertEqual(layout.package(pref),
                          os.path.join(expected_base, PACKAGES_FOLDER,
                                       "456fa678eae68"))
 
diff --git a/conans/test/functional/old/remove_old_export_sources_layout_test.py b/conans/test/functional/old/remove_old_export_sources_layout_test.py
index a8f6c1b70..d5e0457d9 100644
--- a/conans/test/functional/old/remove_old_export_sources_layout_test.py
+++ b/conans/test/functional/old/remove_old_export_sources_layout_test.py
@@ -41,7 +41,7 @@ class MyPkg(ConanFile):
         self.assertEqual(os.listdir(folder), ["myfile.txt"])
         # Now install again
         client.run("install Pkg/0.1@lasote/testing --build=missing")
-        export = client.cache.export(ref)
+        export = client.cache.package_layout(ref).export()
         self.assertNotIn(EXPORT_SOURCES_DIR_OLD, os.listdir(export))
-        export_sources = client.cache.export_sources(ref)
+        export_sources = client.cache.package_layout(ref).export_sources()
         self.assertEqual(os.listdir(export_sources), ["myfile.txt"])
diff --git a/conans/test/functional/old/rmdir_fail_test.py b/conans/test/functional/old/rmdir_fail_test.py
index 0bd839afa..51fe7b28f 100644
--- a/conans/test/functional/old/rmdir_fail_test.py
+++ b/conans/test/functional/old/rmdir_fail_test.py
@@ -21,7 +21,7 @@ class MyPkg(ConanFile):
         client.run("export . lasote/testing")
         client.run("install MyPkg/0.1@lasote/testing --build")
         ref = ConanFileReference.loads("MyPkg/0.1@lasote/testing")
-        builds = client.cache.builds(ref)
+        builds = client.cache.package_layout(ref).builds()
         build_folder = os.listdir(builds)[0]
         build_folder = os.path.join(builds, build_folder)
         f = open(os.path.join(build_folder, "myfile"), "wb")
diff --git a/conans/test/functional/python_requires/python_requires_test.py b/conans/test/functional/python_requires/python_requires_test.py
index ade31040d..a47175a69 100644
--- a/conans/test/functional/python_requires/python_requires_test.py
+++ b/conans/test/functional/python_requires/python_requires_test.py
@@ -383,7 +383,7 @@ class PkgTest(base.MyConanfileBase):
         self.assertIn("Pkg/0.1@lasote/testing: License! MyLicense", client.out)
         self.assertIn("Pkg/0.1@lasote/testing: Author! author@company.com", client.out)
         ref = ConanFileReference.loads("Pkg/0.1@lasote/testing")
-        self.assertTrue(os.path.exists(os.path.join(client.cache.export(ref),
+        self.assertTrue(os.path.exists(os.path.join(client.cache.package_layout(ref).export(),
                                                     "other.txt")))
 
     def reuse_exports_conflict_test(self):
diff --git a/conans/test/functional/remote/broken_download_test.py b/conans/test/functional/remote/broken_download_test.py
index 1b268a9b7..1e30d82d5 100644
--- a/conans/test/functional/remote/broken_download_test.py
+++ b/conans/test/functional/remote/broken_download_test.py
@@ -17,10 +17,10 @@ class BrokenDownloadTest(unittest.TestCase):
         client.save(files)
         client.run("export . lasote/stable")
         ref = ConanFileReference.loads("Hello/0.1@lasote/stable")
-        self.assertTrue(os.path.exists(client.cache.export(ref)))
+        self.assertTrue(os.path.exists(client.cache.package_layout(ref).export()))
         client.run("upload Hello/0.1@lasote/stable")
         client.run("remove Hello/0.1@lasote/stable -f")
-        self.assertFalse(os.path.exists(client.cache.export(ref)))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).export()))
 
         rev = server.server_store.get_last_revision(ref).revision
         ref = ref.copy_with_rev(rev)
@@ -29,7 +29,7 @@ class BrokenDownloadTest(unittest.TestCase):
         save(tgz, "contents")  # dummy content to break it, so the download decompress will fail
         client.run("install Hello/0.1@lasote/stable --build", assert_error=True)
         self.assertIn("ERROR: Error while downloading/extracting files to", client.user_io.out)
-        self.assertFalse(os.path.exists(client.cache.export(ref)))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).export()))
 
     def client_retries_test(self):
         server = TestServer()
diff --git a/conans/test/functional/scm/scm_test.py b/conans/test/functional/scm/scm_test.py
index 544ee3dc5..97a29d40b 100644
--- a/conans/test/functional/scm/scm_test.py
+++ b/conans/test/functional/scm/scm_test.py
@@ -69,7 +69,7 @@ class ConanLib(ConanFile):
     name = "lib"
     version = "0.1"
     scm = ["Other stuff"]
-    
+
     def build(self):
         self.output.writeln("scm: {}".format(self.scm))
 '''
@@ -100,7 +100,7 @@ class ConanLib(ConanFile):
         conanfile = conanfile.replace('"onesubfolder"', '"othersubfolder"')
         self.client.save({"conanfile.py": conanfile})
         self.client.run("create . user/channel")
-        folder = self.client.cache.source(self.ref)
+        folder = self.client.cache.package_layout(self.ref).source()
         self.assertIn("othersubfolder", os.listdir(folder))
         self.assertTrue(os.path.exists(os.path.join(folder, "othersubfolder", "myfile")))
 
@@ -114,10 +114,11 @@ class ConanLib(ConanFile):
         self.client.runner('git config user.name "Your Name"', cwd=repo)
         self.client.runner("git add .", cwd=repo)
         self.client.runner('git commit -m  "commiting"', cwd=repo)
-        self.client.runner('git clone "%s" .' % repo.replace('\\', '/'), cwd=self.client.current_folder)
+        self.client.runner('git clone "%s" .' % repo.replace('\\', '/'),
+                           cwd=self.client.current_folder)
         self.client.run("export . user/channel")
         self.assertIn("WARN: Repo origin looks like a local path", self.client.out)
-        os.remove(self.client.cache.scm_folder(self.ref))
+        os.remove(self.client.cache.package_layout(self.ref).scm_folder())
         self.client.run("install lib/0.1@user/channel --build")
         self.assertIn("lib/0.1@user/channel: Getting sources from url:", self.client.out)
 
@@ -133,7 +134,7 @@ class ConanLib(ConanFile):
 
         # Create the package, will copy the sources from the local folder
         self.client.run("create . user/channel")
-        sources_dir = self.client.cache.scm_folder(self.ref)
+        sources_dir = self.client.cache.package_layout(self.ref).scm_folder()
         self.assertEqual(load(sources_dir), curdir)
         self.assertIn("Repo origin deduced by 'auto': https://myrepo.com.git", self.client.out)
         self.assertIn("Revision deduced by 'auto'", self.client.out)
@@ -148,9 +149,10 @@ class ConanLib(ConanFile):
 
         # Export again but now with absolute reference, so no pointer file is created nor kept
         git = Git(curdir)
-        self.client.save({"conanfile.py": base_git.format(url=_quoted(curdir), revision=git.get_revision())})
+        self.client.save({"conanfile.py": base_git.format(url=_quoted(curdir),
+                                                          revision=git.get_revision())})
         self.client.run("create . user/channel")
-        sources_dir = self.client.cache.scm_folder(self.ref)
+        sources_dir = self.client.cache.package_layout(self.ref).scm_folder()
         self.assertFalse(os.path.exists(sources_dir))
         self.assertNotIn("Repo origin deduced by 'auto'", self.client.out)
         self.assertNotIn("Revision deduced by 'auto'", self.client.out)
@@ -169,7 +171,8 @@ class ConanLib(ConanFile):
         self.client.runner('git remote add origin https://myrepo.com.git', cwd=curdir)
         self.client.run("create . user/channel")
 
-        folder = self.client.cache.source(ConanFileReference.loads("lib/0.1@user/channel"))
+        ref = ConanFileReference.loads("lib/0.1@user/channel")
+        folder = self.client.cache.package_layout(ref).source()
         self.assertTrue(os.path.exists(os.path.join(folder, "mysub", "myfile.txt")))
         self.assertFalse(os.path.exists(os.path.join(folder, "mysub", "conanfile.py")))
 
@@ -185,7 +188,7 @@ class ConanLib(ConanFile):
 
         # Create the package
         self.client.run("create conan/ user/channel")
-        sources_dir = self.client.cache.scm_folder(self.ref)
+        sources_dir = self.client.cache.package_layout(self.ref).scm_folder()
         self.assertEqual(load(sources_dir), curdir.replace('\\', '/'))  # Root of git is 'curdir'
 
     def test_deleted_source_folder(self):
@@ -225,7 +228,7 @@ other_folder/excluded_subfolder
         self.assertIn("Copying sources to build folder", self.client.out)
         pref = PackageReference(ConanFileReference.loads("lib/0.1@user/channel"),
                                 NO_SETTINGS_PACKAGE_ID)
-        bf = self.client.cache.build(pref)
+        bf = self.client.cache.package_layout(pref.ref).build(pref)
         self.assertTrue(os.path.exists(os.path.join(bf, "myfile.txt")))
         self.assertTrue(os.path.exists(os.path.join(bf, "myfile")))
         self.assertTrue(os.path.exists(os.path.join(bf, ".git")))
@@ -368,7 +371,8 @@ class ConanLib(ConanFile):
         self.client.save({"conanfile.py": conanfile})
         self.client.run("create . user/channel")
 
-        folder = self.client.cache.source(ConanFileReference.loads("lib/0.1@user/channel"))
+        ref = ConanFileReference.loads("lib/0.1@user/channel")
+        folder = self.client.cache.package_layout(ref).source()
         submodule_path, _ = _relative_paths(folder)
         self.assertTrue(os.path.exists(os.path.join(folder, "myfile")))
         self.assertFalse(os.path.exists(os.path.join(submodule_path, "submodule")))
@@ -399,7 +403,8 @@ class ConanLib(ConanFile):
         self.client.save({"conanfile.py": conanfile})
         self.client.run("create . user/channel")
 
-        folder = self.client.cache.source(ConanFileReference.loads("lib/0.1@user/channel"))
+        ref = ConanFileReference.loads("lib/0.1@user/channel")
+        folder = self.client.cache.package_layout(ref).source()
         submodule_path, subsubmodule_path = _relative_paths(folder)
         self.assertTrue(os.path.exists(os.path.join(folder, "myfile")))
         self.assertTrue(os.path.exists(os.path.join(submodule_path, "submodule")))
@@ -410,7 +415,8 @@ class ConanLib(ConanFile):
         self.client.save({"conanfile.py": conanfile})
         self.client.run("create . user/channel")
 
-        folder = self.client.cache.source(ConanFileReference.loads("lib/0.1@user/channel"))
+        ref = ConanFileReference.loads("lib/0.1@user/channel")
+        folder = self.client.cache.package_layout(ref).source()
         submodule_path, subsubmodule_path = _relative_paths(folder)
         self.assertTrue(os.path.exists(os.path.join(folder, "myfile")))
         self.assertTrue(os.path.exists(os.path.join(submodule_path, "submodule")))
@@ -517,7 +523,7 @@ class MyLib(ConanFile):
 
         self.client.run("export . user/channel")
         ref = ConanFileReference.loads("issue/3831@user/channel")
-        exported_conanfile = self.client.cache.conanfile(ref)
+        exported_conanfile = self.client.cache.package_layout(ref).conanfile()
         content = load(exported_conanfile)
         self.assertIn(commit, content)
 
@@ -554,7 +560,7 @@ class MyLib(ConanFile):
 
         client.run("export . pkg/0.1@user/channel")
         ref = ConanFileReference.loads("pkg/0.1@user/channel")
-        exported_conanfile = client.cache.conanfile(ref)
+        exported_conanfile = client.cache.package_layout(ref).conanfile()
         content = load(exported_conanfile)
         self.assertIn(commit, content)
 
@@ -609,7 +615,8 @@ class ConanLib(ConanFile):
         conanfile = conanfile.replace('"onesubfolder"', '"othersubfolder"')
         self.client.save({"conanfile.py": conanfile})
         self.client.run("create . user/channel")
-        folder = self.client.cache.source(ConanFileReference.loads("lib/0.1@user/channel"))
+        ref = ConanFileReference.loads("lib/0.1@user/channel")
+        folder = self.client.cache.package_layout(ref).source()
         self.assertIn("othersubfolder", os.listdir(folder))
         self.assertTrue(os.path.exists(os.path.join(folder, "othersubfolder", "myfile")))
 
@@ -628,7 +635,7 @@ class ConanLib(ConanFile):
         curdir = self.client.current_folder.replace("\\", "/")
         # Create the package, will copy the sources from the local folder
         self.client.run("create . user/channel")
-        sources_dir = self.client.cache.scm_folder(self.ref)
+        sources_dir = self.client.cache.package_layout(self.ref).scm_folder()
         self.assertEqual(load(sources_dir), curdir)
         self.assertIn("Repo origin deduced by 'auto': {}".format(project_url).lower(),
                       str(self.client.out).lower())
@@ -641,7 +648,7 @@ class ConanLib(ConanFile):
         self.client.save({"conanfile.py": base_svn.format(url=_quoted(svn.get_remote_url()),
                                                           revision=svn.get_revision())})
         self.client.run("create . user/channel")
-        sources_dir = self.client.cache.scm_folder(self.ref)
+        sources_dir = self.client.cache.package_layout(self.ref).scm_folder()
         self.assertFalse(os.path.exists(sources_dir))
         self.assertNotIn("Repo origin deduced by 'auto'", self.client.out)
         self.assertNotIn("Revision deduced by 'auto'", self.client.out)
@@ -663,7 +670,8 @@ class ConanLib(ConanFile):
                                                             path=self.client.current_folder))
         self.client.run("create . user/channel")
 
-        folder = self.client.cache.source(ConanFileReference.loads("lib/0.1@user/channel"))
+        ref = ConanFileReference.loads("lib/0.1@user/channel")
+        folder = self.client.cache.package_layout(ref).source()
         self.assertTrue(os.path.exists(os.path.join(folder, "mysub", "myfile.txt")))
         self.assertFalse(os.path.exists(os.path.join(folder, "mysub", "conanfile.py")))
 
@@ -679,7 +687,7 @@ class ConanLib(ConanFile):
                                                             path=self.client.current_folder))
         self.client.run("create conan/ user/channel")
 
-        sources_dir = self.client.cache.scm_folder(self.ref)
+        sources_dir = self.client.cache.package_layout(self.ref).scm_folder()
         self.assertEqual(load(sources_dir), curdir.replace('\\', '/'))  # Root of git is 'curdir'
 
     def test_deleted_source_folder(self):
@@ -704,7 +712,7 @@ class ConanLib(ConanFile):
         self.assertIn("Copying sources to build folder", self.client.out)
         pref = PackageReference(ConanFileReference.loads("lib/0.1@user/channel"),
                                 NO_SETTINGS_PACKAGE_ID)
-        bf = self.client.cache.build(pref)
+        bf = self.client.cache.package_layout(pref.ref).build(pref)
         self.assertTrue(os.path.exists(os.path.join(bf, "myfile.txt")))
         self.assertTrue(os.path.exists(os.path.join(bf, "myfile")))
         self.assertTrue(os.path.exists(os.path.join(bf, ".svn")))
@@ -877,7 +885,7 @@ class SCMSVNWithLockedFilesTest(SVNLocalRepoTestCase):
         """ Apply svn:needs-lock property to every file in the own working-copy of the repository """
 
         conanfile = base_svn.format(directory="None", url=_quoted("auto"), revision="auto")
-        project_url, _ = self.create_project(files={"conanfile.py": conanfile,})
+        project_url, _ = self.create_project(files={"conanfile.py": conanfile})
         project_url = project_url.replace(" ", "%20")
 
         # Add property needs-lock to my own copy
diff --git a/conans/test/functional/tgz_macos_dot_files.py b/conans/test/functional/tgz_macos_dot_files.py
index 7ee6858d8..0ba25f218 100644
--- a/conans/test/functional/tgz_macos_dot_files.py
+++ b/conans/test/functional/tgz_macos_dot_files.py
@@ -96,7 +96,7 @@ class TgzMacosDotFilesTest(unittest.TestCase):
 
         # 3) In the upload process, the metadata is lost again
         ref = ConanFileReference.loads("lib/version@lasote/channel")
-        export_folder = t.cache.export(ref)
+        export_folder = t.cache.package_layout(ref).export()
         tgz = os.path.join(export_folder, EXPORT_SOURCES_TGZ_NAME)
         self.assertFalse(os.path.exists(tgz))
         t.run("upload lib/version@lasote/channel")
diff --git a/conans/test/integration/complete_test.py b/conans/test/integration/complete_test.py
index b8221a271..c22801aed 100644
--- a/conans/test/integration/complete_test.py
+++ b/conans/test/integration/complete_test.py
@@ -96,7 +96,7 @@ class CompleteFlowTest(unittest.TestCase):
         other_conan = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]})
         other_conan.run("install %s" % str(ref))
         # Build should be empty
-        build_path = other_conan.cache.build(pref)
+        build_path = other_conan.cache.package_layout(pref.ref).build(pref)
         self.assertFalse(os.path.exists(build_path))
         # Lib should exist
         self._assert_library_exists(pref, other_conan.cache)
diff --git a/conans/test/integration/devflow_test.py b/conans/test/integration/devflow_test.py
index 622601706..54e856f56 100644
--- a/conans/test/integration/devflow_test.py
+++ b/conans/test/integration/devflow_test.py
@@ -63,7 +63,7 @@ class DevInSourceFlowTest(unittest.TestCase):
         client.run("export-pkg . Pkg/0.1@lasote/testing -bf=../pkg")
 
         ref = ConanFileReference.loads("Pkg/0.1@lasote/testing")
-        cache_package_folder = client.cache.packages(ref)
+        cache_package_folder = client.cache.package_layout(ref).packages()
         cache_package_folder = os.path.join(cache_package_folder,
                                             os.listdir(cache_package_folder)[0])
         self._assert_pkg(cache_package_folder)
@@ -86,7 +86,7 @@ class DevInSourceFlowTest(unittest.TestCase):
         client.run("export-pkg . Pkg/0.1@lasote/testing -bf='%s' -if=." % package_folder)
 
         ref = ConanFileReference.loads("Pkg/0.1@lasote/testing")
-        cache_package_folder = client.cache.packages(ref)
+        cache_package_folder = client.cache.package_layout(ref).packages()
         cache_package_folder = os.path.join(cache_package_folder,
                                             os.listdir(cache_package_folder)[0])
         self._assert_pkg(cache_package_folder)
@@ -114,7 +114,7 @@ class DevInSourceFlowTest(unittest.TestCase):
         client.run("export-pkg .. Pkg/0.1@lasote/testing --source-folder=.. ")
 
         ref = ConanFileReference.loads("Pkg/0.1@lasote/testing")
-        cache_package_folder = client.cache.packages(ref)
+        cache_package_folder = client.cache.package_layout(ref).packages()
         cache_package_folder = os.path.join(cache_package_folder,
                                             os.listdir(cache_package_folder)[0])
         self._assert_pkg(cache_package_folder)
@@ -177,7 +177,7 @@ class DevOutSourceFlowTest(unittest.TestCase):
         client.run("export-pkg . Pkg/0.1@lasote/testing -bf=../build/package")
 
         ref = ConanFileReference.loads("Pkg/0.1@lasote/testing")
-        cache_package_folder = client.cache.packages(ref)
+        cache_package_folder = client.cache.package_layout(ref).packages()
         cache_package_folder = os.path.join(cache_package_folder,
                                             os.listdir(cache_package_folder)[0])
         self._assert_pkg(cache_package_folder)
@@ -200,7 +200,7 @@ class DevOutSourceFlowTest(unittest.TestCase):
         client.run("export-pkg . Pkg/0.1@lasote/testing -bf=./pkg")
 
         ref = ConanFileReference.loads("Pkg/0.1@lasote/testing")
-        cache_package_folder = client.cache.packages(ref)
+        cache_package_folder = client.cache.package_layout(ref).packages()
         cache_package_folder = os.path.join(cache_package_folder,
                                             os.listdir(cache_package_folder)[0])
         self._assert_pkg(cache_package_folder)
@@ -227,7 +227,7 @@ class DevOutSourceFlowTest(unittest.TestCase):
         client.run("export-pkg . Pkg/0.1@lasote/testing -bf=./build")
 
         ref = ConanFileReference.loads("Pkg/0.1@lasote/testing")
-        cache_package_folder = client.cache.packages(ref)
+        cache_package_folder = client.cache.package_layout(ref).packages()
         cache_package_folder = os.path.join(cache_package_folder,
                                             os.listdir(cache_package_folder)[0])
         self._assert_pkg(cache_package_folder)
diff --git a/conans/test/integration/export_sources_test.py b/conans/test/integration/export_sources_test.py
index 6acbb6957..8b4157fa9 100644
--- a/conans/test/integration/export_sources_test.py
+++ b/conans/test/integration/export_sources_test.py
@@ -78,10 +78,10 @@ class ExportsSourcesTest(unittest.TestCase):
         self.client = client
         self.ref = ConanFileReference.loads("Hello/0.1@lasote/testing")
         self.pref = PackageReference(self.ref, NO_SETTINGS_PACKAGE_ID)
-        self.source_folder = self.client.cache.source(self.ref)
-        self.package_folder = self.client.cache.package(self.pref)
-        self.export_folder = self.client.cache.export(self.ref)
-        self.export_sources_folder = self.client.cache.export_sources(self.ref)
+        self.source_folder = self.client.cache.package_layout(self.ref).source()
+        self.package_folder = self.client.cache.package_layout(self.ref).package(self.pref)
+        self.export_folder = self.client.cache.package_layout(self.ref).export()
+        self.export_sources_folder = self.client.cache.package_layout(self.ref).export_sources()
 
     def _check_source_folder(self, mode):
         """ Source folder MUST be always the same
@@ -263,8 +263,8 @@ class ExportsSourcesTest(unittest.TestCase):
 
         # new copied package data
         ref = ConanFileReference.loads("Hello/0.1@lasote/stable")
-        source_folder = self.client.cache.source(ref)
-        export_folder = self.client.cache.export(ref)
+        source_folder = self.client.cache.package_layout(ref).source()
+        export_folder = self.client.cache.package_layout(ref).export()
 
         self.client.run("copy Hello/0.1@lasote/testing lasote/stable")
         self._check_export_folder(mode, export_folder)
diff --git a/conans/test/integration/go_complete_test.py b/conans/test/integration/go_complete_test.py
index 9ee60ef83..2bed41e6f 100644
--- a/conans/test/integration/go_complete_test.py
+++ b/conans/test/integration/go_complete_test.py
@@ -122,7 +122,7 @@ class GoCompleteTest(unittest.TestCase):
         other_conan = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]})
         other_conan.run("install %s --build missing" % str(ref))
         # Build should be empty
-        build_path = other_conan.cache.build(pref)
+        build_path = other_conan.cache.package_layout(pref.ref).build(pref)
         self.assertFalse(os.path.exists(build_path))
         # Lib should exist
         self._assert_package_exists(pref, other_conan.cache, files_without_conanfile)
diff --git a/conans/test/integration/hook_test.py b/conans/test/integration/hook_test.py
index 389e637d9..a6722f378 100644
--- a/conans/test/integration/hook_test.py
+++ b/conans/test/integration/hook_test.py
@@ -170,8 +170,8 @@ class HookTest(unittest.TestCase):
                                  "complete_hook.py")
         client.save({hook_path: complete_hook, "conanfile.py": conanfile_basic})
         conanfile_path = os.path.join(client.current_folder, "conanfile.py")
-        conanfile_cache_path = client.cache.conanfile(
-            ConanFileReference("basic", "0.1", "danimtb", "testing"))
+        conanfile_cache_path = client.cache.package_layout(
+            ConanFileReference("basic", "0.1", "danimtb", "testing")).conanfile()
         client.run("config set hooks.complete_hook/complete_hook.py")
 
         client.run("source .")
diff --git a/conans/test/integration/install_outdated_test.py b/conans/test/integration/install_outdated_test.py
index 38f280945..25ce4da7d 100644
--- a/conans/test/integration/install_outdated_test.py
+++ b/conans/test/integration/install_outdated_test.py
@@ -81,7 +81,7 @@ class InstallOutdatedPackagesTest(unittest.TestCase):
         self.client.run("upload Hello0/0.1@lasote/stable")
 
         # Now, with the new_client, remove only the binary package from Hello0
-        rmdir(new_client.cache.packages(self.ref))
+        rmdir(new_client.cache.package_layout(self.ref).packages())
         # And try to install Hello1 again, should not complain because the remote
         # binary is in the "same version" than local cached Hello0
         new_client.run("install Hello1/0.1@lasote/stable --build outdated")
@@ -121,7 +121,7 @@ class InstallOutdatedPackagesTest(unittest.TestCase):
         self.client.run("upload Hello0/0.1@lasote/stable")
 
         # Now, with the new_client, remove only the binary package from Hello0
-        rmdir(new_client.cache.packages(self.ref))
+        rmdir(new_client.cache.package_layout(self.ref).packages())
         # And try to install Hello1 again, should not complain because the remote
         # binary is in the "same version" than local cached Hello0
         new_client.run("install Hello1/0.1@lasote/stable --build outdated --build Hello1")
diff --git a/conans/test/integration/install_selected_packages_test.py b/conans/test/integration/install_selected_packages_test.py
index 8bdeff6d2..3cbadf153 100644
--- a/conans/test/integration/install_selected_packages_test.py
+++ b/conans/test/integration/install_selected_packages_test.py
@@ -21,34 +21,35 @@ class InstallSelectedPackagesTest(unittest.TestCase):
     def install_all_test(self):
         # Should retrieve the three packages
         self.new_client.run("download Hello0/0.1@lasote/stable")
-        p1 = os.path.join(self.new_client.cache.packages(self.ref))
+        p1 = os.path.join(self.new_client.cache.package_layout(self.ref).packages())
         packages = os.listdir(p1)
         self.assertEqual(len(packages), 3)
 
     def install_some_reference_test(self):
         # Should retrieve the specified packages
         self.new_client.run("download Hello0/0.1@lasote/stable -p %s" % self.package_ids[0])
-        packages = os.listdir(self.new_client.cache.packages(self.ref))
+        packages = os.listdir(self.new_client.cache.package_layout(self.ref).packages())
         self.assertEqual(len(packages), 1)
         self.assertEqual(packages[0], self.package_ids[0])
 
         self.new_client.run("download Hello0/0.1@lasote/stable -p %s -p %s" % (self.package_ids[0],
                                                                                self.package_ids[1]))
-        packages = os.listdir(self.new_client.cache.packages(self.ref))
+        packages = os.listdir(self.new_client.cache.package_layout(self.ref).packages())
         self.assertEqual(len(packages), 2)
 
     def download_recipe_twice_test(self):
         expected_conanfile_contents = self.files[CONANFILE]
         self.new_client.run("download Hello0/0.1@lasote/stable")
-        got_conanfile = load(os.path.join(self.new_client.cache.export(self.ref), CONANFILE))
+        conanfile_path = self.new_client.cache.package_layout(self.ref).conanfile()
+        got_conanfile = load(conanfile_path)
         self.assertEqual(expected_conanfile_contents, got_conanfile)
 
         self.new_client.run("download Hello0/0.1@lasote/stable")
-        got_conanfile = load(os.path.join(self.new_client.cache.export(self.ref), CONANFILE))
+        got_conanfile = load(conanfile_path)
         self.assertEqual(expected_conanfile_contents, got_conanfile)
 
         self.new_client.run("download Hello0/0.1@lasote/stable")
-        got_conanfile = load(os.path.join(self.new_client.cache.export(self.ref), CONANFILE))
+        got_conanfile = load(conanfile_path)
         self.assertEqual(expected_conanfile_contents, got_conanfile)
 
     def download_packages_twice_test(self):
@@ -99,4 +100,4 @@ class InstallSelectedPackagesTest(unittest.TestCase):
         client.run("install Hello0/0.1@lasote/stable -s os=Linux -s compiler=gcc -s "
                    "compiler.version=4.6 -s compiler.libcxx=libstdc++ --build missing")
         client.run("upload  Hello0/0.1@lasote/stable --all")
-        return os.listdir(self.client.cache.packages(self.ref))
+        return os.listdir(self.client.cache.package_layout(self.ref).packages())
diff --git a/conans/test/integration/install_update_test.py b/conans/test/integration/install_update_test.py
index 7a0bf51f1..b8dde39e1 100644
--- a/conans/test/integration/install_update_test.py
+++ b/conans/test/integration/install_update_test.py
@@ -174,7 +174,7 @@ class Pkg(ConanFile):
 
         ref = ConanFileReference.loads("Hello0/1.0@lasote/stable")
         pref = PackageReference(ref, "55a3af76272ead64e6f543c12ecece30f94d3eda")
-        export_folder = self.client.cache.export(ref)
+        export_folder = self.client.cache.package_layout(ref).export()
         recipe_manifest = os.path.join(export_folder, CONAN_MANIFEST)
         package_folder = self.client.cache.package(pref)
         package_manifest = os.path.join(package_folder, CONAN_MANIFEST)
diff --git a/conans/test/integration/manifest_validation_test.py b/conans/test/integration/manifest_validation_test.py
index 5cf69f612..d82923ed5 100644
--- a/conans/test/integration/manifest_validation_test.py
+++ b/conans/test/integration/manifest_validation_test.py
@@ -1,4 +1,5 @@
 import os
+import platform
 import unittest
 
 from parameterized.parameterized import parameterized
@@ -118,6 +119,21 @@ class ConsumerFileTest(ConanFile):
         self.assertIn("Manifest for 'Hello/0.1@lasote/stable': OK", self.client.user_io.out)
         self.assertIn("Manifest for '%s': OK" % str(pref), self.client.user_io.out)
 
+    @unittest.skipUnless(platform.system() == "Windows", "Only Windows with shortpaths")
+    def capture_verify_short_paths_manifest_test(self):
+        conanfile = """from conans import ConanFile
+
+class ConanFileTest(ConanFile):
+    name = "Hello"
+    version = "0.1"
+    exports = "*"
+    short_paths = True
+"""
+        self.files = {CONANFILE: conanfile, "data.txt": "MyData"}
+        self.client.save(self.files)
+        self.client.run("export . lasote/stable")
+        self._capture_verify_manifest("Hello/0.1@lasote/stable")
+
     def capture_verify_manifest_test(self):
         self._capture_verify_manifest("Hello/0.1@lasote/stable")
 
@@ -239,11 +255,11 @@ class ConanFileTest(ConanFile):
         client.save(self.files)
         client.run("export . lasote/stable")
         client.run("install Hello/0.1@lasote/stable --build=missing")
-        info = os.path.join(client.cache.package(pref), "conaninfo.txt")
+        package_folder_path = client.cache.package_layout(pref.ref).package(pref)
+        info = os.path.join(package_folder_path, "conaninfo.txt")
         info_content = load(info)
         info_content += "# Dummy string"
         save(info, info_content)
-        package_folder_path = client.cache.package(pref)
         manifest = FileTreeManifest.load(package_folder_path)
         manifest.file_sums["conaninfo.txt"] = md5(info_content)
         manifest.save(package_folder_path)
@@ -284,7 +300,7 @@ class ConanFileTest(ConanFile):
         self.assertIn("ERROR: Do not specify both", self.client.user_io.out)
 
     def test_corrupted_recipe(self):
-        export_path = self.client.cache.export(self.ref)
+        export_path = self.client.cache.package_layout(self.ref).export()
         file_path = os.path.join(export_path, "data.txt")
         save(file_path, "BAD CONTENT")
 
@@ -296,7 +312,7 @@ class ConanFileTest(ConanFile):
     def test_corrupted_package(self):
         self.client.run("install %s --build missing" % str(self.ref))
         pref = PackageReference.loads("Hello/0.1@lasote/stable:%s" % NO_SETTINGS_PACKAGE_ID)
-        package_path = self.client.cache.package(pref)
+        package_path = self.client.cache.package_layout(pref.ref).package(pref)
         file_path = os.path.join(package_path, "conaninfo.txt")
         save(file_path, load(file_path) + "  ")
 
diff --git a/conans/test/integration/only_source_test.py b/conans/test/integration/only_source_test.py
index 2f200035d..27ea09b98 100644
--- a/conans/test/integration/only_source_test.py
+++ b/conans/test/integration/only_source_test.py
@@ -158,8 +158,8 @@ class MyPackage(ConanFile):
         client.run("export . lasote/stable")
         client.run("install %s --build missing" % str(ref))
 
-        self.assertTrue(os.path.exists(client.cache.builds(ref)))
-        self.assertTrue(os.path.exists(client.cache.packages(ref)))
+        self.assertTrue(os.path.exists(client.cache.package_layout(ref).builds()))
+        self.assertTrue(os.path.exists(client.cache.package_layout(ref).packages()))
 
         # Upload
         client.run("upload %s --all" % str(ref))
@@ -167,28 +167,28 @@ class MyPackage(ConanFile):
         # Now from other "computer" install the uploaded conans with same options (nothing)
         other_conan = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]})
         other_conan.run("install %s --build missing" % str(ref))
-        self.assertFalse(os.path.exists(other_conan.cache.builds(ref)))
-        self.assertTrue(os.path.exists(other_conan.cache.packages(ref)))
+        self.assertFalse(os.path.exists(other_conan.cache.package_layout(ref).builds()))
+        self.assertTrue(os.path.exists(other_conan.cache.package_layout(ref).packages()))
 
         # Now from other "computer" install the uploaded conans with same options (nothing)
         other_conan = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]})
         other_conan.run("install %s --build" % str(ref))
-        self.assertTrue(os.path.exists(other_conan.cache.builds(ref)))
-        self.assertTrue(os.path.exists(other_conan.cache.packages(ref)))
+        self.assertTrue(os.path.exists(other_conan.cache.package_layout(ref).builds()))
+        self.assertTrue(os.path.exists(other_conan.cache.package_layout(ref).packages()))
 
         # Use an invalid pattern and check that its not builded from source
         other_conan = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]})
         other_conan.run("install %s --build HelloInvalid" % str(ref))
         self.assertIn("No package matching 'HelloInvalid' pattern", other_conan.user_io.out)
-        self.assertFalse(os.path.exists(other_conan.cache.builds(ref)))
-        # self.assertFalse(os.path.exists(other_conan.cache.packages(ref)))
+        self.assertFalse(os.path.exists(other_conan.cache.package_layout(ref).builds()))
+        # self.assertFalse(os.path.exists(other_conan.cache.package_layout(ref).packages()))
 
         # Use another valid pattern and check that its not builded from source
         other_conan = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]})
         other_conan.run("install %s --build HelloInvalid -b Hello" % str(ref))
         self.assertIn("No package matching 'HelloInvalid' pattern", other_conan.user_io.out)
-        # self.assertFalse(os.path.exists(other_conan.cache.builds(ref)))
-        # self.assertFalse(os.path.exists(other_conan.cache.packages(ref)))
+        # self.assertFalse(os.path.exists(other_conan.cache.package_layout(ref).builds()))
+        # self.assertFalse(os.path.exists(other_conan.cache.package_layout(ref).packages()))
 
         # Now even if the package is in local store, check that's rebuilded
         other_conan.run("install %s -b Hello*" % str(ref))
diff --git a/conans/test/integration/package_id_test.py b/conans/test/integration/package_id_test.py
index 95e84293f..817480f0e 100644
--- a/conans/test/integration/package_id_test.py
+++ b/conans/test/integration/package_id_test.py
@@ -296,7 +296,7 @@ class Pkg(ConanFile):
                             ' --build missing')
 
             ref = ConanFileReference.loads("Hello/1.2.0@user/testing")
-            pkg = os.listdir(self.client.cache.packages(ref))
+            pkg = os.listdir(self.client.cache.package_layout(ref).packages())
             pref = PackageReference(ref, pkg[0])
             pkg_folder = self.client.cache.package(pref)
             return ConanInfo.loads(load(os.path.join(pkg_folder, CONANINFO)))
@@ -348,7 +348,7 @@ class Pkg(ConanFile):
                         ' -s arch_build="x86"'
                         ' --build missing')
         ref = ConanFileReference.loads("Hello/1.2.0@user/testing")
-        pkg = os.listdir(self.client.cache.packages(ref))
+        pkg = os.listdir(self.client.cache.package_layout(ref).packages())
         pref = PackageReference(ref, pkg[0])
         pkg_folder = self.client.cache.package(pref)
         info = ConanInfo.loads(load(os.path.join(pkg_folder, CONANINFO)))
diff --git a/conans/test/integration/settings_override_test.py b/conans/test/integration/settings_override_test.py
index 0413981b9..d667c5524 100644
--- a/conans/test/integration/settings_override_test.py
+++ b/conans/test/integration/settings_override_test.py
@@ -35,13 +35,13 @@ class SettingsOverrideTest(unittest.TestCase):
         self.assertIn("COMPILER=> VisualBuild Visual Studio", self.client.user_io.out)
 
         # CHECK CONANINFO FILE
-        packs_dir = self.client.cache.packages(ConanFileReference.loads("MinGWBuild/0.1@lasote/testing"))
+        packs_dir = self.client.cache.package_layout(ConanFileReference.loads("MinGWBuild/0.1@lasote/testing")).packages()
         pack_dir = os.path.join(packs_dir, os.listdir(packs_dir)[0])
         conaninfo = load(os.path.join(pack_dir, CONANINFO))
         self.assertIn("compiler=gcc", conaninfo)
 
         # CHECK CONANINFO FILE
-        packs_dir = self.client.cache.packages(ConanFileReference.loads("VisualBuild/0.1@lasote/testing"))
+        packs_dir = self.client.cache.package_layout(ConanFileReference.loads("VisualBuild/0.1@lasote/testing")).packages()
         pack_dir = os.path.join(packs_dir, os.listdir(packs_dir)[0])
         conaninfo = load(os.path.join(pack_dir, CONANINFO))
         self.assertIn("compiler=Visual Studio", conaninfo)
diff --git a/conans/test/integration/symlinks_test.py b/conans/test/integration/symlinks_test.py
index 192ad139e..4792a0cb6 100644
--- a/conans/test/integration/symlinks_test.py
+++ b/conans/test/integration/symlinks_test.py
@@ -45,7 +45,7 @@ class SymLinksTest(unittest.TestCase):
     def _check(self, client, ref, build=True):
         folders = [client.cache.package(ref), client.current_folder]
         if build:
-            folders.append(client.cache.build(ref))
+            folders.append(client.cache.package_layout(ref.ref).build(ref))
         for base in folders:
             filepath = os.path.join(base, "file1.txt")
             link = os.path.join(base, "file1.txt.1")
@@ -128,12 +128,12 @@ class TestConan(ConanFile):
         pref = PackageReference(ref, NO_SETTINGS_PACKAGE_ID)
         team_pref = PackageReference(team_ref, NO_SETTINGS_PACKAGE_ID)
 
-        for folder in [client.cache.export(ref),
-                       client.cache.source(ref),
-                       client.cache.build(pref),
-                       client.cache.package(pref),
-                       client.cache.export(team_ref),
-                       client.cache.package(team_pref)]:
+        for folder in [client.cache.package_layout(ref).export(),
+                       client.cache.package_layout(ref).source(),
+                       client.cache.package_layout(ref).build(pref),
+                       client.cache.package_layout(ref).package(pref),
+                       client.cache.package_layout(team_ref).export(),
+                       client.cache.package_layout(team_ref).package(team_pref)]:
             exported_lib = os.path.join(folder, lib_name)
             exported_link = os.path.join(folder, link_name)
             self.assertEqual(os.readlink(exported_link), lib_name)
@@ -183,7 +183,7 @@ class ConanSymlink(ConanFile):
             os.symlink(symlinked_path, symlink_path)
             client.run("export . danimtb/testing")
             ref = ConanFileReference("ConanSymlink", "3.0.0", "danimtb", "testing")
-            export_sources = client.cache.export_sources(ref)
+            export_sources = client.cache.package_layout(ref).export_sources()
             cache_other_dir = os.path.join(export_sources, "another_other_directory")
             cache_src = os.path.join(export_sources, "src")
             cache_main = os.path.join(cache_src, "main.cpp")
@@ -216,10 +216,10 @@ class ConanSymlink(ConanFile):
         os.symlink(symlinked_path, symlink_path)
         client.run("create . danimtb/testing")
         ref = ConanFileReference("ConanSymlink", "3.0.0", "danimtb", "testing")
-        cache_file = os.path.join(client.cache.export_sources(ref), "another_directory",
+        cache_file = os.path.join(client.cache.package_layout(ref).export_sources(), "another_directory",
                                   "not_to_copy.txt")
         self.assertTrue(os.path.exists(cache_file))
-        cache_other_dir = os.path.join(client.cache.export_sources(ref),
+        cache_other_dir = os.path.join(client.cache.package_layout(ref).export_sources(),
                                        "another_other_directory")
         self.assertTrue(os.path.exists(cache_other_dir))
         pref = PackageReference(ref, NO_SETTINGS_PACKAGE_ID)
diff --git a/conans/test/integration/system_reqs_test.py b/conans/test/integration/system_reqs_test.py
index 1c299b2b0..46bbb0b54 100644
--- a/conans/test/integration/system_reqs_test.py
+++ b/conans/test/integration/system_reqs_test.py
@@ -34,9 +34,9 @@ class SystemReqsTest(unittest.TestCase):
         client.run("install Test/0.1@user/channel")
         self.assertNotIn("*+Running system requirements+*", client.user_io.out)
         ref = ConanFileReference.loads("Test/0.1@user/channel")
-        pfs = client.cache.packages(ref)
+        pfs = client.cache.package_layout(ref).packages()
         pid = os.listdir(pfs)[0]
-        reqs_file = client.cache.system_reqs_package(PackageReference(ref, pid))
+        reqs_file = client.cache.package_layout(ref).system_reqs_package(PackageReference(ref, pid))
         os.unlink(reqs_file)
         client.run("install Test/0.1@user/channel")
         self.assertIn("*+Running system requirements+*", client.user_io.out)
@@ -62,35 +62,37 @@ class SystemReqsTest(unittest.TestCase):
         client.run("install Test/0.1@user/testing --build missing")
         self.assertIn("*+Running system requirements+*", client.user_io.out)
         ref = ConanFileReference.loads("Test/0.1@user/testing")
-        self.assertFalse(os.path.exists(client.cache.system_reqs(ref)))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).system_reqs()))
         pref = PackageReference(ref, "f0ba3ca2c218df4a877080ba99b65834b9413798")
-        load_file = load(client.cache.system_reqs_package(pref))
+        load_file = load(client.cache.package_layout(ref).system_reqs_package(pref))
         self.assertIn("Installed my stuff", load_file)
 
         # Run again
         client.run("install Test/0.1@user/testing --build missing")
         self.assertNotIn("*+Running system requirements+*", client.user_io.out)
-        self.assertFalse(os.path.exists(client.cache.system_reqs(ref)))
-        load_file = load(client.cache.system_reqs_package(pref))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).system_reqs()))
+        load_file = load(client.cache.package_layout(ref).system_reqs_package(pref))
         self.assertIn("Installed my stuff", load_file)
 
         # Run with different option
         client.run("install Test/0.1@user/testing -o myopt=False --build missing")
         self.assertIn("*+Running system requirements+*", client.user_io.out)
-        self.assertFalse(os.path.exists(client.cache.system_reqs(ref)))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).system_reqs()))
         pref2 = PackageReference(ref, NO_SETTINGS_PACKAGE_ID)
-        load_file = load(client.cache.system_reqs_package(pref2))
+        load_file = load(client.cache.package_layout(ref).system_reqs_package(pref2))
         self.assertIn("Installed my stuff", load_file)
 
         # remove packages
         client.run("remove Test* -f -p 544")
-        self.assertTrue(os.path.exists(client.cache.system_reqs_package(pref)))
+        layout1 = client.cache.package_layout(pref.ref)
+        layout2 = client.cache.package_layout(pref2.ref)
+        self.assertTrue(os.path.exists(layout1.system_reqs_package(pref)))
         client.run("remove Test* -f -p f0ba3ca2c218df4a877080ba99b65834b9413798")
-        self.assertFalse(os.path.exists(client.cache.system_reqs_package(pref)))
-        self.assertTrue(os.path.exists(client.cache.system_reqs_package(pref2)))
+        self.assertFalse(os.path.exists(layout1.system_reqs_package(pref)))
+        self.assertTrue(os.path.exists(layout2.system_reqs_package(pref2)))
         client.run("remove Test* -f -p %s" % NO_SETTINGS_PACKAGE_ID)
-        self.assertFalse(os.path.exists(client.cache.system_reqs_package(pref)))
-        self.assertFalse(os.path.exists(client.cache.system_reqs_package(pref2)))
+        self.assertFalse(os.path.exists(layout1.system_reqs_package(pref)))
+        self.assertFalse(os.path.exists(layout2.system_reqs_package(pref2)))
 
     def global_test(self):
         client = TestClient()
@@ -104,31 +106,31 @@ class SystemReqsTest(unittest.TestCase):
         self.assertIn("*+Running system requirements+*", client.user_io.out)
         ref = ConanFileReference.loads("Test/0.1@user/testing")
         pref = PackageReference(ref, "a527106fd9f2e3738a55b02087c20c0a63afce9d")
-        self.assertFalse(os.path.exists(client.cache.system_reqs_package(pref)))
-        load_file = load(client.cache.system_reqs(ref))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).system_reqs_package(pref)))
+        load_file = load(client.cache.package_layout(ref).system_reqs())
         self.assertIn("Installed my stuff", load_file)
 
         # Run again
         client.run("install Test/0.1@user/testing --build missing")
         self.assertNotIn("*+Running system requirements+*", client.user_io.out)
-        self.assertFalse(os.path.exists(client.cache.system_reqs_package(pref)))
-        load_file = load(client.cache.system_reqs(ref))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).system_reqs_package(pref)))
+        load_file = load(client.cache.package_layout(ref).system_reqs())
         self.assertIn("Installed my stuff", load_file)
 
         # Run with different option
         client.run("install Test/0.1@user/testing -o myopt=False --build missing")
         self.assertNotIn("*+Running system requirements+*", client.user_io.out)
         pref2 = PackageReference(ref, "54c9626b48cefa3b819e64316b49d3b1e1a78c26")
-        self.assertFalse(os.path.exists(client.cache.system_reqs_package(pref)))
-        self.assertFalse(os.path.exists(client.cache.system_reqs_package(pref2)))
-        load_file = load(client.cache.system_reqs(ref))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).system_reqs_package(pref)))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).system_reqs_package(pref2)))
+        load_file = load(client.cache.package_layout(ref).system_reqs())
         self.assertIn("Installed my stuff", load_file)
 
         # remove packages
         client.run("remove Test* -f -p")
-        self.assertFalse(os.path.exists(client.cache.system_reqs_package(pref)))
-        self.assertFalse(os.path.exists(client.cache.system_reqs_package(pref2)))
-        self.assertFalse(os.path.exists(client.cache.system_reqs(ref)))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).system_reqs_package(pref)))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).system_reqs_package(pref2)))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).system_reqs()))
 
     def wrong_output_test(self):
         client = TestClient()
@@ -141,9 +143,9 @@ class SystemReqsTest(unittest.TestCase):
         client.run("install Test/0.1@user/testing --build missing")
         self.assertIn("*+Running system requirements+*", client.user_io.out)
         ref = ConanFileReference.loads("Test/0.1@user/testing")
-        self.assertFalse(os.path.exists(client.cache.system_reqs(ref)))
+        self.assertFalse(os.path.exists(client.cache.package_layout(ref).system_reqs()))
         pref = PackageReference(ref, "f0ba3ca2c218df4a877080ba99b65834b9413798")
-        load_file = load(client.cache.system_reqs_package(pref))
+        load_file = load(client.cache.package_layout(pref.ref).system_reqs_package(pref))
         self.assertEqual('', load_file)
 
     def remove_system_reqs_test(self):
@@ -178,19 +180,20 @@ class SystemReqsTest(unittest.TestCase):
     def invalid_remove_reqs_test(self):
         client = TestClient()
 
-        with six.assertRaisesRegex(self,
-                Exception, "ERROR: Please specify a valid package reference to be cleaned"):
+        with six.assertRaisesRegex(self, Exception,
+                                   "ERROR: Please specify a valid package reference to be cleaned"):
             client.run("remove --system-reqs")
 
         # wrong file reference should be treated as error
-        with six.assertRaisesRegex(self,
-                Exception, "ERROR: Unable to remove system_reqs: foo/version@bar/testing does not exist"):
+        with six.assertRaisesRegex(self, Exception, "ERROR: Unable to remove system_reqs: "
+                                   "foo/version@bar/testing does not exist"):
             client.run("remove --system-reqs foo/version@bar/testing")
 
         # package is not supported with system_reqs
-        with six.assertRaisesRegex(self,
-                Exception, "ERROR: '-t' and '-p' parameters can't be used at the same time"):
-            client.run("remove --system-reqs foo/bar@foo/bar -p f0ba3ca2c218df4a877080ba99b65834b9413798")
+        with six.assertRaisesRegex(self, Exception, "ERROR: '-t' and '-p' parameters "
+                                   "can't be used at the same time"):
+            client.run("remove --system-reqs foo/bar@foo/bar "
+                       "-p f0ba3ca2c218df4a877080ba99b65834b9413798")
 
     def permission_denied_remove_system_reqs_test(self):
         ref = ConanFileReference.loads("Test/0.1@user/channel")
@@ -210,8 +213,7 @@ class SystemReqsTest(unittest.TestCase):
         os.chmod(system_reqs_path, current & ~stat.S_IWRITE)
 
         # friendly message for permission error
-        with six.assertRaisesRegex(self,
-                Exception, "ERROR: Unable to remove system_reqs:"):
+        with six.assertRaisesRegex(self, Exception, "ERROR: Unable to remove system_reqs:"):
             client.run("remove --system-reqs Test/0.1@user/channel")
         self.assertTrue(os.path.exists(system_reqs_path))
 
diff --git a/conans/test/unittests/client/build/msbuild_test.py b/conans/test/unittests/client/build/msbuild_test.py
index 6d7193883..6822c4791 100644
--- a/conans/test/unittests/client/build/msbuild_test.py
+++ b/conans/test/unittests/client/build/msbuild_test.py
@@ -8,6 +8,7 @@ import six
 from parameterized import parameterized
 
 from conans.client import tools
+from conans.client.tools.files import chdir
 from conans.client.build.msbuild import MSBuild
 from conans.errors import ConanException
 from conans.model.version import Version
@@ -152,6 +153,36 @@ class MSBuildTest(unittest.TestCase):
         command = msbuild.get_command("project_should_flags_test_file.sln")
         self.assertIn('/p:PlatformToolset="%s"' % expected_toolset, command)
 
+    @unittest.skipUnless(platform.system() == "Windows", "Requires MSBuild")
+    def skip_toolset_test(self):
+        settings = MockSettings({"build_type": "Debug",
+                                 "compiler": "Visual Studio",
+                                 "compiler.version": "15",
+                                 "arch": "x86_64"})
+
+        class Runner(object):
+
+            def __init__(self):
+                self.commands = []
+
+            def __call__(self, *args, **kwargs):
+                self.commands.append(args[0])
+
+        with chdir(tools.mkdir_tmp()):
+            runner = Runner()
+            conanfile = MockConanfile(settings, runner=runner)
+            msbuild = MSBuild(conanfile)
+            msbuild.build("myproject", toolset=False)
+            self.assertEqual(len(runner.commands), 1)
+            self.assertNotIn("PlatformToolset", runner.commands[0])
+
+            runner = Runner()
+            conanfile = MockConanfile(settings, runner=runner)
+            msbuild = MSBuild(conanfile)
+            msbuild.build("myproject", toolset="mytoolset")
+            self.assertEqual(len(runner.commands), 1)
+            self.assertIn('/p:PlatformToolset="mytoolset"', runner.commands[0])
+
     @parameterized.expand([("v142",),
                            ("v141",),
                            ("v140",),
diff --git a/conans/test/unittests/client/cache_test.py b/conans/test/unittests/client/cache_test.py
index 7fc0f027a..5f859241b 100644
--- a/conans/test/unittests/client/cache_test.py
+++ b/conans/test/unittests/client/cache_test.py
@@ -27,12 +27,12 @@ class CacheTest(unittest.TestCase):
         layout = self.cache.package_layout(self.ref)
         self.assertFalse(layout.recipe_exists())
 
-        mkdir(self.cache.export(self.ref))
+        mkdir(layout.export())
         self.assertTrue(layout.recipe_exists())
 
         # But if ref has revision and it doesn't match, it doesn't exist
-        save(os.path.join(self.cache.base_folder(self.ref), "metadata.json"),
-             PackageMetadata().dumps())
+        with layout.update_metadata() as metadata:
+            metadata.clear()
 
         ref2 = self.ref.copy_with_rev("revision")
         layout2 = self.cache.package_layout(ref2)
@@ -49,8 +49,8 @@ class CacheTest(unittest.TestCase):
         layout = self.cache.package_layout(self.ref)
         self.assertFalse(layout.package_exists(pref))
 
-        mkdir(self.cache.export(self.ref))
-        mkdir(self.cache.package(pref))
+        mkdir(layout.export())
+        mkdir(layout.package(pref))
         save(os.path.join(self.cache.base_folder(self.ref), "metadata.json"),
              PackageMetadata().dumps())
 
diff --git a/conans/test/unittests/model/settings_test.py b/conans/test/unittests/model/settings_test.py
index a85ee6c3c..670bceabe 100644
--- a/conans/test/unittests/model/settings_test.py
+++ b/conans/test/unittests/model/settings_test.py
@@ -25,6 +25,66 @@ class SettingsLoadsTest(unittest.TestCase):
         self.assertTrue(settings.os == "Windows")
         self.assertEqual("os=Windows", settings.values.dumps())
 
+    def test_any(self):
+        yml = "os: ANY"
+        settings = Settings.loads(yml)
+        with six.assertRaisesRegex(self, ConanException, "'settings.os' value not defined"):
+            settings.validate()  # Raise exception if unset
+        settings.os = "None"
+        settings.validate()
+        self.assertTrue(settings.os == "None")
+        self.assertEqual("os=None", settings.values.dumps())
+        settings.os = "Windows"
+        self.assertTrue(settings.os == "Windows")
+        self.assertEqual("os=Windows", settings.values.dumps())
+
+    def test_none_any(self):
+        yml = "os: [None, ANY]"
+        settings = Settings.loads(yml)
+        settings.validate()
+        settings.os = "None"
+        settings.validate()
+        self.assertTrue(settings.os == "None")
+        self.assertEqual("os=None", settings.values.dumps())
+        settings.os = "Windows"
+        self.assertTrue(settings.os == "Windows")
+        self.assertEqual("os=Windows", settings.values.dumps())
+
+    def test_windows_linux_remove(self):
+        yml = "os: [Windows, Linux]"
+        settings = Settings.loads(yml)
+        settings.os = "Windows"
+        settings.os.remove("Linux")
+        # removing a definition which is not contained shall not raise an exception
+        settings.os.remove("invalid")
+        settings.os.remove("ANY")
+        with six.assertRaisesRegex(self, ConanException, "Invalid setting 'Windows'"):
+            settings.os.remove("Windows")
+
+    def test_none_any_remove(self):
+        yml = "os: [None, ANY]"
+        settings = Settings.loads(yml)
+        settings.os = "Windows"
+        # removing a definition which is not contained shall not raise an exception
+        settings.os.remove("invalid")
+        with six.assertRaisesRegex(self, ConanException, "Invalid setting 'Windows'"):
+            settings.os.remove("ANY")
+
+        settings = Settings.loads(yml)
+        settings.os = "None"
+        settings.os.remove("ANY")  # "None" is still valid
+        with six.assertRaisesRegex(self, ConanException, "Invalid setting 'None'"):
+            settings.os.remove("None")  # "None" is not valid anymore
+
+    def test_any_remove(self):
+        yml = "os: ANY"
+        settings = Settings.loads(yml)
+        settings.os = "Windows"
+        # removing a definition which is not contained shall not raise an exception
+        settings.os.remove("invalid")
+        with six.assertRaisesRegex(self, ConanException, "Invalid setting 'Windows'"):
+            settings.os.remove("ANY")
+
     def getattr_none_test(self):
         yml = "os: [None, Windows]"
         settings = Settings.loads(yml)
@@ -71,7 +131,7 @@ class SettingsLoadsTest(unittest.TestCase):
     Windows:
 """
         with six.assertRaisesRegex(self, ConanException,
-                                     "settings.yml: None setting can't have subsettings"):
+                                   "settings.yml: None setting can't have subsettings"):
             Settings.loads(yml)
 
 
@@ -210,8 +270,8 @@ compiler:
 os: [Windows, Linux]
 """)
         settings.values_list = [('compiler', 'Visual Studio'),
-                          ('compiler.version', '10'),
-                          ('compiler.version.arch', '32')]
+                                ('compiler.version', '10'),
+                                ('compiler.version.arch', '32')]
         self.assertEqual(settings.values_list,
                          [('compiler', 'Visual Studio'),
                           ('compiler.version', '10'),
@@ -282,19 +342,18 @@ os: [Windows, Linux]
         with self.assertRaises(ConanException) as cm:
             self.sut.constraint(s2)
         self.assertEqual(str(cm.exception), str(undefined_field("settings.compiler", "version2",
-                                                            ['runtime', 'version'])))
+                                                                ['runtime', 'version'])))
         self.sut.os = "Windows"
 
     def constraint6_test(self):
         s2 = {"os": None,
               "compiler": {"Visual Studio": {"version": None}}}
-
         self.sut.constraint(s2)
         self.sut.compiler = "Visual Studio"
         with self.assertRaises(ConanException) as cm:
             self.sut.compiler.arch
         self.assertEqual(str(cm.exception), str(undefined_field("settings.compiler", "arch",
-                                                            ['version'], "Visual Studio")))
+                                                                ['version'], "Visual Studio")))
         self.sut.os = "Windows"
         self.sut.compiler.version = "11"
         self.sut.compiler.version = "12"
@@ -320,16 +379,18 @@ os: [Windows, Linux]
             self.sut.validate()
 
         self.sut.compiler = "gcc"
-        with six.assertRaisesRegex(self, ConanException, str(undefined_value("settings.compiler.arch"))):
+        with six.assertRaisesRegex(self, ConanException,
+                                   str(undefined_value("settings.compiler.arch"))):
             self.sut.validate()
 
         self.sut.compiler.arch = "x86"
         with six.assertRaisesRegex(self, ConanException,
-                                     str(undefined_value("settings.compiler.arch.speed"))):
+                                   str(undefined_value("settings.compiler.arch.speed"))):
             self.sut.validate()
 
         self.sut.compiler.arch.speed = "A"
-        with six.assertRaisesRegex(self, ConanException, str(undefined_value("settings.compiler.version"))):
+        with six.assertRaisesRegex(self, ConanException,
+                                   str(undefined_value("settings.compiler.version"))):
             self.sut.validate()
 
         self.sut.compiler.version = "4.8"
@@ -339,28 +400,30 @@ os: [Windows, Linux]
         self.sut.os = "Windows"
         self.sut.validate()
         self.assertEqual(self.sut.values_list, [("compiler", "gcc"),
-                                           ("compiler.arch", "x86"),
-                                           ("compiler.arch.speed", "A"),
-                                           ("compiler.version", "4.8"),
-                                           ("os", "Windows")])
+                                                ("compiler.arch", "x86"),
+                                                ("compiler.arch.speed", "A"),
+                                                ("compiler.version", "4.8"),
+                                                ("os", "Windows")])
 
     def validate2_test(self):
         self.sut.os = "Windows"
         self.sut.compiler = "Visual Studio"
-        with six.assertRaisesRegex(self, ConanException, str(undefined_value("settings.compiler.runtime"))):
+        with six.assertRaisesRegex(self, ConanException,
+                                   str(undefined_value("settings.compiler.runtime"))):
             self.sut.validate()
 
         self.sut.compiler.runtime = "MD"
-        with six.assertRaisesRegex(self, ConanException, str(undefined_value("settings.compiler.version"))):
+        with six.assertRaisesRegex(self, ConanException,
+                                   str(undefined_value("settings.compiler.version"))):
             self.sut.validate()
 
         self.sut.compiler.version = "10"
         self.sut.validate()
 
         self.assertEqual(self.sut.values_list, [("compiler", "Visual Studio"),
-                                            ("compiler.runtime", "MD"),
-                                            ("compiler.version", "10"),
-                                            ("os", "Windows")])
+                                                ("compiler.runtime", "MD"),
+                                                ("compiler.version", "10"),
+                                                ("os", "Windows")])
 
     def basic_test(self):
         s = Settings({"os": ["Windows", "Linux"]})
@@ -386,7 +449,7 @@ os: [Windows, Linux]
             self.sut.compiler.kk
         self.assertEqual(str(cm.exception),
                          str(undefined_field("settings.compiler", "kk", "['runtime', 'version']",
-                                         "Visual Studio")))
+                                             "Visual Studio")))
 
         self.assertEqual(self.sut.compiler.version, None)
 
@@ -420,7 +483,7 @@ os: [Windows, Linux]
             self.sut.compiler.runtime
         self.assertEqual(str(cm.exception),
                          str(undefined_field("settings.compiler", "runtime", "['arch', 'version']",
-                                         "gcc")))
+                                             "gcc")))
 
         self.sut.compiler.arch = "x86"
         self.sut.compiler.arch.speed = "A"
diff --git a/conans/test/utils/tools.py b/conans/test/utils/tools.py
index 278e8e6f6..cae335990 100644
--- a/conans/test/utils/tools.py
+++ b/conans/test/utils/tools.py
@@ -66,7 +66,7 @@ ARTIFACTORY_DEFAULT_URL = os.getenv("ARTIFACTORY_DEFAULT_URL", "http://localhost
 
 def inc_recipe_manifest_timestamp(cache, reference, inc_time):
     ref = ConanFileReference.loads(reference)
-    path = cache.export(ref)
+    path = cache.package_layout(ref).export()
     manifest = FileTreeManifest.load(path)
     manifest.time += inc_time
     manifest.save(path)