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

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git


The following commit(s) were added to refs/heads/master by this push:
     new 3f9fec2307 [MNG-8026] Maven drives regarding scopes (#1391)
3f9fec2307 is described below

commit 3f9fec2307aee199eedfa3e46b1b83b54eaa276a
Author: Tamas Cservenak <[email protected]>
AuthorDate: Mon Feb 5 10:42:51 2024 +0100

    [MNG-8026] Maven drives regarding scopes (#1391)
    
    Changes:
    * new types for build path, path scope, dependency scope, language
    * introduce "extensible enum" and provides registries, SPI providers, etc...
    ---------
    Co-authored-by: Guillaume Nodet <[email protected]>
---
 .../main/java/org/apache/maven/api/Dependency.java |  10 +-
 .../org/apache/maven/api/DependencyCoordinate.java |   2 +-
 .../java/org/apache/maven/api/DependencyScope.java | 128 +++++++++++++++++++++
 ...pendencyCoordinate.java => ExtensibleEnum.java} |  30 ++---
 .../java/org/apache/maven/api/ExtensibleEnums.java | 100 ++++++++++++++++
 .../{DependencyCoordinate.java => Language.java}   |  35 +++---
 .../{DependencyProperties.java => Packaging.java}  |  34 +++---
 .../main/java/org/apache/maven/api/PathScope.java  |  84 ++++++++++++++
 .../main/java/org/apache/maven/api/Project.java    |  12 +-
 .../maven/api/{Scope.java => ProjectScope.java}    |  63 ++++------
 .../java/org/apache/maven/api/ResolutionScope.java |  97 ----------------
 .../main/java/org/apache/maven/api/Session.java    |  21 +++-
 .../src/main/java/org/apache/maven/api/Type.java   |  36 ++----
 .../DependencyCoordinateFactoryRequest.java        |   2 +-
 .../maven/api/services/DependencyResolver.java     |  14 +--
 .../api/services/DependencyResolverRequest.java    |  41 ++++---
 ...peRegistry.java => ExtensibleEnumRegistry.java} |  28 ++---
 .../{TypeRegistry.java => LanguageRegistry.java}   |  25 +---
 .../{TypeRegistry.java => PackagingRegistry.java}  |  25 +---
 .../{TypeRegistry.java => PathScopeRegistry.java}  |  25 +---
 ...TypeRegistry.java => ProjectScopeRegistry.java} |  24 +---
 .../apache/maven/api/services/TypeRegistry.java    |   5 +-
 .../maven/api/spi/ExtensibleEnumProvider.java}     |  31 +----
 .../apache/maven/api/spi/LanguageProvider.java}    |  34 +-----
 .../apache/maven/api/spi/PathScopeProvider.java}   |  34 +-----
 .../maven/api/spi/ProjectScopeProvider.java}       |  34 +-----
 .../maven/artifact/handler/ArtifactHandler.java    |   4 +
 .../manager/DefaultArtifactHandlerManager.java     |  10 +-
 .../maven/internal/aether/TypeRegistryAdapter.java |   7 +-
 .../maven/internal/impl/AbstractSession.java       |  34 +++++-
 .../maven/internal/impl/DefaultDependency.java     |  18 +--
 .../internal/impl/DefaultDependencyCoordinate.java |   7 +-
 .../internal/impl/DefaultDependencyProperties.java |  66 -----------
 .../internal/impl/DefaultDependencyResolver.java   |  26 ++---
 .../internal/impl/DefaultPackagingRegistry.java    |  73 ++++++++++++
 .../apache/maven/internal/impl/DefaultProject.java |  13 ++-
 .../apache/maven/internal/impl/DefaultType.java    |  54 ++++++---
 .../maven/internal/impl/DefaultTypeRegistry.java   |  29 ++---
 .../internal/impl/ExtensibleEnumRegistries.java    |  92 +++++++++++++++
 .../maven/internal/impl/types/BomTypeProvider.java |   4 +-
 .../maven/internal/impl/types/EarTypeProvider.java |  10 +-
 .../internal/impl/types/EjbClientTypeProvider.java |  10 +-
 .../maven/internal/impl/types/EjbTypeProvider.java |  10 +-
 .../maven/internal/impl/types/JarTypeProvider.java |  10 +-
 .../impl/types/JavaSourceTypeProvider.java         |   4 +-
 .../internal/impl/types/JavadocTypeProvider.java   |  10 +-
 .../impl/types/MavenPluginTypeProvider.java        |  10 +-
 .../maven/internal/impl/types/ParTypeProvider.java |  10 +-
 .../maven/internal/impl/types/PomTypeProvider.java |   4 +-
 .../maven/internal/impl/types/RarTypeProvider.java |  10 +-
 .../internal/impl/types/TestJarTypeProvider.java   |  10 +-
 .../maven/internal/impl/types/WarTypeProvider.java |  10 +-
 .../maven/AbstractCoreMavenComponentTestCase.java  |   3 +-
 .../org/apache/maven/internal/impl/TestApi.java    |  10 +-
 .../internal/scopes/MavenDependencyScopes.java     |  20 ++--
 55 files changed, 807 insertions(+), 745 deletions(-)

diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/Dependency.java 
b/api/maven-api-core/src/main/java/org/apache/maven/api/Dependency.java
index efad1415ad..b64fffc0d5 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/Dependency.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Dependency.java
@@ -30,16 +30,8 @@ public interface Dependency extends Artifact {
     @Nonnull
     Type getType();
 
-    /**
-     * The dependency properties.
-     *
-     * @return the dependency properties, never {@code null}
-     */
-    @Nonnull
-    DependencyProperties getDependencyProperties();
-
     @Nonnull
-    Scope getScope();
+    DependencyScope getScope();
 
     boolean isOptional();
 
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
 
b/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
index 7ba4bd1ec7..c0295bfaa0 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
+++ 
b/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
@@ -41,7 +41,7 @@ public interface DependencyCoordinate extends 
ArtifactCoordinate {
     Type getType();
 
     @Nonnull
-    Scope getScope();
+    DependencyScope getScope();
 
     @Nullable
     Boolean getOptional();
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyScope.java 
b/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyScope.java
new file mode 100644
index 0000000000..2b4d410064
--- /dev/null
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyScope.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Immutable;
+import org.apache.maven.api.annotations.Nonnull;
+
+/**
+ * Dependency scope.
+ * This represents at which time the dependency will be used, for example, at 
compile time only,
+ * at run time or at test time.  For a given dependency, the scope is directly 
derived from the
+ * {@link org.apache.maven.api.model.Dependency#getScope()} and will be used 
when using {@link PathScope}
+ * and the {@link org.apache.maven.api.services.DependencyResolver}.
+ *
+ * @since 4.0.0
+ * @see org.apache.maven.api.model.Dependency#getScope()
+ * @see org.apache.maven.api.services.DependencyResolver
+ */
+@Experimental
+@Immutable
+public enum DependencyScope {
+
+    /**
+     * None. Allows you to declare dependencies (for example to alter reactor 
build order) but in reality dependencies
+     * in this scope are not part of any path scope.
+     */
+    NONE("none", false),
+
+    /**
+     * Empty scope.
+     */
+    EMPTY("", false),
+
+    /**
+     * Compile only.
+     */
+    COMPILE_ONLY("compile-only", false),
+
+    /**
+     * Compile, runtime and test.
+     */
+    COMPILE("compile", true),
+
+    /**
+     * Runtime and test.
+     */
+    RUNTIME("runtime", true),
+
+    /**
+     * Provided.
+     */
+    PROVIDED("provided", false),
+
+    /**
+     * Test compile only.
+     */
+    TEST_ONLY("test-only", false),
+
+    /**
+     * Test compile and test runtime.
+     */
+    TEST("test", false),
+
+    /**
+     * Test runtime.
+     */
+    TEST_RUNTIME("test-runtime", true),
+
+    /**
+     * System scope.
+     * <p>
+     * Important: this scope {@code id} MUST BE KEPT in sync with label in
+     * {@code org.eclipse.aether.util.artifact.Scopes#SYSTEM}.
+     */
+    SYSTEM("system", false);
+
+    private static final Map<String, DependencyScope> IDS = 
Collections.unmodifiableMap(
+            Stream.of(DependencyScope.values()).collect(Collectors.toMap(s -> 
s.id, s -> s)));
+
+    public static DependencyScope forId(String id) {
+        return IDS.get(id);
+    }
+
+    private final String id;
+    private final boolean transitive;
+
+    DependencyScope(String id, boolean transitive) {
+        this.id = id;
+        this.transitive = transitive;
+    }
+
+    /**
+     * The {@code id} uniquely represents a value for this extensible enum.
+     * This id should be used to compute the equality and hash code for the 
instance.
+     *
+     * @return the id
+     */
+    @Nonnull
+    public String id() {
+        return id;
+    }
+
+    public boolean isTransitive() {
+        return transitive;
+    }
+}
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
 b/api/maven-api-core/src/main/java/org/apache/maven/api/ExtensibleEnum.java
similarity index 64%
copy from 
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
copy to 
api/maven-api-core/src/main/java/org/apache/maven/api/ExtensibleEnum.java
index 7ba4bd1ec7..87d80075dd 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/ExtensibleEnum.java
@@ -18,34 +18,20 @@
  */
 package org.apache.maven.api;
 
-import java.util.Collection;
-
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Immutable;
 import org.apache.maven.api.annotations.Nonnull;
-import org.apache.maven.api.annotations.Nullable;
 
 /**
- *
- * @since 4.0.0
+ * Implementation must have {@code equals()} and {@code hashCode()} 
implemented, so implementations of this interface
+ * can be used as keys.
  */
-@Experimental
-@Immutable
-public interface DependencyCoordinate extends ArtifactCoordinate {
+public interface ExtensibleEnum {
+
     /**
-     * The type of the artifact.
+     * The {@code id} uniquely represents a value for this extensible enum.
+     * This id should be used to compute the equality and hash code for the 
instance.
      *
-     * @return the type
+     * @return the id
      */
     @Nonnull
-    Type getType();
-
-    @Nonnull
-    Scope getScope();
-
-    @Nullable
-    Boolean getOptional();
-
-    @Nonnull
-    Collection<Exclusion> getExclusions();
+    String id();
 }
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/ExtensibleEnums.java 
b/api/maven-api-core/src/main/java/org/apache/maven/api/ExtensibleEnums.java
new file mode 100644
index 0000000000..7843cbef70
--- /dev/null
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/ExtensibleEnums.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api;
+
+import java.util.*;
+
+abstract class ExtensibleEnums {
+
+    static Language language(String id) {
+        return new DefaultLanguage(id);
+    }
+
+    static PathScope pathScope(String id, ProjectScope projectScope, 
DependencyScope... dependencyScopes) {
+        return new DefaultPathScope(id, projectScope, dependencyScopes);
+    }
+
+    static ProjectScope projectScope(String id) {
+        return new DefaultProjectScope(id);
+    }
+
+    private static class DefaultExtensibleEnum implements ExtensibleEnum {
+
+        private final String id;
+
+        DefaultExtensibleEnum(String id) {
+            this.id = Objects.requireNonNull(id);
+        }
+
+        public String id() {
+            return id;
+        }
+
+        @Override
+        public int hashCode() {
+            return id().hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return obj != null && getClass() == obj.getClass() && 
id().equals(((DefaultExtensibleEnum) obj).id());
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "[" + id() + "]";
+        }
+    }
+
+    private static class DefaultPathScope extends DefaultExtensibleEnum 
implements PathScope {
+        private final ProjectScope projectScope;
+        private final Set<DependencyScope> dependencyScopes;
+
+        DefaultPathScope(String id, ProjectScope projectScope, 
DependencyScope... dependencyScopes) {
+            super(id);
+            this.projectScope = Objects.requireNonNull(projectScope);
+            this.dependencyScopes =
+                    Collections.unmodifiableSet(new 
HashSet<>(Arrays.asList(Objects.requireNonNull(dependencyScopes))));
+        }
+
+        @Override
+        public ProjectScope projectScope() {
+            return projectScope;
+        }
+
+        @Override
+        public Set<DependencyScope> dependencyScopes() {
+            return dependencyScopes;
+        }
+    }
+
+    private static class DefaultProjectScope extends DefaultExtensibleEnum 
implements ProjectScope {
+
+        DefaultProjectScope(String id) {
+            super(id);
+        }
+    }
+
+    private static class DefaultLanguage extends DefaultExtensibleEnum 
implements Language {
+
+        DefaultLanguage(String id) {
+            super(id);
+        }
+    }
+}
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
 b/api/maven-api-core/src/main/java/org/apache/maven/api/Language.java
similarity index 53%
copy from 
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
copy to api/maven-api-core/src/main/java/org/apache/maven/api/Language.java
index 7ba4bd1ec7..42aede9d89 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Language.java
@@ -18,34 +18,33 @@
  */
 package org.apache.maven.api;
 
-import java.util.Collection;
-
 import org.apache.maven.api.annotations.Experimental;
 import org.apache.maven.api.annotations.Immutable;
-import org.apache.maven.api.annotations.Nonnull;
-import org.apache.maven.api.annotations.Nullable;
+
+import static org.apache.maven.api.ExtensibleEnums.language;
 
 /**
+ * Language.
+ * <p>
+ * This extensible enum has two defined values, {@link #NONE} and {@link 
#JAVA_FAMILY},
+ * but can be extended by registering a {@code 
org.apache.maven.api.spi.LanguageProvider}.
+ * <p>
+ * Implementation must have {@code equals()} and {@code hashCode()} 
implemented, so implementations of this interface
+ * can be used as keys.
  *
  * @since 4.0.0
  */
 @Experimental
 @Immutable
-public interface DependencyCoordinate extends ArtifactCoordinate {
+@SuppressWarnings("checkstyle:InterfaceIsType")
+public interface Language extends ExtensibleEnum {
+
     /**
-     * The type of the artifact.
-     *
-     * @return the type
+     * The "none" language. It is not versioned, family is same to itself, and 
compatible with itself only.
+     * In turn, every {@link Language} implementation must be compatible with 
{@code NONE} language.
      */
-    @Nonnull
-    Type getType();
-
-    @Nonnull
-    Scope getScope();
-
-    @Nullable
-    Boolean getOptional();
+    Language NONE = language("none");
 
-    @Nonnull
-    Collection<Exclusion> getExclusions();
+    // TODO: this should be moved out from here to Java Support (builtin into 
core)
+    Language JAVA_FAMILY = language("java");
 }
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java
 b/api/maven-api-core/src/main/java/org/apache/maven/api/Packaging.java
similarity index 54%
rename from 
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java
rename to api/maven-api-core/src/main/java/org/apache/maven/api/Packaging.java
index 9f63416848..b64d1e0705 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyProperties.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Packaging.java
@@ -18,42 +18,38 @@
  */
 package org.apache.maven.api;
 
-import java.util.Map;
-
 import org.apache.maven.api.annotations.Experimental;
 import org.apache.maven.api.annotations.Immutable;
 import org.apache.maven.api.annotations.Nonnull;
 
 /**
- * Dependency properties supported by Maven Core.
+ * Interface representing a Maven project packaging.
+ * <p>
+ * TODO: define how to plug in new packaging definitions using the SPI.
+ *   the packaging are currently defined by Maven 3 {@code 
Provider<LifecycleMapping>}
  *
  * @since 4.0.0
  */
 @Experimental
 @Immutable
-public interface DependencyProperties {
-    /**
-     * Boolean flag telling that dependency contains all of its dependencies. 
Value of this key should be parsed with
-     * {@link Boolean#parseBoolean(String)} to obtain value.
-     * <p>
-     * <em>Important: this flag must be kept in sync with resolver! (as is 
used during collection)</em>
-     */
-    String FLAG_INCLUDES_DEPENDENCIES = "includesDependencies";
-
+public interface Packaging extends ExtensibleEnum {
     /**
-     * Boolean flag telling that dependency is meant to be placed on class 
path. Value of this key should be parsed with
-     * {@link Boolean#parseBoolean(String)} to obtain value.
+     * The packaging id.
      */
-    String FLAG_CLASS_PATH_CONSTITUENT = "classPathConstituent";
+    @Nonnull
+    String id();
 
     /**
-     * Returns immutable "map view" of all the properties.
+     * The language of this packaging.
      */
     @Nonnull
-    Map<String, String> asMap();
+    default Language language() {
+        return getType().getLanguage();
+    }
 
     /**
-     * Returns {@code true} if given flag is {@code true}.
+     * The type of main artifact produced by this packaging.
      */
-    boolean checkFlag(@Nonnull String flag);
+    @Nonnull
+    Type getType();
 }
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/PathScope.java 
b/api/maven-api-core/src/main/java/org/apache/maven/api/PathScope.java
new file mode 100644
index 0000000000..35a63b0240
--- /dev/null
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/PathScope.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.api;
+
+import java.util.*;
+
+import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Immutable;
+import org.apache.maven.api.annotations.Nonnull;
+
+import static org.apache.maven.api.ExtensibleEnums.pathScope;
+
+/**
+ * Path scope.
+ * A path scope is used to determine the kind of build or class path that will 
be built when resolving
+ * dependencies using the {@link 
org.apache.maven.api.services.DependencyResolver} service.
+ * <p>
+ * This extensible enum has four defined values, {@link #MAIN_COMPILE}, {@link 
#MAIN_RUNTIME},
+ * {@link #TEST_COMPILE} and {@link #TEST_RUNTIME}, but can be extended by 
registering a
+ * {@code org.apache.maven.api.spi.PathScopeProvider}.
+ * <p>
+ * Implementation must have {@code equals()} and {@code hashCode()} 
implemented, so implementations of this interface
+ * can be used as keys.
+ *
+ * @since 4.0.0
+ * @see org.apache.maven.api.services.DependencyResolver
+ * @see DependencyScope
+ */
+@Experimental
+@Immutable
+public interface PathScope extends ExtensibleEnum {
+
+    @Nonnull
+    ProjectScope projectScope();
+
+    @Nonnull
+    Set<DependencyScope> dependencyScopes();
+
+    PathScope MAIN_COMPILE = pathScope(
+            "main-compile",
+            ProjectScope.MAIN,
+            DependencyScope.EMPTY,
+            DependencyScope.COMPILE_ONLY,
+            DependencyScope.COMPILE,
+            DependencyScope.PROVIDED);
+
+    PathScope MAIN_RUNTIME = pathScope(
+            "main-runtime", ProjectScope.MAIN, DependencyScope.EMPTY, 
DependencyScope.COMPILE, DependencyScope.RUNTIME);
+
+    PathScope TEST_COMPILE = pathScope(
+            "test-compile",
+            ProjectScope.TEST,
+            DependencyScope.EMPTY,
+            DependencyScope.COMPILE,
+            DependencyScope.PROVIDED,
+            DependencyScope.TEST_ONLY,
+            DependencyScope.TEST);
+
+    PathScope TEST_RUNTIME = pathScope(
+            "test-runtime",
+            ProjectScope.TEST,
+            DependencyScope.EMPTY,
+            DependencyScope.COMPILE,
+            DependencyScope.RUNTIME,
+            DependencyScope.PROVIDED,
+            DependencyScope.TEST,
+            DependencyScope.TEST_RUNTIME);
+}
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java 
b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java
index 1b448f9bc3..948bb25612 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java
@@ -76,7 +76,17 @@ public interface Project {
      * @see #getArtifacts()
      */
     @Nonnull
-    String getPackaging();
+    Packaging getPackaging();
+
+    /**
+     * Returns the project language. It is by default determined by {@link 
#getPackaging()}.
+     *
+     * @see #getPackaging()
+     */
+    @Nonnull
+    default Language getLanguage() {
+        return getPackaging().language();
+    }
 
     /**
      * Returns the project POM artifact, which is the artifact of the POM of 
this project. Every project have a POM
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Scope.java 
b/api/maven-api-core/src/main/java/org/apache/maven/api/ProjectScope.java
similarity index 50%
rename from api/maven-api-core/src/main/java/org/apache/maven/api/Scope.java
rename to 
api/maven-api-core/src/main/java/org/apache/maven/api/ProjectScope.java
index 624293c1e9..1a4cd3da08 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/Scope.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/ProjectScope.java
@@ -18,49 +18,36 @@
  */
 package org.apache.maven.api;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import org.apache.maven.api.annotations.Experimental;
+import org.apache.maven.api.annotations.Immutable;
+
+import static org.apache.maven.api.ExtensibleEnums.projectScope;
 
 /**
- * Scope for a dependency
+ * Project scope.
+ * Defines the type of source files to compile, usually either the one that 
compose the output package
+ * (i.e. the <i>main</i> artifact) or the ones that will be used when building 
<i>tests</i>).
+ * <p>
+ * This extensible enum has two defined values, {@link #MAIN} and {@link 
#TEST},
+ * but can be extended by registering a {@code 
org.apache.maven.api.spi.ProjectScopeProvider}.
+ * <p>
+ * Implementation must have {@code equals()} and {@code hashCode()} 
implemented, so implementations of this interface
+ * can be used as keys.
  *
  * @since 4.0.0
  */
 @Experimental
-public enum Scope {
-    EMPTY(""),
-    COMPILE_ONLY("compile-only"),
-    COMPILE("compile"),
-    RUNTIME("runtime"),
-    PROVIDED("provided"),
-    TEST_COMPILE_ONLY("test-compile-only"),
-    TEST("test"),
-    TEST_RUNTIME("test-runtime"),
-    IMPORT("import"); // TODO: v4: remove import scope somehow
-
-    private final String id;
-
-    private static final Map<String, Scope> SCOPES;
-
-    static {
-        Map<String, Scope> scopes = new HashMap<>();
-        for (Scope s : Scope.values()) {
-            scopes.put(s.id, s);
-        }
-        SCOPES = scopes;
-    }
-
-    Scope(String id) {
-        this.id = id;
-    }
-
-    public String id() {
-        return this.id;
-    }
-
-    public static Scope get(String scope) {
-        return SCOPES.get(scope);
-    }
+@Immutable
+@SuppressWarnings("checkstyle:InterfaceIsType")
+public interface ProjectScope extends ExtensibleEnum {
+
+    /**
+     * Main scope.
+     */
+    ProjectScope MAIN = projectScope("main");
+
+    /**
+     * Test scope.
+     */
+    ProjectScope TEST = projectScope("test");
 }
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/ResolutionScope.java 
b/api/maven-api-core/src/main/java/org/apache/maven/api/ResolutionScope.java
deleted file mode 100644
index 7d003694d6..0000000000
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/ResolutionScope.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.api;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import org.apache.maven.api.annotations.Experimental;
-
-/**
- * Dependencies resolution scopes available before
- * <a 
href="/ref/current/maven-core/apidocs/org/apache/maven/lifecycle/internal/MojoExecutor.html">mojo
 execution</a>.
- *
- * Important note: The {@code id} values of this enum correspond to constants 
of
- * {@code org.apache.maven.artifact.Artifact} class and MUST BE KEPT IN SYNC.
- *
- * @since 4.0.0
- */
-@Experimental
-public enum ResolutionScope {
-    /**
-     * <code>compile</code> resolution scope
-     * = <code>compile-only</code> + <code>compile</code> + 
<code>provided</code> dependencies
-     */
-    PROJECT_COMPILE("project-compile", Scope.EMPTY, Scope.COMPILE_ONLY, 
Scope.COMPILE, Scope.PROVIDED),
-    /**
-     * <code>runtime</code> resolution scope
-     * = <code>compile</code> + <code>runtime</code> dependencies
-     */
-    PROJECT_RUNTIME("project-runtime", Scope.EMPTY, Scope.COMPILE, 
Scope.RUNTIME),
-    /**
-     * <code>test-compile</code> resolution scope
-     * = <code>compile-only</code> + <code>compile</code> + 
<code>provided</code> + <code>test-compile-only</code> + <code>test</code>
-     * dependencies
-     */
-    TEST_COMPILE(
-            "test-compile",
-            Scope.EMPTY,
-            Scope.COMPILE_ONLY,
-            Scope.COMPILE,
-            Scope.PROVIDED,
-            Scope.TEST_COMPILE_ONLY,
-            Scope.TEST),
-    /**
-     * <code>test</code> resolution scope
-     * = <code>compile</code> + <code>runtime</code> + <code>provided</code> + 
<code>test</code> + <code>test-runtime</code>
-     * dependencies
-     */
-    TEST_RUNTIME(
-            "test-runtime", Scope.EMPTY, Scope.COMPILE, Scope.RUNTIME, 
Scope.PROVIDED, Scope.TEST, Scope.TEST_RUNTIME);
-
-    private static final Map<String, ResolutionScope> VALUES =
-            
Stream.of(ResolutionScope.values()).collect(Collectors.toMap(ResolutionScope::id,
 s -> s));
-
-    public static ResolutionScope fromString(String id) {
-        return Optional.ofNullable(VALUES.get(id))
-                .orElseThrow(() -> new IllegalArgumentException("Unknown 
resolution scope " + id));
-    }
-
-    private final String id;
-    private final Set<Scope> scopes;
-
-    ResolutionScope(String id, Scope... scopes) {
-        this.id = id;
-        this.scopes = Collections.unmodifiableSet(new 
HashSet<>(Arrays.asList(scopes)));
-    }
-
-    public String id() {
-        return this.id;
-    }
-
-    public Set<Scope> scopes() {
-        return scopes;
-    }
-}
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java 
b/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java
index 65d4798c7c..4f414fe1fe 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Session.java
@@ -385,6 +385,9 @@ public interface Session {
      * Checks whether a given artifact version is considered a {@code 
SNAPSHOT} or not.
      * <p>
      * Shortcut for {@code getService(ArtifactManager.class).isSnapshot(...)}.
+     * <p>
+     * In case there is {@link Artifact} in scope, the recommended way to 
perform this check is
+     * use of {@link Artifact#isSnapshot()} instead.
      *
      * @see org.apache.maven.api.services.VersionParser#isSnapshot(String)
      */
@@ -424,11 +427,11 @@ public interface Session {
     /**
      * Shortcut for {@code getService(DependencyResolver.class).flatten(...)}.
      *
-     * @see org.apache.maven.api.services.DependencyResolver#flatten(Session, 
Node, ResolutionScope)
+     * @see org.apache.maven.api.services.DependencyResolver#flatten(Session, 
Node, PathScope)
      * @throws org.apache.maven.api.services.DependencyResolverException if 
the dependency flattening failed
      */
     @Nonnull
-    List<Node> flattenDependencies(@Nonnull Node node, @Nonnull 
ResolutionScope scope);
+    List<Node> flattenDependencies(@Nonnull Node node, @Nonnull PathScope 
scope);
 
     @Nonnull
     List<Path> resolveDependencies(@Nonnull DependencyCoordinate 
dependencyCoordinate);
@@ -437,7 +440,7 @@ public interface Session {
     List<Path> resolveDependencies(@Nonnull List<DependencyCoordinate> 
dependencyCoordinates);
 
     @Nonnull
-    List<Path> resolveDependencies(@Nonnull Project project, @Nonnull 
ResolutionScope scope);
+    List<Path> resolveDependencies(@Nonnull Project project, @Nonnull 
PathScope scope);
 
     /**
      * Resolves an artifact's meta version (if any) to a concrete version. For 
example, resolves "1.0-SNAPSHOT"
@@ -498,4 +501,16 @@ public interface Session {
      */
     @Nonnull
     VersionConstraint parseVersionConstraint(@Nonnull String 
versionConstraint);
+
+    Type requireType(String id);
+
+    Language requireLanguage(String id);
+
+    Packaging requirePackaging(String id);
+
+    ProjectScope requireProjectScope(String id);
+
+    DependencyScope requireDependencyScope(String id);
+
+    PathScope requirePathScope(String id);
 }
diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Type.java 
b/api/maven-api-core/src/main/java/org/apache/maven/api/Type.java
index 15ffc0b59a..45a46fd1a1 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/Type.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Type.java
@@ -30,21 +30,17 @@ import org.apache.maven.api.model.Dependency;
  * <p>
  * It provides information about the file type (or extension) of the 
associated artifact,
  * its default classifier, and how the artifact will be used in the build when 
creating
- * classpaths.
+ * various build paths.
  * <p>
  * For example, the type {@code java-source} has a {@code jar} extension and a
  * {@code sources} classifier. The artifact and its dependencies should be 
added
- * to the classpath.
+ * to the build path.
  *
  * @since 4.0.0
  */
 @Experimental
 @Immutable
-public interface Type {
-
-    String LANGUAGE_NONE = "none";
-    String LANGUAGE_JAVA = "java";
-
+public interface Type extends ExtensibleEnum {
     /**
      * Returns the dependency type id.
      * The id uniquely identifies this <i>dependency type</i>.
@@ -52,14 +48,15 @@ public interface Type {
      * @return the id of this type, never {@code null}.
      */
     @Nonnull
-    String getId();
+    String id();
 
     /**
      * Returns the dependency type language.
      *
      * @return the language of this type, never {@code null}.
      */
-    String getLanguage();
+    @Nonnull
+    Language getLanguage();
 
     /**
      * Get the file extension of artifacts of this type.
@@ -80,14 +77,11 @@ public interface Type {
     String getClassifier();
 
     /**
-     * Specifies if the artifact contains java classes and should be
-     * added to the classpath.
+     * Specifies if the artifact should be added to the build path.
      *
-     * @return if the artifact should be added to the class path
+     * @return if the artifact should be added to the build path
      */
-    default boolean isAddedToClassPath() {
-        return 
getDependencyProperties().checkFlag(DependencyProperties.FLAG_CLASS_PATH_CONSTITUENT);
-    }
+    boolean isBuildPathConstituent();
 
     /**
      * Specifies if the artifact already embeds its own dependencies.
@@ -96,15 +90,5 @@ public interface Type {
      *
      * @return if the artifact's dependencies are included in the artifact
      */
-    default boolean isIncludesDependencies() {
-        return 
getDependencyProperties().checkFlag(DependencyProperties.FLAG_INCLUDES_DEPENDENCIES);
-    }
-
-    /**
-     * Gets the default properties associated with this dependency type.
-     *
-     * @return the default properties, never {@code null}.
-     */
-    @Nonnull
-    DependencyProperties getDependencyProperties();
+    boolean isIncludesDependencies();
 }
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCoordinateFactoryRequest.java
 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCoordinateFactoryRequest.java
index 6db92dbe65..34483be0de 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCoordinateFactoryRequest.java
+++ 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyCoordinateFactoryRequest.java
@@ -89,7 +89,7 @@ public interface DependencyCoordinateFactoryRequest extends 
ArtifactCoordinateFa
                 .version(dependency.getVersion().asString())
                 .classifier(dependency.getClassifier())
                 .extension(dependency.getExtension())
-                .type(dependency.getType().getId())
+                .type(dependency.getType().id())
                 .scope(dependency.getScope().id())
                 .optional(dependency.isOptional())
                 .build();
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolver.java
 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolver.java
index 3da46b1f5b..9fefbc4cda 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolver.java
+++ 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolver.java
@@ -22,8 +22,8 @@ import java.util.List;
 
 import org.apache.maven.api.DependencyCoordinate;
 import org.apache.maven.api.Node;
+import org.apache.maven.api.PathScope;
 import org.apache.maven.api.Project;
-import org.apache.maven.api.ResolutionScope;
 import org.apache.maven.api.Service;
 import org.apache.maven.api.Session;
 import org.apache.maven.api.annotations.Experimental;
@@ -35,7 +35,7 @@ import org.apache.maven.api.annotations.Nonnull;
 @Experimental
 public interface DependencyResolver extends Service {
 
-    List<Node> flatten(Session session, Node node, ResolutionScope scope) 
throws DependencyResolverException;
+    List<Node> flatten(Session session, Node node, PathScope scope) throws 
DependencyResolverException;
 
     /**
      * This method collects, flattens and resolves the dependencies.
@@ -47,7 +47,7 @@ public interface DependencyResolver extends Service {
      * @throws ArtifactResolverException
      *
      * @see DependencyCollector#collect(DependencyCollectorRequest)
-     * @see #flatten(Session, Node, ResolutionScope)
+     * @see #flatten(Session, Node, PathScope)
      * @see ArtifactResolver#resolve(ArtifactResolverRequest)
      */
     DependencyResolverResult resolve(DependencyResolverRequest request)
@@ -60,7 +60,7 @@ public interface DependencyResolver extends Service {
 
     @Nonnull
     default DependencyResolverResult resolve(
-            @Nonnull Session session, @Nonnull Project project, @Nonnull 
ResolutionScope scope) {
+            @Nonnull Session session, @Nonnull Project project, @Nonnull 
PathScope scope) {
         return resolve(DependencyResolverRequest.build(session, project, 
scope));
     }
 
@@ -71,7 +71,7 @@ public interface DependencyResolver extends Service {
 
     @Nonnull
     default DependencyResolverResult resolve(
-            @Nonnull Session session, @Nonnull DependencyCoordinate 
dependency, @Nonnull ResolutionScope scope) {
+            @Nonnull Session session, @Nonnull DependencyCoordinate 
dependency, @Nonnull PathScope scope) {
         return resolve(DependencyResolverRequest.build(session, dependency, 
scope));
     }
 
@@ -83,9 +83,7 @@ public interface DependencyResolver extends Service {
 
     @Nonnull
     default DependencyResolverResult resolve(
-            @Nonnull Session session,
-            @Nonnull List<DependencyCoordinate> dependencies,
-            @Nonnull ResolutionScope scope) {
+            @Nonnull Session session, @Nonnull List<DependencyCoordinate> 
dependencies, @Nonnull PathScope scope) {
         return resolve(DependencyResolverRequest.build(session, dependencies, 
scope));
     }
 }
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java
 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java
index 0519ececf1..6d8f009353 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java
+++ 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/DependencyResolverRequest.java
@@ -23,8 +23,8 @@ import java.util.List;
 
 import org.apache.maven.api.Artifact;
 import org.apache.maven.api.DependencyCoordinate;
+import org.apache.maven.api.PathScope;
 import org.apache.maven.api.Project;
-import org.apache.maven.api.ResolutionScope;
 import org.apache.maven.api.Session;
 import org.apache.maven.api.annotations.Experimental;
 import org.apache.maven.api.annotations.Nonnull;
@@ -35,7 +35,7 @@ import org.apache.maven.api.annotations.Nullable;
 public interface DependencyResolverRequest extends DependencyCollectorRequest {
 
     @Nonnull
-    ResolutionScope getResolutionScope();
+    PathScope getPathScope();
 
     @Nonnull
     static DependencyResolverRequestBuilder builder() {
@@ -44,50 +44,49 @@ public interface DependencyResolverRequest extends 
DependencyCollectorRequest {
 
     @Nonnull
     static DependencyResolverRequest build(Session session, Project project) {
-        return build(session, project, ResolutionScope.PROJECT_RUNTIME);
+        return build(session, project, PathScope.MAIN_RUNTIME);
     }
 
     @Nonnull
-    static DependencyResolverRequest build(Session session, Project project, 
ResolutionScope scope) {
+    static DependencyResolverRequest build(Session session, Project project, 
PathScope scope) {
         return new DependencyResolverRequestBuilder()
                 .session(session)
                 .project(project)
-                .resolutionScope(scope)
+                .pathScope(scope)
                 .build();
     }
 
     @Nonnull
     static DependencyResolverRequest build(Session session, 
DependencyCoordinate dependency) {
-        return build(session, dependency, ResolutionScope.PROJECT_RUNTIME);
+        return build(session, dependency, PathScope.MAIN_RUNTIME);
     }
 
     @Nonnull
-    static DependencyResolverRequest build(Session session, 
DependencyCoordinate dependency, ResolutionScope scope) {
+    static DependencyResolverRequest build(Session session, 
DependencyCoordinate dependency, PathScope scope) {
         return new DependencyResolverRequestBuilder()
                 .session(session)
                 .dependency(dependency)
-                .resolutionScope(scope)
+                .pathScope(scope)
                 .build();
     }
 
     @Nonnull
     static DependencyResolverRequest build(Session session, 
List<DependencyCoordinate> dependencies) {
-        return build(session, dependencies, ResolutionScope.PROJECT_RUNTIME);
+        return build(session, dependencies, PathScope.MAIN_RUNTIME);
     }
 
     @Nonnull
-    static DependencyResolverRequest build(
-            Session session, List<DependencyCoordinate> dependencies, 
ResolutionScope scope) {
+    static DependencyResolverRequest build(Session session, 
List<DependencyCoordinate> dependencies, PathScope scope) {
         return new DependencyResolverRequestBuilder()
                 .session(session)
                 .dependencies(dependencies)
-                .resolutionScope(scope)
+                .pathScope(scope)
                 .build();
     }
 
     @NotThreadSafe
     class DependencyResolverRequestBuilder extends 
DependencyCollectorRequestBuilder {
-        ResolutionScope resolutionScope;
+        PathScope pathScope;
 
         @Nonnull
         @Override
@@ -154,20 +153,20 @@ public interface DependencyResolverRequest extends 
DependencyCollectorRequest {
         }
 
         @Nonnull
-        public DependencyResolverRequestBuilder resolutionScope(@Nonnull 
ResolutionScope resolutionScope) {
-            this.resolutionScope = resolutionScope;
+        public DependencyResolverRequestBuilder pathScope(@Nonnull PathScope 
pathScope) {
+            this.pathScope = pathScope;
             return this;
         }
 
         @Override
         public DependencyResolverRequest build() {
             return new DefaultDependencyResolverRequest(
-                    session, project, rootArtifact, root, dependencies, 
managedDependencies, verbose, resolutionScope);
+                    session, project, rootArtifact, root, dependencies, 
managedDependencies, verbose, pathScope);
         }
 
         static class DefaultDependencyResolverRequest extends 
DefaultDependencyCollectorRequest
                 implements DependencyResolverRequest {
-            private final ResolutionScope resolutionScope;
+            private final PathScope pathScope;
 
             DefaultDependencyResolverRequest(
                     Session session,
@@ -177,9 +176,9 @@ public interface DependencyResolverRequest extends 
DependencyCollectorRequest {
                     Collection<DependencyCoordinate> dependencies,
                     Collection<DependencyCoordinate> managedDependencies,
                     boolean verbose,
-                    ResolutionScope resolutionScope) {
+                    PathScope pathScope) {
                 super(session, project, rootArtifact, root, dependencies, 
managedDependencies, verbose);
-                this.resolutionScope = nonNull(resolutionScope, 
"resolutionScope cannot be null");
+                this.pathScope = nonNull(pathScope, "pathScope cannot be 
null");
                 if (verbose) {
                     throw new IllegalArgumentException("verbose cannot be true 
for resolving dependencies");
                 }
@@ -187,8 +186,8 @@ public interface DependencyResolverRequest extends 
DependencyCollectorRequest {
 
             @Nonnull
             @Override
-            public ResolutionScope getResolutionScope() {
-                return resolutionScope;
+            public PathScope getPathScope() {
+                return pathScope;
             }
         }
     }
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ExtensibleEnumRegistry.java
similarity index 64%
copy from 
api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
copy to 
api/maven-api-core/src/main/java/org/apache/maven/api/services/ExtensibleEnumRegistry.java
index c484df40f5..3a5673c583 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
+++ 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ExtensibleEnumRegistry.java
@@ -18,27 +18,17 @@
  */
 package org.apache.maven.api.services;
 
+import java.util.Optional;
+
+import org.apache.maven.api.ExtensibleEnum;
 import org.apache.maven.api.Service;
-import org.apache.maven.api.Type;
-import org.apache.maven.api.annotations.Experimental;
 import org.apache.maven.api.annotations.Nonnull;
 
-/**
- * Access to {@link Type} registry.
- *
- * @since 4.0.0
- */
-@Experimental
-public interface TypeRegistry extends Service {
-
-    /**
-     * Obtain the {@link Type} from the specified {@code id}.
-     * If no type is known for {@code id}, the registry will
-     * create a custom {@code Type} for it.
-     *
-     * @param id the id of the type to retrieve
-     * @return the type
-     */
+public interface ExtensibleEnumRegistry<T extends ExtensibleEnum> extends 
Service {
     @Nonnull
-    Type getType(@Nonnull String id);
+    Optional<T> lookup(String id);
+
+    default T require(String id) {
+        return lookup(id).orElseThrow(() -> new 
IllegalArgumentException("Unknown extensible enum value '" + id + "'"));
+    }
 }
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/LanguageRegistry.java
similarity index 57%
copy from 
api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
copy to 
api/maven-api-core/src/main/java/org/apache/maven/api/services/LanguageRegistry.java
index c484df40f5..d2f0f09331 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
+++ 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/LanguageRegistry.java
@@ -18,27 +18,6 @@
  */
 package org.apache.maven.api.services;
 
-import org.apache.maven.api.Service;
-import org.apache.maven.api.Type;
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Nonnull;
+import org.apache.maven.api.Language;
 
-/**
- * Access to {@link Type} registry.
- *
- * @since 4.0.0
- */
-@Experimental
-public interface TypeRegistry extends Service {
-
-    /**
-     * Obtain the {@link Type} from the specified {@code id}.
-     * If no type is known for {@code id}, the registry will
-     * create a custom {@code Type} for it.
-     *
-     * @param id the id of the type to retrieve
-     * @return the type
-     */
-    @Nonnull
-    Type getType(@Nonnull String id);
-}
+public interface LanguageRegistry extends ExtensibleEnumRegistry<Language> {}
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/PackagingRegistry.java
similarity index 57%
copy from 
api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
copy to 
api/maven-api-core/src/main/java/org/apache/maven/api/services/PackagingRegistry.java
index c484df40f5..e114e26640 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
+++ 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/PackagingRegistry.java
@@ -18,27 +18,6 @@
  */
 package org.apache.maven.api.services;
 
-import org.apache.maven.api.Service;
-import org.apache.maven.api.Type;
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Nonnull;
+import org.apache.maven.api.Packaging;
 
-/**
- * Access to {@link Type} registry.
- *
- * @since 4.0.0
- */
-@Experimental
-public interface TypeRegistry extends Service {
-
-    /**
-     * Obtain the {@link Type} from the specified {@code id}.
-     * If no type is known for {@code id}, the registry will
-     * create a custom {@code Type} for it.
-     *
-     * @param id the id of the type to retrieve
-     * @return the type
-     */
-    @Nonnull
-    Type getType(@Nonnull String id);
-}
+public interface PackagingRegistry extends ExtensibleEnumRegistry<Packaging> {}
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/PathScopeRegistry.java
similarity index 57%
copy from 
api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
copy to 
api/maven-api-core/src/main/java/org/apache/maven/api/services/PathScopeRegistry.java
index c484df40f5..06b5d59647 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
+++ 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/PathScopeRegistry.java
@@ -18,27 +18,6 @@
  */
 package org.apache.maven.api.services;
 
-import org.apache.maven.api.Service;
-import org.apache.maven.api.Type;
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Nonnull;
+import org.apache.maven.api.PathScope;
 
-/**
- * Access to {@link Type} registry.
- *
- * @since 4.0.0
- */
-@Experimental
-public interface TypeRegistry extends Service {
-
-    /**
-     * Obtain the {@link Type} from the specified {@code id}.
-     * If no type is known for {@code id}, the registry will
-     * create a custom {@code Type} for it.
-     *
-     * @param id the id of the type to retrieve
-     * @return the type
-     */
-    @Nonnull
-    Type getType(@Nonnull String id);
-}
+public interface PathScopeRegistry extends ExtensibleEnumRegistry<PathScope> {}
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectScopeRegistry.java
similarity index 58%
copy from 
api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
copy to 
api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectScopeRegistry.java
index c484df40f5..a3b4f24a5d 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
+++ 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/ProjectScopeRegistry.java
@@ -18,27 +18,9 @@
  */
 package org.apache.maven.api.services;
 
-import org.apache.maven.api.Service;
-import org.apache.maven.api.Type;
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Nonnull;
+import org.apache.maven.api.ProjectScope;
 
 /**
- * Access to {@link Type} registry.
- *
- * @since 4.0.0
+ * Manager for {@link ProjectScope}.
  */
-@Experimental
-public interface TypeRegistry extends Service {
-
-    /**
-     * Obtain the {@link Type} from the specified {@code id}.
-     * If no type is known for {@code id}, the registry will
-     * create a custom {@code Type} for it.
-     *
-     * @param id the id of the type to retrieve
-     * @return the type
-     */
-    @Nonnull
-    Type getType(@Nonnull String id);
-}
+public interface ProjectScopeRegistry extends 
ExtensibleEnumRegistry<ProjectScope> {}
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
index c484df40f5..ca4c40d48a 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
+++ 
b/api/maven-api-core/src/main/java/org/apache/maven/api/services/TypeRegistry.java
@@ -18,7 +18,6 @@
  */
 package org.apache.maven.api.services;
 
-import org.apache.maven.api.Service;
 import org.apache.maven.api.Type;
 import org.apache.maven.api.annotations.Experimental;
 import org.apache.maven.api.annotations.Nonnull;
@@ -29,7 +28,7 @@ import org.apache.maven.api.annotations.Nonnull;
  * @since 4.0.0
  */
 @Experimental
-public interface TypeRegistry extends Service {
+public interface TypeRegistry extends ExtensibleEnumRegistry<Type> {
 
     /**
      * Obtain the {@link Type} from the specified {@code id}.
@@ -40,5 +39,5 @@ public interface TypeRegistry extends Service {
      * @return the type
      */
     @Nonnull
-    Type getType(@Nonnull String id);
+    Type require(@Nonnull String id);
 }
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
 
b/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ExtensibleEnumProvider.java
similarity index 58%
copy from 
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
copy to 
api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ExtensibleEnumProvider.java
index 7ba4bd1ec7..514651088a 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
+++ 
b/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ExtensibleEnumProvider.java
@@ -16,36 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.api;
+package org.apache.maven.api.spi;
 
 import java.util.Collection;
 
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Immutable;
-import org.apache.maven.api.annotations.Nonnull;
-import org.apache.maven.api.annotations.Nullable;
+import org.apache.maven.api.ExtensibleEnum;
 
-/**
- *
- * @since 4.0.0
- */
-@Experimental
-@Immutable
-public interface DependencyCoordinate extends ArtifactCoordinate {
-    /**
-     * The type of the artifact.
-     *
-     * @return the type
-     */
-    @Nonnull
-    Type getType();
-
-    @Nonnull
-    Scope getScope();
-
-    @Nullable
-    Boolean getOptional();
+public interface ExtensibleEnumProvider<T extends ExtensibleEnum> {
 
-    @Nonnull
-    Collection<Exclusion> getExclusions();
+    Collection<T> provides();
 }
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
 
b/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/LanguageProvider.java
similarity index 56%
copy from 
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
copy to 
api/maven-api-spi/src/main/java/org/apache/maven/api/spi/LanguageProvider.java
index 7ba4bd1ec7..9757d04f20 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
+++ 
b/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/LanguageProvider.java
@@ -16,36 +16,8 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.api;
+package org.apache.maven.api.spi;
 
-import java.util.Collection;
+import org.apache.maven.api.Language;
 
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Immutable;
-import org.apache.maven.api.annotations.Nonnull;
-import org.apache.maven.api.annotations.Nullable;
-
-/**
- *
- * @since 4.0.0
- */
-@Experimental
-@Immutable
-public interface DependencyCoordinate extends ArtifactCoordinate {
-    /**
-     * The type of the artifact.
-     *
-     * @return the type
-     */
-    @Nonnull
-    Type getType();
-
-    @Nonnull
-    Scope getScope();
-
-    @Nullable
-    Boolean getOptional();
-
-    @Nonnull
-    Collection<Exclusion> getExclusions();
-}
+public interface LanguageProvider extends ExtensibleEnumProvider<Language> {}
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
 
b/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/PathScopeProvider.java
similarity index 56%
copy from 
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
copy to 
api/maven-api-spi/src/main/java/org/apache/maven/api/spi/PathScopeProvider.java
index 7ba4bd1ec7..2e2597b839 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
+++ 
b/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/PathScopeProvider.java
@@ -16,36 +16,8 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.api;
+package org.apache.maven.api.spi;
 
-import java.util.Collection;
+import org.apache.maven.api.PathScope;
 
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Immutable;
-import org.apache.maven.api.annotations.Nonnull;
-import org.apache.maven.api.annotations.Nullable;
-
-/**
- *
- * @since 4.0.0
- */
-@Experimental
-@Immutable
-public interface DependencyCoordinate extends ArtifactCoordinate {
-    /**
-     * The type of the artifact.
-     *
-     * @return the type
-     */
-    @Nonnull
-    Type getType();
-
-    @Nonnull
-    Scope getScope();
-
-    @Nullable
-    Boolean getOptional();
-
-    @Nonnull
-    Collection<Exclusion> getExclusions();
-}
+public interface PathScopeProvider extends ExtensibleEnumProvider<PathScope> {}
diff --git 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
 
b/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ProjectScopeProvider.java
similarity index 56%
copy from 
api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
copy to 
api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ProjectScopeProvider.java
index 7ba4bd1ec7..c4a9a1f992 100644
--- 
a/api/maven-api-core/src/main/java/org/apache/maven/api/DependencyCoordinate.java
+++ 
b/api/maven-api-spi/src/main/java/org/apache/maven/api/spi/ProjectScopeProvider.java
@@ -16,36 +16,8 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.maven.api;
+package org.apache.maven.api.spi;
 
-import java.util.Collection;
+import org.apache.maven.api.ProjectScope;
 
-import org.apache.maven.api.annotations.Experimental;
-import org.apache.maven.api.annotations.Immutable;
-import org.apache.maven.api.annotations.Nonnull;
-import org.apache.maven.api.annotations.Nullable;
-
-/**
- *
- * @since 4.0.0
- */
-@Experimental
-@Immutable
-public interface DependencyCoordinate extends ArtifactCoordinate {
-    /**
-     * The type of the artifact.
-     *
-     * @return the type
-     */
-    @Nonnull
-    Type getType();
-
-    @Nonnull
-    Scope getScope();
-
-    @Nullable
-    Boolean getOptional();
-
-    @Nonnull
-    Collection<Exclusion> getExclusions();
-}
+public interface ProjectScopeProvider extends 
ExtensibleEnumProvider<ProjectScope> {}
diff --git 
a/maven-artifact/src/main/java/org/apache/maven/artifact/handler/ArtifactHandler.java
 
b/maven-artifact/src/main/java/org/apache/maven/artifact/handler/ArtifactHandler.java
index 92cca2a069..364e12425e 100644
--- 
a/maven-artifact/src/main/java/org/apache/maven/artifact/handler/ArtifactHandler.java
+++ 
b/maven-artifact/src/main/java/org/apache/maven/artifact/handler/ArtifactHandler.java
@@ -53,5 +53,9 @@ public interface ArtifactHandler {
 
     String getLanguage();
 
+    /**
+     * IMPORTANT: this is WRONGLY NAMED method (and/or remnant for Maven2).
+     * Its meaning is "is added to build path", that is used to create 
classpath/modulepath/etc.
+     */
     boolean isAddedToClasspath();
 }
diff --git 
a/maven-core/src/main/java/org/apache/maven/artifact/handler/manager/DefaultArtifactHandlerManager.java
 
b/maven-core/src/main/java/org/apache/maven/artifact/handler/manager/DefaultArtifactHandlerManager.java
index 87166eb29a..3a0c1a234f 100644
--- 
a/maven-core/src/main/java/org/apache/maven/artifact/handler/manager/DefaultArtifactHandlerManager.java
+++ 
b/maven-core/src/main/java/org/apache/maven/artifact/handler/manager/DefaultArtifactHandlerManager.java
@@ -62,7 +62,7 @@ public class DefaultArtifactHandlerManager extends 
AbstractEventSpy implements A
 
     public ArtifactHandler getArtifactHandler(String id) {
         return allHandlers.computeIfAbsent(id, k -> {
-            Type type = typeRegistry.getType(id);
+            Type type = typeRegistry.require(id);
             return new DefaultArtifactHandler(
                     id,
                     type.getExtension(),
@@ -70,9 +70,13 @@ public class DefaultArtifactHandlerManager extends 
AbstractEventSpy implements A
                     null,
                     null,
                     type.isIncludesDependencies(),
-                    type.getLanguage(),
-                    type.isAddedToClassPath()); // TODO: watch out for module 
path
+                    type.getLanguage().id(),
+                    type.isBuildPathConstituent());
         });
+
+        // Note: here, type decides is artifact added to "build path" (for 
example during resolution)
+        // and "build path" is intermediate data that is used to create actual 
Java classpath/modulepath
+        // but to create those, proper filtering should happen via Type 
properties.
     }
 
     public void addHandlers(Map<String, ArtifactHandler> handlers) {
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/aether/TypeRegistryAdapter.java
 
b/maven-core/src/main/java/org/apache/maven/internal/aether/TypeRegistryAdapter.java
index b5f3f9c614..e06dd9e13c 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/aether/TypeRegistryAdapter.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/aether/TypeRegistryAdapter.java
@@ -35,17 +35,18 @@ class TypeRegistryAdapter implements ArtifactTypeRegistry {
 
     @Override
     public ArtifactType get(String typeId) {
-        Type type = typeRegistry.getType(typeId);
+        Type type = typeRegistry.require(typeId);
         if (type instanceof ArtifactType) {
             return (ArtifactType) type;
         }
         if (type != null) {
             return new DefaultType(
-                    type.getId(),
+                    type.id(),
                     type.getLanguage(),
                     type.getExtension(),
                     type.getClassifier(),
-                    type.getDependencyProperties());
+                    type.isBuildPathConstituent(),
+                    type.isIncludesDependencies());
         }
         return null;
     }
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/AbstractSession.java 
b/maven-core/src/main/java/org/apache/maven/internal/impl/AbstractSession.java
index ce90e19be7..1b97790119 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/AbstractSession.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/AbstractSession.java
@@ -462,7 +462,7 @@ public abstract class AbstractSession implements 
InternalSession {
 
     @Nonnull
     @Override
-    public List<Node> flattenDependencies(@Nonnull Node node, @Nonnull 
ResolutionScope scope) {
+    public List<Node> flattenDependencies(@Nonnull Node node, @Nonnull 
PathScope scope) {
         return getService(DependencyResolver.class).flatten(this, node, scope);
     }
 
@@ -477,7 +477,7 @@ public abstract class AbstractSession implements 
InternalSession {
     }
 
     @Override
-    public List<Path> resolveDependencies(Project project, ResolutionScope 
scope) {
+    public List<Path> resolveDependencies(Project project, PathScope scope) {
         return getService(DependencyResolver.class)
                 .resolve(this, project, scope)
                 .getPaths();
@@ -518,4 +518,34 @@ public abstract class AbstractSession implements 
InternalSession {
     public List<Version> resolveVersionRange(ArtifactCoordinate artifact) {
         return getService(VersionRangeResolver.class).resolve(this, 
artifact).getVersions();
     }
+
+    @Override
+    public Type requireType(String id) {
+        return getService(TypeRegistry.class).require(id);
+    }
+
+    @Override
+    public Language requireLanguage(String id) {
+        return getService(LanguageRegistry.class).require(id);
+    }
+
+    @Override
+    public Packaging requirePackaging(String id) {
+        return getService(PackagingRegistry.class).require(id);
+    }
+
+    @Override
+    public ProjectScope requireProjectScope(String id) {
+        return getService(ProjectScopeRegistry.class).require(id);
+    }
+
+    @Override
+    public DependencyScope requireDependencyScope(String id) {
+        return DependencyScope.forId(id);
+    }
+
+    @Override
+    public PathScope requirePathScope(String id) {
+        return getService(PathScopeRegistry.class).require(id);
+    }
 }
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependency.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependency.java
index 3f2f06893e..5a5b3f9b05 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependency.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependency.java
@@ -23,13 +23,11 @@ import java.util.Objects;
 import org.apache.maven.api.Artifact;
 import org.apache.maven.api.Dependency;
 import org.apache.maven.api.DependencyCoordinate;
-import org.apache.maven.api.DependencyProperties;
-import org.apache.maven.api.Scope;
+import org.apache.maven.api.DependencyScope;
 import org.apache.maven.api.Type;
 import org.apache.maven.api.Version;
 import org.apache.maven.api.annotations.Nonnull;
 import org.apache.maven.api.annotations.Nullable;
-import org.apache.maven.api.services.TypeRegistry;
 import org.apache.maven.repository.internal.DefaultModelVersionParser;
 import org.eclipse.aether.artifact.ArtifactProperties;
 
@@ -38,15 +36,12 @@ import static org.apache.maven.internal.impl.Utils.nonNull;
 public class DefaultDependency implements Dependency {
     private final InternalSession session;
     private final org.eclipse.aether.graph.Dependency dependency;
-    private final DependencyProperties dependencyProperties;
     private final String key;
 
     public DefaultDependency(
             @Nonnull InternalSession session, @Nonnull 
org.eclipse.aether.graph.Dependency dependency) {
         this.session = nonNull(session, "session");
         this.dependency = nonNull(dependency, "dependency");
-        this.dependencyProperties =
-                new 
DefaultDependencyProperties(dependency.getArtifact().getProperties());
         this.key = getGroupId()
                 + ':'
                 + getArtifactId()
@@ -102,12 +97,7 @@ public class DefaultDependency implements Dependency {
         String type = dependency
                 .getArtifact()
                 .getProperty(ArtifactProperties.TYPE, 
dependency.getArtifact().getExtension());
-        return session.getService(TypeRegistry.class).getType(type);
-    }
-
-    @Override
-    public DependencyProperties getDependencyProperties() {
-        return dependencyProperties;
+        return session.requireType(type);
     }
 
     @Override
@@ -117,8 +107,8 @@ public class DefaultDependency implements Dependency {
 
     @Nonnull
     @Override
-    public Scope getScope() {
-        return Scope.get(dependency.getScope());
+    public DependencyScope getScope() {
+        return session.requireDependencyScope(dependency.getScope());
     }
 
     @Nullable
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCoordinate.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCoordinate.java
index 54121e8da6..c0420f5fbb 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCoordinate.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyCoordinate.java
@@ -23,7 +23,6 @@ import java.util.Collection;
 import org.apache.maven.api.*;
 import org.apache.maven.api.annotations.Nonnull;
 import org.apache.maven.api.annotations.Nullable;
-import org.apache.maven.api.services.TypeRegistry;
 import org.eclipse.aether.artifact.ArtifactProperties;
 
 import static org.apache.maven.internal.impl.Utils.nonNull;
@@ -73,13 +72,13 @@ public class DefaultDependencyCoordinate implements 
DependencyCoordinate {
         String type = dependency
                 .getArtifact()
                 .getProperty(ArtifactProperties.TYPE, 
dependency.getArtifact().getExtension());
-        return session.getService(TypeRegistry.class).getType(type);
+        return session.requireType(type);
     }
 
     @Nonnull
     @Override
-    public Scope getScope() {
-        return Scope.get(dependency.getScope());
+    public DependencyScope getScope() {
+        return session.requireDependencyScope(dependency.getScope());
     }
 
     @Nullable
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyProperties.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyProperties.java
deleted file mode 100644
index 2ee7807130..0000000000
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyProperties.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.maven.internal.impl;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.maven.api.DependencyProperties;
-import org.apache.maven.api.annotations.Nonnull;
-
-import static org.apache.maven.internal.impl.Utils.nonNull;
-
-/**
- * Default implementation of artifact properties.
- */
-public class DefaultDependencyProperties implements DependencyProperties {
-    private final Map<String, String> properties;
-
-    public DefaultDependencyProperties(String... flags) {
-        this(Arrays.asList(flags));
-    }
-
-    public DefaultDependencyProperties(@Nonnull Collection<String> flags) {
-        nonNull(flags, "flags");
-        HashMap<String, String> map = new HashMap<>();
-        for (String flag : flags) {
-            map.put(flag, Boolean.TRUE.toString());
-        }
-        this.properties = Collections.unmodifiableMap(map);
-    }
-
-    public DefaultDependencyProperties(@Nonnull Map<String, String> 
properties) {
-        this.properties = Collections.unmodifiableMap(nonNull(properties, 
"properties"));
-    }
-
-    @Nonnull
-    @Override
-    public Map<String, String> asMap() {
-        return properties;
-    }
-
-    @Override
-    public boolean checkFlag(@Nonnull String flag) {
-        nonNull(flag, "flag");
-        return Boolean.parseBoolean(properties.getOrDefault(flag, ""));
-    }
-}
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java
index c5ba1a32b0..298576d5f4 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultDependencyResolver.java
@@ -33,14 +33,7 @@ import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import org.apache.maven.api.Artifact;
-import org.apache.maven.api.ArtifactCoordinate;
-import org.apache.maven.api.Dependency;
-import org.apache.maven.api.Node;
-import org.apache.maven.api.Project;
-import org.apache.maven.api.ResolutionScope;
-import org.apache.maven.api.Scope;
-import org.apache.maven.api.Session;
+import org.apache.maven.api.*;
 import org.apache.maven.api.services.*;
 import org.apache.maven.lifecycle.LifecycleExecutionException;
 import org.apache.maven.lifecycle.internal.LifecycleDependencyResolver;
@@ -58,7 +51,7 @@ import static org.apache.maven.internal.impl.Utils.nonNull;
 public class DefaultDependencyResolver implements DependencyResolver {
 
     @Override
-    public List<Node> flatten(Session s, Node node, ResolutionScope scope) 
throws DependencyResolverException {
+    public List<Node> flatten(Session s, Node node, PathScope scope) throws 
DependencyResolverException {
         InternalSession session = InternalSession.from(s);
         DependencyNode root = cast(AbstractNode.class, node, 
"node").getDependencyNode();
         List<DependencyNode> dependencies = session.getRepositorySystem()
@@ -67,8 +60,9 @@ public class DefaultDependencyResolver implements 
DependencyResolver {
         return map(dependencies, session::getNode);
     }
 
-    private static DependencyFilter getScopeDependencyFilter(ResolutionScope 
scope) {
-        Set<String> scopes = 
scope.scopes().stream().map(Scope::id).collect(Collectors.toSet());
+    private static DependencyFilter getScopeDependencyFilter(PathScope scope) {
+        Set<String> scopes =
+                
scope.dependencyScopes().stream().map(DependencyScope::id).collect(Collectors.toSet());
         return (n, p) -> {
             org.eclipse.aether.graph.Dependency d = n.getDependency();
             return d == null || scopes.contains(d.getScope());
@@ -83,7 +77,7 @@ public class DefaultDependencyResolver implements 
DependencyResolver {
 
         if (request.getProject().isPresent()) {
             DependencyResolutionResult result = resolveDependencies(
-                    request.getSession(), request.getProject().get(), 
request.getResolutionScope());
+                    request.getSession(), request.getProject().get(), 
request.getPathScope());
 
             Map<org.eclipse.aether.graph.Dependency, 
org.eclipse.aether.graph.DependencyNode> nodes = stream(
                             result.getDependencyGraph())
@@ -106,7 +100,7 @@ public class DefaultDependencyResolver implements 
DependencyResolver {
 
         DependencyCollectorResult collectorResult =
                 session.getService(DependencyCollector.class).collect(request);
-        List<Node> nodes = flatten(session, collectorResult.getRoot(), 
request.getResolutionScope());
+        List<Node> nodes = flatten(session, collectorResult.getRoot(), 
request.getPathScope());
         List<Dependency> deps =
                 
nodes.stream().map(Node::getDependency).filter(Objects::nonNull).collect(Collectors.toList());
         List<ArtifactCoordinate> coordinates =
@@ -130,7 +124,7 @@ public class DefaultDependencyResolver implements 
DependencyResolver {
         return Stream.concat(Stream.of(node), 
node.getChildren().stream().flatMap(this::stream));
     }
 
-    private DependencyResolutionResult resolveDependencies(Session session, 
Project project, ResolutionScope scope) {
+    private DependencyResolutionResult resolveDependencies(Session session, 
Project project, PathScope scope) {
         Collection<String> toResolve = toScopes(scope);
         try {
             LifecycleDependencyResolver lifecycleDependencyResolver =
@@ -151,8 +145,8 @@ public class DefaultDependencyResolver implements 
DependencyResolver {
         return ((DefaultProject) project).getProject();
     }
 
-    private Collection<String> toScopes(ResolutionScope scope) {
-        return map(scope.scopes(), Scope::id);
+    private Collection<String> toScopes(PathScope scope) {
+        return map(scope.dependencyScopes(), DependencyScope::id);
     }
 
     static class DefaultDependencyResolverResult implements 
DependencyResolverResult {
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultPackagingRegistry.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultPackagingRegistry.java
new file mode 100644
index 0000000000..2a5b8a63b5
--- /dev/null
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultPackagingRegistry.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.internal.impl;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import java.util.Map;
+import java.util.Optional;
+
+import org.apache.maven.api.Packaging;
+import org.apache.maven.api.Type;
+import org.apache.maven.api.services.PackagingRegistry;
+import org.apache.maven.api.services.TypeRegistry;
+import org.apache.maven.lifecycle.mapping.LifecycleMapping;
+
+/**
+ * TODO: this is session scoped as SPI can contribute.
+ */
+@Named
+@Singleton
+public class DefaultPackagingRegistry implements PackagingRegistry {
+    private final Map<String, LifecycleMapping> lifecycleMappings;
+
+    private final TypeRegistry typeRegistry;
+
+    @Inject
+    public DefaultPackagingRegistry(Map<String, LifecycleMapping> 
lifecycleMappings, TypeRegistry typeRegistry) {
+        this.lifecycleMappings = lifecycleMappings;
+        this.typeRegistry = typeRegistry;
+    }
+
+    @Override
+    public Optional<Packaging> lookup(String id) {
+        LifecycleMapping lifecycleMapping = lifecycleMappings.get(id);
+        if (lifecycleMapping == null) {
+            return Optional.empty();
+        }
+        Type type = typeRegistry.lookup(id).orElse(null);
+        if (type == null) {
+            return Optional.empty();
+        }
+
+        return Optional.of(new Packaging() {
+            @Override
+            public String id() {
+                return id;
+            }
+
+            @Override
+            public Type getType() {
+                return type;
+            }
+        });
+    }
+}
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java
index f438261aee..e2f59668ec 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java
@@ -27,7 +27,6 @@ import org.apache.maven.api.annotations.Nonnull;
 import org.apache.maven.api.annotations.Nullable;
 import org.apache.maven.api.model.DependencyManagement;
 import org.apache.maven.api.model.Model;
-import org.apache.maven.api.services.TypeRegistry;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.project.artifact.ProjectArtifact;
 import org.eclipse.aether.util.artifact.ArtifactIdUtils;
@@ -38,10 +37,12 @@ public class DefaultProject implements Project {
 
     private final InternalSession session;
     private final MavenProject project;
+    private final Packaging packaging;
 
     public DefaultProject(InternalSession session, MavenProject project) {
         this.session = session;
         this.project = project;
+        this.packaging = session.requirePackaging(project.getPackaging());
     }
 
     public InternalSession getSession() {
@@ -86,8 +87,8 @@ public class DefaultProject implements Project {
 
     @Nonnull
     @Override
-    public String getPackaging() {
-        return project.getPackaging();
+    public Packaging getPackaging() {
+        return packaging;
     }
 
     @Nonnull
@@ -175,13 +176,13 @@ public class DefaultProject implements Project {
             @Override
             public Type getType() {
                 String type = dependency.getType();
-                return session.getService(TypeRegistry.class).getType(type);
+                return session.requireType(type);
             }
 
             @Nonnull
             @Override
-            public Scope getScope() {
-                return Scope.get(dependency.getScope());
+            public DependencyScope getScope() {
+                return session.requireDependencyScope(dependency.getScope());
             }
 
             @Override
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultType.java 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultType.java
index 6297f5c4dd..9dca04e0ea 100644
--- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultType.java
+++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultType.java
@@ -18,10 +18,11 @@
  */
 package org.apache.maven.internal.impl;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.maven.api.DependencyProperties;
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
 import org.eclipse.aether.artifact.ArtifactProperties;
 import org.eclipse.aether.artifact.ArtifactType;
@@ -29,37 +30,44 @@ import org.eclipse.aether.artifact.ArtifactType;
 import static org.apache.maven.internal.impl.Utils.nonNull;
 
 public class DefaultType implements Type, ArtifactType {
+    private final String id;
+
+    private final Language language;
+
     private final String extension;
 
     private final String classifier;
-
-    private final DependencyProperties dependencyProperties;
+    private final boolean buildPathConstituent;
+    private final boolean includesDependencies;
 
     public DefaultType(
             String id,
-            String language,
+            Language language,
             String extension,
             String classifier,
-            DependencyProperties dependencyProperties) {
-        nonNull(id, "id");
-        nonNull(language, "language");
+            boolean buildPathConstituent,
+            boolean includesDependencies) {
+        this.id = nonNull(id, "id");
+        this.language = nonNull(language, "language");
         this.extension = nonNull(extension, "extension");
         this.classifier = classifier;
-        nonNull(dependencyProperties, "dependencyProperties");
-        HashMap<String, String> props = new 
HashMap<>(dependencyProperties.asMap());
-        props.put(ArtifactProperties.TYPE, id);
-        props.put(ArtifactProperties.LANGUAGE, language);
-        this.dependencyProperties = new DefaultDependencyProperties(props);
+        this.buildPathConstituent = buildPathConstituent;
+        this.includesDependencies = includesDependencies;
+    }
+
+    @Override
+    public String id() {
+        return id;
     }
 
     @Override
     public String getId() {
-        return dependencyProperties.asMap().get(ArtifactProperties.TYPE);
+        return id();
     }
 
     @Override
-    public String getLanguage() {
-        return dependencyProperties.asMap().get(ArtifactProperties.LANGUAGE);
+    public Language getLanguage() {
+        return language;
     }
 
     @Override
@@ -73,12 +81,22 @@ public class DefaultType implements Type, ArtifactType {
     }
 
     @Override
-    public DependencyProperties getDependencyProperties() {
-        return dependencyProperties;
+    public boolean isBuildPathConstituent() {
+        return this.buildPathConstituent;
+    }
+
+    @Override
+    public boolean isIncludesDependencies() {
+        return this.includesDependencies;
     }
 
     @Override
     public Map<String, String> getProperties() {
-        return getDependencyProperties().asMap();
+        Map<String, String> properties = new HashMap<>();
+        properties.put(ArtifactProperties.TYPE, this.id);
+        properties.put(ArtifactProperties.LANGUAGE, this.language.id());
+        properties.put(ArtifactProperties.INCLUDES_DEPENDENCIES, 
String.valueOf(includesDependencies));
+        properties.put(ArtifactProperties.CONSTITUTES_BUILD_PATH, 
String.valueOf(buildPathConstituent));
+        return Collections.unmodifiableMap(properties);
     }
 }
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultTypeRegistry.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultTypeRegistry.java
index cebd30cc66..faf8d4ca93 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultTypeRegistry.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultTypeRegistry.java
@@ -22,13 +22,13 @@ import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Singleton;
 
-import java.util.ArrayList;
 import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.maven.api.DependencyProperties;
 import org.apache.maven.api.Type;
 import org.apache.maven.api.annotations.Nonnull;
+import org.apache.maven.api.services.LanguageRegistry;
 import org.apache.maven.api.services.TypeRegistry;
 import org.apache.maven.artifact.handler.ArtifactHandler;
 import org.apache.maven.artifact.handler.manager.LegacyArtifactHandlerManager;
@@ -42,6 +42,8 @@ import static org.apache.maven.internal.impl.Utils.nonNull;
 public class DefaultTypeRegistry extends AbstractEventSpy implements 
TypeRegistry {
     private final Map<String, Type> types;
 
+    private final LanguageRegistry languageRegistry;
+
     private final ConcurrentHashMap<String, Type> usedTypes;
 
     private final ConcurrentHashMap<String, Type> legacyTypes;
@@ -49,8 +51,10 @@ public class DefaultTypeRegistry extends AbstractEventSpy 
implements TypeRegistr
     private final LegacyArtifactHandlerManager manager;
 
     @Inject
-    public DefaultTypeRegistry(Map<String, Type> types, 
LegacyArtifactHandlerManager manager) {
+    public DefaultTypeRegistry(
+            Map<String, Type> types, LanguageRegistry languageRegistry, 
LegacyArtifactHandlerManager manager) {
         this.types = nonNull(types, "types");
+        this.languageRegistry = nonNull(languageRegistry, "languageRegistry");
         this.usedTypes = new ConcurrentHashMap<>();
         this.legacyTypes = new ConcurrentHashMap<>();
         this.manager = nonNull(manager, "artifactHandlerManager");
@@ -67,9 +71,14 @@ public class DefaultTypeRegistry extends AbstractEventSpy 
implements TypeRegistr
         }
     }
 
+    @Override
+    public Optional<Type> lookup(String id) {
+        return Optional.of(require(id));
+    }
+
     @Override
     @Nonnull
-    public Type getType(String id) {
+    public Type require(String id) {
         nonNull(id, "id");
         return usedTypes.computeIfAbsent(id, i -> {
             Type type = types.get(id);
@@ -78,19 +87,13 @@ public class DefaultTypeRegistry extends AbstractEventSpy 
implements TypeRegistr
                 type = legacyTypes.computeIfAbsent(id, k -> {
                     // Copy data as the ArtifactHandler is not immutable, but 
Type should be.
                     ArtifactHandler handler = manager.getArtifactHandler(id);
-                    ArrayList<String> flags = new ArrayList<>();
-                    if (handler.isAddedToClasspath()) {
-                        
flags.add(DependencyProperties.FLAG_CLASS_PATH_CONSTITUENT);
-                    }
-                    if (handler.isIncludesDependencies()) {
-                        
flags.add(DependencyProperties.FLAG_INCLUDES_DEPENDENCIES);
-                    }
                     return new DefaultType(
                             id,
-                            handler.getLanguage(),
+                            languageRegistry.require(handler.getLanguage()),
                             handler.getExtension(),
                             handler.getClassifier(),
-                            new DefaultDependencyProperties(flags));
+                            handler.isAddedToClasspath(),
+                            handler.isIncludesDependencies());
                 });
             }
             return type;
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/ExtensibleEnumRegistries.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/ExtensibleEnumRegistries.java
new file mode 100644
index 0000000000..d512e74b46
--- /dev/null
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/ExtensibleEnumRegistries.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.internal.impl;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.maven.SessionScoped;
+import org.apache.maven.api.*;
+import org.apache.maven.api.services.*;
+import org.apache.maven.api.spi.*;
+
+public class ExtensibleEnumRegistries {
+
+    @Named
+    @SessionScoped
+    public static class DefaultPathScopeRegistry extends 
DefaultExtensibleEnumRegistry<PathScope, PathScopeProvider>
+            implements PathScopeRegistry {
+
+        @Inject
+        public DefaultPathScopeRegistry(List<PathScopeProvider> providers) {
+            super(
+                    providers,
+                    PathScope.MAIN_COMPILE,
+                    PathScope.MAIN_RUNTIME,
+                    PathScope.TEST_COMPILE,
+                    PathScope.TEST_RUNTIME);
+        }
+    }
+
+    @Named
+    @SessionScoped
+    public static class DefaultProjectScopeRegistry
+            extends DefaultExtensibleEnumRegistry<ProjectScope, 
ProjectScopeProvider> implements ProjectScopeRegistry {
+
+        @Inject
+        public DefaultProjectScopeRegistry(List<ProjectScopeProvider> 
providers) {
+            super(providers, ProjectScope.MAIN, ProjectScope.TEST);
+        }
+    }
+
+    @Named
+    @Singleton
+    public static class DefaultLanguageRegistry extends 
DefaultExtensibleEnumRegistry<Language, LanguageProvider>
+            implements LanguageRegistry {
+
+        @Inject
+        public DefaultLanguageRegistry(List<LanguageProvider> providers) {
+            super(providers, Language.NONE, Language.JAVA_FAMILY);
+        }
+    }
+
+    static class DefaultExtensibleEnumRegistry<T extends ExtensibleEnum, P 
extends ExtensibleEnumProvider<T>>
+            implements ExtensibleEnumRegistry<T> {
+
+        private final Map<String, T> values;
+
+        DefaultExtensibleEnumRegistry(List<P> providers, T... builtinValues) {
+            values = Stream.<T>concat(
+                            Stream.of(builtinValues), 
providers.stream().flatMap(p -> p.provides().stream()))
+                    .collect(Collectors.toMap(t -> t.id(), t -> t));
+        }
+
+        @Override
+        public Optional<T> lookup(String id) {
+            return Optional.ofNullable(values.get(id));
+        }
+    }
+}
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/BomTypeProvider.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/BomTypeProvider.java
index d7387a1780..801bfef782 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/BomTypeProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/BomTypeProvider.java
@@ -22,8 +22,8 @@ import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
-import org.apache.maven.internal.impl.DefaultDependencyProperties;
 import org.apache.maven.internal.impl.DefaultType;
 
 @Named(BomTypeProvider.NAME)
@@ -34,7 +34,7 @@ public class BomTypeProvider implements Provider<Type> {
     private final Type type;
 
     public BomTypeProvider() {
-        this.type = new DefaultType(NAME, Type.LANGUAGE_NONE, "pom", null, new 
DefaultDependencyProperties());
+        this.type = new DefaultType(NAME, Language.NONE, "pom", null, false, 
false);
     }
 
     @Override
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/EarTypeProvider.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/EarTypeProvider.java
index 489ed638bb..5512b8e442 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/EarTypeProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/EarTypeProvider.java
@@ -22,9 +22,8 @@ import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
-import org.apache.maven.api.DependencyProperties;
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
-import org.apache.maven.internal.impl.DefaultDependencyProperties;
 import org.apache.maven.internal.impl.DefaultType;
 
 @Named(EarTypeProvider.NAME)
@@ -35,12 +34,7 @@ public class EarTypeProvider implements Provider<Type> {
     private final Type type;
 
     public EarTypeProvider() {
-        this.type = new DefaultType(
-                NAME,
-                Type.LANGUAGE_JAVA,
-                "ear",
-                null,
-                new 
DefaultDependencyProperties(DependencyProperties.FLAG_INCLUDES_DEPENDENCIES));
+        this.type = new DefaultType(NAME, Language.JAVA_FAMILY, "ear", null, 
false, true);
     }
 
     @Override
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/EjbClientTypeProvider.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/EjbClientTypeProvider.java
index efbfe05a1c..a1a97dfcbb 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/EjbClientTypeProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/EjbClientTypeProvider.java
@@ -22,9 +22,8 @@ import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
-import org.apache.maven.api.DependencyProperties;
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
-import org.apache.maven.internal.impl.DefaultDependencyProperties;
 import org.apache.maven.internal.impl.DefaultType;
 
 @Named(EjbClientTypeProvider.NAME)
@@ -35,12 +34,7 @@ public class EjbClientTypeProvider implements Provider<Type> 
{
     private final Type type;
 
     public EjbClientTypeProvider() {
-        this.type = new DefaultType(
-                NAME,
-                Type.LANGUAGE_JAVA,
-                "jar",
-                "client",
-                new 
DefaultDependencyProperties(DependencyProperties.FLAG_CLASS_PATH_CONSTITUENT));
+        this.type = new DefaultType(NAME, Language.JAVA_FAMILY, "jar", 
"client", true, false);
     }
 
     @Override
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/EjbTypeProvider.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/EjbTypeProvider.java
index e6f8fbdb4b..01a8dfcb9f 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/EjbTypeProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/EjbTypeProvider.java
@@ -22,9 +22,8 @@ import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
-import org.apache.maven.api.DependencyProperties;
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
-import org.apache.maven.internal.impl.DefaultDependencyProperties;
 import org.apache.maven.internal.impl.DefaultType;
 
 @Named(EjbTypeProvider.NAME)
@@ -35,12 +34,7 @@ public class EjbTypeProvider implements Provider<Type> {
     private final Type type;
 
     public EjbTypeProvider() {
-        this.type = new DefaultType(
-                NAME,
-                Type.LANGUAGE_JAVA,
-                "jar",
-                null,
-                new 
DefaultDependencyProperties(DependencyProperties.FLAG_CLASS_PATH_CONSTITUENT));
+        this.type = new DefaultType(NAME, Language.JAVA_FAMILY, "jar", null, 
true, false);
     }
 
     @Override
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/JarTypeProvider.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/JarTypeProvider.java
index 974c34e0ed..df61f6bd3b 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/JarTypeProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/JarTypeProvider.java
@@ -22,9 +22,8 @@ import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
-import org.apache.maven.api.DependencyProperties;
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
-import org.apache.maven.internal.impl.DefaultDependencyProperties;
 import org.apache.maven.internal.impl.DefaultType;
 
 @Named(JarTypeProvider.NAME)
@@ -35,12 +34,7 @@ public class JarTypeProvider implements Provider<Type> {
     private final Type type;
 
     public JarTypeProvider() {
-        this.type = new DefaultType(
-                NAME,
-                Type.LANGUAGE_JAVA,
-                "jar",
-                null,
-                new 
DefaultDependencyProperties(DependencyProperties.FLAG_CLASS_PATH_CONSTITUENT));
+        this.type = new DefaultType(NAME, Language.JAVA_FAMILY, "jar", null, 
true, false);
     }
 
     @Override
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/JavaSourceTypeProvider.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/JavaSourceTypeProvider.java
index bef8acf716..4e90d4591a 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/JavaSourceTypeProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/JavaSourceTypeProvider.java
@@ -22,8 +22,8 @@ import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
-import org.apache.maven.internal.impl.DefaultDependencyProperties;
 import org.apache.maven.internal.impl.DefaultType;
 
 @Named(JavaSourceTypeProvider.NAME)
@@ -34,7 +34,7 @@ public class JavaSourceTypeProvider implements Provider<Type> 
{
     private final Type type;
 
     public JavaSourceTypeProvider() {
-        this.type = new DefaultType(NAME, Type.LANGUAGE_JAVA, "jar", 
"sources", new DefaultDependencyProperties());
+        this.type = new DefaultType(NAME, Language.JAVA_FAMILY, "jar", 
"sources", false, false);
     }
 
     @Override
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/JavadocTypeProvider.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/JavadocTypeProvider.java
index 1ccac4f04b..1f6e9aee8f 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/JavadocTypeProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/JavadocTypeProvider.java
@@ -22,9 +22,8 @@ import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
-import org.apache.maven.api.DependencyProperties;
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
-import org.apache.maven.internal.impl.DefaultDependencyProperties;
 import org.apache.maven.internal.impl.DefaultType;
 
 @Named(JavadocTypeProvider.NAME)
@@ -35,12 +34,7 @@ public class JavadocTypeProvider implements Provider<Type> {
     private final Type type;
 
     public JavadocTypeProvider() {
-        this.type = new DefaultType(
-                NAME,
-                Type.LANGUAGE_JAVA,
-                "jar",
-                "javadoc",
-                new 
DefaultDependencyProperties(DependencyProperties.FLAG_CLASS_PATH_CONSTITUENT));
+        this.type = new DefaultType(NAME, Language.JAVA_FAMILY, "jar", 
"javadoc", true, false);
     }
 
     @Override
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/MavenPluginTypeProvider.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/MavenPluginTypeProvider.java
index bfdb424c27..ec5a45ff55 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/MavenPluginTypeProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/MavenPluginTypeProvider.java
@@ -22,9 +22,8 @@ import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
-import org.apache.maven.api.DependencyProperties;
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
-import org.apache.maven.internal.impl.DefaultDependencyProperties;
 import org.apache.maven.internal.impl.DefaultType;
 
 @Named(MavenPluginTypeProvider.NAME)
@@ -35,12 +34,7 @@ public class MavenPluginTypeProvider implements 
Provider<Type> {
     private final Type type;
 
     public MavenPluginTypeProvider() {
-        this.type = new DefaultType(
-                NAME,
-                Type.LANGUAGE_JAVA,
-                "jar",
-                null,
-                new 
DefaultDependencyProperties(DependencyProperties.FLAG_CLASS_PATH_CONSTITUENT));
+        this.type = new DefaultType(NAME, Language.JAVA_FAMILY, "jar", null, 
true, false);
     }
 
     @Override
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/ParTypeProvider.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/ParTypeProvider.java
index 91db9ba182..b804b69597 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/ParTypeProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/ParTypeProvider.java
@@ -22,9 +22,8 @@ import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
-import org.apache.maven.api.DependencyProperties;
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
-import org.apache.maven.internal.impl.DefaultDependencyProperties;
 import org.apache.maven.internal.impl.DefaultType;
 
 @Named(ParTypeProvider.NAME)
@@ -35,12 +34,7 @@ public class ParTypeProvider implements Provider<Type> {
     private final Type type;
 
     public ParTypeProvider() {
-        this.type = new DefaultType(
-                NAME,
-                Type.LANGUAGE_JAVA,
-                "par",
-                null,
-                new 
DefaultDependencyProperties(DependencyProperties.FLAG_INCLUDES_DEPENDENCIES));
+        this.type = new DefaultType(NAME, Language.JAVA_FAMILY, "par", null, 
false, true);
     }
 
     @Override
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/PomTypeProvider.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/PomTypeProvider.java
index fe0f9705d0..9f38564116 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/PomTypeProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/PomTypeProvider.java
@@ -22,8 +22,8 @@ import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
-import org.apache.maven.internal.impl.DefaultDependencyProperties;
 import org.apache.maven.internal.impl.DefaultType;
 
 @Named(PomTypeProvider.NAME)
@@ -34,7 +34,7 @@ public class PomTypeProvider implements Provider<Type> {
     private final Type type;
 
     public PomTypeProvider() {
-        this.type = new DefaultType(NAME, Type.LANGUAGE_NONE, "pom", null, new 
DefaultDependencyProperties());
+        this.type = new DefaultType(NAME, Language.NONE, "pom", null, false, 
false);
     }
 
     @Override
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/RarTypeProvider.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/RarTypeProvider.java
index ad5accd3cd..39e36777c0 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/RarTypeProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/RarTypeProvider.java
@@ -22,9 +22,8 @@ import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
-import org.apache.maven.api.DependencyProperties;
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
-import org.apache.maven.internal.impl.DefaultDependencyProperties;
 import org.apache.maven.internal.impl.DefaultType;
 
 @Named(RarTypeProvider.NAME)
@@ -35,12 +34,7 @@ public class RarTypeProvider implements Provider<Type> {
     private final Type type;
 
     public RarTypeProvider() {
-        this.type = new DefaultType(
-                NAME,
-                Type.LANGUAGE_JAVA,
-                "rar",
-                null,
-                new 
DefaultDependencyProperties(DependencyProperties.FLAG_INCLUDES_DEPENDENCIES));
+        this.type = new DefaultType(NAME, Language.JAVA_FAMILY, "rar", null, 
false, true);
     }
 
     @Override
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/TestJarTypeProvider.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/TestJarTypeProvider.java
index 6bd7ea2da7..39f9653e9f 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/TestJarTypeProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/TestJarTypeProvider.java
@@ -22,9 +22,8 @@ import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
-import org.apache.maven.api.DependencyProperties;
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
-import org.apache.maven.internal.impl.DefaultDependencyProperties;
 import org.apache.maven.internal.impl.DefaultType;
 
 @Named(TestJarTypeProvider.NAME)
@@ -35,12 +34,7 @@ public class TestJarTypeProvider implements Provider<Type> {
     private final Type type;
 
     public TestJarTypeProvider() {
-        this.type = new DefaultType(
-                NAME,
-                Type.LANGUAGE_JAVA,
-                "jar",
-                "tests",
-                new 
DefaultDependencyProperties(DependencyProperties.FLAG_CLASS_PATH_CONSTITUENT));
+        this.type = new DefaultType(NAME, Language.JAVA_FAMILY, "jar", 
"tests", true, false);
     }
 
     @Override
diff --git 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/WarTypeProvider.java
 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/WarTypeProvider.java
index a2b339001d..732ff09a7e 100644
--- 
a/maven-core/src/main/java/org/apache/maven/internal/impl/types/WarTypeProvider.java
+++ 
b/maven-core/src/main/java/org/apache/maven/internal/impl/types/WarTypeProvider.java
@@ -22,9 +22,8 @@ import javax.inject.Named;
 import javax.inject.Provider;
 import javax.inject.Singleton;
 
-import org.apache.maven.api.DependencyProperties;
+import org.apache.maven.api.Language;
 import org.apache.maven.api.Type;
-import org.apache.maven.internal.impl.DefaultDependencyProperties;
 import org.apache.maven.internal.impl.DefaultType;
 
 @Named(WarTypeProvider.NAME)
@@ -35,12 +34,7 @@ public class WarTypeProvider implements Provider<Type> {
     private final Type type;
 
     public WarTypeProvider() {
-        this.type = new DefaultType(
-                NAME,
-                Type.LANGUAGE_JAVA,
-                "war",
-                null,
-                new 
DefaultDependencyProperties(DependencyProperties.FLAG_INCLUDES_DEPENDENCIES));
+        this.type = new DefaultType(NAME, Language.JAVA_FAMILY, "war", null, 
false, true);
     }
 
     @Override
diff --git 
a/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java
 
b/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java
index 8feff06717..dd6beba8af 100644
--- 
a/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java
+++ 
b/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java
@@ -34,6 +34,7 @@ import 
org.apache.maven.execution.DefaultMavenExecutionRequest;
 import org.apache.maven.execution.DefaultMavenExecutionResult;
 import org.apache.maven.execution.MavenExecutionRequest;
 import org.apache.maven.execution.MavenSession;
+import org.apache.maven.internal.impl.DefaultLookup;
 import org.apache.maven.internal.impl.DefaultSessionFactory;
 import org.apache.maven.model.Build;
 import org.apache.maven.model.Dependency;
@@ -149,7 +150,7 @@ public abstract class AbstractCoreMavenComponentTestCase {
         initRepoSession(configuration);
 
         DefaultSessionFactory defaultSessionFactory =
-                new DefaultSessionFactory(mock(RepositorySystem.class), null, 
null, null);
+                new DefaultSessionFactory(mock(RepositorySystem.class), null, 
new DefaultLookup(container), null);
 
         MavenSession session = new MavenSession(
                 getContainer(), configuration.getRepositorySession(), request, 
new DefaultMavenExecutionResult());
diff --git 
a/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java 
b/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java
index 8f2ec04eb9..18ce020307 100644
--- a/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java
+++ b/maven-core/src/test/java/org/apache/maven/internal/impl/TestApi.java
@@ -30,13 +30,7 @@ import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
-import org.apache.maven.api.Artifact;
-import org.apache.maven.api.ArtifactCoordinate;
-import org.apache.maven.api.Dependency;
-import org.apache.maven.api.Node;
-import org.apache.maven.api.Project;
-import org.apache.maven.api.ResolutionScope;
-import org.apache.maven.api.Session;
+import org.apache.maven.api.*;
 import org.apache.maven.api.services.DependencyResolver;
 import org.apache.maven.api.services.DependencyResolverResult;
 import org.apache.maven.api.services.ProjectBuilder;
@@ -200,7 +194,7 @@ class TestApi {
         assertNotNull(root);
 
         DependencyResolverResult result =
-                session.getService(DependencyResolver.class).resolve(session, 
project, ResolutionScope.PROJECT_RUNTIME);
+                session.getService(DependencyResolver.class).resolve(session, 
project, PathScope.MAIN_RUNTIME);
         assertNotNull(result);
         List<Dependency> deps = new 
ArrayList<>(result.getDependencies().keySet());
         List<Dependency> deps2 = result.getNodes().stream()
diff --git 
a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/scopes/MavenDependencyScopes.java
 
b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/scopes/MavenDependencyScopes.java
index 2d074a4e07..fa0fe5b8f7 100644
--- 
a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/scopes/MavenDependencyScopes.java
+++ 
b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/scopes/MavenDependencyScopes.java
@@ -18,7 +18,7 @@
  */
 package org.apache.maven.repository.internal.scopes;
 
-import org.eclipse.aether.util.artifact.DependencyScopes;
+import org.apache.maven.api.DependencyScope;
 
 /**
  * The dependency scopes used for Java dependencies in Maven. This class 
defines labels only, that are doing pass-thru
@@ -31,21 +31,23 @@ public final class MavenDependencyScopes {
     /**
      * Important: keep this label in sync with Resolver.
      */
-    public static final String SYSTEM = DependencyScopes.SYSTEM;
+    public static final String SYSTEM = DependencyScope.SYSTEM.id();
 
-    public static final String COMPILE_ONLY = "compile-only";
+    public static final String NONE = DependencyScope.NONE.id();
 
-    public static final String COMPILE = "compile";
+    public static final String COMPILE_ONLY = 
DependencyScope.COMPILE_ONLY.id();
 
-    public static final String PROVIDED = "provided";
+    public static final String COMPILE = DependencyScope.COMPILE.id();
 
-    public static final String RUNTIME = "runtime";
+    public static final String PROVIDED = DependencyScope.PROVIDED.id();
 
-    public static final String TEST_ONLY = "test-only";
+    public static final String RUNTIME = DependencyScope.RUNTIME.id();
 
-    public static final String TEST = "test";
+    public static final String TEST_ONLY = DependencyScope.TEST_ONLY.id();
 
-    public static final String TEST_RUNTIME = "test-runtime";
+    public static final String TEST = DependencyScope.TEST.id();
+
+    public static final String TEST_RUNTIME = 
DependencyScope.TEST_RUNTIME.id();
 
     private MavenDependencyScopes() {
         // hide constructor

Reply via email to