From fc2d71f51d9375075bc8b563dec87371dab13d5a Mon Sep 17 00:00:00 2001
From: Anatol Sialitski <asi@enonic.com>
Date: Fri, 6 Oct 2023 14:50:28 +0200
Subject: [PATCH] Remove deprecated source code #557

---
 .../app/guillotine/graphql/Constants.java     |   2 -
 .../app/guillotine/graphql/GraphQLApi.java    |  17 +-
 .../guillotine/graphql/GuillotineContext.java |  42 +---
 .../graphql/commands/GetContentCommand.java   |   2 +-
 .../graphql/factory/ContentTypesFactory.java  |  16 +-
 .../factory/HeadlessCmsTypeFactory.java       |  39 +---
 .../graphql/factory/InputTypesFactory.java    |  80 -------
 .../fetchers/BaseContentDataFetcher.java      |  52 ++---
 .../GetAttachmentUrlByIdDataFetcher.java      |   8 +-
 .../GetAttachmentUrlByNameDataFetcher.java    |   7 +-
 .../GetChildrenConnectionDataFetcher.java     |   5 +-
 .../fetchers/GetChildrenDataFetcher.java      |   5 +-
 .../fetchers/GetContentDataFetcher.java       |   5 +-
 .../fetchers/GetContentParentDataFetcher.java |  13 +-
 .../fetchers/GetContentPathDataFetcher.java   |  60 ++----
 .../fetchers/GetImageUrlDataFetcher.java      |   7 +-
 .../fetchers/GetPageUrlDataFetcher.java       |   7 +-
 .../fetchers/GetPermissionsDataFetcher.java   |   5 +-
 .../graphql/fetchers/GetSiteDataFetcher.java  |  30 +--
 .../fetchers/QueryBaseDataFetcher.java        | 203 ++----------------
 .../fetchers/QueryConnectionDataFetcher.java  |  57 -----
 .../graphql/fetchers/QueryDataFetcher.java    |  41 ----
 .../QueryDslConnectionDataFetcher.java        |   6 +-
 .../graphql/fetchers/QueryDslDataFetcher.java |   6 +-
 .../graphql/fetchers/RichTextDataFetcher.java |  34 +--
 .../helper/GuillotineLocalContextHelper.java  |  56 ++---
 .../graphql/helper/SecurityHelper.java        |  40 +---
 src/main/resources/api/api.js                 |  18 +-
 .../graphql/BaseGraphQLIntegrationTest.java   |   2 +-
 .../guillotine/graphql/ContentFixtures.java   |   7 +
 .../GuillotineApiGraphQLIntegrationTest.java  |  54 ++++-
 .../QueryDslGraphQLIntegrationTest.java       |  40 ----
 .../graphql/factory/ContentTypesVerifier.java |  12 --
 .../factory/HeadlessCmsTypeVerifier.java      |  32 +--
 .../graphql/factory/InputTypesVerifier.java   |  83 -------
 .../GetContentParentDataFetcherTest.java      |  88 ++++++++
 .../fetchers/GetSiteDataFetcherTest.java      |  67 ++++++
 .../fetchers/UrlFieldDataFetcherTest.java     | 107 +++++++++
 .../resources/graphql/getContentPath.graphql  |  12 ++
 .../resources/graphql/getSiteField.graphql    |   8 +-
 40 files changed, 474 insertions(+), 901 deletions(-)
 delete mode 100644 src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryConnectionDataFetcher.java
 delete mode 100644 src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryDataFetcher.java
 create mode 100644 src/test/java/com/enonic/app/guillotine/graphql/fetchers/GetContentParentDataFetcherTest.java
 create mode 100644 src/test/java/com/enonic/app/guillotine/graphql/fetchers/GetSiteDataFetcherTest.java
 create mode 100644 src/test/java/com/enonic/app/guillotine/graphql/fetchers/UrlFieldDataFetcherTest.java
 create mode 100644 src/test/resources/graphql/getContentPath.graphql

diff --git a/src/main/java/com/enonic/app/guillotine/graphql/Constants.java b/src/main/java/com/enonic/app/guillotine/graphql/Constants.java
index 3df2cc5d..84ccbb8f 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/Constants.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/Constants.java
@@ -6,8 +6,6 @@ public interface Constants
 {
     String CONTENT_ID_FIELD = "__contentId";
 
-    String GUILLOTINE_LOCAL_CTX = "__guillotineLocalContext";
-
     String GUILLOTINE_TARGET_REPO_CTX = "__targetRepository";
 
     String GUILLOTINE_TARGET_BRANCH_CTX = "__targetBranch";
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/GraphQLApi.java b/src/main/java/com/enonic/app/guillotine/graphql/GraphQLApi.java
index 4f390b6a..60ce4501 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/GraphQLApi.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/GraphQLApi.java
@@ -187,14 +187,11 @@ private void generateGuillotineApi( GraphQLTypesRegister typesRegister )
         typesRegister.addCreationCallback( "Query", guillotineQueryCreationCallback );
 
         typesRegister.addResolver( "Query", "guillotine", environment -> {
-            final Map<String, Object> sourceMap = new HashMap<>();
-
-            sourceMap.put( Constants.GUILLOTINE_TARGET_REPO_CTX, environment.getArgument( "repo" ) );
-            sourceMap.put( Constants.GUILLOTINE_TARGET_BRANCH_CTX, environment.getArgument( "branch" ) );
-            sourceMap.put( Constants.GUILLOTINE_TARGET_SITE_CTX, environment.getArgument( "siteKey" ) );
-
             final Map<String, Object> localContext = environment.getLocalContext();
-            localContext.put( Constants.GUILLOTINE_LOCAL_CTX, sourceMap );
+
+            localContext.put( Constants.GUILLOTINE_TARGET_REPO_CTX, environment.getArgument( "repo" ) );
+            localContext.put( Constants.GUILLOTINE_TARGET_BRANCH_CTX, environment.getArgument( "branch" ) );
+            localContext.put( Constants.GUILLOTINE_TARGET_SITE_CTX, environment.getArgument( "siteKey" ) );
 
             return new Object();
         } );
@@ -208,13 +205,13 @@ private void generateGuillotineApi( GraphQLTypesRegister typesRegister )
         context.getTypeResolvers().forEach( typesRegister::addTypeResolver );
     }
 
-    public Object execute( GraphQLSchema graphQLSchema, String query, ScriptValue variables, ScriptValue queryContext )
+    public Object execute( GraphQLSchema graphQLSchema, String query, ScriptValue variables )
     {
         GraphQL graphQL = GraphQL.newGraphQL( graphQLSchema ).build();
 
         ExecutionInput executionInput =
-            ExecutionInput.newExecutionInput().query( query ).variables( extractValue( variables ) ).graphQLContext(
-                extractValue( queryContext ) ).localContext( new HashMap<String, Object>() ).build();
+            ExecutionInput.newExecutionInput().query( query ).variables( extractValue( variables ) ).localContext(
+                new HashMap<String, Object>() ).build();
 
         return new ExecutionResultMapper( graphQL.execute( executionInput ) );
     }
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/GuillotineContext.java b/src/main/java/com/enonic/app/guillotine/graphql/GuillotineContext.java
index 2e500c15..91928359 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/GuillotineContext.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/GuillotineContext.java
@@ -1,5 +1,6 @@
 package com.enonic.app.guillotine.graphql;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -7,6 +8,7 @@
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
 import graphql.schema.DataFetcher;
@@ -19,8 +21,6 @@
 import graphql.schema.TypeResolver;
 
 import com.enonic.xp.macro.MacroDescriptor;
