diff --git a/src/apps/basic-wrapper/index.ts b/src/apps/basic-wrapper/index.ts
index d788144ebb5fa4242766fe74851aac9f82f5f327..9d87fa121b980b6c0659285b1a1ac8bd939f1623 100644
--- a/src/apps/basic-wrapper/index.ts
+++ b/src/apps/basic-wrapper/index.ts
@@ -47,7 +47,7 @@ class BasicWrapper {
             }
         });
 
-        this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add(StripedResidues.propertyProvider.descriptor.name, StripedResidues.colorThemeProvider!);
+        this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add(StripedResidues.colorThemeProvider!);
         this.plugin.managers.lociLabels.addProvider(StripedResidues.labelProvider!);
         this.plugin.customModelProperties.register(StripedResidues.propertyProvider, true);
     }
diff --git a/src/examples/proteopedia-wrapper/coloring.ts b/src/examples/proteopedia-wrapper/coloring.ts
index 3b25496365d11cc143d1c182c1e8a273286a171b..2eb6d9e80cc9d175f53269e2133c2d343010afd6 100644
--- a/src/examples/proteopedia-wrapper/coloring.ts
+++ b/src/examples/proteopedia-wrapper/coloring.ts
@@ -94,7 +94,8 @@ export function createProteopediaCustomTheme(colors: number[]) {
         }
     }
 
