public EntityProxyMethodService(
     SessionContext<?, Entity, ?, ?, ?, Relation, ?, ?, ?> sessionContext) {
   for (TypeMetadata typeMetadata : sessionContext.getMetadataProvider().getRegisteredMetadata()) {
     for (MethodMetadata methodMetadata : typeMetadata.getProperties()) {
       AnnotatedMethod typeMethod = methodMetadata.getAnnotatedMethod();
       addUnsupportedOperationMethod(methodMetadata, typeMethod);
       addImplementedByMethod(methodMetadata, typeMethod);
       if (methodMetadata instanceof ResultOfMethodMetadata) {
         ResultOfMethodMetadata resultOfMethodMetadata = (ResultOfMethodMetadata) methodMetadata;
         addProxyMethod(
             new ResultOfMethod(sessionContext, resultOfMethodMetadata),
             typeMethod.getAnnotatedElement());
       }
       if (methodMetadata instanceof AbstractPropertyMethodMetadata) {
         PropertyMethod propertyMethod = (PropertyMethod) typeMethod;
         Method method = propertyMethod.getAnnotatedElement();
         EntityPropertyManager<Entity, Relation, ?> propertyManager =
             sessionContext.getEntityPropertyManager();
         if (methodMetadata instanceof PrimitivePropertyMethodMetadata) {
           if (propertyMethod instanceof GetPropertyMethod) {
             addProxyMethod(
                 new PrimitivePropertyGetMethod(
                     propertyManager, (PrimitivePropertyMethodMetadata) methodMetadata),
                 method);
           } else if (propertyMethod instanceof SetPropertyMethod) {
             addProxyMethod(
                 new PrimitivePropertySetMethod(
                     propertyManager, (PrimitivePropertyMethodMetadata) methodMetadata),
                 method);
           }
         } else if (methodMetadata instanceof TransientPropertyMethodMetadata) {
           if (propertyMethod instanceof GetPropertyMethod) {
             addProxyMethod(
                 new TransientPropertyGetMethod(
                     propertyManager, (TransientPropertyMethodMetadata) methodMetadata),
                 method);
           } else if (propertyMethod instanceof SetPropertyMethod) {
             addProxyMethod(
                 new TransientPropertySetMethod(
                     propertyManager, (TransientPropertyMethodMetadata) methodMetadata),
                 method);
           }
         } else if (methodMetadata instanceof EntityReferencePropertyMethodMetadata) {
           if (propertyMethod instanceof GetPropertyMethod) {
             addProxyMethod(
                 new EntityReferencePropertyGetMethod(
                     propertyManager, (EntityReferencePropertyMethodMetadata) methodMetadata),
                 method);
           } else if (propertyMethod instanceof SetPropertyMethod) {
             addProxyMethod(
                 new EntityReferencePropertySetMethod(
                     propertyManager, (EntityReferencePropertyMethodMetadata) methodMetadata),
                 method);
           }
         } else if (methodMetadata instanceof RelationReferencePropertyMethodMetadata) {
           if (propertyMethod instanceof GetPropertyMethod) {
             addProxyMethod(
                 new RelationReferencePropertyGetMethod(
                     propertyManager, (RelationReferencePropertyMethodMetadata) methodMetadata),
                 method);
           }
         } else if (methodMetadata instanceof EntityCollectionPropertyMethodMetadata) {
           if (propertyMethod instanceof GetPropertyMethod) {
             EntityCollectionPropertyGetMethod<Entity, ?> proxyMethod =
                 new EntityCollectionPropertyGetMethod<>(
                     sessionContext, (EntityCollectionPropertyMethodMetadata<?>) methodMetadata);
             addProxyMethod(proxyMethod, method);
           } else if (propertyMethod instanceof SetPropertyMethod) {
             addProxyMethod(
                 new EntityCollectionPropertySetMethod(
                     propertyManager, (EntityCollectionPropertyMethodMetadata) methodMetadata),
                 method);
           }
         } else if (methodMetadata instanceof RelationCollectionPropertyMethodMetadata) {
           if (propertyMethod instanceof GetPropertyMethod) {
             RelationCollectionPropertyGetMethod<Entity, ?> proxyMethod =
                 new RelationCollectionPropertyGetMethod<>(
                     sessionContext, (RelationCollectionPropertyMethodMetadata<?>) methodMetadata);
             addProxyMethod(proxyMethod, method);
           }
         }
       }
     }
   }
   addMethod(new AsMethod<>(sessionContext), CompositeObject.class, "as", Class.class);
   addMethod(new GetIdMethod<>(sessionContext), CompositeObject.class, "getId");
   addMethod(new GetDelegateMethod<Entity>(), CompositeObject.class, "getDelegate");
   addMethod(new HashCodeMethod<>(sessionContext), Object.class, "hashCode");
   addMethod(new EqualsMethod<>(sessionContext), Object.class, "equals", Object.class);
   addMethod(new ToStringMethod<>(sessionContext), Object.class, "toString");
 }