-import com.enonic.xp.portal.PortalRequest;
-import com.enonic.xp.portal.PortalRequestAccessor;
 
 public class GuillotineContext
 {
@@ -36,42 +36,21 @@ public class GuillotineContext
 
     private final ConcurrentMap<String, TypeResolver> typeResolvers = new ConcurrentHashMap<>();
 
-    private final CopyOnWriteArrayList<String> applications;
+    private final ImmutableList<String> applications;
 
     private final ImmutableMap<String, MacroDescriptor> macroDecorators;
 
-    private final CopyOnWriteArrayList<String> allowPaths;
-
     private GuillotineContext( final Builder builder )
     {
-        this.applications = builder.applications;
-        this.allowPaths = builder.allowPaths;
+        this.applications = ImmutableList.<String>builder().addAll( builder.applications ).build();
         this.macroDecorators = ImmutableMap.<String, MacroDescriptor>builder().putAll( builder.macroDecorators ).build();
     }
 
-    public boolean isGlobalMode()
-    {
-        if ( options.containsKey( "__globalModeOn" ) )
-        {
-            return options.get( "__globalModeOn" ) == null || (boolean) options.get( "__globalModeOn" );
-        }
-
-        PortalRequest portalRequest = PortalRequestAccessor.get();
-        boolean globalModeOn = portalRequest.getSite() == null;
-        options.put( "__globalModeOn", globalModeOn );
-        return globalModeOn;
-    }
-
     public List<String> getApplications()
     {
         return applications;
     }
 
-    public List<String> getAllowPaths()
-    {
-        return allowPaths;
-    }
-
     public Map<String, MacroDescriptor> getMacroDecorators()
     {
         return macroDecorators;
@@ -158,9 +137,7 @@ public static Builder create()
     public static final class Builder
     {
 
-        private final CopyOnWriteArrayList<String> applications = new CopyOnWriteArrayList<>();
-
-        private final CopyOnWriteArrayList<String> allowPaths = new CopyOnWriteArrayList<>();
+        private final List<String> applications = new ArrayList<>();
 
         private final Map<String, MacroDescriptor> macroDecorators = new HashMap<>();
 
@@ -178,15 +155,6 @@ public Builder addApplications( final List<String> applications )
             return this;
         }
 
-        public Builder addAllowPaths( final List<String> allowPaths )
-        {
-            if ( allowPaths != null )
-            {
-                this.allowPaths.addAll( allowPaths );
-            }
-            return this;
-        }
-
         public Builder addMacroDecorators( final Map<String, MacroDescriptor> macroDecorators )
         {
             if ( macroDecorators != null )
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/commands/GetContentCommand.java b/src/main/java/com/enonic/app/guillotine/graphql/commands/GetContentCommand.java
index 0f38c91f..fddb5045 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/commands/GetContentCommand.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/commands/GetContentCommand.java
@@ -27,7 +27,7 @@ public Map<String, Object> execute( String key, DataFetchingEnvironment environm
 
     private Map<String, Object> doExecute( String key )
     {
-        if ( key == null )
+        if ( key == null || key.isEmpty() )
         {
             return null;
         }
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/factory/ContentTypesFactory.java b/src/main/java/com/enonic/app/guillotine/graphql/factory/ContentTypesFactory.java
index 46ce3a85..c09c27e2 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/factory/ContentTypesFactory.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/factory/ContentTypesFactory.java
@@ -71,7 +71,6 @@ public void create()
         context.registerType( contentInterface.getName(), contentInterface );
 
         new ConnectionTypeFactory( context ).createConnectionType( contentInterface.getName() );
-        createQueryContentConnectionType();
         createQueryDslContentConnectionType();
 
         GraphQLObjectType untypedContent = newObject( context.uniqueName( "UntypedContent" ), "UntypedContent", List.of( contentInterface ),
@@ -86,17 +85,6 @@ public void create()
         contentTypes.forEach( contentType -> createContentObjectType( contentType, contentInterface ) );
     }
 
-    private void createQueryContentConnectionType()
-    {
-        GraphQLObjectType edgeType = context.getOutputType( "ContentEdge" );
-
-        List<GraphQLFieldDefinition> fields = List.of( outputField( "aggregationsAsJson", ExtendedScalars.Json ) );
-
-        GraphQLObjectType outputObject = new ConnectionTypeFactory( context ).createConnectionType( "QueryContent", edgeType, fields );
-
-        context.registerType( outputObject.getName(), outputObject );
-    }
-
     private void createQueryDslContentConnectionType()
     {
         GraphQLObjectType edgeType = context.getOutputType( "ContentEdge" );
@@ -270,7 +258,7 @@ private List<GraphQLFieldDefinition> getGenericContentFields( String contentType
                                           newArgument( "sort", Scalars.GraphQLString ) ) ) );
         result.add( outputField( "permissions", GraphQLTypeReference.typeRef( "Permissions" ) ) );
 
-        context.registerDataFetcher( contentType, "_path", new GetContentPathDataFetcher( context, serviceFacade.getContentService() ) );
+        context.registerDataFetcher( contentType, "_path", new GetContentPathDataFetcher( serviceFacade.getContentService() ) );
 
         context.registerDataFetcher( contentType, "contentType",
                                      new ContentTypeDataFetcher( serviceFacade.getMixinService(), serviceFacade.getContentTypeService() ) );
@@ -283,7 +271,7 @@ private List<GraphQLFieldDefinition> getGenericContentFields( String contentType
 
         context.registerDataFetcher( contentType, "attachments", new GetAttachmentsDataFetcher() );
 
-        context.registerDataFetcher( contentType, "parent", new GetContentParentDataFetcher( serviceFacade.getContentService(), context ) );
+        context.registerDataFetcher( contentType, "parent", new GetContentParentDataFetcher( serviceFacade.getContentService() ) );
 
         context.registerDataFetcher( contentType, "owner", new GetContentFieldDataFetcher( "owner" ) );
 
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/factory/HeadlessCmsTypeFactory.java b/src/main/java/com/enonic/app/guillotine/graphql/factory/HeadlessCmsTypeFactory.java
index 99add577..cefccd63 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/factory/HeadlessCmsTypeFactory.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/factory/HeadlessCmsTypeFactory.java
@@ -19,8 +19,6 @@
 import com.enonic.app.guillotine.graphql.fetchers.GetSiteDataFetcher;
 import com.enonic.app.guillotine.graphql.fetchers.GetTypeDataFetcher;
 import com.enonic.app.guillotine.graphql.fetchers.GetTypesDataFetcher;
-import com.enonic.app.guillotine.graphql.fetchers.QueryConnectionDataFetcher;
-import com.enonic.app.guillotine.graphql.fetchers.QueryDataFetcher;
 import com.enonic.app.guillotine.graphql.fetchers.QueryDslConnectionDataFetcher;
 import com.enonic.app.guillotine.graphql.fetchers.QueryDslDataFetcher;
 
@@ -48,31 +46,23 @@ public GraphQLObjectType create()
 
         context.registerType( headlessCms.getName(), headlessCms );
 
-        context.registerDataFetcher( headlessCms.getName(), "get",
-                                     new GetContentDataFetcher( context, serviceFacade.getContentService() ) );
+        context.registerDataFetcher( headlessCms.getName(), "get", new GetContentDataFetcher( serviceFacade.getContentService() ) );
 
         context.registerDataFetcher( headlessCms.getName(), "getChildren",
-                                     new GetChildrenDataFetcher( context, serviceFacade.getContentService() ) );
+                                     new GetChildrenDataFetcher( serviceFacade.getContentService() ) );
 
         context.registerDataFetcher( headlessCms.getName(), "getChildrenConnection",
-                                     new GetChildrenConnectionDataFetcher( context, serviceFacade.getContentService() ) );
+                                     new GetChildrenConnectionDataFetcher( serviceFacade.getContentService() ) );
 
         context.registerDataFetcher( headlessCms.getName(), "getPermissions",
-                                     new GetPermissionsDataFetcher( context, serviceFacade.getContentService() ) );
+                                     new GetPermissionsDataFetcher( serviceFacade.getContentService() ) );
 
-        context.registerDataFetcher( headlessCms.getName(), "getSite",
-                                     new GetSiteDataFetcher( context, serviceFacade.getContentService() ) );
+        context.registerDataFetcher( headlessCms.getName(), "getSite", new GetSiteDataFetcher( serviceFacade.getContentService() ) );
 
-        context.registerDataFetcher( headlessCms.getName(), "query", new QueryDataFetcher( context, serviceFacade.getContentService() ) );
-
-        context.registerDataFetcher( headlessCms.getName(), "queryConnection",
-                                     new QueryConnectionDataFetcher( context, serviceFacade.getContentService() ) );
-
-        context.registerDataFetcher( headlessCms.getName(), "queryDsl",
-                                     new QueryDslDataFetcher( context, serviceFacade.getContentService() ) );
+        context.registerDataFetcher( headlessCms.getName(), "queryDsl", new QueryDslDataFetcher( serviceFacade.getContentService() ) );
 
         context.registerDataFetcher( headlessCms.getName(), "queryDslConnection",
-                                     new QueryDslConnectionDataFetcher( context, serviceFacade.getContentService() ) );
+                                     new QueryDslConnectionDataFetcher( serviceFacade.getContentService() ) );
 
         context.registerDataFetcher( headlessCms.getName(), "getType",
                                      new GetTypeDataFetcher( context, serviceFacade.getContentTypeService() ) );
@@ -104,21 +94,6 @@ private List<GraphQLFieldDefinition> createHeadlessCMSFields()
 
         fields.add( outputField( "getSite", GraphQLTypeReference.typeRef( "portal_Site" ) ) );
 
-        fields.add( outputField( "query", new GraphQLList( contentInterface ),
-                                 List.of( newArgument( "query", Scalars.GraphQLString ), newArgument( "offset", Scalars.GraphQLInt ),
-                                          newArgument( "first", Scalars.GraphQLInt ), newArgument( "sort", Scalars.GraphQLString ),
-                                          newArgument( "contentTypes", new GraphQLList( Scalars.GraphQLString ) ),
-                                          newArgument( "filters", new GraphQLList( GraphQLTypeReference.typeRef( "FilterInput" ) ) ) ) ) );
-
-        fields.add( outputField( "queryConnection", GraphQLTypeReference.typeRef( "QueryContentConnection" ),
-                                 List.of( newArgument( "query", new GraphQLNonNull( Scalars.GraphQLString ) ),
-                                          newArgument( "after", Scalars.GraphQLString ), newArgument( "first", Scalars.GraphQLInt ),
-                                          newArgument( "sort", Scalars.GraphQLString ),
-                                          newArgument( "contentTypes", new GraphQLList( Scalars.GraphQLString ) ),
-                                          newArgument( "aggregations",
-                                                       new GraphQLList( GraphQLTypeReference.typeRef( "AggregationInput" ) ) ),
-                                          newArgument( "filters", new GraphQLList( GraphQLTypeReference.typeRef( "FilterInput" ) ) ) ) ) );
-
         fields.add( outputField( "queryDsl", new GraphQLList( contentInterface ),
                                  List.of( newArgument( "query", GraphQLTypeReference.typeRef( "QueryDSLInput" ) ),
                                           newArgument( "offset", Scalars.GraphQLInt ), newArgument( "first", Scalars.GraphQLInt ),
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/factory/InputTypesFactory.java b/src/main/java/com/enonic/app/guillotine/graphql/factory/InputTypesFactory.java
index aefe1082..e9368ff6 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/factory/InputTypesFactory.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/factory/InputTypesFactory.java
@@ -44,13 +44,6 @@ public void create()
         createValueCountAggregationInputType();
         createAggregationInputType();
 
-        createExistsFilterInputType();
-        createNotExistsFilterInputType();
-        createHasValueFilterInputType();
-        createIdsFilterInputType();
-        createBooleanFilterInputType();
-        createFilterInputType();
-
         createDslExpressionValueInputType();
         createTermExpressionDslInputType();
         createLikeDslExpressionInputType();
@@ -249,79 +242,6 @@ private void createAggregationInputType()
         context.registerType( inputObject.getName(), inputObject );
     }
 
-    private void createExistsFilterInputType()
-    {
-        List<GraphQLInputObjectField> fields = new ArrayList<>();
-
-        fields.add( inputField( "field", new GraphQLNonNull( Scalars.GraphQLString ) ) );
-
-        GraphQLInputObjectType inputObject = newInputObject( context.uniqueName( "ExistsFilterInput" ), "ExistsFilter input type", fields );
-        context.registerType( inputObject.getName(), inputObject );
-    }
-
-    private void createNotExistsFilterInputType()
-    {
-        List<GraphQLInputObjectField> fields = new ArrayList<>();
-
-        fields.add( inputField( "field", new GraphQLNonNull( Scalars.GraphQLString ) ) );
-
-        GraphQLInputObjectType inputObject =
-            newInputObject( context.uniqueName( "NotExistsFilterInput" ), "NotExistsFilter input type", fields );
-        context.registerType( inputObject.getName(), inputObject );
-    }
-
-    private void createHasValueFilterInputType()
-    {
-        List<GraphQLInputObjectField> fields = new ArrayList<>();
-
-        fields.add( inputField( "field", new GraphQLNonNull( Scalars.GraphQLString ) ) );
-        fields.add( inputField( "stringValues", new GraphQLList( Scalars.GraphQLString ) ) );
-        fields.add( inputField( "intValues", new GraphQLList( Scalars.GraphQLInt ) ) );
-        fields.add( inputField( "floatValues", new GraphQLList( Scalars.GraphQLFloat ) ) );
-        fields.add( inputField( "booleanValues", new GraphQLList( Scalars.GraphQLBoolean ) ) );
-
-        GraphQLInputObjectType inputObject =
-            newInputObject( context.uniqueName( "HasValueFilterInput" ), "HasValueFilter input type", fields );
-        context.registerType( inputObject.getName(), inputObject );
-    }
-
-    private void createIdsFilterInputType()
-    {
-        List<GraphQLInputObjectField> fields = new ArrayList<>();
-
-        fields.add( inputField( "values", new GraphQLList( Scalars.GraphQLString ) ) );
-
-        GraphQLInputObjectType inputObject = newInputObject( context.uniqueName( "IdsFilterInput" ), "IdsFilter input type", fields );
-        context.registerType( inputObject.getName(), inputObject );
-    }
-
-    private void createBooleanFilterInputType()
-    {
-        List<GraphQLInputObjectField> fields = new ArrayList<>();
-
-        fields.add( inputField( "must", new GraphQLList( GraphQLTypeReference.typeRef( "FilterInput" ) ) ) );
-        fields.add( inputField( "mustNot", new GraphQLList( GraphQLTypeReference.typeRef( "FilterInput" ) ) ) );
-        fields.add( inputField( "should", new GraphQLList( GraphQLTypeReference.typeRef( "FilterInput" ) ) ) );
-
-        GraphQLInputObjectType inputObject =
-            newInputObject( context.uniqueName( "BooleanFilterInput" ), "BooleanFilter input type", fields );
-        context.registerType( inputObject.getName(), inputObject );
-    }
-
-    private void createFilterInputType()
-    {
-        List<GraphQLInputObjectField> fields = new ArrayList<>();
-
-        fields.add( inputField( "boolean", GraphQLTypeReference.typeRef( "BooleanFilterInput" ) ) );
-        fields.add( inputField( "exists", GraphQLTypeReference.typeRef( "ExistsFilterInput" ) ) );
-        fields.add( inputField( "notExists", GraphQLTypeReference.typeRef( "NotExistsFilterInput" ) ) );
-        fields.add( inputField( "hasValue", GraphQLTypeReference.typeRef( "HasValueFilterInput" ) ) );
-        fields.add( inputField( "ids", GraphQLTypeReference.typeRef( "IdsFilterInput" ) ) );
-
-        GraphQLInputObjectType inputObject = newInputObject( context.uniqueName( "FilterInput" ), "Filter input type", fields );
-        context.registerType( inputObject.getName(), inputObject );
-    }
-
     private void createDslExpressionValueInputType()
     {
         List<GraphQLInputObjectField> fields = new ArrayList<>();
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/BaseContentDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/BaseContentDataFetcher.java
index a41ea64c..ef821f6c 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/BaseContentDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/BaseContentDataFetcher.java
@@ -6,8 +6,6 @@
 import graphql.schema.DataFetcher;
 import graphql.schema.DataFetchingEnvironment;
 
-import com.enonic.app.guillotine.graphql.ContentSerializer;
-import com.enonic.app.guillotine.graphql.GuillotineContext;
 import com.enonic.app.guillotine.graphql.commands.GetContentCommand;
 import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
 import com.enonic.app.guillotine.graphql.helper.SecurityHelper;
@@ -16,8 +14,6 @@
 import com.enonic.xp.content.ContentService;
 import com.enonic.xp.context.ContextAccessor;
 import com.enonic.xp.context.ContextBuilder;
-import com.enonic.xp.portal.PortalRequest;
-import com.enonic.xp.portal.PortalRequestAccessor;
 import com.enonic.xp.site.Site;
 
 public abstract class BaseContentDataFetcher
@@ -25,20 +21,15 @@ public abstract class BaseContentDataFetcher
 {
     private final static Pattern SITE_KEY_PATTERN = Pattern.compile( "\\$\\{site\\}" );
 
-    protected final GuillotineContext context;
-
     protected final ContentService contentService;
 
-    public BaseContentDataFetcher( final GuillotineContext context, final ContentService contentService )
+    public BaseContentDataFetcher( final ContentService contentService )
     {
-        this.context = context;
         this.contentService = contentService;
     }
 
     protected Map<String, Object> getContent( DataFetchingEnvironment environment, boolean returnRootContent )
     {
-        PortalRequest portalRequest = PortalRequestAccessor.get();
-
         String siteKey = GuillotineLocalContextHelper.getSiteKey( environment );
 
         String argumentKey = environment.getArgument( "key" );
@@ -46,40 +37,29 @@ protected Map<String, Object> getContent( DataFetchingEnvironment environment, b
         if ( argumentKey != null )
         {
             String key = argumentKey;
-
-            Site site = portalRequest.getSite();
-
-            if ( context.isGlobalMode() && !siteKey.isEmpty() )
+            if ( siteKey != null && !siteKey.isEmpty() )
             {
-                site = getSiteByKey( siteKey );
-            }
-            if ( site != null )
-            {
-                key = argumentKey.replaceAll( SITE_KEY_PATTERN.pattern(), site.getPath().toString() );
-            }
-            if ( SITE_KEY_PATTERN.matcher( key ).find() )
-            {
-                return null;
+                Site site = getSiteByKey( siteKey );
+                if ( site != null )
+                {
+                    key = argumentKey.replaceAll( SITE_KEY_PATTERN.pattern(), site.getPath().toString() );
+                }
             }
-
             return getContentByKey( key, returnRootContent, environment );
         }
         else
         {
-            if ( context.isGlobalMode() )
+            if ( siteKey != null && !siteKey.isEmpty() )
             {
-                if ( !siteKey.isEmpty() )
-                {
-                    return getContentByKey( siteKey, returnRootContent, environment );
-                }
-                if ( returnRootContent )
-                {
-                    return ContextBuilder.from( ContextAccessor.current() ).build().callWith(
-                        () -> new GetContentCommand( contentService ).execute( "/", environment ) );
-                }
+                return getContentByKey( siteKey, returnRootContent, environment );
+            }
+            if ( returnRootContent )
+            {
+                return ContextBuilder.from( ContextAccessor.current() ).build().callWith(
+                    () -> new GetContentCommand( contentService ).execute( "/", environment ) );
             }
-            return ContentSerializer.serialize( portalRequest.getContent() );
         }
+        return null;
     }
 
     private Site getSiteByKey( String siteKey )
@@ -98,6 +78,6 @@ private Map<String, Object> getContentByKey( String key, boolean returnRootConte
             return null;
         }
 
-        return SecurityHelper.filterForbiddenContent( contentAsMap, context );
+        return SecurityHelper.filterForbiddenContent( contentAsMap );
     }
 }
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetAttachmentUrlByIdDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetAttachmentUrlByIdDataFetcher.java
index e0d47d52..4531f921 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetAttachmentUrlByIdDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetAttachmentUrlByIdDataFetcher.java
@@ -7,12 +7,10 @@
 import graphql.schema.DataFetchingEnvironment;
 
 import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
-import com.enonic.xp.branch.Branch;
 import com.enonic.xp.portal.PortalRequest;
 import com.enonic.xp.portal.PortalRequestAccessor;
 import com.enonic.xp.portal.url.AttachmentUrlParams;
 import com.enonic.xp.portal.url.PortalUrlService;
-import com.enonic.xp.repository.RepositoryId;
 
 public class GetAttachmentUrlByIdDataFetcher
     implements DataFetcher<String>
@@ -34,10 +32,8 @@ public String get( final DataFetchingEnvironment environment )
     private String doGet( final DataFetchingEnvironment environment )
     {
         PortalRequest portalRequest = PortalRequestAccessor.get();
-
-        portalRequest.setRepositoryId(
-            RepositoryId.from( GuillotineLocalContextHelper.getRepositoryId( environment, portalRequest.getRepositoryId() ) ) );
-        portalRequest.setBranch( Branch.from( GuillotineLocalContextHelper.getBranch( environment, portalRequest.getBranch() ) ) );
+        portalRequest.setRepositoryId( GuillotineLocalContextHelper.getRepositoryId( environment, portalRequest.getRepositoryId() ) );
+        portalRequest.setBranch( GuillotineLocalContextHelper.getBranch( environment, portalRequest.getBranch() ) );
 
         Map<String, Object> sourceAsMap = environment.getSource();
 
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetAttachmentUrlByNameDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetAttachmentUrlByNameDataFetcher.java
index 90276f4c..92bdccf8 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetAttachmentUrlByNameDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetAttachmentUrlByNameDataFetcher.java
@@ -8,12 +8,10 @@
 
 import com.enonic.app.guillotine.graphql.Constants;
 import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
-import com.enonic.xp.branch.Branch;
 import com.enonic.xp.portal.PortalRequest;
 import com.enonic.xp.portal.PortalRequestAccessor;
 import com.enonic.xp.portal.url.AttachmentUrlParams;
 import com.enonic.xp.portal.url.PortalUrlService;
-import com.enonic.xp.repository.RepositoryId;
 
 public class GetAttachmentUrlByNameDataFetcher
     implements DataFetcher<String>
@@ -35,9 +33,8 @@ public String get( final DataFetchingEnvironment environment )
     private String doGet( final DataFetchingEnvironment environment )
     {
         PortalRequest portalRequest = PortalRequestAccessor.get();
-        portalRequest.setRepositoryId(
-            RepositoryId.from( GuillotineLocalContextHelper.getRepositoryId( environment, portalRequest.getRepositoryId() ) ) );
-        portalRequest.setBranch( Branch.from( GuillotineLocalContextHelper.getBranch( environment, portalRequest.getBranch() ) ) );
+        portalRequest.setRepositoryId( GuillotineLocalContextHelper.getRepositoryId( environment, portalRequest.getRepositoryId() ) );
+        portalRequest.setBranch( GuillotineLocalContextHelper.getBranch( environment, portalRequest.getBranch() ) );
 
         Map<String, Object> attachmentAsMap = environment.getSource();
 
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetChildrenConnectionDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetChildrenConnectionDataFetcher.java
index fd287483..d25d1424 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetChildrenConnectionDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetChildrenConnectionDataFetcher.java
@@ -11,7 +11,6 @@
 
 import com.enonic.app.guillotine.graphql.ArgumentsValidator;
 import com.enonic.app.guillotine.graphql.ContentSerializer;
-import com.enonic.app.guillotine.graphql.GuillotineContext;
 import com.enonic.app.guillotine.graphql.helper.ConnectionHelper;
 import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
 import com.enonic.xp.content.ContentId;
@@ -23,9 +22,9 @@
 public class GetChildrenConnectionDataFetcher
     extends BaseContentDataFetcher
 {
-    public GetChildrenConnectionDataFetcher( final GuillotineContext context, final ContentService contentService )
+    public GetChildrenConnectionDataFetcher( final ContentService contentService )
     {
-        super( context, contentService );
+        super( contentService );
     }
 
     @Override
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetChildrenDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetChildrenDataFetcher.java
index a325ca58..058617b3 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetChildrenDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetChildrenDataFetcher.java
@@ -9,7 +9,6 @@
 
 import com.enonic.app.guillotine.graphql.ArgumentsValidator;
 import com.enonic.app.guillotine.graphql.ContentSerializer;
-import com.enonic.app.guillotine.graphql.GuillotineContext;
 import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
 import com.enonic.xp.content.ContentId;
 import com.enonic.xp.content.ContentNotFoundException;
@@ -21,9 +20,9 @@
 public class GetChildrenDataFetcher
     extends BaseContentDataFetcher
 {
-    public GetChildrenDataFetcher( final GuillotineContext context, final ContentService contentService )
+    public GetChildrenDataFetcher( final ContentService contentService )
     {
-        super( context, contentService );
+        super( contentService );
     }
 
     @Override
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetContentDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetContentDataFetcher.java
index 7750140e..cff8c08f 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetContentDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetContentDataFetcher.java
@@ -2,16 +2,15 @@
 
 import graphql.schema.DataFetchingEnvironment;
 
-import com.enonic.app.guillotine.graphql.GuillotineContext;
 import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
 import com.enonic.xp.content.ContentService;
 
 public class GetContentDataFetcher
     extends BaseContentDataFetcher
 {
-    public GetContentDataFetcher( final GuillotineContext context, final ContentService contentService )
+    public GetContentDataFetcher( final ContentService contentService )
     {
-        super( context, contentService );
+        super( contentService );
     }
 
     @Override
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetContentParentDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetContentParentDataFetcher.java
index 6c1f322d..f42bf354 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetContentParentDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetContentParentDataFetcher.java
@@ -5,10 +5,8 @@
 import graphql.schema.DataFetcher;
 import graphql.schema.DataFetchingEnvironment;
 
-import com.enonic.app.guillotine.graphql.helper.CastHelper;
-import com.enonic.app.guillotine.graphql.GuillotineContext;
-import com.enonic.app.guillotine.graphql.helper.SecurityHelper;
 import com.enonic.app.guillotine.graphql.commands.GetContentCommand;
+import com.enonic.app.guillotine.graphql.helper.SecurityHelper;
 import com.enonic.xp.content.ContentService;
 
 public class GetContentParentDataFetcher
@@ -16,12 +14,9 @@ public class GetContentParentDataFetcher
 {
     private final ContentService contentService;
 
-    private final GuillotineContext guillotineContext;
-
-    public GetContentParentDataFetcher( final ContentService contentService, final GuillotineContext guillotineContext )
+    public GetContentParentDataFetcher( final ContentService contentService )
     {
         this.contentService = contentService;
-        this.guillotineContext = guillotineContext;
     }
 
     @Override
@@ -35,9 +30,7 @@ public Object get( final DataFetchingEnvironment environment )
             return null;
         }
 
-        Object parent = new GetContentCommand( contentService ).execute( parentPath, environment );
-
-        return SecurityHelper.filterForbiddenContent( CastHelper.cast( parent ), guillotineContext );
+        return SecurityHelper.filterForbiddenContent( new GetContentCommand( contentService ).execute( parentPath, environment ) );
     }
 
     private String resolveParentPath( DataFetchingEnvironment environment )
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetContentPathDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetContentPathDataFetcher.java
index bb8b28ab..672576c8 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetContentPathDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetContentPathDataFetcher.java
@@ -6,30 +6,22 @@
 import graphql.schema.DataFetcher;
 import graphql.schema.DataFetchingEnvironment;
 
-import com.enonic.app.guillotine.graphql.GuillotineContext;
+import com.enonic.app.guillotine.graphql.commands.GetContentCommand;
 import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
-import com.enonic.xp.content.ContentId;
-import com.enonic.xp.content.ContentNotFoundException;
-import com.enonic.xp.content.ContentPath;
 import com.enonic.xp.content.ContentService;
 import com.enonic.xp.context.Context;
 import com.enonic.xp.context.ContextAccessor;
 import com.enonic.xp.context.ContextBuilder;
-import com.enonic.xp.portal.PortalRequest;
-import com.enonic.xp.portal.PortalRequestAccessor;
-import com.enonic.xp.security.PrincipalKey;
+import com.enonic.xp.security.RoleKeys;
 import com.enonic.xp.security.auth.AuthenticationInfo;
 
 public class GetContentPathDataFetcher
     implements DataFetcher<String>
 {
-    private final GuillotineContext guillotineContext;
-
     private final ContentService contentService;
 
-    public GetContentPathDataFetcher( final GuillotineContext guillotineContext, final ContentService contentService )
+    public GetContentPathDataFetcher( final ContentService contentService )
     {
-        this.guillotineContext = guillotineContext;
         this.contentService = contentService;
     }
 
@@ -37,25 +29,15 @@ public GetContentPathDataFetcher( final GuillotineContext guillotineContext, fin
     public String get( final DataFetchingEnvironment environment )
         throws Exception
     {
-        PortalRequest portalRequest = PortalRequestAccessor.get();
-
         Map<String, Object> contentAsMap = environment.getSource();
         String originalPath = contentAsMap.get( "_path" ).toString();
+
         if ( Objects.equals( "siteRelative", environment.getArgument( "type" ) ) )
         {
-            String sitePath = adminContext().callWith( () -> {
-                if ( guillotineContext.isGlobalMode() )
-                {
-                    return GuillotineLocalContextHelper.executeInContext( environment, () -> {
-                        String siteKey = GuillotineLocalContextHelper.getSiteKey( environment );
-                        return Objects.toString( getSitePathBySiteKey( siteKey ), originalPath );
-                    } );
-                }
-                else
-                {
-                    return portalRequest.getSite().getPath().toString();
-                }
-            } );
+            String sitePath = adminContext().callWith( () -> GuillotineLocalContextHelper.executeInContext( environment, () -> {
+                String siteKey = GuillotineLocalContextHelper.getSiteKey( environment );
+                return Objects.requireNonNullElse( getSitePathBySiteKey( siteKey, environment ), originalPath );
+            } ) );
             String normalizedPath = originalPath.replace( sitePath, "" );
             return normalizedPath.startsWith( "/" ) ? normalizedPath.substring( 1 ) : normalizedPath;
         }
@@ -65,33 +47,19 @@ public String get( final DataFetchingEnvironment environment )
         }
     }
 
-    private ContentPath getSitePathBySiteKey( final String siteKey )
+    private String getSitePathBySiteKey( final String siteKey, DataFetchingEnvironment environment )
     {
-        if ( siteKey.isEmpty() )
-        {
-            return null;
-        }
-        try
-        {
-            if ( siteKey.startsWith( "/" ) )
-            {
-                return contentService.getByPath( ContentPath.from( siteKey ) ).getPath();
-            }
-            else
-            {
-                return contentService.getById( ContentId.from( siteKey ) ).getPath();
-            }
-        }
-        catch ( ContentNotFoundException e )
+        Map<String, Object> contentAsMap = new GetContentCommand( contentService ).execute( siteKey, environment );
+        if ( contentAsMap == null )
         {
             return null;
         }
+        return contentAsMap.get( "_path" ).toString();
     }
 
     public Context adminContext()
     {
-        AuthenticationInfo authenticationInfo = AuthenticationInfo.copyOf( ContextAccessor.current().getAuthInfo() ).principals(
-            PrincipalKey.ofRole( "system.admin" ) ).build();
-        return ContextBuilder.from( ContextAccessor.current() ).authInfo( authenticationInfo ).build();
+        return ContextBuilder.from( ContextAccessor.current() ).authInfo(
+            AuthenticationInfo.copyOf( ContextAccessor.current().getAuthInfo() ).principals( RoleKeys.ADMIN ).build() ).build();
     }
 }
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetImageUrlDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetImageUrlDataFetcher.java
index 3d5baab0..d35a0c35 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetImageUrlDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetImageUrlDataFetcher.java
@@ -6,12 +6,10 @@
 import graphql.schema.DataFetchingEnvironment;
 
 import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
-import com.enonic.xp.branch.Branch;
 import com.enonic.xp.portal.PortalRequest;
 import com.enonic.xp.portal.PortalRequestAccessor;
 import com.enonic.xp.portal.url.ImageUrlParams;
 import com.enonic.xp.portal.url.PortalUrlService;
-import com.enonic.xp.repository.RepositoryId;
 
 public class GetImageUrlDataFetcher
     implements DataFetcher<String>
@@ -33,9 +31,8 @@ public String get( final DataFetchingEnvironment environment )
     private String doGet( final DataFetchingEnvironment environment )
     {
         PortalRequest portalRequest = PortalRequestAccessor.get();
-        portalRequest.setRepositoryId(
-            RepositoryId.from( GuillotineLocalContextHelper.getRepositoryId( environment, portalRequest.getRepositoryId() ) ) );
-        portalRequest.setBranch( Branch.from( GuillotineLocalContextHelper.getBranch( environment, portalRequest.getBranch() ) ) );
+        portalRequest.setRepositoryId( GuillotineLocalContextHelper.getRepositoryId( environment, portalRequest.getRepositoryId() ) );
+        portalRequest.setBranch( GuillotineLocalContextHelper.getBranch( environment, portalRequest.getBranch() ) );
 
         Map<String, Object> sourceAsMap = environment.getSource();
 
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetPageUrlDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetPageUrlDataFetcher.java
index 256489b8..de3ad83e 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetPageUrlDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetPageUrlDataFetcher.java
@@ -6,12 +6,10 @@
 import graphql.schema.DataFetchingEnvironment;
 
 import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
-import com.enonic.xp.branch.Branch;
 import com.enonic.xp.portal.PortalRequest;
 import com.enonic.xp.portal.PortalRequestAccessor;
 import com.enonic.xp.portal.url.PageUrlParams;
 import com.enonic.xp.portal.url.PortalUrlService;
-import com.enonic.xp.repository.RepositoryId;
 
 public class GetPageUrlDataFetcher
     implements DataFetcher<String>
@@ -33,9 +31,8 @@ public String get( final DataFetchingEnvironment environment )
     private String doGet( final DataFetchingEnvironment environment )
     {
         PortalRequest portalRequest = PortalRequestAccessor.get();
-        portalRequest.setRepositoryId(
-            RepositoryId.from( GuillotineLocalContextHelper.getRepositoryId( environment, portalRequest.getRepositoryId() ) ) );
-        portalRequest.setBranch( Branch.from( GuillotineLocalContextHelper.getBranch( environment, portalRequest.getBranch() ) ) );
+        portalRequest.setRepositoryId( GuillotineLocalContextHelper.getRepositoryId( environment, portalRequest.getRepositoryId() ) );
+        portalRequest.setBranch( GuillotineLocalContextHelper.getBranch( environment, portalRequest.getBranch() ) );
 
         Map<String, Object> sourceAsMap = environment.getSource();
 
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetPermissionsDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetPermissionsDataFetcher.java
index c1275d23..d47ce542 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetPermissionsDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetPermissionsDataFetcher.java
@@ -4,16 +4,15 @@
 
 import graphql.schema.DataFetchingEnvironment;
 
-import com.enonic.app.guillotine.graphql.GuillotineContext;
 import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
 import com.enonic.xp.content.ContentService;
 
 public class GetPermissionsDataFetcher
     extends BaseContentDataFetcher
 {
-    public GetPermissionsDataFetcher( final GuillotineContext context, final ContentService contentService )
+    public GetPermissionsDataFetcher( final ContentService contentService )
     {
-        super( context, contentService );
+        super( contentService );
     }
 
     @Override
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetSiteDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetSiteDataFetcher.java
index f2f4f3a5..644106b1 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetSiteDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/GetSiteDataFetcher.java
@@ -6,25 +6,19 @@
 import graphql.schema.DataFetchingEnvironment;
 
 import com.enonic.app.guillotine.graphql.ContentSerializer;
-import com.enonic.app.guillotine.graphql.GuillotineContext;
 import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
 import com.enonic.xp.content.ContentId;
 import com.enonic.xp.content.ContentPath;
 import com.enonic.xp.content.ContentService;
-import com.enonic.xp.portal.PortalRequest;
-import com.enonic.xp.portal.PortalRequestAccessor;
 import com.enonic.xp.site.Site;
 
 public class GetSiteDataFetcher
     implements DataFetcher<Map<String, Object>>
 {
-    private final GuillotineContext guillotineContext;
-
     private final ContentService contentService;
 
-    public GetSiteDataFetcher( final GuillotineContext guillotineContext, final ContentService contentService )
+    public GetSiteDataFetcher( final ContentService contentService )
     {
-        this.guillotineContext = guillotineContext;
         this.contentService = contentService;
     }
 
@@ -37,23 +31,15 @@ public Map<String, Object> get( final DataFetchingEnvironment environment )
 
     private Map<String, Object> doGet( final DataFetchingEnvironment environment )
     {
-        Site site = null;
-        if ( guillotineContext.isGlobalMode() )
-        {
-            String siteKey = GuillotineLocalContextHelper.getSiteKey( environment );
-            if ( !siteKey.isEmpty() )
-            {
-                site = siteKey.startsWith( "/" )
-                    ? contentService.findNearestSiteByPath( ContentPath.from( siteKey ) )
-                    : contentService.getNearestSite( ContentId.from( siteKey ) );
-            }
-        }
-        else
+        String siteKey = GuillotineLocalContextHelper.getSiteKey( environment );
+        if ( siteKey != null && !siteKey.isEmpty() )
         {
-            PortalRequest portalRequest = PortalRequestAccessor.get();
-            site = portalRequest.getSite();
+            Site site = siteKey.startsWith( "/" )
+                ? contentService.findNearestSiteByPath( ContentPath.from( siteKey ) )
+                : contentService.getNearestSite( ContentId.from( siteKey ) );
+            return ContentSerializer.serialize( site );
         }
 
-        return ContentSerializer.serialize( site );
+        return null;
     }
 }
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryBaseDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryBaseDataFetcher.java
index 0aa435c2..f8a58f39 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryBaseDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryBaseDataFetcher.java
@@ -2,56 +2,32 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 import graphql.schema.DataFetcher;
 import graphql.schema.DataFetchingEnvironment;
 
 import com.enonic.app.guillotine.graphql.Constants;
-import com.enonic.app.guillotine.graphql.GuillotineContext;
 import com.enonic.app.guillotine.graphql.commands.FindContentsParams;
 import com.enonic.app.guillotine.graphql.helper.ArrayHelper;
 import com.enonic.app.guillotine.graphql.helper.CastHelper;
-import com.enonic.app.guillotine.graphql.helper.SecurityHelper;
 
 public abstract class QueryBaseDataFetcher
     implements DataFetcher<Object>
 {
-    private final List<String> HAS_VALUE_FILTERS_VALUES = List.of( "stringValues", "intValues", "floatValues", "booleanValues" );
-
-    protected final GuillotineContext context;
-
-    protected QueryBaseDataFetcher( final GuillotineContext context )
-    {
-        this.context = context;
-    }
-
-    protected FindContentsParams createQueryParams( Integer offset, Integer first, DataFetchingEnvironment environment, boolean queryDsl )
+    protected FindContentsParams createQueryParams( Integer offset, Integer first, DataFetchingEnvironment environment )
     {
         FindContentsParams.Builder builder = FindContentsParams.create().setStart( offset ).setFirst( first ).setQuery(
-            createQuery( environment.getArgument( "query" ), queryDsl ) ).setSort(
-            createSort( environment.getArgument( "sort" ), queryDsl ) );
+            createQuery( environment.getArgument( "query" ) ) ).setSort( createSort( environment.getArgument( "sort" ) ) );
 
         if ( environment.getArgument( "aggregations" ) != null )
         {
             builder.setAggregations( createAggregations( environment.getArgument( "aggregations" ) ) );
         }
 
-        if ( environment.getArgument( "filters" ) != null )
-        {
-            builder.setFilters( createFilters( environment.getArgument( "filters" ) ) );
-        }
-
-        if ( environment.getArgument( "contentTypes" ) != null )
-        {
-            builder.setContentTypes( environment.getArgument( "contentTypes" ) );
-        }
-
         if ( environment.getArgument( "highlight" ) != null )
         {
             builder.setHighlight( createHighlight( environment.getArgument( "highlight" ) ) );
@@ -60,46 +36,34 @@ protected FindContentsParams createQueryParams( Integer offset, Integer first, D
         return builder.build();
     }
 
-    private Object createQuery( final Object query, final boolean queryDsl )
+    private Object createQuery( final Object query )
     {
-        if ( query != null && queryDsl )
-        {
-            return adaptDslQuery( createDslQuery( CastHelper.cast( query ) ), context );
-        }
-        return adaptQuery( (String) query, context );
+        return query != null ? createDslQuery( CastHelper.cast( query ) ) : null;
     }
 
-    private Object createSort( final Object sort, final boolean queryDsl )
+    private Object createSort( final Object sort )
     {
-        if ( queryDsl )
-        {
-            List<Map<String, Object>> result = new ArrayList<>();
+        List<Map<String, Object>> result = new ArrayList<>();
 
-            ArrayHelper.forceArray( sort ).forEach( sortItem -> {
-                Map<String, Object> sortItemAsMap = CastHelper.cast( sortItem );
+        ArrayHelper.forceArray( sort ).forEach( sortItem -> {
+            Map<String, Object> sortItemAsMap = CastHelper.cast( sortItem );
 
-                Map<String, Object> sortAsMap = new HashMap<>();
-                sortAsMap.put( "field", sortItemAsMap.get( "field" ) );
-                if ( sortItemAsMap.get( "direction" ) != null )
-                {
-                    sortAsMap.put( "direction", sortItemAsMap.get( "direction" ) );
-                }
-                if ( sortItemAsMap.get( "location" ) != null )
-                {
-                    Map<String, Object> locationAsMap = CastHelper.cast( sortItemAsMap.get( "location" ) );
-                    sortAsMap.put( "location", Map.of( "lat", locationAsMap.get( "lat" ), "lon", locationAsMap.get( "lon" ) ) );
-                }
-                if ( sortItemAsMap.get( "unit" ) != null )
-                {
-                    sortAsMap.put( "unit", sortItemAsMap.get( "unit" ) );
-                }
+            Map<String, Object> sortAsMap = new HashMap<>();
 
-                result.add( sortAsMap );
-            } );
+            sortAsMap.put( "field", sortItemAsMap.get( "field" ) );
+            sortAsMap.computeIfAbsent( "direction", k -> sortItemAsMap.get( "direction" ) );
+            sortAsMap.computeIfAbsent( "unit", k -> sortItemAsMap.get( "unit" ) );
 
-            return result;
-        }
-        return sort;
+            if ( sortItemAsMap.get( "location" ) != null )
+            {
+                Map<String, Object> locationAsMap = CastHelper.cast( sortItemAsMap.get( "location" ) );
+                sortAsMap.put( "location", Map.of( "lat", locationAsMap.get( "lat" ), "lon", locationAsMap.get( "lon" ) ) );
+            }
+
+            result.add( sortAsMap );
+        } );
+
+        return result;
     }
 
     private Map<String, Object> createAggregations( List<Map<String, Object>> inputAggregations )
@@ -135,81 +99,6 @@ private void createAggregation( Map<String, Object> holder, Map<String, Object>
         }
     }
 
-    private List<Map<String, Object>> createFilters( List<Map<String, Object>> inputFilters )
-    {
-        if ( inputFilters == null || inputFilters.isEmpty() )
-        {
-            return Collections.emptyList();
-        }
-
-        List<Map<String, Object>> result = new ArrayList<>();
-
-        inputFilters.forEach( inputFilter -> {
-            Map<String, Object> filter = new HashMap<>();
-
-            inputFilter.keySet().forEach( filterName -> {
-                if ( "hasValue".equals( filterName ) )
-                {
-                    filter.put( filterName, processHasValueFilter( CastHelper.cast( inputFilter.get( "hasValue" ) ) ) );
-                }
-                else if ( "boolean".equals( filterName ) )
-                {
-                    filter.put( filterName, processBooleanFilter( CastHelper.cast( inputFilter.get( "boolean" ) ) ) );
-                }
-                else
-                {
-                    filter.put( filterName, inputFilter.get( filterName ) );
-                }
-            } );
-
-            result.add( filter );
-        } );
-
-        return result;
-    }
-
-    private Map<String, Object> processHasValueFilter( final Map<String, Object> inputHasValueFilter )
-    {
-        if ( inputHasValueFilter.containsKey( "field" ) && inputHasValueFilter.keySet().size() > 2 )
-        {
-            throw new IllegalArgumentException(
-                "HasValueFilter must have only one type of values from (\"stringValues, intValues, floatValues and booleanValues\")" );
-        }
-
-        Map<String, Object> result = new HashMap<>();
-
-        result.put( "field", inputHasValueFilter.get( "field" ) );
-
-        HAS_VALUE_FILTERS_VALUES.forEach( fieldName -> {
-            if ( inputHasValueFilter.get( fieldName ) != null )
-            {
-                result.put( "values", inputHasValueFilter.get( fieldName ) );
-            }
-        } );
-
-        return result;
-    }
-
-    private Map<String, Object> processBooleanFilter( final Map<String, Object> inputBooleanFilter )
-    {
-        Map<String, Object> result = new HashMap<>();
-
-        if ( inputBooleanFilter.get( "must" ) != null )
-        {
-            result.put( "must", createFilters( CastHelper.cast( inputBooleanFilter.get( "must" ) ) ) );
-        }
-        if ( inputBooleanFilter.get( "mustNot" ) != null )
-        {
-            result.put( "mustNot", createFilters( CastHelper.cast( inputBooleanFilter.get( "mustNot" ) ) ) );
-        }
-        if ( inputBooleanFilter.get( "should" ) != null )
-        {
-            result.put( "should", createFilters( CastHelper.cast( inputBooleanFilter.get( "should" ) ) ) );
-        }
-
-        return result;
-    }
-
     private Map<String, Object> createDslQuery( Map<String, Object> inputQueryDsl )
     {
         Map<String, Object> result = new HashMap<>();
@@ -574,52 +463,4 @@ private Object extractPropertyValues( Map<String, Object> graphQLValue )
 
         throw new IllegalArgumentException( "Value must be not null" );
     }
-
-    private Object adaptQuery( String query, GuillotineContext context )
-    {
-        if ( context.isGlobalMode() )
-        {
-            return query;
-        }
-
-        String queryPrefix = getAllowedNodePaths( context ).stream().map(
-            nodePath -> "_path = \"" + nodePath + "\" OR _path LIKE \"" + nodePath + "/*\"" ).collect( Collectors.joining( " OR " ) );
-
-        return "(" + queryPrefix + ")" + ( query != null ? " AND (" + query + ")" : "" );
-    }
-
-    private Object adaptDslQuery( Map<String, Object> dslQuery, GuillotineContext context )
-    {
-        if ( context.isGlobalMode() )
-        {
-            return dslQuery;
-        }
-
-        List<Map<String, Object>> dslExpressions = new ArrayList<>();
-
-        getAllowedNodePaths( context ).forEach( nodePath -> {
-            dslExpressions.add( Collections.singletonMap( "term", createTermOrLikeDslExpression( nodePath ) ) );
-            dslExpressions.add( Collections.singletonMap( "like", createTermOrLikeDslExpression( nodePath + "/*" ) ) );
-        } );
-
-        return dslQuery != null
-            ? Map.of( "boolean", Map.of( "must", List.of( dslQuery, Map.of( "boolean", Map.of( "should", dslExpressions ) ) ) ) )
-            : Map.of( "boolean", Map.of( "should", dslExpressions ) );
-    }
-
-    private Map<String, String> createTermOrLikeDslExpression( String value )
-    {
-        Map<String, String> result = new HashMap<>();
-
-        result.put( "field", "_path" );
-        result.put( "value", value );
-
-        return result;
-    }
-
-    private static List<String> getAllowedNodePaths( GuillotineContext context )
-    {
-        return SecurityHelper.getAllowedContentPaths( context ).stream().map( contentPath -> "/content" + contentPath ).collect(
-            Collectors.toList() );
-    }
 }
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryConnectionDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryConnectionDataFetcher.java
deleted file mode 100644
index 9d10d288..00000000
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryConnectionDataFetcher.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package com.enonic.app.guillotine.graphql.fetchers;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import graphql.schema.DataFetchingEnvironment;
-
-import com.enonic.app.guillotine.graphql.ArgumentsValidator;
-import com.enonic.app.guillotine.graphql.GuillotineContext;
-import com.enonic.app.guillotine.graphql.commands.FindContentsCommand;
-import com.enonic.app.guillotine.graphql.helper.ConnectionHelper;
-import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
-import com.enonic.xp.content.ContentService;
-
-public class QueryConnectionDataFetcher
-    extends QueryBaseDataFetcher
-
-{
-    private final ContentService contentService;
-
-    public QueryConnectionDataFetcher( final GuillotineContext context, final ContentService contentService )
-    {
-        super( context );
-        this.contentService = contentService;
-    }
-
-    @Override
-    public Object get( final DataFetchingEnvironment environment )
-        throws Exception
-    {
-        return GuillotineLocalContextHelper.executeInContext( environment, () -> doGet( environment ) );
-    }
-
-    private Object doGet( final DataFetchingEnvironment environment )
-    {
-        ArgumentsValidator.validateArgumentsForQueryField( environment.getArguments() );
-
-        int offset = environment.getArgument( "after" ) != null ?
-            Integer.parseInt( ConnectionHelper.decodeCursor( environment.getArgument( "after" ) ) ) + 1 : 0;
-
-        int first = environment.getArgument( "first" ) != null ? environment.getArgument( "first" ) : 10;
-
-        Map<String, Object> queryResult =
-            new FindContentsCommand( createQueryParams( offset, first, environment, false ), contentService ).execute();
-
-        Map<String, Object> result = new HashMap<>();
-
-        result.put( "total", queryResult.get( "total" ) );
-        result.put( "start", offset );
-        result.put( "hits", queryResult.get( "hits" ) );
-        result.put( "aggregationsAsJson", queryResult.get( "aggregations" ) );
-
-        return result;
-    }
-
-
-}
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryDataFetcher.java
deleted file mode 100644
index a7a30008..00000000
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryDataFetcher.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.enonic.app.guillotine.graphql.fetchers;
-
-import java.util.Map;
-
-import graphql.schema.DataFetchingEnvironment;
-
-import com.enonic.app.guillotine.graphql.ArgumentsValidator;
-import com.enonic.app.guillotine.graphql.GuillotineContext;
-import com.enonic.app.guillotine.graphql.commands.FindContentsCommand;
-import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
-import com.enonic.xp.content.ContentService;
-
-public class QueryDataFetcher
-    extends QueryBaseDataFetcher
-{
-    private final ContentService contentService;
-
-    public QueryDataFetcher( final GuillotineContext context, final ContentService contentService )
-    {
-        super( context );
-        this.contentService = contentService;
-    }
-
-    @Override
-    public Object get( final DataFetchingEnvironment environment )
-        throws Exception
-    {
-        return GuillotineLocalContextHelper.executeInContext( environment, () -> doGet( environment ) );
-    }
-
-    private Object doGet( final DataFetchingEnvironment environment )
-    {
-        ArgumentsValidator.validateArguments( environment.getArguments() );
-
-        Map<String, Object> queryResult = new FindContentsCommand(
-            createQueryParams( environment.getArgument( "offset" ), environment.getArgument( "first" ), environment, false ),
-            contentService ).execute();
-
-        return queryResult.get( "hits" );
-    }
-}
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryDslConnectionDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryDslConnectionDataFetcher.java
index 2219536f..8a2e9fc7 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryDslConnectionDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryDslConnectionDataFetcher.java
@@ -6,7 +6,6 @@
 import graphql.schema.DataFetchingEnvironment;
 
 import com.enonic.app.guillotine.graphql.ArgumentsValidator;
-import com.enonic.app.guillotine.graphql.GuillotineContext;
 import com.enonic.app.guillotine.graphql.commands.FindContentsCommand;
 import com.enonic.app.guillotine.graphql.helper.ConnectionHelper;
 import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
@@ -17,9 +16,8 @@ public class QueryDslConnectionDataFetcher
 {
     private final ContentService contentService;
 
-    public QueryDslConnectionDataFetcher( final GuillotineContext context, final ContentService contentService )
+    public QueryDslConnectionDataFetcher( final ContentService contentService )
     {
-        super( context );
         this.contentService = contentService;
     }
 
@@ -40,7 +38,7 @@ private Object doGet( DataFetchingEnvironment environment )
         int first = environment.getArgument( "first" ) != null ? environment.getArgument( "first" ) : 10;
 
         Map<String, Object> queryResult =
-            new FindContentsCommand( createQueryParams( offset, first, environment, true ), contentService ).execute();
+            new FindContentsCommand( createQueryParams( offset, first, environment ), contentService ).execute();
 
         Map<String, Object> result = new HashMap<>();
 
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryDslDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryDslDataFetcher.java
index ace8de74..6d1f3e4d 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryDslDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/QueryDslDataFetcher.java
@@ -5,7 +5,6 @@
 import graphql.schema.DataFetchingEnvironment;
 
 import com.enonic.app.guillotine.graphql.ArgumentsValidator;
-import com.enonic.app.guillotine.graphql.GuillotineContext;
 import com.enonic.app.guillotine.graphql.commands.FindContentsCommand;
 import com.enonic.app.guillotine.graphql.helper.GuillotineLocalContextHelper;
 import com.enonic.xp.content.ContentService;
@@ -15,9 +14,8 @@ public class QueryDslDataFetcher
 {
     private final ContentService contentService;
 
-    public QueryDslDataFetcher( final GuillotineContext context, final ContentService contentService )
+    public QueryDslDataFetcher( final ContentService contentService )
     {
-        super( context );
         this.contentService = contentService;
     }
 
@@ -33,7 +31,7 @@ private Object doGet( final DataFetchingEnvironment environment )
         ArgumentsValidator.validateDslQuery( environment.getArguments() );
 
         Map<String, Object> queryResult = new FindContentsCommand(
-            createQueryParams( environment.getArgument( "offset" ), environment.getArgument( "first" ), environment, true ),
+            createQueryParams( environment.getArgument( "offset" ), environment.getArgument( "first" ), environment ),
             contentService ).execute();
 
         return queryResult.get( "hits" );
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/RichTextDataFetcher.java b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/RichTextDataFetcher.java
index 6f0de195..935ede5f 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/fetchers/RichTextDataFetcher.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/fetchers/RichTextDataFetcher.java
@@ -1,7 +1,6 @@
 package com.enonic.app.guillotine.graphql.fetchers;
 
 import java.util.ArrayList;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -19,15 +18,12 @@
 import com.enonic.app.guillotine.macro.MacroEditorSerializer;
 import com.enonic.app.guillotine.mapper.GuillotineMapGenerator;
 import com.enonic.app.guillotine.mapper.HtmlEditorResultMapper;
-import com.enonic.xp.app.ApplicationKey;
-import com.enonic.xp.app.ApplicationKeys;
 import com.enonic.xp.macro.MacroDescriptor;
 import com.enonic.xp.portal.PortalRequest;
 import com.enonic.xp.portal.PortalRequestAccessor;
 import com.enonic.xp.portal.html.HtmlDocument;
 import com.enonic.xp.portal.html.HtmlElement;
 import com.enonic.xp.portal.url.ProcessHtmlParams;
-import com.enonic.xp.site.SiteConfig;
 
 public class RichTextDataFetcher
     implements DataFetcher<Object>
@@ -71,10 +67,7 @@ public Object get( final DataFetchingEnvironment environment )
         List<Map<String, Object>> images = new ArrayList<>();
         List<MacroDecorator> processedMacros = new ArrayList<>();
 
-        PortalRequest portalRequest = PortalRequestAccessor.get();
-
-        Map<String, MacroDescriptor> registeredMacros =
-            portalRequest.getSite() != null ? getRegisteredMacrosInSystemForSite( portalRequest ) : guillotineContext.getMacroDecorators();
+        Map<String, MacroDescriptor> registeredMacros = guillotineContext.getMacroDecorators();
 
         htmlParams.processMacros( false );
         htmlParams.customHtmlProcessor( processor -> {
@@ -115,7 +108,11 @@ public Object get( final DataFetchingEnvironment environment )
 
     private ProcessHtmlParams createProcessHtmlParams( DataFetchingEnvironment environment )
     {
-        ProcessHtmlParams htmlParams = new ProcessHtmlParams().portalRequest( PortalRequestAccessor.get() ).value( htmlText );
+        final PortalRequest portalRequest = PortalRequestAccessor.get();
+        portalRequest.setRepositoryId( GuillotineLocalContextHelper.getRepositoryId( environment, portalRequest.getRepositoryId() ) );
+        portalRequest.setBranch( GuillotineLocalContextHelper.getBranch( environment, portalRequest.getBranch() ) );
+
+        ProcessHtmlParams htmlParams = new ProcessHtmlParams().portalRequest( portalRequest ).value( htmlText );
 
         Map<String, Object> processHtmlParams = environment.getArgument( "processHtml" );
 
@@ -137,23 +134,4 @@ private ProcessHtmlParams createProcessHtmlParams( DataFetchingEnvironment envir
 
         return htmlParams;
     }
-
-    private Map<String, MacroDescriptor> getRegisteredMacrosInSystemForSite( final PortalRequest portalRequest )
-    {
-        List<ApplicationKey> applicationKeys = new ArrayList<>();
-        applicationKeys.add( ApplicationKey.SYSTEM );
-        applicationKeys.addAll(
-            portalRequest.getSite().getSiteConfigs().stream().map( SiteConfig::getApplicationKey ).collect( Collectors.toList() ) );
-
-        Map<String, MacroDescriptor> result = new LinkedHashMap<>();
-
-        serviceFacade.getMacroDescriptorService().getByApplications( ApplicationKeys.from( applicationKeys ) ).forEach( macroDescriptor -> {
-            if ( !result.containsKey( macroDescriptor.getName() ) )
-            {
-                result.put( macroDescriptor.getName(), macroDescriptor );
-            }
-        } );
-
-        return result;
-    }
 }
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/helper/GuillotineLocalContextHelper.java b/src/main/java/com/enonic/app/guillotine/graphql/helper/GuillotineLocalContextHelper.java
index 42a74fae..cb036f32 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/helper/GuillotineLocalContextHelper.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/helper/GuillotineLocalContextHelper.java
@@ -17,21 +17,18 @@ public class GuillotineLocalContextHelper
 {
     public static <T> T executeInContext( final DataFetchingEnvironment environment, Callable<T> callable )
     {
-        final Map<String, Object> targetContext = getTargetContext( environment );
+        final Map<String, Object> localContext = environment.getLocalContext();
 
         final ContextBuilder contextBuilder = ContextBuilder.from( ContextAccessor.current() );
 
-        if ( targetContext != null )
+        if ( localContext.get( Constants.GUILLOTINE_TARGET_BRANCH_CTX ) != null )
+        {
+            contextBuilder.branch( localContext.get( Constants.GUILLOTINE_TARGET_BRANCH_CTX ).toString() );
+        }
+        if ( localContext.get( Constants.GUILLOTINE_TARGET_REPO_CTX ) != null )
         {
-            if ( targetContext.get( Constants.GUILLOTINE_TARGET_BRANCH_CTX ) != null )
-            {
-                contextBuilder.branch( targetContext.get( Constants.GUILLOTINE_TARGET_BRANCH_CTX ).toString() );
-            }
-            if ( targetContext.get( Constants.GUILLOTINE_TARGET_REPO_CTX ) != null )
-            {
-                contextBuilder.repositoryId(
-                    ProjectConstants.PROJECT_REPO_ID_PREFIX + targetContext.get( Constants.GUILLOTINE_TARGET_REPO_CTX ).toString() );
-            }
+            contextBuilder.repositoryId(
+                ProjectConstants.PROJECT_REPO_ID_PREFIX + localContext.get( Constants.GUILLOTINE_TARGET_REPO_CTX ).toString() );
         }
 
         return contextBuilder.build().callWith( callable );
@@ -39,39 +36,28 @@ public static <T> T executeInContext( final DataFetchingEnvironment environment,
 
     public static String getSiteKey( final DataFetchingEnvironment environment )
     {
-        final Map<String, Object> targetContext = getTargetContext( environment );
-
-        if ( targetContext != null && !Objects.toString( targetContext.get( Constants.GUILLOTINE_TARGET_SITE_CTX ), "" ).isEmpty() )
-        {
-            return targetContext.get( Constants.GUILLOTINE_TARGET_SITE_CTX ).toString();
-        }
-
-        return environment.getGraphQlContext().getOrDefault( "__siteKey", "" );
+        final Map<String, Object> localContext = environment.getLocalContext();
+        return Objects.toString( localContext.get( Constants.GUILLOTINE_TARGET_SITE_CTX ), null );
     }
 
-    public static String getRepositoryId( final DataFetchingEnvironment environment, final RepositoryId defaultRepoId )
+    public static RepositoryId getRepositoryId( final DataFetchingEnvironment environment, final RepositoryId defaultRepoId )
     {
-        final Map<String, Object> targetContext = getTargetContext( environment );
-        if ( targetContext != null && targetContext.get( Constants.GUILLOTINE_TARGET_REPO_CTX ) != null )
+        final Map<String, Object> localContext = environment.getLocalContext();
+        if ( localContext.get( Constants.GUILLOTINE_TARGET_REPO_CTX ) != null )
         {
-            return ProjectConstants.PROJECT_REPO_ID_PREFIX + targetContext.get( Constants.GUILLOTINE_TARGET_REPO_CTX ).toString();
+            return RepositoryId.from(
+                ProjectConstants.PROJECT_REPO_ID_PREFIX + localContext.get( Constants.GUILLOTINE_TARGET_REPO_CTX ).toString() );
         }
-        return defaultRepoId.toString();
+        return defaultRepoId;
     }
 
-    public static String getBranch( final DataFetchingEnvironment environment, final Branch defaultBranch )
+    public static Branch getBranch( final DataFetchingEnvironment environment, final Branch defaultBranch )
     {
-        final Map<String, Object> targetContext = getTargetContext( environment );
-        if ( targetContext != null && targetContext.get( Constants.GUILLOTINE_TARGET_BRANCH_CTX ) != null )
+        final Map<String, Object> localContext = environment.getLocalContext();
+        if ( localContext.get( Constants.GUILLOTINE_TARGET_BRANCH_CTX ) != null )
         {
-            return targetContext.get( Constants.GUILLOTINE_TARGET_BRANCH_CTX ).toString();
+            return Branch.from( localContext.get( Constants.GUILLOTINE_TARGET_BRANCH_CTX ).toString() );
         }
-        return defaultBranch.toString();
-    }
-
-    private static Map<String, Object> getTargetContext( final DataFetchingEnvironment environment )
-    {
-        final Map<String, Object> localContext = environment.getLocalContext();
-        return CastHelper.cast( localContext.get( Constants.GUILLOTINE_LOCAL_CTX ) );
+        return defaultBranch;
     }
 }
diff --git a/src/main/java/com/enonic/app/guillotine/graphql/helper/SecurityHelper.java b/src/main/java/com/enonic/app/guillotine/graphql/helper/SecurityHelper.java
index 406d8666..8067d2d0 100644
--- a/src/main/java/com/enonic/app/guillotine/graphql/helper/SecurityHelper.java
+++ b/src/main/java/com/enonic/app/guillotine/graphql/helper/SecurityHelper.java
@@ -1,14 +1,8 @@
 package com.enonic.app.guillotine.graphql.helper;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 
-import com.enonic.app.guillotine.graphql.GuillotineContext;
 import com.enonic.xp.context.ContextAccessor;
-import com.enonic.xp.portal.PortalRequest;
-import com.enonic.xp.portal.PortalRequestAccessor;
 
 public class SecurityHelper
 {
@@ -32,39 +26,9 @@ public static boolean canAccessCmsData()
         return isAdmin() || isCmsAdmin() || isCmsUser();
     }
 
-    public static Map<String, Object> filterForbiddenContent( Map<String, Object> content, GuillotineContext context )
+    public static Map<String, Object> filterForbiddenContent( Map<String, Object> content )
     {
-        if ( content == null )
-        {
-            return null;
-        }
-        if ( context.isGlobalMode() )
-        {
-            return content;
-        }
-
-        for ( String allowedContentType : getAllowedContentPaths( context ) )
-        {
-            String contentPath = content.get( "_path" ).toString();
-            if ( Objects.equals( contentPath, allowedContentType ) || contentPath.startsWith( allowedContentType + "/" ) )
-            {
-                return content;
-            }
-        }
-
-        return null;
-    }
-
-    public static List<String> getAllowedContentPaths( GuillotineContext context )
-    {
-        PortalRequest portalRequest = PortalRequestAccessor.get();
-        List<String> allowPaths = new ArrayList<>( context.getAllowPaths() );
-        if ( portalRequest != null && portalRequest.getSite() != null )
-        {
-            allowPaths.add( portalRequest.getSite().getPath().toString() );
-        }
-
-        return allowPaths;
+        return content;
     }
 
 }
diff --git a/src/main/resources/api/api.js b/src/main/resources/api/api.js
index f89240c4..5c4b061f 100644
--- a/src/main/resources/api/api.js
+++ b/src/main/resources/api/api.js
@@ -40,21 +40,6 @@ function getSchema() {
     return schema;
 }
 
-function createQueryContext(headers) {
-    let siteKey = null;
-    Object.keys(headers).every(header => {
-        if ('x-guillotine-sitekey' === header.toLowerCase()) {
-            siteKey = headers[header];
-            return false;
-        }
-        return true;
-    });
-
-    return {
-        __siteKey: siteKey,
-    }
-}
-
 exports.get = function (req) {
     return {
         status: 404
@@ -67,7 +52,6 @@ exports.post = function (req) {
     return {
         contentType: 'application/json',
         headers: CORS_HEADERS,
-        body: JSON.stringify(__.toNativeObject(graphQLApi.execute(getSchema(), input.query, __.toScriptValue(input.variables),
-            __.toScriptValue(createQueryContext(req.headers)))))
+        body: JSON.stringify(__.toNativeObject(graphQLApi.execute(getSchema(), input.query, __.toScriptValue(input.variables))))
     };
 }
diff --git a/src/test/java/com/enonic/app/guillotine/graphql/BaseGraphQLIntegrationTest.java b/src/test/java/com/enonic/app/guillotine/graphql/BaseGraphQLIntegrationTest.java
index 4cfa5ef4..01da1dc3 100644
--- a/src/test/java/com/enonic/app/guillotine/graphql/BaseGraphQLIntegrationTest.java
+++ b/src/test/java/com/enonic/app/guillotine/graphql/BaseGraphQLIntegrationTest.java
@@ -134,7 +134,7 @@ protected List<ContentType> getCustomContentTypes()
     protected Map<String, Object> executeQuery( final GraphQLSchema graphQLSchema, final String query )
     {
         ExecutionResultMapper executionResultMapper =
-            createAdminContext().callWith( () -> (ExecutionResultMapper) bean.execute( graphQLSchema, query, null, null ) );
+            createAdminContext().callWith( () -> (ExecutionResultMapper) bean.execute( graphQLSchema, query, null ) );
 
         GuillotineMapGenerator generator = new GuillotineMapGenerator();
         executionResultMapper.serialize( generator );
diff --git a/src/test/java/com/enonic/app/guillotine/graphql/ContentFixtures.java b/src/test/java/com/enonic/app/guillotine/graphql/ContentFixtures.java
index 06c925b9..bd74934d 100644
--- a/src/test/java/com/enonic/app/guillotine/graphql/ContentFixtures.java
+++ b/src/test/java/com/enonic/app/guillotine/graphql/ContentFixtures.java
@@ -5,6 +5,7 @@
 
 import com.enonic.xp.attachment.Attachment;
 import com.enonic.xp.attachment.Attachments;
+import com.enonic.xp.content.Content;
 import com.enonic.xp.content.ContentId;
 import com.enonic.xp.content.ContentPath;
 import com.enonic.xp.content.ContentPublishInfo;
@@ -177,6 +178,12 @@ public static Region newBottomRegion()
             ImageComponent.create().build() ).build();
     }
 
+    public static Content createContent( String contentId, String name, String parentPath )
+    {
+        return Content.create().id( ContentId.from( contentId ) ).name( name ).parentPath( ContentPath.from( parentPath ) ).valid(
+            false ).creator( PrincipalKey.ofAnonymous() ).createdTime( Instant.parse( "1975-01-08T00:00:00Z" ) ).build();
+    }
+
     private static ImageComponent createImageComponent( final String imageId, final String imageDisplayName,
                                                         final PropertyTree imageConfig )
     {
diff --git a/src/test/java/com/enonic/app/guillotine/graphql/GuillotineApiGraphQLIntegrationTest.java b/src/test/java/com/enonic/app/guillotine/graphql/GuillotineApiGraphQLIntegrationTest.java
index c7894ff6..7e60c6b0 100644
--- a/src/test/java/com/enonic/app/guillotine/graphql/GuillotineApiGraphQLIntegrationTest.java
+++ b/src/test/java/com/enonic/app/guillotine/graphql/GuillotineApiGraphQLIntegrationTest.java
@@ -172,7 +172,7 @@ public void testGetSiteField()
 
         ExecutionInput executionInput =
             ExecutionInput.newExecutionInput().query( ResourceHelper.readGraphQLQuery( "graphql/getSiteField.graphql" ) ).localContext(
-                new HashMap<>() ).graphQLContext( Map.of( "__siteKey", "/hmdb" ) ).build();
+                new HashMap<>() ).build();
 
         ExecutionResultMapper executionResultMapper = new ExecutionResultMapper( graphQL.execute( executionInput ) );
 
@@ -184,11 +184,22 @@ public void testGetSiteField()
         assertFalse( response.containsKey( "errors" ) );
         assertTrue( response.containsKey( "data" ) );
 
-        Map<String, Object> getSiteField = CastHelper.cast( getFieldFromGuillotine( response, "getSite" ) );
+        Map<String, Object> data = CastHelper.cast( response.get( "data" ) );
 
-        assertNotNull( getSiteField );
-        assertEquals( "siteId", getSiteField.get( "_id" ) );
-        assertEquals( "Site", getSiteField.get( "displayName" ) );
+        assertTrue( data.containsKey( "getSite" ) );
+        Map<String, Object> getSite = CastHelper.cast( data.get( "getSite" ) );
+        Map<String, Object> getForGetSite = CastHelper.cast( getSite.get( "getSite" ) );
+
+        assertNull( getForGetSite );
+
+        assertTrue( data.containsKey( "getSiteByKey" ) );
+
+        Map<String, Object> getSiteByKey = CastHelper.cast( data.get( "getSiteByKey" ) );
+        Map<String, Object> getForGetSiteByKey = CastHelper.cast( getSiteByKey.get( "getSite" ) );
+
+        assertNotNull( getForGetSiteByKey );
+        assertEquals( "siteId", getForGetSiteByKey.get( "_id" ) );
+        assertEquals( "Site", getForGetSiteByKey.get( "displayName" ) );
     }
 
     @Override
@@ -267,4 +278,37 @@ public void testExecuteQueryInLocalContext()
         assertEquals( "New Name", getFoG2.get( "displayName" ) );
         assertEquals( "contentId", getFoG2.get( "_id" ) );
     }
+
+    @Test
+    public void testGetContentPath()
+    {
+        when( contentService.getByPath( ContentPath.from( "/a/b" ) ) ).thenReturn( ContentFixtures.createContent( "id_1", "b", "/a" ) );
+
+        final Site site = Site.create().name( "site" ).type( ContentTypeName.site() ).parentPath( ContentPath.ROOT ).data(
+            new PropertyTree() ).displayName( "Site" ).id( ContentId.from( "id_0" ) ).build();
+
+        when( contentService.findNearestSiteByPath( ContentPath.from( "/site" ) ) ).thenReturn( site );
+        when( contentService.getByPath( ContentPath.from( "/site/c/d" ) ) ).thenReturn(
+            ContentFixtures.createContent( "id_2", "d", "/site/c" ) );
+        when( contentService.getByPath( ContentPath.from( "/site" ) ) ).thenReturn( site );
+
+        GraphQLSchema graphQLSchema = getBean().createSchema();
+
+        Map<String, Object> result = executeQuery( graphQLSchema, ResourceHelper.readGraphQLQuery( "graphql/getContentPath.graphql" ) );
+
+        assertFalse( result.containsKey( "errors" ) );
+        assertTrue( result.containsKey( "data" ) );
+
+        Map<String, Object> data = CastHelper.cast( result.get( "data" ) );
+
+        assertTrue( data.containsKey( "q1" ) );
+        Map<String, Object> q1 = CastHelper.cast( data.get( "q1" ) );
+        Map<String, Object> getForQ1 = CastHelper.cast( q1.get( "get" ) );
+        assertEquals( "", getForQ1.get( "_path" ) );
+
+        assertTrue( data.containsKey( "q2" ) );
+        Map<String, Object> q2 = CastHelper.cast( data.get( "q2" ) );
+        Map<String, Object> getForQ2 = CastHelper.cast( q2.get( "get" ) );
+        assertEquals( "c/d", getForQ2.get( "_path" ) );
+    }
 }
diff --git a/src/test/java/com/enonic/app/guillotine/graphql/QueryDslGraphQLIntegrationTest.java b/src/test/java/com/enonic/app/guillotine/graphql/QueryDslGraphQLIntegrationTest.java
index aa518556..750a4cb8 100644
--- a/src/test/java/com/enonic/app/guillotine/graphql/QueryDslGraphQLIntegrationTest.java
+++ b/src/test/java/com/enonic/app/guillotine/graphql/QueryDslGraphQLIntegrationTest.java
@@ -90,44 +90,4 @@ public void testQueryDslConnectionField()
         assertNotNull( queryDslConnection );
     }
 
-    @Test
-    public void testQueryField()
-    {
-        when( contentService.find( any( ContentQuery.class ) ) ).thenReturn(
-            FindContentIdsByQueryResult.create().contents( ContentIds.from( "contentId" ) ).hits( 100 ).totalHits( 1000 ).build() );
-
-        when( contentService.getByIds( any() ) ).thenReturn( Contents.from( ContentFixtures.createMediaContent() ) );
-
-        GraphQLSchema graphQLSchema = getBean().createSchema();
-
-        Map<String, Object> result = executeQuery( graphQLSchema, ResourceHelper.readGraphQLQuery( "graphql/QueryField.graphql" ) );
-
-        assertFalse( result.containsKey( "errors" ) );
-        assertTrue( result.containsKey( "data" ) );
-
-        List<Map<String, Object>> query = CastHelper.cast( getFieldFromGuillotine( result, "query" ) );
-
-        assertNotNull( query );
-        assertEquals( 1, query.size() );
-    }
-
-    @Test
-    public void testQueryConnectionField()
-    {
-        when( contentService.find( any( ContentQuery.class ) ) ).thenReturn(
-            FindContentIdsByQueryResult.create().contents( ContentIds.from( "contentId" ) ).hits( 100 ).totalHits( 1000 ).build() );
-
-        when( contentService.getByIds( any() ) ).thenReturn( Contents.from( ContentFixtures.createMediaContent() ) );
-
-        GraphQLSchema graphQLSchema = getBean().createSchema();
-
-        Map<String, Object> result = executeQuery( graphQLSchema, ResourceHelper.readGraphQLQuery( "graphql/QueryConnection.graphql" ) );
-
-        assertFalse( result.containsKey( "errors" ) );
-        assertTrue( result.containsKey( "data" ) );
-
-        Map<String, Object> queryConnection = CastHelper.cast( getFieldFromGuillotine( result, "queryConnection" ) );
-
-        assertNotNull( queryConnection );
-    }
 }
diff --git a/src/test/java/com/enonic/app/guillotine/graphql/factory/ContentTypesVerifier.java b/src/test/java/com/enonic/app/guillotine/graphql/factory/ContentTypesVerifier.java
index fcc4a8da..bfb05247 100644
--- a/src/test/java/com/enonic/app/guillotine/graphql/factory/ContentTypesVerifier.java
+++ b/src/test/java/com/enonic/app/guillotine/graphql/factory/ContentTypesVerifier.java
@@ -34,7 +34,6 @@ public void verify()
         verifyPageInfo();
         verifyContentConnection();
         verifyContentEdge();
-        verifyQueryContentConnection();
         verifyQueryDSLContentConnection();
 
         verifyDynamicallyCreatedContentType();
@@ -113,17 +112,6 @@ private void verifyQueryDSLContentConnection()
         assertEquals( "PageInfo", getNameForGraphQLTypeReference( type.getField( "pageInfo" ).getType() ) );
     }
 
-    private void verifyQueryContentConnection()
-    {
-        GraphQLObjectType type = context.getOutputType( "QueryContentConnection" );
-        assertEquals( "QueryContentConnection.", type.getDescription() );
-
-        assertEquals( Scalars.GraphQLInt, getOriginalTypeFromGraphQLNonNull( type, "totalCount" ) );
-        assertEquals( ExtendedScalars.Json, type.getField( "aggregationsAsJson" ).getType() );
-        assertEquals( "ContentEdge", ( (GraphQLObjectType) getOriginalTypeFromGraphQLList( type, "edges" ) ).getName() );
-        assertEquals( "PageInfo", getNameForGraphQLTypeReference( type.getField( "pageInfo" ).getType() ) );
-    }
-
     private void verifyContentEdge()
     {
         GraphQLObjectType type = context.getOutputType( "ContentEdge" );
diff --git a/src/test/java/com/enonic/app/guillotine/graphql/factory/HeadlessCmsTypeVerifier.java b/src/test/java/com/enonic/app/guillotine/graphql/factory/HeadlessCmsTypeVerifier.java
index 168e329f..3b3c4a39 100644
--- a/src/test/java/com/enonic/app/guillotine/graphql/factory/HeadlessCmsTypeVerifier.java
+++ b/src/test/java/com/enonic/app/guillotine/graphql/factory/HeadlessCmsTypeVerifier.java
@@ -26,7 +26,7 @@ public void verify()
         GraphQLObjectType guillotineApiType = context.getOutputType( "HeadlessCms" );
         assertEquals( "Headless CMS", guillotineApiType.getDescription() );
 
-        assertEquals( 11, guillotineApiType.getFieldDefinitions().size() );
+        assertEquals( 9, guillotineApiType.getFieldDefinitions().size() );
 
         // verify get field
         GraphQLFieldDefinition getField = guillotineApiType.getFieldDefinition( "get" );
@@ -62,36 +62,6 @@ public void verify()
         GraphQLFieldDefinition getSiteField = guillotineApiType.getFieldDefinition( "getSite" );
         assertEquals( "portal_Site", getNameForGraphQLTypeReference( getSiteField.getType() ) );
 
-        // verify query field
-        GraphQLFieldDefinition queryField = guillotineApiType.getFieldDefinition( "query" );
-        assertEquals( "Content", getNameForGraphQLTypeReference( getOriginalTypeFromGraphQLList( guillotineApiType, "query" ) ) );
-        assertEquals( 6, queryField.getArguments().size() );
-        assertEquals( Scalars.GraphQLString, queryField.getArgument( "query" ).getType() );
-        assertEquals( Scalars.GraphQLInt, queryField.getArgument( "offset" ).getType() );
-        assertEquals( Scalars.GraphQLInt, queryField.getArgument( "first" ).getType() );
-        assertEquals( Scalars.GraphQLString, queryField.getArgument( "sort" ).getType() );
-        assertEquals( Scalars.GraphQLString,
-                      ( (GraphQLList) queryField.getArgument( "contentTypes" ).getType() ).getOriginalWrappedType() );
-        assertEquals( "FilterInput", getNameForGraphQLTypeReference(
-            ( (GraphQLList) queryField.getArgument( "filters" ).getType() ).getOriginalWrappedType() ) );
-
-        // verify queryConnection field
-        GraphQLFieldDefinition queryConnectionField = guillotineApiType.getFieldDefinition( "queryConnection" );
-        assertEquals( "QueryContentConnection",
-                      getNameForGraphQLTypeReference( guillotineApiType.getFieldDefinition( "queryConnection" ).getType() ) );
-        assertEquals( 7, queryConnectionField.getArguments().size() );
-        assertEquals( Scalars.GraphQLString,
-                      ( (GraphQLNonNull) queryConnectionField.getArgument( "query" ).getType() ).getOriginalWrappedType() );
-        assertEquals( Scalars.GraphQLString, queryConnectionField.getArgument( "after" ).getType() );
-        assertEquals( Scalars.GraphQLInt, queryConnectionField.getArgument( "first" ).getType() );
-        assertEquals( Scalars.GraphQLString, queryConnectionField.getArgument( "sort" ).getType() );
-        assertEquals( Scalars.GraphQLString,
-                      ( (GraphQLList) queryConnectionField.getArgument( "contentTypes" ).getType() ).getOriginalWrappedType() );
-        assertEquals( "AggregationInput", getNameForGraphQLTypeReference(
-            ( (GraphQLList) queryConnectionField.getArgument( "aggregations" ).getType() ).getOriginalWrappedType() ) );
-        assertEquals( "FilterInput", getNameForGraphQLTypeReference(
-            ( (GraphQLList) queryConnectionField.getArgument( "filters" ).getType() ).getOriginalWrappedType() ) );
-
         // verify queryDsl field
         GraphQLFieldDefinition queryDslField = guillotineApiType.getFieldDefinition( "queryDsl" );
         assertEquals( "Content", getNameForGraphQLTypeReference( getOriginalTypeFromGraphQLList( guillotineApiType, "queryDsl" ) ) );
diff --git a/src/test/java/com/enonic/app/guillotine/graphql/factory/InputTypesVerifier.java b/src/test/java/com/enonic/app/guillotine/graphql/factory/InputTypesVerifier.java
index 937132c1..ed4d2e10 100644
--- a/src/test/java/com/enonic/app/guillotine/graphql/factory/InputTypesVerifier.java
+++ b/src/test/java/com/enonic/app/guillotine/graphql/factory/InputTypesVerifier.java
@@ -45,12 +45,6 @@ public void verify()
         verifyMaxAggregationInput();
         verifyValueCountAggregationInput();
         verifyAggregationInput();
-        verifyExistsFilterInput();
-        verifyNotExistsFilterInput();
-        verifyHasValueFilterInput();
-        verifyIdsFilterInput();
-        verifyBooleanFilterInput();
-        verifyFilterInput();
         verifyDSLExpressionValueInput();
         verifyTermDSLExpressionInput();
         verifyLikeDSLExpressionInput();
@@ -328,83 +322,6 @@ private void verifyDSLExpressionValueInput()
         assertEquals( ExtendedScalars.DateTime, type.getField( "instant" ).getType() );
     }
 
-    private void verifyFilterInput()
-    {
-        GraphQLInputObjectType type = context.getInputType( "FilterInput" );
-
-        assertEquals( "Filter input type", type.getDescription() );
-
-        assertEquals( "BooleanFilterInput", getNameForGraphQLTypeReference( type.getFieldDefinition( "boolean" ).getType() ) );
-        assertEquals( "ExistsFilterInput", getNameForGraphQLTypeReference( type.getFieldDefinition( "exists" ).getType() ) );
-        assertEquals( "NotExistsFilterInput", getNameForGraphQLTypeReference( type.getFieldDefinition( "notExists" ).getType() ) );
-        assertEquals( "HasValueFilterInput", getNameForGraphQLTypeReference( type.getFieldDefinition( "hasValue" ).getType() ) );
-        assertEquals( "IdsFilterInput", getNameForGraphQLTypeReference( type.getFieldDefinition( "ids" ).getType() ) );
-    }
-
-    private void verifyBooleanFilterInput()
-    {
-        GraphQLInputObjectType type = context.getInputType( "BooleanFilterInput" );
-
-        assertEquals( "BooleanFilter input type", type.getDescription() );
-
-        GraphQLType mustField = getOriginalTypeFromGraphQLList( type, "must" );
-        assertTrue( mustField instanceof GraphQLTypeReference );
-        assertEquals( "FilterInput", ( (GraphQLTypeReference) mustField ).getName() );
-
-        GraphQLType mustNotField = getOriginalTypeFromGraphQLList( type, "mustNot" );
-        assertTrue( mustNotField instanceof GraphQLTypeReference );
-        assertEquals( "FilterInput", ( (GraphQLTypeReference) mustNotField ).getName() );
-
-        GraphQLType shouldField = getOriginalTypeFromGraphQLList( type, "should" );
-        assertTrue( shouldField instanceof GraphQLTypeReference );
-        assertEquals( "FilterInput", ( (GraphQLTypeReference) shouldField ).getName() );
-    }
-
-    private void verifyIdsFilterInput()
-    {
-        GraphQLInputObjectType type = context.getInputType( "IdsFilterInput" );
-
-        assertEquals( "IdsFilter input type", type.getDescription() );
-        assertEquals( Scalars.GraphQLString, getOriginalTypeFromGraphQLList( type, "values" ) );
-    }
-
-
-    private void verifyHasValueFilterInput()
-    {
-        GraphQLInputObjectType type = context.getInputType( "HasValueFilterInput" );
-
-        assertEquals( "HasValueFilter input type", type.getDescription() );
-        assertEquals( Scalars.GraphQLString, getOriginalTypeFromGraphQLNonNull( type, "field" ) );
-        assertEquals( Scalars.GraphQLString, getOriginalTypeFromGraphQLList( type, "stringValues" ) );
-        assertEquals( Scalars.GraphQLInt, getOriginalTypeFromGraphQLList( type, "intValues" ) );
-        assertEquals( Scalars.GraphQLFloat, getOriginalTypeFromGraphQLList( type, "floatValues" ) );
-        assertEquals( Scalars.GraphQLBoolean, getOriginalTypeFromGraphQLList( type, "booleanValues" ) );
-    }
-
-    private void verifyNotExistsFilterInput()
-    {
-        GraphQLInputObjectType type = context.getInputType( "NotExistsFilterInput" );
-
-        assertEquals( "NotExistsFilter input type", type.getDescription() );
-
-        assertEquals( 1, type.getFieldDefinitions().size() );
-        GraphQLInputType typeOfFieldField = type.getField( "field" ).getType();
-        assertTrue( typeOfFieldField instanceof GraphQLNonNull );
-        assertEquals( Scalars.GraphQLString, ( (GraphQLNonNull) typeOfFieldField ).getOriginalWrappedType() );
-    }
-
-    private void verifyExistsFilterInput()
-    {
-        GraphQLInputObjectType type = context.getInputType( "ExistsFilterInput" );
-
-        assertEquals( "ExistsFilter input type", type.getDescription() );
-
-        assertEquals( 1, type.getFieldDefinitions().size() );
-        GraphQLInputType typeOfFieldField = type.getField( "field" ).getType();
-        assertTrue( typeOfFieldField instanceof GraphQLNonNull );
-        assertEquals( Scalars.GraphQLString, ( (GraphQLNonNull) typeOfFieldField ).getOriginalWrappedType() );
-    }
-
     private void verifyAggregationInput()
     {
         GraphQLInputObjectType type = context.getInputType( "AggregationInput" );
diff --git a/src/test/java/com/enonic/app/guillotine/graphql/fetchers/GetContentParentDataFetcherTest.java b/src/test/java/com/enonic/app/guillotine/graphql/fetchers/GetContentParentDataFetcherTest.java
new file mode 100644
index 00000000..fa3addb6
--- /dev/null
+++ b/src/test/java/com/enonic/app/guillotine/graphql/fetchers/GetContentParentDataFetcherTest.java
@@ -0,0 +1,88 @@
+package com.enonic.app.guillotine.graphql.fetchers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import graphql.schema.DataFetchingEnvironment;
+
+import com.enonic.app.guillotine.graphql.Constants;
+import com.enonic.app.guillotine.graphql.ContentFixtures;
+import com.enonic.xp.branch.Branch;
+import com.enonic.xp.content.ContentPath;
+import com.enonic.xp.content.ContentService;
+import com.enonic.xp.portal.PortalRequest;
+import com.enonic.xp.portal.PortalRequestAccessor;
+import com.enonic.xp.repository.RepositoryId;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class GetContentParentDataFetcherTest
+{
+    private ContentService contentService;
+
+    private DataFetchingEnvironment environment;
+
+    @BeforeEach
+    public void setUp()
+    {
+        this.contentService = mock( ContentService.class );
+
+        final PortalRequest portalRequest = new PortalRequest();
+        portalRequest.setRepositoryId( RepositoryId.from( "repo" ) );
+        portalRequest.setBranch( Branch.from( "draft" ) );
+        PortalRequestAccessor.set( portalRequest );
+
+        Map<String, Object> localContext = new HashMap<>();
+        localContext.put( Constants.GUILLOTINE_TARGET_REPO_CTX, "repo" );
+        localContext.put( Constants.GUILLOTINE_TARGET_BRANCH_CTX, "draft" );
+
+        this.environment = mock( DataFetchingEnvironment.class );
+        when( environment.getLocalContext() ).thenReturn( localContext );
+    }
+
+    @AfterEach
+    public void cleanUp()
+    {
+        PortalRequestAccessor.remove();
+    }
+
+    @Test
+    public void testGet()
+        throws Exception
+    {
+        when( contentService.getByPath( Mockito.any( ContentPath.class ) ) ).thenReturn( ContentFixtures.createMediaContent() );
+
+        Map<String, Object> source = new HashMap<>();
+        source.put( "_path", "/a/b" );
+
+        when( environment.getSource() ).thenReturn( source );
+
+        GetContentParentDataFetcher instance = new GetContentParentDataFetcher( contentService );
+        Object result = instance.get( environment );
+
+        assertNotNull( result );
+    }
+
+    @Test
+    public void testGetParentForRoot()
+        throws Exception
+    {
+        Map<String, Object> source = new HashMap<>();
+        source.put( "_path", "/a" );
+
+        when( environment.getSource() ).thenReturn( source );
+
+        GetContentParentDataFetcher instance = new GetContentParentDataFetcher( contentService );
+        Object result = instance.get( environment );
+
+        assertNull( result );
+    }
+}
diff --git a/src/test/java/com/enonic/app/guillotine/graphql/fetchers/GetSiteDataFetcherTest.java b/src/test/java/com/enonic/app/guillotine/graphql/fetchers/GetSiteDataFetcherTest.java
new file mode 100644
index 00000000..5fd9941f
--- /dev/null
+++ b/src/test/java/com/enonic/app/guillotine/graphql/fetchers/GetSiteDataFetcherTest.java
@@ -0,0 +1,67 @@
+package com.enonic.app.guillotine.graphql.fetchers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import graphql.schema.DataFetchingEnvironment;
+
+import com.enonic.app.guillotine.graphql.Constants;
+import com.enonic.xp.branch.Branch;
+import com.enonic.xp.content.ContentId;
+import com.enonic.xp.content.ContentPath;
+import com.enonic.xp.content.ContentService;
+import com.enonic.xp.data.PropertyTree;
+import com.enonic.xp.portal.PortalRequest;
+import com.enonic.xp.portal.PortalRequestAccessor;
+import com.enonic.xp.repository.RepositoryId;
+import com.enonic.xp.schema.content.ContentTypeName;
+import com.enonic.xp.site.Site;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.when;
+
+public class GetSiteDataFetcherTest
+{
+    private DataFetchingEnvironment environment;
+
+    @BeforeEach
+    public void setUp()
+    {
+        final PortalRequest portalRequest = new PortalRequest();
+        portalRequest.setRepositoryId( RepositoryId.from( "repo" ) );
+        portalRequest.setBranch( Branch.from( "draft" ) );
+        PortalRequestAccessor.set( portalRequest );
+
+        Map<String, Object> localContext = new HashMap<>();
+        localContext.put( Constants.GUILLOTINE_TARGET_REPO_CTX, "repo" );
+        localContext.put( Constants.GUILLOTINE_TARGET_BRANCH_CTX, "draft" );
+        localContext.put( Constants.GUILLOTINE_TARGET_SITE_CTX, "/siteKey" );
+
+        environment = Mockito.mock( DataFetchingEnvironment.class );
+        when( environment.getLocalContext() ).thenReturn( localContext );
+    }
+
+    @AfterEach
+    public void cleanUp()
+    {
+        PortalRequestAccessor.remove();
+    }
+
+    @Test
+    public void testGet()
+        throws Exception
+    {
+        ContentService contentService = Mockito.mock( ContentService.class );
+        when( contentService.findNearestSiteByPath( Mockito.any() ) ).thenReturn(
+            Site.create().name( "site" ).type( ContentTypeName.site() ).parentPath( ContentPath.ROOT ).data(
+                new PropertyTree() ).displayName( "Site" ).id( ContentId.from( "siteId" ) ).build() );
+
+        GetSiteDataFetcher instance = new GetSiteDataFetcher( contentService );
+        assertNotNull( instance.get( environment ) );
+    }
+}
diff --git a/src/test/java/com/enonic/app/guillotine/graphql/fetchers/UrlFieldDataFetcherTest.java b/src/test/java/com/enonic/app/guillotine/graphql/fetchers/UrlFieldDataFetcherTest.java
new file mode 100644
index 00000000..d82ef95f
--- /dev/null
+++ b/src/test/java/com/enonic/app/guillotine/graphql/fetchers/UrlFieldDataFetcherTest.java
@@ -0,0 +1,107 @@
+package com.enonic.app.guillotine.graphql.fetchers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import graphql.schema.DataFetchingEnvironment;
+
+import com.enonic.app.guillotine.graphql.Constants;
+import com.enonic.xp.branch.Branch;
+import com.enonic.xp.portal.PortalRequest;
+import com.enonic.xp.portal.PortalRequestAccessor;
+import com.enonic.xp.portal.url.PortalUrlService;
+import com.enonic.xp.repository.RepositoryId;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.when;
+
+public class UrlFieldDataFetcherTest
+{
+
+    private DataFetchingEnvironment environment;
+
+    @BeforeEach
+    public void setUp()
+    {
+        final PortalRequest portalRequest = new PortalRequest();
+        portalRequest.setRepositoryId( RepositoryId.from( "repo" ) );
+        portalRequest.setBranch( Branch.from( "draft" ) );
+        PortalRequestAccessor.set( portalRequest );
+
+        Map<String, Object> localContext = new HashMap<>();
+        localContext.put( Constants.GUILLOTINE_TARGET_REPO_CTX, "repo" );
+        localContext.put( Constants.GUILLOTINE_TARGET_BRANCH_CTX, "draft" );
+
+        environment = Mockito.mock( DataFetchingEnvironment.class );
+        when( environment.getLocalContext() ).thenReturn( localContext );
+    }
+
+    @AfterEach
+    public void cleanUp()
+    {
+        PortalRequestAccessor.remove();
+    }
+
+    @Test
+    public void testAttachmentUrlByName()
+        throws Exception
+    {
+        PortalUrlService portalUrlService = Mockito.mock( PortalUrlService.class );
+        when( portalUrlService.attachmentUrl( Mockito.any() ) ).thenReturn( "attachmentUrl" );
+
+        Map<String, Object> source = new HashMap<>();
+        source.put( Constants.CONTENT_ID_FIELD, "contentId" );
+        source.put( "name", "name" );
+
+        when( environment.getSource() ).thenReturn( source );
+
+        GetAttachmentUrlByNameDataFetcher instance = new GetAttachmentUrlByNameDataFetcher( portalUrlService );
+        assertEquals( "attachmentUrl", instance.get( environment ) );
+    }
+
+    @Test
+    public void testImageUrl()
+        throws Exception
+    {
+        PortalUrlService portalUrlService = Mockito.mock( PortalUrlService.class );
+        when( portalUrlService.imageUrl( Mockito.any() ) ).thenReturn( "imageUrl" );
+
+        Map<String, Object> source = new HashMap<>();
+        source.put( "_id", "contentId" );
+
+        when( environment.getSource() ).thenReturn( source );
+
+        when( environment.getArgument( "scale" ) ).thenReturn( "scale" );
+        when( environment.getArgument( "quality" ) ).thenReturn( 1 );
+        when( environment.getArgument( "background" ) ).thenReturn( "background" );
+        when( environment.getArgument( "format" ) ).thenReturn( "format" );
+        when( environment.getArgument( "filter" ) ).thenReturn( "filter" );
+        when( environment.getArgument( "type" ) ).thenReturn( "type" );
+
+        GetImageUrlDataFetcher instance = new GetImageUrlDataFetcher( portalUrlService );
+        assertEquals( "imageUrl", instance.get( environment ) );
+    }
+
+    @Test
+    public void testAttachmentUrlById()
+        throws Exception
+    {
+        PortalUrlService portalUrlService = Mockito.mock( PortalUrlService.class );
+        when( portalUrlService.attachmentUrl( Mockito.any() ) ).thenReturn( "attachmentUrl" );
+
+        Map<String, Object> source = new HashMap<>();
+        source.put( "_id", "contentId" );
+        source.put( "name", "name" );
+
+        when( environment.getSource() ).thenReturn( source );
+        when( environment.getArgument( "download" ) ).thenReturn( false );
+
+        GetAttachmentUrlByIdDataFetcher instance = new GetAttachmentUrlByIdDataFetcher( portalUrlService );
+        assertEquals( "attachmentUrl", instance.get( environment ) );
+    }
+}
diff --git a/src/test/resources/graphql/getContentPath.graphql b/src/test/resources/graphql/getContentPath.graphql
new file mode 100644
index 00000000..f61e3354
--- /dev/null
+++ b/src/test/resources/graphql/getContentPath.graphql
@@ -0,0 +1,12 @@
+query {
+    q1: guillotine(repo: "repo", branch: "draft") {
+        get(key: "/a/b"){
+            _path(type: siteRelative)
+        }
+    },
+    q2: guillotine(repo: "repo", branch: "draft", siteKey: "/site") {
+        get(key: "${site}/c/d"){
+            _path(type: siteRelative)
+        }
+    }
+}
diff --git a/src/test/resources/graphql/getSiteField.graphql b/src/test/resources/graphql/getSiteField.graphql
index 6d48d9e1..ebbce8d8 100644
--- a/src/test/resources/graphql/getSiteField.graphql
+++ b/src/test/resources/graphql/getSiteField.graphql
@@ -1,5 +1,11 @@
 query {
-    guillotine {
+    getSite: guillotine {
+        getSite {
+            _id
+            displayName
+        }
+    }
+    getSiteByKey: guillotine(siteKey: "/siteKey") {
         getSite {
             _id
             displayName