public Memory getProperty(Environment env, TraceInfo trace, IObject object, String property,
                              PropertyCallCache callCache, int cacheIndex)
            throws Throwable {
        Memory value;

        PropertyEntity entity = callCache == null || env instanceof ConcurrentEnvironment ? null : callCache.get(env, cacheIndex);

        if (entity == null) {
            ClassEntity context = env.getLastClassOnStack();
            entity = isInstanceOf(context) ? context.properties.get(property) : properties.get(property);

            if (callCache != null && entity != null) {
                callCache.put(env, cacheIndex, entity);
            }
        } else if (entity.getClazz() != object.getReflection()) {
            ClassEntity context = env.getLastClassOnStack();
            entity = isInstanceOf(context) ? context.properties.get(property) : properties.get(property);
        }

        if (entity == null) {
            PropertyEntity staticEntity = staticProperties.get(property);

            if (staticEntity != null) {
                invalidAccessToProperty(env, trace, staticEntity, staticEntity.canAccess(env));
                env.error(trace, ErrorType.E_STRICT,
                        Messages.ERR_ACCESSING_STATIC_PROPERTY_AS_NON_STATIC,
                        staticEntity.getClazz().getName(),
                        staticEntity.getName()
                );
            }
        }

        int accessFlag = entity == null ? 0 : entity.canAccess(env);

        if (entity != null && accessFlag != 0) {
            value = null;
        } else {
            if (entity != null) {
                value = entity.getValue(env, trace, object);
            } else {
                ArrayMemory props = object.getProperties();
                value = props == null ? null : props.getByScalar(property);
            }
        }

        if (value != null) {
            if (value.isUninitialized()) {
                if (methodMagicGet == null) {
                    env.exception(trace,
                            BaseError.class,
                            "Typed property %s::$%s must not be accessed before initialization",
                            entity.getClazz().getName(), property
                    );
                }
            } else {
                return value;
            }
        }

        if (methodMagicGet != null) {
            Memory result;

            ClassEntity context = env.getLastClassOnStack();

            if (context != null && context.getId() == methodMagicGet.getClazz().getId()) {
                if (env.peekCall(0).flags == FLAG_GET) {
                    env.error(trace, ErrorType.E_NOTICE, Messages.ERR_UNDEFINED_PROPERTY, name, property);
                    return Memory.NULL;
                }
            }

            try {
                Memory[] args = new Memory[]{new StringMemory(property)};
                env.pushCall(trace, object, args, methodMagicGet.getName(), methodMagicGet.getClazz().getName(), name);
                env.peekCall(0).flags = FLAG_GET;

                InvokeArgumentHelper.checkType(env, trace, methodMagicGet, args);
                result = methodMagicGet.invokeDynamic(object, env, trace, args);

                if (entity != null && entity.isTyped() && accessFlag == 0) {
                    result = entity.typedValue(env, trace, result);
                }
            } finally {
                env.popCall();
            }
            return result;
        }

        if (accessFlag != 0)
            invalidAccessToProperty(env, trace, entity, accessFlag);

        env.error(trace, ErrorType.E_NOTICE, Messages.ERR_UNDEFINED_PROPERTY, name, property);
        return Memory.NULL;
    }
return empty list if success else list with not valid implemented methods in class

@param _interface
@return
jphp-runtime/src/php/runtime/reflection/ClassEntity.java