@Override
        protected IStatus run(final DBRProgressMonitor monitor) {
            final Map<OBJECT_TYPE, List<ObjectColumn>> objectMap = obtainLazyObjects();
            if (isDisposed()) {
                return Status.OK_STATUS;
            }
            monitor.beginTask(UINavigatorMessages.controls_object_list_monitor_load_lazy_props, objectMap.size());
            for (Map.Entry<OBJECT_TYPE, List<ObjectColumn>> entry : objectMap.entrySet()) {
                if (monitor.isCanceled() || isDisposed()) {
                    break;
                }
                final OBJECT_TYPE element = entry.getKey();
                Object object = getObjectValue(element);
                if (object == null) {
                    continue;
                }
                Map<String, Object> objectCache;
                synchronized (lazyCache) {
                    objectCache = lazyCache.get(element);
                    if (objectCache == null) {
                        objectCache = new HashMap<>();
                        lazyCache.put(element, objectCache);
                    }
                }
                String objectName = GeneralUtils.makeDisplayString(getObjectValue(element)).toString();
                monitor.subTask(NLS.bind(UINavigatorMessages.controls_object_list_monitor_load_props, objectName));
                for (ObjectColumn column : entry.getValue()) {
                    if (monitor.isCanceled() || isDisposed()) {
                        break;
                    }
                    ObjectPropertyDescriptor prop = getPropertyByObject(column, object);
                    if (prop != null) {
                        try {
                            synchronized (lazyCache) {
                                if (objectCache.containsKey(prop.getId())) {
                                    // This property already cached
                                    continue;
                                }
                            }
                            Object lazyValue = prop.readValue(object, monitor, false);
                            if (lazyValue == null) {
                                lazyValue = NULL_VALUE;
                            }
                            synchronized (lazyCache) {
                                objectCache.put(prop.getId(), lazyValue);
                            }
                        } catch (Throwable e) {
                            if (e instanceof InvocationTargetException) {
                                e = ((InvocationTargetException) e).getTargetException();
                            }
                            log.error("Error reading property '" + prop.getId() + "' from " + object, e); //$NON-NLS-1$ //$NON-NLS-2$
                            // do not return error - it causes a lot of error boxes
                            //return RuntimeUtils.makeExceptionStatus(e);
                        }
                    }
                }
                monitor.worked(1);
            }
            monitor.done();
            if (!isDisposed()) {
                // Make refresh of whole table
                // Some other objects could also be updated implicitly with our lazy loader
                UIUtils.asyncExec(() -> {
                    if (!isDisposed()) {
                        itemsViewer.refresh();
                    }
                });
            }
            if (monitor.isCanceled()) {
                lazyLoadCanceled = true;
                obtainLazyObjects();
            }
            return Status.OK_STATUS;
        }
Creates service for object loading.
@param forUpdate true if it is update/merge operation. I.e. existing object modifications should remain.
plugins/org.jkiss.dbeaver.ui.navigator/src/org/jkiss/dbeaver/ui/navigator/itemlist/ObjectListControl.java