diff --git a/src/mol-data/model.ts b/src/mol-data/model.ts
index 2be289a54e5df7b809c5bbf54a378525a06023f0..70d5c31f2380055c388c5a0c07b08d417d8a4f05 100644
--- a/src/mol-data/model.ts
+++ b/src/mol-data/model.ts
@@ -4,37 +4,8 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import * as Formats from './model/formats'
-import HierarchyProperties from './model/properties/hierarchy'
-import ConformationProperties from './model/properties/conformation'
-import UUID from '../mol-base/utils/uuid'
-import buildMmCIF from './model/builders/mmcif'
+import Model from './model/model'
+import ModelDataFormat from './model/data-format'
+import * as ModelConstants from './model/constants'
 
-export interface Version {
-    hierarchy: UUID,
-    conformation: UUID
-}
-
-/**
- * Interface to the "source data" of the molecule.
- *
- * "Atoms" are integers in the range [0, atomCount).
- */
-interface Model extends Readonly<{
-    id: UUID,
-
-    modelNum: number,
-
-    sourceData: Formats.RawData,
-
-    hierarchy: HierarchyProperties,
-    conformation: ConformationProperties,
-
-    atomCount: number
-}> { }
-
-namespace Model {
-    export const ofMmCIF = buildMmCIF;
-}
-
-export default Model
\ No newline at end of file
+export { Model, ModelConstants, ModelDataFormat }
\ No newline at end of file
diff --git a/src/mol-data/model/builders/mmcif.ts b/src/mol-data/model/builders/mmcif.ts
index 240e1e5037666d1e6a7407c93bdd0000bac211c1..4d92bbc56ad435cf453d6cfe13c23e12c7b30c2f 100644
--- a/src/mol-data/model/builders/mmcif.ts
+++ b/src/mol-data/model/builders/mmcif.ts
@@ -4,9 +4,9 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { RawData } from '../formats'
-import { Frame as mmCIF } from '../../../mol-io/reader/cif/schema/mmcif'
-import Model from '../../model'
+import { mmCIF } from '../data-format'
+//import { Frame as mmCIF } from '../../../mol-io/reader/cif/schema/mmcif'
+import Model from '../model'
 import Column from '../../../mol-base/collections/column'
 import Table from '../../../mol-base/collections/table'
 import { Interval, Segmentation } from '../../../mol-base/collections/integer'
@@ -15,7 +15,7 @@ import * as Hierarchy from '../properties/hierarchy'
 import Conformation from '../properties/conformation'
 import findHierarchyKeys from '../utils/hierarchy-keys'
 