-    const ProteopediaCustomColorThemeProvider: ColorTheme.Provider<ProteopediaCustomColorThemeParams> = {
+    return {
+        name: 'proteopedia-custom',
         label: 'Proteopedia Custom',
         category: 'Custom',
         factory: ProteopediaCustomColorTheme,
@@ -102,6 +103,4 @@ export function createProteopediaCustomTheme(colors: number[]) {
         defaultValues: PD.getDefaultValues(ProteopediaCustomColorThemeParams),
         isApplicable: (ctx: ThemeDataContext) => !!ctx.structure
     }
-
-    return ProteopediaCustomColorThemeProvider;
 }
\ No newline at end of file
diff --git a/src/examples/proteopedia-wrapper/index.ts b/src/examples/proteopedia-wrapper/index.ts
index 1b3594e5bd49d1cbb47edc67b5a4ee7d4c36bc62..54e6876b8956365a9fdf2ad1f19e7304c4f20204 100644
--- a/src/examples/proteopedia-wrapper/index.ts
+++ b/src/examples/proteopedia-wrapper/index.ts
@@ -67,8 +67,8 @@ class MolStarProteopediaWrapper {
 
         const customColoring = createProteopediaCustomTheme((options && options.customColorList) || []);
 
-        this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add('proteopedia-custom', customColoring);
-        this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add(EvolutionaryConservation.propertyProvider.descriptor.name, EvolutionaryConservation.colorThemeProvider!);
+        this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add(customColoring);
+        this.plugin.structureRepresentation.themeCtx.colorThemeRegistry.add(EvolutionaryConservation.colorThemeProvider!);
         this.plugin.managers.lociLabels.addProvider(EvolutionaryConservation.labelProvider!);
         this.plugin.customModelProperties.register(EvolutionaryConservation.propertyProvider, true);
     }
diff --git a/src/mol-model-props/common/custom-element-property.ts b/src/mol-model-props/common/custom-element-property.ts
index 580ff14c2301a73f4654260a8cce790b1660c0e2..c174a0996430185bb6b79d77611fb60b52268667 100644
--- a/src/mol-model-props/common/custom-element-property.ts
+++ b/src/mol-model-props/common/custom-element-property.ts
@@ -98,6 +98,7 @@ namespace CustomElementProperty {
         }
 
         return {
+            name: modelProperty.descriptor.name,
             label: modelProperty.label,
             category: 'Custom',
             factory: Coloring,
diff --git a/src/mol-model-props/computed/themes/accessible-surface-area.ts b/src/mol-model-props/computed/themes/accessible-surface-area.ts
index 77a71797c1c4b1296b50d7950efe9d4b64f17393..d9023f779fdb9ab9fd8ced3750b4d81564ccee16 100644
--- a/src/mol-model-props/computed/themes/accessible-surface-area.ts
+++ b/src/mol-model-props/computed/themes/accessible-surface-area.ts
@@ -64,7 +64,8 @@ export function AccessibleSurfaceAreaColorTheme(ctx: ThemeDataContext, props: PD
     }
 }
 
-export const AccessibleSurfaceAreaColorThemeProvider: ColorTheme.Provider<AccessibleSurfaceAreaColorThemeParams> = {
+export const AccessibleSurfaceAreaColorThemeProvider: ColorTheme.Provider<AccessibleSurfaceAreaColorThemeParams, 'accessible-surface-area'> = {
+    name: 'accessible-surface-area',
     label: 'Accessible Surface Area',
     category: ColorTheme.Category.Residue,
     factory: AccessibleSurfaceAreaColorTheme,
diff --git a/src/mol-model-props/computed/themes/interaction-type.ts b/src/mol-model-props/computed/themes/interaction-type.ts
index 5ecf849e64ca364006f9c17266db03fcdc283703..90f272daad46a32d05cec343122ded64bb013161 100644
--- a/src/mol-model-props/computed/themes/interaction-type.ts
+++ b/src/mol-model-props/computed/themes/interaction-type.ts
@@ -106,7 +106,8 @@ export function InteractionTypeColorTheme(ctx: ThemeDataContext, props: PD.Value
     }
 }
 
-export const InteractionTypeColorThemeProvider: ColorTheme.Provider<InteractionTypeColorThemeParams> = {
+export const InteractionTypeColorThemeProvider: ColorTheme.Provider<InteractionTypeColorThemeParams, 'interaction-type'> = {
+    name: 'interaction-type',
     label: 'Interaction Type',
     category: ColorTheme.Category.Misc,
     factory: InteractionTypeColorTheme,
diff --git a/src/mol-model-props/integrative/cross-link-restraint/color.ts b/src/mol-model-props/integrative/cross-link-restraint/color.ts
index df0794ae9d0911acbc9e9210b7b1589b3f5f783f..b81d0a0c07d84790c400b71f19aee9215ea68f84 100644
--- a/src/mol-model-props/integrative/cross-link-restraint/color.ts
+++ b/src/mol-model-props/integrative/cross-link-restraint/color.ts
@@ -61,7 +61,8 @@ export function CrossLinkColorTheme(ctx: ThemeDataContext, props: PD.Values<Cros
     }
 }
 
-export const CrossLinkColorThemeProvider: ColorTheme.Provider<CrossLinkColorThemeParams> = {
+export const CrossLinkColorThemeProvider: ColorTheme.Provider<CrossLinkColorThemeParams, 'cross-link'> = {
+    name: 'cross-link',
     label: 'Cross Link',
     category: ColorTheme.Category.Misc,
     factory: CrossLinkColorTheme,
diff --git a/src/mol-model-props/pdbe/themes/structure-quality-report.ts b/src/mol-model-props/pdbe/themes/structure-quality-report.ts
index 5d09d35abbe5e13050b798126ae3576e75fd2c54..a50de3460df42bbac7ab7d13f441b7d0a38abe40 100644
--- a/src/mol-model-props/pdbe/themes/structure-quality-report.ts
+++ b/src/mol-model-props/pdbe/themes/structure-quality-report.ts
@@ -77,7 +77,8 @@ export function StructureQualityReportColorTheme(ctx: ThemeDataContext, props: P
     }
 }
 
-export const StructureQualityReportColorThemeProvider: ColorTheme.Provider<Params> =  {
+export const StructureQualityReportColorThemeProvider: ColorTheme.Provider<Params, 'pdbe-structure-quality-report'> =  {
+    name: 'pdbe-structure-quality-report',
     label: 'Structure Quality Report',
     category: ColorTheme.Category.Validation,
     factory: StructureQualityReportColorTheme,
diff --git a/src/mol-model-props/rcsb/themes/assembly-symmetry-cluster.ts b/src/mol-model-props/rcsb/themes/assembly-symmetry-cluster.ts
index 82bc4c97484c1ebf3b75d113bb0ba1b7ae5a03a6..830cbf51a709bea60256694d4a0af469fbb360fe 100644
--- a/src/mol-model-props/rcsb/themes/assembly-symmetry-cluster.ts
+++ b/src/mol-model-props/rcsb/themes/assembly-symmetry-cluster.ts
@@ -91,7 +91,8 @@ export function AssemblySymmetryClusterColorTheme(ctx: ThemeDataContext, props:
     }
 }
 
-export const AssemblySymmetryClusterColorThemeProvider: ColorTheme.Provider<AssemblySymmetryClusterColorThemeParams> = {
+export const AssemblySymmetryClusterColorThemeProvider: ColorTheme.Provider<AssemblySymmetryClusterColorThemeParams, AssemblySymmetry.Tag.Cluster> = {
+    name: AssemblySymmetry.Tag.Cluster,
     label: 'Assembly Symmetry Cluster',
     category: ColorTheme.Category.Symmetry,
     factory: AssemblySymmetryClusterColorTheme,
diff --git a/src/mol-model-props/rcsb/themes/density-fit.ts b/src/mol-model-props/rcsb/themes/density-fit.ts
index 13b682781be37ff398789ac2dbdfa290d69f697e..7a159a7dac918d2b5faca2a37ef9faabe845c82e 100644
--- a/src/mol-model-props/rcsb/themes/density-fit.ts
+++ b/src/mol-model-props/rcsb/themes/density-fit.ts
@@ -60,7 +60,8 @@ export function DensityFitColorTheme(ctx: ThemeDataContext, props: {}): ColorThe
     }
 }
 
-export const DensityFitColorThemeProvider: ColorTheme.Provider<{}> = {
+export const DensityFitColorThemeProvider: ColorTheme.Provider<{}, ValidationReport.Tag.DensityFit> = {
+    name: ValidationReport.Tag.DensityFit,
     label: 'Density Fit',
     category: ColorTheme.Category.Validation,
     factory: DensityFitColorTheme,
diff --git a/src/mol-model-props/rcsb/themes/geometry-quality.ts b/src/mol-model-props/rcsb/themes/geometry-quality.ts
index fc88baa9095edb71dd4a75f480d2e0a615a8d6c2..d6c1f9cf7860d6f6657068d777774805672ebc7b 100644
--- a/src/mol-model-props/rcsb/themes/geometry-quality.ts
+++ b/src/mol-model-props/rcsb/themes/geometry-quality.ts
@@ -100,7 +100,8 @@ export function GeometryQualityColorTheme(ctx: ThemeDataContext, props: PD.Value
     }
 }
 
-export const GeometryQualityColorThemeProvider: ColorTheme.Provider<GeometricQualityColorThemeParams> = {
+export const GeometryQualityColorThemeProvider: ColorTheme.Provider<GeometricQualityColorThemeParams, ValidationReport.Tag.GeometryQuality> = {
+    name: ValidationReport.Tag.GeometryQuality,
     label: 'Geometry Quality',
     category: ColorTheme.Category.Validation,
     factory: GeometryQualityColorTheme,
diff --git a/src/mol-model-props/rcsb/themes/random-coil-index.ts b/src/mol-model-props/rcsb/themes/random-coil-index.ts
index ca3943eab74c185cf8e37ab79bef352bb76857cc..c339e85cf2cf82f6cd56c407c0a991fca10c0436 100644
--- a/src/mol-model-props/rcsb/themes/random-coil-index.ts
+++ b/src/mol-model-props/rcsb/themes/random-coil-index.ts
@@ -51,7 +51,8 @@ export function RandomCoilIndexColorTheme(ctx: ThemeDataContext, props: {}): Col
     }
 }
 
-export const RandomCoilIndexColorThemeProvider: ColorTheme.Provider<{}> = {
+export const RandomCoilIndexColorThemeProvider: ColorTheme.Provider<{}, ValidationReport.Tag.RandomCoilIndex> = {
+    name: ValidationReport.Tag.RandomCoilIndex,
     label: 'Random Coil Index',
     category: ColorTheme.Category.Validation,
     factory: RandomCoilIndexColorTheme,
diff --git a/src/mol-plugin-state/helpers/structure-representation-params.ts b/src/mol-plugin-state/helpers/structure-representation-params.ts
index 2ce0e738e27221bf2339127e965ddb3cae7ea8af..151842f9a863cccac80208657e74ede48c88e350 100644
--- a/src/mol-plugin-state/helpers/structure-representation-params.ts
+++ b/src/mol-plugin-state/helpers/structure-representation-params.ts
@@ -80,20 +80,18 @@ function createParamsProvider(ctx: PluginContext, structure: Structure, props: S
     const reprParams = Object.assign(reprDefaultParams, props.typeParams);
     
     const color = props.color || themeCtx.colorThemeRegistry.get(repr.defaultColorTheme.name);
-    const colorName = themeCtx.colorThemeRegistry.getName(color);
     const colorDefaultParams = PD.getDefaultValues(color.getParams(themeDataCtx));
-    if (colorName === repr.defaultColorTheme.name) Object.assign(colorDefaultParams, repr.defaultColorTheme.props);
+    if (color.name === repr.defaultColorTheme.name) Object.assign(colorDefaultParams, repr.defaultColorTheme.props);
     const colorParams = Object.assign(colorDefaultParams, props.colorParams);
 
     const size = props.size || themeCtx.sizeThemeRegistry.get(repr.defaultSizeTheme.name);
-    const sizeName = themeCtx.sizeThemeRegistry.getName(size);
     const sizeDefaultParams = PD.getDefaultValues(size.getParams(themeDataCtx));
-    if (sizeName === repr.defaultSizeTheme.name) Object.assign(sizeDefaultParams, repr.defaultSizeTheme.props);
+    if (size.name === repr.defaultSizeTheme.name) Object.assign(sizeDefaultParams, repr.defaultSizeTheme.props);
     const sizeParams = Object.assign(sizeDefaultParams, props.sizeParams);
 
     return ({
-        type: { name: ctx.structureRepresentation.registry.getName(repr), params: reprParams },
-        colorTheme: { name: colorName, params: colorParams },
-        sizeTheme: { name: sizeName, params: sizeParams }
+        type: { name: repr.name, params: reprParams },
+        colorTheme: { name: color.name, params: colorParams },
+        sizeTheme: { name: size.name, params: sizeParams }
     });
 }
\ No newline at end of file
diff --git a/src/mol-plugin/behavior/dynamic/custom-props/computed/accessible-surface-area.ts b/src/mol-plugin/behavior/dynamic/custom-props/computed/accessible-surface-area.ts
index 3acedd05499f31d9b62a8eb6994f4849604a9acb..cbee2a620a2317eda07122e35ebcf95a82e80cc3 100644
--- a/src/mol-plugin/behavior/dynamic/custom-props/computed/accessible-surface-area.ts
+++ b/src/mol-plugin/behavior/dynamic/custom-props/computed/accessible-surface-area.ts
@@ -40,7 +40,7 @@ export const AccessibleSurfaceArea = PluginBehavior.create<{ autoAttach: boolean
             DefaultQueryRuntimeTable.addCustomProp(this.provider.descriptor);
 
             this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add('accessible-surface-area', AccessibleSurfaceAreaColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(AccessibleSurfaceAreaColorThemeProvider)
             this.ctx.managers.lociLabels.addProvider(this.label);
         }
 
@@ -49,7 +49,7 @@ export const AccessibleSurfaceArea = PluginBehavior.create<{ autoAttach: boolean
             // DefaultQueryRuntimeTable.removeCustomProp(this.provider.descriptor);
 
             this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove('accessible-surface-area')
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(AccessibleSurfaceAreaColorThemeProvider)
             this.ctx.managers.lociLabels.removeProvider(this.label);
         }
     },
diff --git a/src/mol-plugin/behavior/dynamic/custom-props/computed/interactions.ts b/src/mol-plugin/behavior/dynamic/custom-props/computed/interactions.ts
index a625f4d7d1f8741b98609b51b79c14853beae432..1c4c7546303a444d1cb34ba3d93251882fd0679b 100644
--- a/src/mol-plugin/behavior/dynamic/custom-props/computed/interactions.ts
+++ b/src/mol-plugin/behavior/dynamic/custom-props/computed/interactions.ts
@@ -99,14 +99,14 @@ export const Interactions = PluginBehavior.create<{ autoAttach: boolean, showToo
 
         register(): void {
             this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add('interaction-type', InteractionTypeColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(InteractionTypeColorThemeProvider)
             this.ctx.managers.lociLabels.addProvider(this.label);
             this.ctx.structureRepresentation.registry.add(InteractionsRepresentationProvider)
         }
 
         unregister() {
             this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove('interaction-type')
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(InteractionTypeColorThemeProvider)
             this.ctx.managers.lociLabels.removeProvider(this.label);
             this.ctx.structureRepresentation.registry.remove(InteractionsRepresentationProvider)
         }
diff --git a/src/mol-plugin/behavior/dynamic/custom-props/integrative/cross-link-restraint.ts b/src/mol-plugin/behavior/dynamic/custom-props/integrative/cross-link-restraint.ts
index cc83cfbfde8806995c17a3008ae25af3d0cc7671..d21a2f167107601918b10ad1063a0bdf23f0ddbb 100644
--- a/src/mol-plugin/behavior/dynamic/custom-props/integrative/cross-link-restraint.ts
+++ b/src/mol-plugin/behavior/dynamic/custom-props/integrative/cross-link-restraint.ts
@@ -12,8 +12,6 @@ import { CrossLinkRestraintRepresentationProvider } from '../../../../../mol-mod
 import { CrossLinkColorThemeProvider } from '../../../../../mol-model-props/integrative/cross-link-restraint/color';
 import { CrossLinkRestraint as _CrossLinkRestraint } from '../../../../../mol-model-props/integrative/cross-link-restraint/property';
 
-const Tag = _CrossLinkRestraint.Tag
-
 export const CrossLinkRestraint = PluginBehavior.create<{ }>({
     name: 'integrative-cross-link-restraint',
     category: 'custom-props',
@@ -24,14 +22,14 @@ export const CrossLinkRestraint = PluginBehavior.create<{ }>({
         register(): void {
             this.provider.formatRegistry.add('mmCIF', crossLinkRestraintFromMmcif)
 
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(Tag.CrossLinkRestraint, CrossLinkColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(CrossLinkColorThemeProvider)
             this.ctx.structureRepresentation.registry.add(CrossLinkRestraintRepresentationProvider)
         }
 
         unregister() {
             this.provider.formatRegistry.remove('mmCIF')
 
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(Tag.CrossLinkRestraint)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(CrossLinkColorThemeProvider)
             this.ctx.structureRepresentation.registry.remove(CrossLinkRestraintRepresentationProvider)
         }
     }
diff --git a/src/mol-plugin/behavior/dynamic/custom-props/pdbe/structure-quality-report.ts b/src/mol-plugin/behavior/dynamic/custom-props/pdbe/structure-quality-report.ts
index a69898ccf86db0301862b4e2703defbc900ea19f..fb581f4a5cecc5bea376eff5cfb5201322b21589 100644
--- a/src/mol-plugin/behavior/dynamic/custom-props/pdbe/structure-quality-report.ts
+++ b/src/mol-plugin/behavior/dynamic/custom-props/pdbe/structure-quality-report.ts
@@ -46,7 +46,7 @@ export const PDBeStructureQualityReport = PluginBehavior.create<{ autoAttach: bo
             this.ctx.customModelProperties.register(this.provider, false);
             this.ctx.managers.lociLabels.addProvider(this.labelPDBeValidation);
 
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add('pdbe-structure-quality-report', StructureQualityReportColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(StructureQualityReportColorThemeProvider)
         }
 
         update(p: { autoAttach: boolean, showTooltip: boolean }) {
@@ -60,7 +60,7 @@ export const PDBeStructureQualityReport = PluginBehavior.create<{ autoAttach: bo
         unregister() {
             this.ctx.customModelProperties.unregister(StructureQualityReportProvider.descriptor.name);
             this.ctx.managers.lociLabels.removeProvider(this.labelPDBeValidation);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove('pdbe-structure-quality-report')
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(StructureQualityReportColorThemeProvider)
         }
     },
     params: () => ({
diff --git a/src/mol-plugin/behavior/dynamic/custom-props/rcsb/assembly-symmetry.ts b/src/mol-plugin/behavior/dynamic/custom-props/rcsb/assembly-symmetry.ts
index dd666747d956935cce3682ff7a48cb351e0fe197..217e24235c1260e512faa869fa1e95c57ec548d9 100644
--- a/src/mol-plugin/behavior/dynamic/custom-props/rcsb/assembly-symmetry.ts
+++ b/src/mol-plugin/behavior/dynamic/custom-props/rcsb/assembly-symmetry.ts
@@ -29,7 +29,7 @@ export const RCSBAssemblySymmetry = PluginBehavior.create<{ autoAttach: boolean
         register(): void {
             this.ctx.state.dataState.actions.add(InitAssemblySymmetry3D)
             this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(Tag.Cluster, AssemblySymmetryClusterColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(AssemblySymmetryClusterColorThemeProvider)
         }
 
         update(p: { autoAttach: boolean }) {
@@ -42,7 +42,7 @@ export const RCSBAssemblySymmetry = PluginBehavior.create<{ autoAttach: boolean
         unregister() {
             this.ctx.state.dataState.actions.remove(InitAssemblySymmetry3D)
             this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(Tag.Cluster)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(AssemblySymmetryClusterColorThemeProvider)
         }
     },
     params: () => ({
diff --git a/src/mol-plugin/behavior/dynamic/custom-props/rcsb/validation-report.ts b/src/mol-plugin/behavior/dynamic/custom-props/rcsb/validation-report.ts
index 255c9c4d801059384e1769f681ce13687929ebb8..8ccddb2f64265369c19574d5a585ef2866769bf8 100644
--- a/src/mol-plugin/behavior/dynamic/custom-props/rcsb/validation-report.ts
+++ b/src/mol-plugin/behavior/dynamic/custom-props/rcsb/validation-report.ts
@@ -16,8 +16,6 @@ import { DensityFitColorThemeProvider } from '../../../../../mol-model-props/rcs
 import { cantorPairing } from '../../../../../mol-data/util';
 import { DefaultQueryRuntimeTable } from '../../../../../mol-script/runtime/query/compiler';
 
-const Tag = ValidationReport.Tag
-
 export const RCSBValidationReport = PluginBehavior.create<{ autoAttach: boolean, showTooltip: boolean }>({
     name: 'rcsb-validation-report-prop',
     category: 'custom-props',
@@ -44,9 +42,9 @@ export const RCSBValidationReport = PluginBehavior.create<{ autoAttach: boolean,
 
             this.ctx.managers.lociLabels.addProvider(this.label);
 
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(Tag.DensityFit, DensityFitColorThemeProvider)
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(Tag.GeometryQuality, GeometryQualityColorThemeProvider)
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(Tag.RandomCoilIndex, RandomCoilIndexColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(DensityFitColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(GeometryQualityColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add(RandomCoilIndexColorThemeProvider)
 
             this.ctx.structureRepresentation.registry.add(ClashesRepresentationProvider)
         }
@@ -67,9 +65,9 @@ export const RCSBValidationReport = PluginBehavior.create<{ autoAttach: boolean,
 
             this.ctx.managers.lociLabels.removeProvider(this.label);
 
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(Tag.DensityFit)
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(Tag.GeometryQuality)
-            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(Tag.RandomCoilIndex)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(DensityFitColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(GeometryQualityColorThemeProvider)
+            this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove(RandomCoilIndexColorThemeProvider)
 
             this.ctx.structureRepresentation.registry.remove(ClashesRepresentationProvider)
         }
diff --git a/src/mol-plugin/behavior/dynamic/selection/structure-representation-interaction.ts b/src/mol-plugin/behavior/dynamic/selection/structure-representation-interaction.ts
index 68aa2d97cf457ec8dfe3527506bb13a243342c36..a67405d1c0eaef89de872134ff23484d3531bb56 100644
--- a/src/mol-plugin/behavior/dynamic/selection/structure-representation-interaction.ts
+++ b/src/mol-plugin/behavior/dynamic/selection/structure-representation-interaction.ts
@@ -48,12 +48,12 @@ const StructureRepresentationInteractionParams = (plugin: PluginContext) => {
         }),
         nciParams: PD.Group(reprParams, {
             label: 'Non-covalent Int.',
-            customDefault: createStructureRepresentationParams(plugin, void 0, { type: 'ball-and-stick', color: 'element-symbol', size: 'uniform' })
-            // customDefault: createStructureRepresentationParams(plugin, void 0, {
-            //     type: InteractionsRepresentationProvider,
-            //     color: InteractionTypeColorThemeProvider,
-            //     size: BuiltInSizeThemes.uniform
-            // })
+            // customDefault: createStructureRepresentationParams(plugin, void 0, { type: 'ball-and-stick', color: 'element-symbol', size: 'uniform' })
+            customDefault: createStructureRepresentationParams(plugin, void 0, {
+                type: InteractionsRepresentationProvider,
+                color: InteractionTypeColorThemeProvider,
+                size: BuiltInSizeThemes.uniform
+            })
         })
     };
 }
diff --git a/src/mol-repr/structure/registry.ts b/src/mol-repr/structure/registry.ts
index cb6791ce9e557700a175fdbbe087b2ef3cc590f8..619692a89298bdc35a4220be61b9366329409a31 100644
--- a/src/mol-repr/structure/registry.ts
+++ b/src/mol-repr/structure/registry.ts
@@ -24,7 +24,7 @@ export class StructureRepresentationRegistry extends RepresentationRegistry<Stru
     constructor() {
         super()
         objectForEach(BuiltInStructureRepresentations, (p, k) => {
-            if (p.name !== k) throw new Error('Fix BuiltInStructureRepresentations to have matching names.');
+            if (p.name !== k) throw new Error(`Fix BuiltInStructureRepresentations to have matching names. ${p.name} ${k}`);
             this.add(p as any)
         })
     }
diff --git a/src/mol-repr/volume/registry.ts b/src/mol-repr/volume/registry.ts
index e8a7ba4f97b3784a98fd3ccf7f28fa1ddee876e3..13119ecdeed793027fa423c55a1cb0451f3894fa 100644
--- a/src/mol-repr/volume/registry.ts
+++ b/src/mol-repr/volume/registry.ts
@@ -14,7 +14,7 @@ export class VolumeRepresentationRegistry extends RepresentationRegistry<VolumeD
         super()
         Object.keys(BuiltInVolumeRepresentations).forEach(name => {
             objectForEach(BuiltInVolumeRepresentations, (p, k) => {
-                if (p.name !== k) throw new Error('Fix BuiltInVolumeRepresentations to have matching names.');
+                if (p.name !== k) throw new Error(`Fix BuiltInVolumeRepresentations to have matching names. ${p.name} ${k}`);
                 this.add(p as any)
             })
         })
diff --git a/src/mol-theme/color.ts b/src/mol-theme/color.ts
index 17065b37ec1d37a6fc9d2ecce4d98f40ec0d2f3b..2e34f61fec8cef0b50ca96301982423eaf867e70 100644
--- a/src/mol-theme/color.ts
+++ b/src/mol-theme/color.ts
@@ -70,8 +70,8 @@ namespace ColorTheme {
         return themeA.contextHash === themeB.contextHash && themeA.factory === themeB.factory && deepEqual(themeA.props, themeB.props)
     }
 
-    export interface Provider<P extends PD.Params = any> extends ThemeProvider<ColorTheme<P>, P> { }
-    export const EmptyProvider: Provider<{}> = { label: '', category: '', factory: EmptyFactory, getParams: () => ({}), defaultValues: {}, isApplicable: () => true }
+    export interface Provider<P extends PD.Params = any, Id extends string = string> extends ThemeProvider<ColorTheme<P>, P, Id> { }
+    export const EmptyProvider: Provider<{}> = { name: '', label: '', category: '', factory: EmptyFactory, getParams: () => ({}), defaultValues: {}, isApplicable: () => true }
 
     export type Registry = ThemeRegistry<ColorTheme<any>>
     export function createRegistry() {
@@ -81,6 +81,8 @@ namespace ColorTheme {
     export type ParamValues<C extends ColorTheme.Provider<any>> = C extends ColorTheme.Provider<infer P> ? PD.Values<P> : never
 }
 
+export function ColorThemeProvider<P extends PD.Params, Id extends string>(p: ColorTheme.Provider<P, Id>): ColorTheme.Provider<P, Id> { return p; }
+
 export const BuiltInColorThemes = {
     'carbohydrate-symbol': CarbohydrateSymbolColorThemeProvider,
     'chain-id': ChainIdColorThemeProvider,
diff --git a/src/mol-theme/color/carbohydrate-symbol.ts b/src/mol-theme/color/carbohydrate-symbol.ts
index 39d41725491f48c9bf5ee3fcccdcc363d401d4c5..d3e306bef684c075cf20a755c6412adf89355f7b 100644
--- a/src/mol-theme/color/carbohydrate-symbol.ts
+++ b/src/mol-theme/color/carbohydrate-symbol.ts
@@ -60,7 +60,8 @@ export function CarbohydrateSymbolColorTheme(ctx: ThemeDataContext, props: PD.Va
     }
 }
 
-export const CarbohydrateSymbolColorThemeProvider: ColorTheme.Provider<CarbohydrateSymbolColorThemeParams> = {
+export const CarbohydrateSymbolColorThemeProvider: ColorTheme.Provider<CarbohydrateSymbolColorThemeParams, 'carbohydrate-symbol'> = {
+    name: 'carbohydrate-symbol',
     label: 'Carbohydrate Symbol',
     category: ColorTheme.Category.Residue,
     factory: CarbohydrateSymbolColorTheme,
diff --git a/src/mol-theme/color/chain-id.ts b/src/mol-theme/color/chain-id.ts
index 46b587c708517f24ee6c052fe6f7c47376c21a87..de4438232c901ec46aaca9545277ee7317b6a088 100644
--- a/src/mol-theme/color/chain-id.ts
+++ b/src/mol-theme/color/chain-id.ts
@@ -117,7 +117,8 @@ export function ChainIdColorTheme(ctx: ThemeDataContext, props: PD.Values<ChainI
     }
 }
 
-export const ChainIdColorThemeProvider: ColorTheme.Provider<ChainIdColorThemeParams> = {
+export const ChainIdColorThemeProvider: ColorTheme.Provider<ChainIdColorThemeParams, 'chain-id'> = {
+    name: 'chain-id',
     label: 'Chain Id',
     category: ColorTheme.Category.Chain,
     factory: ChainIdColorTheme,
diff --git a/src/mol-theme/color/element-index.ts b/src/mol-theme/color/element-index.ts
index 0e796512a00b6af51a604b3a92276aa49f1bf17f..b085cee85b45d2e920c333419d26c003ca4d28fe 100644
--- a/src/mol-theme/color/element-index.ts
+++ b/src/mol-theme/color/element-index.ts
@@ -71,7 +71,8 @@ export function ElementIndexColorTheme(ctx: ThemeDataContext, props: PD.Values<E
     }
 }
 
-export const ElementIndexColorThemeProvider: ColorTheme.Provider<ElementIndexColorThemeParams> = {
+export const ElementIndexColorThemeProvider: ColorTheme.Provider<ElementIndexColorThemeParams, 'element-index'> = {
+    name: 'element-index',
     label: 'Element Index',
     category: ColorTheme.Category.Atom,
     factory: ElementIndexColorTheme,
diff --git a/src/mol-theme/color/element-symbol.ts b/src/mol-theme/color/element-symbol.ts
index 3582d1414f04afaac51849cf3cd262c4b8c6af71..906bf70af4df5bab81e955fc0ea107cf506d8256 100644
--- a/src/mol-theme/color/element-symbol.ts
+++ b/src/mol-theme/color/element-symbol.ts
@@ -67,7 +67,8 @@ export function ElementSymbolColorTheme(ctx: ThemeDataContext, props: PD.Values<
     }
 }
 
-export const ElementSymbolColorThemeProvider: ColorTheme.Provider<ElementSymbolColorThemeParams> = {
+export const ElementSymbolColorThemeProvider: ColorTheme.Provider<ElementSymbolColorThemeParams, 'element-symbol'> = {
+    name: 'element-symbol',
     label: 'Element Symbol',
     category: ColorTheme.Category.Atom,
     factory: ElementSymbolColorTheme,
diff --git a/src/mol-theme/color/entity-source.ts b/src/mol-theme/color/entity-source.ts
index 641839576b59aba23a4e8ac23672aa9150928f64..e7acc9db0c43ed44c55122aad3c1122481e1065a 100644
--- a/src/mol-theme/color/entity-source.ts
+++ b/src/mol-theme/color/entity-source.ts
@@ -173,7 +173,8 @@ export function EntitySourceColorTheme(ctx: ThemeDataContext, props: PD.Values<E
     }
 }
 
-export const EntitySourceColorThemeProvider: ColorTheme.Provider<EntitySourceColorThemeParams> = {
+export const EntitySourceColorThemeProvider: ColorTheme.Provider<EntitySourceColorThemeParams, 'entity-source'> = {
+    name: 'entity-source',
     label: 'Entity Source',
     category: ColorTheme.Category.Chain,
     factory: EntitySourceColorTheme,
diff --git a/src/mol-theme/color/hydrophobicity.ts b/src/mol-theme/color/hydrophobicity.ts
index 0879eba6cb1ffa117f0e410320afc056e1f01dfd..10ce176cf29ec89d2d7cd1debc70df545bff72a0 100644
--- a/src/mol-theme/color/hydrophobicity.ts
+++ b/src/mol-theme/color/hydrophobicity.ts
@@ -92,7 +92,8 @@ export function HydrophobicityColorTheme(ctx: ThemeDataContext, props: PD.Values
     }
 }
 
-export const HydrophobicityColorThemeProvider: ColorTheme.Provider<HydrophobicityColorThemeParams> = {
+export const HydrophobicityColorThemeProvider: ColorTheme.Provider<HydrophobicityColorThemeParams, 'hydrophobicity'> = {
+    name: 'hydrophobicity',
     label: 'Hydrophobicity',
     category: ColorTheme.Category.Residue,
     factory: HydrophobicityColorTheme,
diff --git a/src/mol-theme/color/illustrative.ts b/src/mol-theme/color/illustrative.ts
index 9b86d8b97a76e5ac85504745ffb30c46fa28b17a..cee5e8e87c5638cde2cb336821a4f2bc6eeabaf7 100644
--- a/src/mol-theme/color/illustrative.ts
+++ b/src/mol-theme/color/illustrative.ts
@@ -74,7 +74,8 @@ export function IllustrativeColorTheme(ctx: ThemeDataContext, props: PD.Values<I
     }
 }
 
-export const IllustrativeColorThemeProvider: ColorTheme.Provider<IllustrativeColorThemeParams> = {
+export const IllustrativeColorThemeProvider: ColorTheme.Provider<IllustrativeColorThemeParams, 'illustrative'> = {
+    name: 'illustrative',
     label: 'Illustrative',
     category: ColorTheme.Category.Misc,
     factory: IllustrativeColorTheme,
diff --git a/src/mol-theme/color/model-index.ts b/src/mol-theme/color/model-index.ts
index b8d49fe68fee5595cf0a3a025545f73bbf6778a1..46e6b2f665e7e2abfff1ebaa924ffc722fbb0c14 100644
--- a/src/mol-theme/color/model-index.ts
+++ b/src/mol-theme/color/model-index.ts
@@ -64,7 +64,8 @@ export function ModelIndexColorTheme(ctx: ThemeDataContext, props: PD.Values<Mod
     }
 }
 
-export const ModelIndexColorThemeProvider: ColorTheme.Provider<ModelIndexColorThemeParams> = {
+export const ModelIndexColorThemeProvider: ColorTheme.Provider<ModelIndexColorThemeParams, 'model-index'> = {
+    name: 'model-index',
     label: 'Model Index',
     category: ColorTheme.Category.Chain,
     factory: ModelIndexColorTheme,
diff --git a/src/mol-theme/color/molecule-type.ts b/src/mol-theme/color/molecule-type.ts
index 1692e649728c5564deef6859b770c0bd6677e060..74a700999187ba2dd1d18d5146899cc917089529 100644
--- a/src/mol-theme/color/molecule-type.ts
+++ b/src/mol-theme/color/molecule-type.ts
@@ -76,7 +76,8 @@ export function MoleculeTypeColorTheme(ctx: ThemeDataContext, props: PD.Values<M
     }
 }
 
-export const MoleculeTypeColorThemeProvider: ColorTheme.Provider<MoleculeTypeColorThemeParams> = {
+export const MoleculeTypeColorThemeProvider: ColorTheme.Provider<MoleculeTypeColorThemeParams, 'molecule-type'> = {
+    name: 'molecule-type',
     label: 'Molecule Type',
     category: ColorTheme.Category.Residue,
     factory: MoleculeTypeColorTheme,
diff --git a/src/mol-theme/color/occupancy.ts b/src/mol-theme/color/occupancy.ts
index 47686503c292c9da785e2fd077b2617de628be14..a2da83eef6a61a94a4bd4609159cce50844ac7dd 100644
--- a/src/mol-theme/color/occupancy.ts
+++ b/src/mol-theme/color/occupancy.ts
@@ -58,7 +58,8 @@ export function OccupancyColorTheme(ctx: ThemeDataContext, props: PD.Values<Occu
     }
 }
 
-export const OccupancyColorThemeProvider: ColorTheme.Provider<OccupancyColorThemeParams> = {
+export const OccupancyColorThemeProvider: ColorTheme.Provider<OccupancyColorThemeParams, 'occupancy'> = {
+    name: 'occupancy',
     label: 'Occupancy',
     category: ColorTheme.Category.Atom,
     factory: OccupancyColorTheme,
diff --git a/src/mol-theme/color/operator-hkl.ts b/src/mol-theme/color/operator-hkl.ts
index b6adab5f2161bd87dd6eb2c6a8fe864295714184..45c5c8a837c3266e6fd21605af5cb098b062c93f 100644
--- a/src/mol-theme/color/operator-hkl.ts
+++ b/src/mol-theme/color/operator-hkl.ts
@@ -117,7 +117,8 @@ export function OperatorHklColorTheme(ctx: ThemeDataContext, props: PD.Values<Op
     }
 }
 
-export const OperatorHklColorThemeProvider: ColorTheme.Provider<OperatorHklColorThemeParams> = {
+export const OperatorHklColorThemeProvider: ColorTheme.Provider<OperatorHklColorThemeParams, 'operator-hkl'> = {
+    name: 'operator-hkl',
     label: 'Operator HKL',
     category: ColorTheme.Category.Symmetry,
     factory: OperatorHklColorTheme,
diff --git a/src/mol-theme/color/operator-name.ts b/src/mol-theme/color/operator-name.ts
index 3c4b60895f0dabda9af8c4bf6a817ed6f11d5830..6ea025e90fde8d7b753aa0a9651a1425fcdaeb70 100644
--- a/src/mol-theme/color/operator-name.ts
+++ b/src/mol-theme/color/operator-name.ts
@@ -83,7 +83,8 @@ export function OperatorNameColorTheme(ctx: ThemeDataContext, props: PD.Values<O
     }
 }
 
-export const OperatorNameColorThemeProvider: ColorTheme.Provider<OperatorNameColorThemeParams> = {
+export const OperatorNameColorThemeProvider: ColorTheme.Provider<OperatorNameColorThemeParams, 'operator-name'> = {
+    name: 'operator-name',
     label: 'Operator Name',
     category: ColorTheme.Category.Symmetry,
     factory: OperatorNameColorTheme,
diff --git a/src/mol-theme/color/polymer-id.ts b/src/mol-theme/color/polymer-id.ts
index 68649703483620535f88e05a03f19076ad7831d2..4749bfa52c46542bd6a97d2333c330b25314a241 100644
--- a/src/mol-theme/color/polymer-id.ts
+++ b/src/mol-theme/color/polymer-id.ts
@@ -126,7 +126,8 @@ export function PolymerIdColorTheme(ctx: ThemeDataContext, props: PD.Values<Poly
     }
 }
 
-export const PolymerIdColorThemeProvider: ColorTheme.Provider<PolymerIdColorThemeParams> = {
+export const PolymerIdColorThemeProvider: ColorTheme.Provider<PolymerIdColorThemeParams, 'polymer-id'> = {
+    name: 'polymer-id',
     label: 'Polymer Chain Id',
     category: ColorTheme.Category.Chain,
     factory: PolymerIdColorTheme,
diff --git a/src/mol-theme/color/polymer-index.ts b/src/mol-theme/color/polymer-index.ts
index 6d6c86dc9ae258c16509e6478d0b1a63ce6d974f..f514c0804e4941e2c78a8d7146709ca67b780e63 100644
--- a/src/mol-theme/color/polymer-index.ts
+++ b/src/mol-theme/color/polymer-index.ts
@@ -86,7 +86,8 @@ export function PolymerIndexColorTheme(ctx: ThemeDataContext, props: PD.Values<P
     }
 }
 
-export const PolymerIndexColorThemeProvider: ColorTheme.Provider<PolymerIndexColorThemeParams> = {
+export const PolymerIndexColorThemeProvider: ColorTheme.Provider<PolymerIndexColorThemeParams, 'polymer-index'> = {
+    name: 'polymer-index',
     label: 'Polymer Chain Instance',
     category: ColorTheme.Category.Chain,
     factory: PolymerIndexColorTheme,
diff --git a/src/mol-theme/color/residue-name.ts b/src/mol-theme/color/residue-name.ts
index 741601e1cd2e6f37dd068d3d59857ac24b4e45de..dc341a3112288acdf64366475de46bf6d0a67194 100644
--- a/src/mol-theme/color/residue-name.ts
+++ b/src/mol-theme/color/residue-name.ts
@@ -128,7 +128,8 @@ export function ResidueNameColorTheme(ctx: ThemeDataContext, props: PD.Values<Re
     }
 }
 
-export const ResidueNameColorThemeProvider: ColorTheme.Provider<ResidueNameColorThemeParams> = {
+export const ResidueNameColorThemeProvider: ColorTheme.Provider<ResidueNameColorThemeParams, 'residue-name'> = {
+    name: 'residue-name',
     label: 'Residue Name',
     category: ColorTheme.Category.Residue,
     factory: ResidueNameColorTheme,
diff --git a/src/mol-theme/color/secondary-structure.ts b/src/mol-theme/color/secondary-structure.ts
index c3854195eb4e536ebfe50c20ba10ce0f1bf5bd34..34ed6fd0e18c654420f4eac9ec57a5f6938a30d1 100644
--- a/src/mol-theme/color/secondary-structure.ts
+++ b/src/mol-theme/color/secondary-structure.ts
@@ -111,7 +111,8 @@ export function SecondaryStructureColorTheme(ctx: ThemeDataContext, props: PD.Va
     }
 }
 
-export const SecondaryStructureColorThemeProvider: ColorTheme.Provider<SecondaryStructureColorThemeParams> = {
+export const SecondaryStructureColorThemeProvider: ColorTheme.Provider<SecondaryStructureColorThemeParams, 'secondary-structure'> = {
+    name: 'secondary-structure',
     label: 'Secondary Structure',
     category: ColorTheme.Category.Residue,
     factory: SecondaryStructureColorTheme,
diff --git a/src/mol-theme/color/sequence-id.ts b/src/mol-theme/color/sequence-id.ts
index 26881241a45d546ec50da3cba5c17b4cf6314487..3c5d062ba38b1896264cdb1fc53fe20096bc4af0 100644
--- a/src/mol-theme/color/sequence-id.ts
+++ b/src/mol-theme/color/sequence-id.ts
@@ -99,7 +99,8 @@ export function SequenceIdColorTheme(ctx: ThemeDataContext, props: PD.Values<Seq
     }
 }
 
-export const SequenceIdColorThemeProvider: ColorTheme.Provider<SequenceIdColorThemeParams> = {
+export const SequenceIdColorThemeProvider: ColorTheme.Provider<SequenceIdColorThemeParams, 'sequence-id'> = {
+    name: 'sequence-id',
     label: 'Sequence Id',
     category: ColorTheme.Category.Residue,
     factory: SequenceIdColorTheme,
diff --git a/src/mol-theme/color/shape-group.ts b/src/mol-theme/color/shape-group.ts
index 8a8232657dec24eac00254c08ba2bf2a458b4dc7..12900fa1390e35cf3b517fa876f1845cf43791b8 100644
--- a/src/mol-theme/color/shape-group.ts
+++ b/src/mol-theme/color/shape-group.ts
@@ -35,7 +35,8 @@ export function ShapeGroupColorTheme(ctx: ThemeDataContext, props: PD.Values<Sha
     }
 }
 
-export const ShapeGroupColorThemeProvider: ColorTheme.Provider<ShapeGroupColorThemeParams> = {
+export const ShapeGroupColorThemeProvider: ColorTheme.Provider<ShapeGroupColorThemeParams, 'shape-group'> = {
+    name: 'shape-group',
     label: 'Shape Group',
     category: ColorTheme.Category.Misc,
     factory: ShapeGroupColorTheme,
diff --git a/src/mol-theme/color/uncertainty.ts b/src/mol-theme/color/uncertainty.ts
index 512dbea67781636037f14c4bbf34b9cf7202acf4..66f71fb766d9f8b9325aed2e7a478f3d0c9721f5 100644
--- a/src/mol-theme/color/uncertainty.ts
+++ b/src/mol-theme/color/uncertainty.ts
@@ -62,7 +62,8 @@ export function UncertaintyColorTheme(ctx: ThemeDataContext, props: PD.Values<Un
     }
 }
 
-export const UncertaintyColorThemeProvider: ColorTheme.Provider<UncertaintyColorThemeParams> = {
+export const UncertaintyColorThemeProvider: ColorTheme.Provider<UncertaintyColorThemeParams, 'uncertainty'> = {
+    name: 'uncertainty',
     label: 'Uncertainty/Disorder',
     category: ColorTheme.Category.Atom,
     factory: UncertaintyColorTheme,
diff --git a/src/mol-theme/color/uniform.ts b/src/mol-theme/color/uniform.ts
index 2fd01719375da61b3e1693a7ba213095e8895981..e86b5fbc0b2a84b77d8dbc9adccd42f38db9bc0d 100644
--- a/src/mol-theme/color/uniform.ts
+++ b/src/mol-theme/color/uniform.ts
@@ -35,7 +35,8 @@ export function UniformColorTheme(ctx: ThemeDataContext, props: PD.Values<Unifor
     }
 }
 
-export const UniformColorThemeProvider: ColorTheme.Provider<UniformColorThemeParams> = {
+export const UniformColorThemeProvider: ColorTheme.Provider<UniformColorThemeParams, 'uniform'> = {
+    name: 'uniform',
     label: 'Uniform',
     category: ColorTheme.Category.Misc,
     factory: UniformColorTheme,
diff --git a/src/mol-theme/color/unit-index.ts b/src/mol-theme/color/unit-index.ts
index 3cc6cdcf26bbd93a71bda07611a6e1201cd149c7..3a58492bb95ba69250bd407bebe500aad06b6814 100644
--- a/src/mol-theme/color/unit-index.ts
+++ b/src/mol-theme/color/unit-index.ts
@@ -71,7 +71,8 @@ export function UnitIndexColorTheme(ctx: ThemeDataContext, props: PD.Values<Unit
     }
 }
 
-export const UnitIndexColorThemeProvider: ColorTheme.Provider<UnitIndexColorThemeParams> = {
+export const UnitIndexColorThemeProvider: ColorTheme.Provider<UnitIndexColorThemeParams, 'unit-index'> = {
+    name: 'unit-index',
     label: 'Chain Instance',
     category: ColorTheme.Category.Chain,
     factory: UnitIndexColorTheme,
diff --git a/src/mol-theme/size.ts b/src/mol-theme/size.ts
index 52fc6d8730df32a321921ace20948dbb0501e03f..bd5bfe16e01ef5bd6894aba6efed60c1d7eada54 100644
--- a/src/mol-theme/size.ts
+++ b/src/mol-theme/size.ts
@@ -31,8 +31,8 @@ namespace SizeTheme {
         return themeA.factory === themeB.factory && deepEqual(themeA.props, themeB.props)
     }
 
-    export interface Provider<P extends PD.Params = any> extends ThemeProvider<SizeTheme<P>, P> { }
-    export const EmptyProvider: Provider<{}> = { label: '', category: '', factory: EmptyFactory, getParams: () => ({}), defaultValues: {}, isApplicable: () => true }
+    export interface Provider<P extends PD.Params = any, Id extends string = string> extends ThemeProvider<SizeTheme<P>, P, Id> { }
+    export const EmptyProvider: Provider<{}> = { name: '', label: '', category: '', factory: EmptyFactory, getParams: () => ({}), defaultValues: {}, isApplicable: () => true }
 
     export type Registry = ThemeRegistry<SizeTheme<any>>
     export function createRegistry() {
diff --git a/src/mol-theme/size/physical.ts b/src/mol-theme/size/physical.ts
index 8622967d19f8e774b71b9446d580530e5f9ce01d..441c555c6a5be2f18b0d2105d223d75e358b2283 100644
--- a/src/mol-theme/size/physical.ts
+++ b/src/mol-theme/size/physical.ts
@@ -56,7 +56,8 @@ export function PhysicalSizeTheme(ctx: ThemeDataContext, props: PD.Values<Physic
     }
 }
 
-export const PhysicalSizeThemeProvider: SizeTheme.Provider<PhysicalSizeThemeParams> = {
+export const PhysicalSizeThemeProvider: SizeTheme.Provider<PhysicalSizeThemeParams, 'physical'> = {
+    name: 'physical',
     label: 'Physical',
     category: '',
     factory: PhysicalSizeTheme,
diff --git a/src/mol-theme/size/shape-group.ts b/src/mol-theme/size/shape-group.ts
index b7eaa993fe5d1afcf5af100b6c4fb2ce215f2c26..811b1cb9598d39e8c7889142cb8123ca89319405 100644
--- a/src/mol-theme/size/shape-group.ts
+++ b/src/mol-theme/size/shape-group.ts
@@ -34,7 +34,8 @@ export function ShapeGroupSizeTheme(ctx: ThemeDataContext, props: PD.Values<Shap
     }
 }
 
-export const ShapeGroupSizeThemeProvider: SizeTheme.Provider<ShapeGroupSizeThemeParams> = {
+export const ShapeGroupSizeThemeProvider: SizeTheme.Provider<ShapeGroupSizeThemeParams, 'shape-group'> = {
+    name: 'shape-group',
     label: 'Shape Group',
     category: '',    
     factory: ShapeGroupSizeTheme,
diff --git a/src/mol-theme/size/uncertainty.ts b/src/mol-theme/size/uncertainty.ts
index bbeec077745086a04cdb72d76cd9ef911cd0595f..17d988096d37315551456eb2daf7b6798942bb45 100644
--- a/src/mol-theme/size/uncertainty.ts
+++ b/src/mol-theme/size/uncertainty.ts
@@ -52,7 +52,8 @@ export function UncertaintySizeTheme(ctx: ThemeDataContext, props: PD.Values<Unc
     }
 }
 
-export const UncertaintySizeThemeProvider: SizeTheme.Provider<UncertaintySizeThemeParams> = {
+export const UncertaintySizeThemeProvider: SizeTheme.Provider<UncertaintySizeThemeParams, 'uncertainty'> = {
+    name: 'uncertainty',
     label: 'Uncertainty/Disorder',
     category: '',
     factory: UncertaintySizeTheme,
diff --git a/src/mol-theme/size/uniform.ts b/src/mol-theme/size/uniform.ts
index 32b2718744f145c5ec3540eefb8a7326f46f7d0a..05ca264927adc31f278cd044a4317e61e8b70c64 100644
--- a/src/mol-theme/size/uniform.ts
+++ b/src/mol-theme/size/uniform.ts
@@ -30,7 +30,8 @@ export function UniformSizeTheme(ctx: ThemeDataContext, props: PD.Values<Uniform
     }
 }
 
-export const UniformSizeThemeProvider: SizeTheme.Provider<UniformSizeThemeParams> = {
+export const UniformSizeThemeProvider: SizeTheme.Provider<UniformSizeThemeParams, 'uniform'> = {
+    name: 'uniform',
     label: 'Uniform',
     category: '',
     factory: UniformSizeTheme,
diff --git a/src/mol-theme/theme.ts b/src/mol-theme/theme.ts
index 1ed6dbce22cf95c6b8e486e390cacd730595cad6..185feacc45dceef8f8e1c310edb16607006e2466 100644
--- a/src/mol-theme/theme.ts
+++ b/src/mol-theme/theme.ts
@@ -11,6 +11,7 @@ import { VolumeData } from '../mol-model/volume';
 import { ParamDefinition as PD } from '../mol-util/param-definition';
 import { Shape } from '../mol-model/shape';
 import { CustomProperty } from '../mol-model-props/common/custom-property';
+import { objectForEach } from '../mol-util/object';
 
 export interface ThemeRegistryContext {
     colorThemeRegistry: ColorTheme.Registry
@@ -64,7 +65,8 @@ namespace Theme {
 
 //
 
-export interface ThemeProvider<T extends ColorTheme<P> | SizeTheme<P>, P extends PD.Params> {
+export interface ThemeProvider<T extends ColorTheme<P> | SizeTheme<P>, P extends PD.Params, Id extends string = string> {
+    readonly name: Id
     readonly label: string
     readonly category: string
     readonly factory: (ctx: ThemeDataContext, props: PD.Values<P>) => T
@@ -91,7 +93,10 @@ export class ThemeRegistry<T extends ColorTheme<any> | SizeTheme<any>> {
     get types(): [string, string, string][] { return getTypes(this._list) }
 
     constructor(builtInThemes: { [k: string]: ThemeProvider<T, any> }, private emptyProvider: ThemeProvider<T, any>) {
-        Object.keys(builtInThemes).forEach(name => this.add(name, builtInThemes[name]))
+        objectForEach(builtInThemes, (p, k) => {
+            if (p.name !== k) throw new Error(`Fix build in themes to have matching names. ${p.name} ${k}`);
+            this.add(p as any)
+        })
     }
 
     private sort() {
@@ -103,14 +108,19 @@ export class ThemeRegistry<T extends ColorTheme<any> | SizeTheme<any>> {
         });
     }
 
-    add<P extends PD.Params>(name: string, provider: ThemeProvider<T, P>) {
+    add<P extends PD.Params>(provider: ThemeProvider<T, P>) {
+        if (this._map.has(provider.name)) {
+            throw new Error(`${provider.name} already registered.`);
+        }
+
+        const name = provider.name;
         this._list.push({ name, provider })
         this._map.set(name, provider)
         this._name.set(provider, name)
         this.sort();
     }
 
-    remove(name: string) {
+    remove(provider: ThemeProvider<T, any>) {
         this._list.splice(this._list.findIndex(e => e.name === name), 1)
         const p = this._map.get(name);
         if (p) {