class DefaultSession extends AbstractSession implements InternalMavenSession {

    private final MavenSession mavenSession;
    private final MavenRepositorySystem mavenRepositorySystem;
    private final RuntimeInformation runtimeInformation;
    private final Map<String, Project> allProjects = Collections.synchronizedMap(new WeakHashMap<>());

    @SuppressWarnings("checkstyle:ParameterNumber")
    public DefaultSession(
            @Nonnull MavenSession session,
            @Nonnull RepositorySystem repositorySystem,
            @Nullable List<RemoteRepository> remoteRepositories,
            @Nonnull MavenRepositorySystem mavenRepositorySystem,
            @Nonnull Lookup lookup,
            @Nonnull RuntimeInformation runtimeInformation) {
        super(
                nonNull(session).getRepositorySession(),
                repositorySystem,
                remoteRepositories,
                remoteRepositories == null
                        ? map(session.getRequest().getRemoteRepositories(), RepositoryUtils::toRepo)
                        : null,
                lookup);
        this.mavenSession = session;
        this.mavenRepositorySystem = mavenRepositorySystem;
        this.runtimeInformation = runtimeInformation;
    }

    public MavenSession getMavenSession() {
        return mavenSession;
    }

    @Override
    public List<Project> getProjects(List<MavenProject> projects) {
        return projects == null ? null : map(projects, this::getProject);
    }

    @Override
    public Project getProject(MavenProject project) {
        return allProjects.computeIfAbsent(project.getId(), id -> new DefaultProject(this, project));
    }

    @Override
    public List<ArtifactRepository> toArtifactRepositories(List<RemoteRepository> repositories) {
        return repositories == null ? null : map(repositories, this::toArtifactRepository);
    }

    @Nonnull
    @Override
    public Settings getSettings() {
        return mavenSession.getSettings().getDelegate();
    }

    @Nonnull
    @Override
    public Map<String, String> getUserProperties() {
        return Collections.unmodifiableMap(new PropertiesAsMap(mavenSession.getUserProperties()));
    }

    @Nonnull
    @Override
    public Map<String, String> getSystemProperties() {
        return Collections.unmodifiableMap(new PropertiesAsMap(mavenSession.getSystemProperties()));
    }

    @Nonnull
    @Override
    public Map<String, String> getEffectiveProperties(@Nullable Project project) {
        HashMap<String, String> result = new HashMap<>(getSystemProperties());
        if (project != null) {
            result.putAll(project.getModel().getProperties());
        }
        result.putAll(getUserProperties());
        return result;
    }

    @Nonnull
    @Override
    public Version getMavenVersion() {
        return parseVersion(runtimeInformation.getMavenVersion());
    }

    @Override
    public int getDegreeOfConcurrency() {
        return mavenSession.getRequest().getDegreeOfConcurrency();
    }

    @Nonnull
    @Override
    public Instant getStartTime() {
        return mavenSession.getRequest().getStartTime().toInstant();
    }

    @Override
    public Path getRootDirectory() {
        return mavenSession.getRequest().getRootDirectory();
    }

    @Override
    public Path getTopDirectory() {
        return mavenSession.getRequest().getTopDirectory();
    }

    @Nonnull
    @Override
    public List<Project> getProjects() {
        return getProjects(mavenSession.getProjects());
    }

    @Nonnull
    @Override
    public Map<String, Object> getPluginContext(Project project) {
        nonNull(project, "project");
        try {
            MojoExecution mojoExecution = lookup.lookup(MojoExecution.class);
            MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
            PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
            return mavenSession.getPluginContext(pluginDescriptor, ((DefaultProject) project).getProject());
        } catch (LookupException e) {
            throw new MavenException("The PluginContext is only available during a mojo execution", e);
        }
    }

    protected Session newSession(RepositorySystemSession repoSession, List<RemoteRepository> repositories) {
        final MavenSession ms = nonNull(mavenSession);
        final MavenSession mss;
        if (repoSession != ms.getRepositorySession()) {
            mss = new MavenSession(repoSession, ms.getRequest(), ms.getResult());
        } else {
            mss = ms;
        }
        return newSession(mss, repositories);
    }

    protected Session newSession(MavenSession mavenSession, List<RemoteRepository> repositories) {
        return new DefaultSession(
                nonNull(mavenSession),
                getRepositorySystem(),
                repositories,
                mavenRepositorySystem,
                lookup,
                runtimeInformation);
    }