-function findModelBounds(data: mmCIF, startIndex: number) {
+function findModelBounds({ data }: mmCIF, startIndex: number) {
     const num = data.atom_site.pdbx_PDB_model_num;
     const atomCount = num.rowCount;
     if (!num.isDefined) return Interval.ofBounds(startIndex, atomCount);
@@ -24,7 +24,7 @@ function findModelBounds(data: mmCIF, startIndex: number) {
     return Interval.ofBounds(startIndex, endIndex);
 }
 
-function findHierarchyOffsets(data: mmCIF, bounds: Interval) {
+function findHierarchyOffsets({ data }: mmCIF, bounds: Interval) {
     const start = Interval.start(bounds), end = Interval.end(bounds);
     const residues = [start], chains = [start];
 
@@ -44,7 +44,7 @@ function findHierarchyOffsets(data: mmCIF, bounds: Interval) {
     return { residues, chains };
 }
 
-function createHierarchyData(data: mmCIF, bounds: Interval, offsets: { residues: ArrayLike<number>, chains: ArrayLike<number> }): Hierarchy.Data {
+function createHierarchyData({ data }: mmCIF, bounds: Interval, offsets: { residues: ArrayLike<number>, chains: ArrayLike<number> }): Hierarchy.Data {
     const { atom_site } = data;
     const start = Interval.start(bounds), end = Interval.end(bounds);
     const atoms = Table.ofColumns<Hierarchy.AtomsSchema>({
@@ -62,7 +62,7 @@ function createHierarchyData(data: mmCIF, bounds: Interval, offsets: { residues:
     return { atoms, residues, chains, entities: data.entity };
 }
 
-function getConformation(data: mmCIF, bounds: Interval): Conformation {
+function getConformation({ data }: mmCIF, bounds: Interval): Conformation {
     const start = Interval.start(bounds), end = Interval.end(bounds);
     const { atom_site } = data;
     return {
@@ -83,14 +83,14 @@ function isHierarchyDataEqual(a: Hierarchy.Hierarchy, b: Hierarchy.Data) {
         && Table.areEqual(a.atoms as Table<Hierarchy.AtomsSchema>, b.atoms as Table<Hierarchy.AtomsSchema>)
 }
 
-function createModel(raw: RawData, data: mmCIF, bounds: Interval, previous?: Model): Model {
-    const hierarchyOffsets = findHierarchyOffsets(data, bounds);
-    const hierarchyData = createHierarchyData(data, bounds, hierarchyOffsets);
+function createModel(format: mmCIF, bounds: Interval, previous?: Model): Model {
+    const hierarchyOffsets = findHierarchyOffsets(format, bounds);
+    const hierarchyData = createHierarchyData(format, bounds, hierarchyOffsets);
 
     if (previous && isHierarchyDataEqual(previous.hierarchy, hierarchyData)) {
         return {
             ...previous,
-            conformation: getConformation(data, bounds)
+            conformation: getConformation(format, bounds)
         };
     }
 
@@ -102,25 +102,24 @@ function createModel(raw: RawData, data: mmCIF, bounds: Interval, previous?: Mod
 
     return {
         id: newUUID(),
-        sourceData: raw,
-        modelNum: data.atom_site.pdbx_PDB_model_num.value(Interval.start(bounds)),
+        sourceData: format,
+        modelNum: format.data.atom_site.pdbx_PDB_model_num.value(Interval.start(bounds)),
         hierarchy: { ...hierarchyData, ...hierarchyKeys, ...hierarchySegments },
-        conformation: getConformation(data, bounds),
+        conformation: getConformation(format, bounds),
         atomCount: Interval.size(bounds)
     };
 }
 
-function buildModels(data: mmCIF): ReadonlyArray<Model> {
-    const raw: RawData = { source: 'mmCIF', data };
+function buildModels(format: mmCIF): ReadonlyArray<Model> {
     const models: Model[] = [];
-    const atomCount = data.atom_site._rowCount;
+    const atomCount = format.data.atom_site._rowCount;
 
     if (atomCount === 0) return models;
 
     let modelStart = 0;
     while (modelStart < atomCount) {
-        const bounds = findModelBounds(data, modelStart);
-        const model = createModel(raw, data, bounds, models.length > 0 ? models[models.length - 1] : void 0);
+        const bounds = findModelBounds(format, modelStart);
+        const model = createModel(format, bounds, models.length > 0 ? models[models.length - 1] : void 0);
         models.push(model);
         modelStart = Interval.end(bounds);
     }
diff --git a/src/mol-data/model/formats.ts b/src/mol-data/model/data-format.ts
similarity index 68%
rename from src/mol-data/model/formats.ts
rename to src/mol-data/model/data-format.ts
index 56ec708a4d03e60e7e7578a9a405c73aac39407f..128136b8659d84b309895436b2de7d505d7f0289 100644
--- a/src/mol-data/model/formats.ts
+++ b/src/mol-data/model/data-format.ts
@@ -6,5 +6,9 @@
 
 import { Frame as mmCIF_Frame } from '../../mol-io/reader/cif/schema/mmcif'
 
-export type RawData =
-    | { source: 'mmCIF', data: mmCIF_Frame }
\ No newline at end of file
+export interface mmCIF { kind: 'mmCIF', data: mmCIF_Frame }
+
+type Format =
+    | mmCIF
+
+export default Format
\ No newline at end of file
diff --git a/src/mol-data/model/model.ts b/src/mol-data/model/model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..12c5fe73ad01b26690a1dc6266baa404e6d04d49
--- /dev/null
+++ b/src/mol-data/model/model.ts
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import DataFormat from './data-format'
+import HierarchyProperties from './properties/hierarchy'
+import ConformationProperties from './properties/conformation'
+import UUID from '../../mol-base/utils/uuid'
+
+import buildMmCIF from './builders/mmcif'
+
+/**
+ * Interface to the "source data" of the molecule.
+ *
+ * "Atoms" are integers in the range [0, atomCount).
+ */
+interface Model extends Readonly<{
+    id: UUID,
+
+    modelNum: number,
+
+    sourceData: DataFormat,
+
+    hierarchy: HierarchyProperties,
+    conformation: ConformationProperties,
+
+    atomCount: number
+}> { }
+
+namespace Model {
+    export function create(format: DataFormat) {
+        switch (format.kind) {
+            case 'mmCIF': return buildMmCIF(format);
+        }
+    }
+}
+
+export default Model
\ No newline at end of file
diff --git a/src/mol-data/structure/structure.ts b/src/mol-data/structure/structure.ts
index fcfb15a9d89668aca2b9b3d1c9f510b70920add2..cc995ad2c0c3dfcf0ac7e0e0ababd9a3775f865c 100644
--- a/src/mol-data/structure/structure.ts
+++ b/src/mol-data/structure/structure.ts
@@ -4,7 +4,7 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import Model from '../model'
+import { Model } from '../model'
 import Unit from './unit'
 import Operator from './operator'
 import AtomSet from './atom/set'
diff --git a/src/mol-data/structure/unit.ts b/src/mol-data/structure/unit.ts
index f80a31c4da3d65dd9832246b1f60df567f6de1d8..5ffc3d6ee09cdab4c7328148968e37b86fb1c49b 100644
--- a/src/mol-data/structure/unit.ts
+++ b/src/mol-data/structure/unit.ts
@@ -4,7 +4,7 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import Model from '../model'
+import { Model } from '../model'
 import Operator from './operator'
 
 interface Unit extends Readonly<{
diff --git a/src/perf-tests/structure.ts b/src/perf-tests/structure.ts
index 48b7ae83db426d0dcd65e13261a29777c1cf7504..b066edf918f3c60defde1c005a54b5d68851aec1 100644
--- a/src/perf-tests/structure.ts
+++ b/src/perf-tests/structure.ts
@@ -10,7 +10,7 @@ import * as util from 'util'
 import * as fs from 'fs'
 import CIF from '../mol-io/reader/cif'
 
-import Model from '../mol-data/Model'
+import { Model } from '../mol-data/Model'
 import { Structure, Atom, AtomSet } from '../mol-data/structure'
 import * as Q from '../mol-data/query'
 import { OrderedSet as OrdSet, Segmentation } from '../mol-base/collections/integer'
@@ -47,7 +47,7 @@ export async function readCIF(path: string) {
     const mmcif = CIF.schema.mmCIF(data);
     console.timeEnd('schema')
     console.time('buildModels')
-    const models = Model.ofMmCIF(mmcif);
+    const models = Model.create({ kind: 'mmCIF', data: mmcif });
     console.timeEnd('buildModels')
     const structures = models.map(Structure.ofModel);
 
diff --git a/src/script.ts b/src/script.ts
index 04a4139de8da3213c1805fc6813efe4e3b3be594..e42be6c0bde858119ffa4fee6c9aa6aa4acf2019 100644
--- a/src/script.ts
+++ b/src/script.ts
@@ -115,7 +115,7 @@ async function runCIF(input: string | Uint8Array) {
     console.log(mmcif.pdbx_struct_oper_list.matrix.value(0));
 
     console.time('createModels');
-    const models = buildModels(mmcif);
+    const models = buildModels({ kind: 'mmCIF', data: mmcif });
     console.timeEnd('createModels');
 
     for (let i = 0; i < models.length; i++) {