public function readAll() {
        $cmdbObjectTypes = new CMDBObjectTypes($this->api);
        $cmdbObjectTypeCategories = new CMDBObjectTypeCategories($this->api);
        $categoryConsts = [];
        $objectTypes = $cmdbObjectTypes->read();
        $objectTypeIDs = array_map(function ($objectType) {
            return (int) $objectType['id'];
        }, $objectTypes);
        $objectTypeCategoriesBatch = $cmdbObjectTypeCategories->batchReadByID($objectTypeIDs);
        $catTypes = ['catg', 'cats'];

        foreach ($objectTypeCategoriesBatch as $objectTypeCategories) {
            foreach ($catTypes as $catType) {
                if (!array_key_exists($catType, $objectTypeCategories)) {
                    continue;
                }

                $more = array_map(function ($category) {
                    return $category['const'];
                }, $objectTypeCategories[$catType]);

                $categoryConsts = array_merge($categoryConsts, $more);
            }
        }

        $categoryConsts = array_unique($categoryConsts);

        $blacklistedCategoryConsts = $this->getVirtualCategoryConstants();
        $cleanCategoryConstants = [];

        foreach ($categoryConsts as $categoryConstant) {
            if (!in_array($categoryConstant, $blacklistedCategoryConsts)) {
                $cleanCategoryConstants[] = $categoryConstant;
            }
        }

        sort($cleanCategoryConstants);

        $categories = $this->batchRead($cleanCategoryConstants);

        $combinedArray = array_combine($cleanCategoryConstants, $categories);

        if (!is_array($combinedArray)) {
            throw new RuntimeException('Unable to restructure result');
        }

        return $combinedArray;
    }