    public ArtifactRepository toArtifactRepository(RemoteRepository repository) {<FILL_FUNCTION_BODY>}
}

        if (repository instanceof DefaultRemoteRepository) {
            org.eclipse.aether.repository.RemoteRepository rr = ((DefaultRemoteRepository) repository).getRepository();

            try {
                return mavenRepositorySystem.createRepository(
                        rr.getUrl(),
                        rr.getId(),
                        rr.getPolicy(false).isEnabled(),
                        rr.getPolicy(false).getUpdatePolicy(),
                        rr.getPolicy(true).isEnabled(),
                        rr.getPolicy(true).getUpdatePolicy(),
                        rr.getPolicy(false).getChecksumPolicy());

            } catch (Exception e) {
                throw new RuntimeException("Unable to create repository", e);
            }
        } else {
            // TODO
            throw new UnsupportedOperationException("Not yet implemented");
        }
    
<methods>public void <init>(RepositorySystemSession, RepositorySystem, List<org.apache.maven.api.RemoteRepository>, List<org.eclipse.aether.repository.RemoteRepository>, org.apache.maven.api.services.Lookup) ,public org.apache.maven.api.Node collectDependencies(org.apache.maven.api.Artifact) ,public org.apache.maven.api.Node collectDependencies(org.apache.maven.api.Project) ,public org.apache.maven.api.Node collectDependencies(org.apache.maven.api.DependencyCoordinate) ,public org.apache.maven.api.Artifact createArtifact(java.lang.String, java.lang.String, java.lang.String, java.lang.String) ,public org.apache.maven.api.Artifact createArtifact(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) ,public org.apache.maven.api.ArtifactCoordinate createArtifactCoordinate(java.lang.String, java.lang.String, java.lang.String, java.lang.String) ,public org.apache.maven.api.ArtifactCoordinate createArtifactCoordinate(java.lang.String) ,public org.apache.maven.api.ArtifactCoordinate createArtifactCoordinate(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) ,public org.apache.maven.api.ArtifactCoordinate createArtifactCoordinate(org.apache.maven.api.Artifact) ,public org.apache.maven.api.DependencyCoordinate createDependencyCoordinate(org.apache.maven.api.ArtifactCoordinate) ,public org.apache.maven.api.DependencyCoordinate createDependencyCoordinate(org.apache.maven.api.Dependency) ,public org.apache.maven.api.LocalRepository createLocalRepository(java.nio.file.Path) ,public org.apache.maven.api.RemoteRepository createRemoteRepository(java.lang.String, java.lang.String) ,public org.apache.maven.api.RemoteRepository createRemoteRepository(Repository) ,public transient void deployArtifact(org.apache.maven.api.RemoteRepository, org.apache.maven.api.Artifact[]) ,public List<org.apache.maven.api.Node> flattenDependencies(org.apache.maven.api.Node, org.apache.maven.api.PathScope) ,public org.apache.maven.api.Artifact getArtifact(org.eclipse.aether.artifact.Artifact) ,public Optional<java.nio.file.Path> getArtifactPath(org.apache.maven.api.Artifact) ,public org.apache.maven.api.SessionData getData() ,public org.apache.maven.api.Dependency getDependency(org.eclipse.aether.graph.Dependency) ,public Collection<org.apache.maven.api.Listener> getListeners() ,public org.apache.maven.api.LocalRepository getLocalRepository() ,public org.apache.maven.api.Node getNode(org.eclipse.aether.graph.DependencyNode) ,public org.apache.maven.api.Node getNode(org.eclipse.aether.graph.DependencyNode, boolean) ,public java.nio.file.Path getPathForLocalArtifact(org.apache.maven.api.Artifact) ,public java.nio.file.Path getPathForRemoteArtifact(org.apache.maven.api.RemoteRepository, org.apache.maven.api.Artifact) ,public List<org.apache.maven.api.RemoteRepository> getRemoteRepositories() ,public org.apache.maven.api.RemoteRepository getRemoteRepository(org.eclipse.aether.repository.RemoteRepository) ,public RepositorySystem getRepositorySystem() ,public T getService(Class<T>) throws java.util.NoSuchElementException,public RepositorySystemSession getSession() ,public transient void installArtifacts(org.apache.maven.api.Artifact[]) ,public void installArtifacts(Collection<org.apache.maven.api.Artifact>) ,public boolean isVersionSnapshot(java.lang.String) ,public org.apache.maven.api.Version parseVersion(java.lang.String) ,public org.apache.maven.api.VersionConstraint parseVersionConstraint(java.lang.String) ,public org.apache.maven.api.VersionRange parseVersionRange(java.lang.String) ,public void registerListener(org.apache.maven.api.Listener) ,public org.apache.maven.api.DependencyScope requireDependencyScope(java.lang.String) ,public org.apache.maven.api.Language requireLanguage(java.lang.String) ,public org.apache.maven.api.Packaging requirePackaging(java.lang.String) ,public org.apache.maven.api.PathScope requirePathScope(java.lang.String) ,public org.apache.maven.api.ProjectScope requireProjectScope(java.lang.String) ,public org.apache.maven.api.Type requireType(java.lang.String) ,public Entry<org.apache.maven.api.Artifact,java.nio.file.Path> resolveArtifact(org.apache.maven.api.ArtifactCoordinate) ,public Entry<org.apache.maven.api.Artifact,java.nio.file.Path> resolveArtifact(org.apache.maven.api.Artifact) ,public transient Map<org.apache.maven.api.Artifact,java.nio.file.Path> resolveArtifacts(org.apache.maven.api.ArtifactCoordinate[]) ,public Map<org.apache.maven.api.Artifact,java.nio.file.Path> resolveArtifacts(Collection<? extends org.apache.maven.api.ArtifactCoordinate>) ,public transient Map<org.apache.maven.api.Artifact,java.nio.file.Path> resolveArtifacts(org.apache.maven.api.Artifact[]) ,public List<java.nio.file.Path> resolveDependencies(org.apache.maven.api.DependencyCoordinate) ,public List<java.nio.file.Path> resolveDependencies(List<org.apache.maven.api.DependencyCoordinate>) ,public List<java.nio.file.Path> resolveDependencies(org.apache.maven.api.Project, org.apache.maven.api.PathScope) ,public Map<org.apache.maven.api.PathType,List<java.nio.file.Path>> resolveDependencies(org.apache.maven.api.DependencyCoordinate, org.apache.maven.api.PathScope, Collection<org.apache.maven.api.PathType>) ,public Map<org.apache.maven.api.PathType,List<java.nio.file.Path>> resolveDependencies(org.apache.maven.api.Project, org.apache.maven.api.PathScope, Collection<org.apache.maven.api.PathType>) ,public org.apache.maven.api.Version resolveVersion(org.apache.maven.api.ArtifactCoordinate) ,public List<org.apache.maven.api.Version> resolveVersionRange(org.apache.maven.api.ArtifactCoordinate) ,public void setArtifactPath(org.apache.maven.api.Artifact, java.nio.file.Path) ,public org.eclipse.aether.artifact.Artifact toArtifact(org.apache.maven.api.Artifact) ,public org.eclipse.aether.artifact.Artifact toArtifact(org.apache.maven.api.ArtifactCoordinate) ,public List<org.eclipse.aether.artifact.Artifact> toArtifacts(Collection<org.apache.maven.api.Artifact>) ,public List<org.eclipse.aether.graph.Dependency> toDependencies(Collection<org.apache.maven.api.DependencyCoordinate>, boolean) ,public org.eclipse.aether.graph.Dependency toDependency(org.apache.maven.api.DependencyCoordinate, boolean) ,public List<org.eclipse.aether.repository.RemoteRepository> toRepositories(List<org.apache.maven.api.RemoteRepository>) ,public org.eclipse.aether.repository.RemoteRepository toRepository(org.apache.maven.api.RemoteRepository) ,public org.eclipse.aether.repository.LocalRepository toRepository(org.apache.maven.api.LocalRepository) ,public void unregisterListener(org.apache.maven.api.Listener) ,public org.apache.maven.api.Session withLocalRepository(org.apache.maven.api.LocalRepository) ,public org.apache.maven.api.Session withRemoteRepositories(List<org.apache.maven.api.RemoteRepository>) <variables>private final Map<org.eclipse.aether.artifact.Artifact,org.apache.maven.api.Artifact> allArtifacts,private final Map<org.eclipse.aether.graph.Dependency,org.apache.maven.api.Dependency> allDependencies,private final Map<org.eclipse.aether.graph.DependencyNode,org.apache.maven.api.Node> allNodes,private final Map<org.eclipse.aether.repository.RemoteRepository,org.apache.maven.api.RemoteRepository> allRepositories,private final List<org.apache.maven.api.Listener> listeners,protected final non-sealed org.apache.maven.api.services.Lookup lookup,protected final non-sealed List<org.apache.maven.api.RemoteRepository> repositories,protected final non-sealed RepositorySystem repositorySystem,private final Map<Class<? extends org.apache.maven.api.Service>,org.apache.maven.api.Service> services,protected final non-sealed RepositorySystemSession session