/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.prestosql.plugin.session;

import com.google.common.collect.ImmutableMap;
import io.prestosql.spi.session.SessionConfigurationContext;
import io.prestosql.spi.session.SessionPropertyConfigurationManager;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;

import static com.google.common.collect.ImmutableMap.toImmutableMap;

public abstract class AbstractSessionPropertyManager
        implements SessionPropertyConfigurationManager
{
    @Override
    public final Map<String, String> getSystemSessionProperties(SessionConfigurationContext context)
    {
        return getSessionProperties(context)
                .entrySet()
                .stream()
                .filter(property -> !isCatalogSessionProperty(property))
                .collect(toImmutableMap(Entry::getKey, Entry::getValue));
    }

    @Override
    public final Map<String, Map<String, String>> getCatalogSessionProperties(SessionConfigurationContext context)
    {
        Map<String, ImmutableMap.Builder<String, String>> catalogsSessionProperties = new HashMap<>();
        getSessionProperties(context)
                .entrySet()
                .stream()
                .filter(property -> isCatalogSessionProperty(property))
                .forEach(catalogProperty -> {
                    String[] property = catalogProperty.getKey().split("\\.", 2);
                    String propertyCatalog = property[0];
                    String propertyName = property[1];
                    catalogsSessionProperties.compute(propertyCatalog, (catalog, properties) -> {
                        ImmutableMap.Builder<String, String> catalogPropertiesBuilder =
                                Optional.ofNullable(properties).orElseGet(ImmutableMap::builder);
                        catalogPropertiesBuilder.put(propertyName, catalogProperty.getValue());
                        return catalogPropertiesBuilder;
                    });
                });
        return catalogsSessionProperties
                .entrySet()
                .stream()
                .collect(toImmutableMap(Entry::getKey, entry -> entry.getValue().build()));
    }

    protected abstract List<SessionMatchSpec> getSessionMatchSpecs();

    private Map<String, String> getSessionProperties(SessionConfigurationContext context)
    {
        // later properties override earlier properties
        Map<String, String> combinedProperties = new HashMap<>();
        for (SessionMatchSpec sessionMatchSpec : getSessionMatchSpecs()) {
            combinedProperties.putAll(sessionMatchSpec.match(context));
        }
        return combinedProperties;
    }

    private static boolean isCatalogSessionProperty(Entry<String, String> property)
    {
        return property.getKey().contains(".");
    }
}

@@ -626,28 +626,21 @@
 collect.
-Immut
+T
 able
-Map
 ;%0Aimport
@@ -866,35 +866,8 @@
 try;
-%0Aimport java.util.Optional;
 %0A%0Aim
@@ -932,16 +932,89 @@
 ableMap;
+%0Aimport static com.google.common.collect.ImmutableTable.toImmutableTable;
 %0A%0Apublic
@@ -1246,22 +1246,55 @@
         
-return
+Map%3CString, String%3E sessionProperties =
  getSess
@@ -1307,32 +1307,33 @@
 perties(context)
+;
 %0A               
@@ -1329,44 +1329,43 @@
     
-        .entrySet()%0A                
+return sessionProperties.entrySet()
 .str
@@ -1683,98 +1683,35 @@
 ng, 
-ImmutableMap.Builder%3CString, String%3E%3E catalogsSessionProperties = new HashMap%3C%3E();%0A       
+String%3E sessionProperties =
  get
@@ -1736,31 +1736,26 @@
 context)
+;
 %0A
-      
         
   .entry
@@ -1750,93 +1750,46 @@
     
-  .entrySet()%0A                .stream()%0A                .filter(property -%3E isC
+Table%3CString, String, String%3E c
 atalog
+s
 Sess
@@ -1802,927 +1802,444 @@
 pert
-y(property))%0A                .forEach(catalogProperty -%3E %7B%0A                    String%5B%5D property = catalogProperty.getKey().split(%22%5C%5C.%22, 2);%0A                    String propertyCatalog = property%5B0%5D;%0A                    String propertyName = property%5B1%5D;%0A                    catalogsSessionProperties.compute(propertyCatalog, (catalog, properties) -%3E %7B%0A                        ImmutableMap.Builder%3CString, String%3E catalogPropertiesBuilder =%0A                                Optional.ofNullable(properties).orElseGet(ImmutableMap::builder);%0A                        catalogPropertiesBuilder.put(propertyName, catalogProperty.getValue());%0A                        return catalogPropertiesBuilder;%0A                    %7D);%0A                %7D);%0A        return catalogsSessionProperties%0A                .entrySet()%0A                .stream()%0A                .collect(toImmutableMap(Entry::getKey, entry -%3E entry.getValue().build())
+ies = sessionProperties.entrySet().stream()%0A                .filter(AbstractSessionPropertyManager::isCatalogSessionProperty)%0A                .collect(toImmutableTable(%0A                        catalogProperty -%3E catalogProperty.getKey().split(%22%5C%5C.%22, 2)%5B0%5D,%0A                        catalogProperty -%3E catalogProperty.getKey().split(%22%5C%5C.%22, 2)%5B1%5D,%0A                        Entry::getValue));%0A        return catalogsSessionProperties.rowMap(
 );%0A 

Simplify code