diff --git a/src/mol-state/model/reconcile.ts b/src/mol-state/model/reconcile.ts
deleted file mode 100644
index 16b43943825dc9a7a8648bf2d9c42f38d3831ad3..0000000000000000000000000000000000000000
--- a/src/mol-state/model/reconcile.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- */
-
-import { TransformTree } from '../tree/tree';
-import { ModelTree } from './tree';
-
-export function reconcileTree(transform: TransformTree, model: ModelTree, root?: number) {
-    // TODO
-}
\ No newline at end of file
diff --git a/src/mol-state/model/object.ts b/src/mol-state/object.ts
similarity index 78%
rename from src/mol-state/model/object.ts
rename to src/mol-state/object.ts
index 9665765e4eabeb5ffbfbf6f6d9e6089d48d06d02..391f1e1d00fdc7f4e6a1c4aea6813adfe30793ce 100644
--- a/src/mol-state/model/object.ts
+++ b/src/mol-state/object.ts
@@ -4,9 +4,11 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-export interface StateObject<T = any> {
+/** A mutable state object */
+export interface StateObject<T extends StateObject.Type = any> {
     '@type': T,
-    readonly label: string
+    label: string,
+    version: number
 }
 
 export namespace StateObject {
@@ -26,4 +28,6 @@ export namespace StateObject {
         // The object is currently being created
         Processing
     }
+
+    export type Type = string & { '@type': 'state-object-type' }
 }
\ No newline at end of file
diff --git a/src/mol-state/state.ts b/src/mol-state/state.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0dc9aa8e4beb3b2ec994479187eb10135f3c51ed
--- /dev/null
+++ b/src/mol-state/state.ts
@@ -0,0 +1,15 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import { StateObject } from './object';
+import { TransformTree } from './tree/tree';
+import { Transform } from './tree/transform';
+
+export interface State {
+    tree: TransformTree,
+    objects: Map<Transform.InstanceId, StateObject>,
+    history: TransformTree[]
+}
\ No newline at end of file
diff --git a/src/mol-state/tree/transformer.ts b/src/mol-state/transformer.ts
similarity index 87%
rename from src/mol-state/tree/transformer.ts
rename to src/mol-state/transformer.ts
index 29d1f97c75e9cc019de5d1518ba87647b38d1561..e621fcf494c1296eea0051a17c1e78481ac9703a 100644
--- a/src/mol-state/tree/transformer.ts
+++ b/src/mol-state/transformer.ts
@@ -5,16 +5,16 @@
  */
 
 import { Task } from 'mol-task';
-import { StateObject } from '../model/object';
-import { TransformContext } from './context';
+import { StateObject } from './object';
+import { TransformContext } from './tree/context';
 
 export interface Transformer<A extends StateObject, B extends StateObject, P = any> {
     readonly id: Transformer.Id,
     readonly name: string,
     readonly namespace: string,
     readonly description?: string,
-    readonly from: StateObject.TypeOf<A>[],
-    readonly to: StateObject.TypeOf<B>[],
+    readonly from: StateObject.Type[],
+    readonly to: StateObject.Type[],
 
     /**
      * Apply the actual transformation. It must be pure (i.e. with no side effects).
@@ -40,6 +40,9 @@ export interface Transformer<A extends StateObject, B extends StateObject, P = a
     /** Check the parameters and return a list of errors if the are not valid. */
     validateParams?(a: A, params: P, context: TransformContext): string[] | undefined,
 
+    /** Optional custom parameter equality. Use deep structural equal by default. */
+    areParamsEqual?(oldParams: P, newParams: P): boolean,
+
     /** Test if the transform can be applied to a given node */
     isApplicable?(a: A, context: TransformContext): boolean,
 
diff --git a/src/mol-state/transformer/manager.ts b/src/mol-state/transformer/manager.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fc04509557cbe18ba20c67ac0c364ed4807c38dd
--- /dev/null
+++ b/src/mol-state/transformer/manager.ts
@@ -0,0 +1,7 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+// TODO: index for registered transformers
\ No newline at end of file
diff --git a/src/mol-state/tree/action.ts b/src/mol-state/tree/action.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f5216c5abbeb50e7497369b1675c2109cbf4db49
--- /dev/null
+++ b/src/mol-state/tree/action.ts
@@ -0,0 +1,7 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+// TODO: tree actions: Add, Update, Delete; action queue
\ No newline at end of file
diff --git a/src/mol-state/model/tree.ts b/src/mol-state/tree/transation.ts
similarity index 83%
rename from src/mol-state/model/tree.ts
rename to src/mol-state/tree/transation.ts
index 601f3be436a94cecc04d6e7baba1af1fbf776b26..7c7fe83382a744be37fe5118239b71702aebc60d 100644
--- a/src/mol-state/model/tree.ts
+++ b/src/mol-state/tree/transation.ts
@@ -4,6 +4,4 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-export interface ModelTree {
-
-}
\ No newline at end of file
+// TODO
\ No newline at end of file
diff --git a/src/mol-state/tree/transform.ts b/src/mol-state/tree/transform.ts
index fd35696650826eb7a22d971279469a0cc1cbe16f..e0ea9dd2ac5c0c78dd42f8683e82d1e25386283e 100644
--- a/src/mol-state/tree/transform.ts
+++ b/src/mol-state/tree/transform.ts
@@ -4,24 +4,30 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { Transform } from './transform';
-import { StateObject } from '../model/object';
-import { Transformer } from './transformer';
+import { StateObject } from '../object';
+import { Transformer } from '../transformer';
 
 export interface Transform<A extends StateObject, B extends StateObject, P = any> {
-    readonly instanceId: number,
+    readonly instanceId: Transform.InstanceId,
 
     readonly transformer: Transformer<A, B, P>,
     readonly props: Transform.Props,
 
     readonly transformerId: string,
     readonly params: P,
-    readonly ref: string,
-    readonly version: number,
+    readonly ref: string
+    // version is part of the tree
 }
 
 export namespace Transform {
+    export type InstanceId = number & { '@type': 'transform-instance-id' }
+
     export interface Props {
 
     }
+
+    export enum Flags {
+        // Indicates that the transform was generated by a behaviour and should not be automatically updated
+        Generated
+    }
 }
\ No newline at end of file
diff --git a/src/mol-state/util/immutable-tree.ts b/src/mol-state/util/immutable-tree.ts
index e0d04147dfa0d2ca3ec2cbc358e57817bdb4e2ff..d0ca43c4f8b9c879b4c1cf124ed7a357747121fe 100644
--- a/src/mol-state/util/immutable-tree.ts
+++ b/src/mol-state/util/immutable-tree.ts
@@ -6,6 +6,8 @@
 
 import { Map as ImmutableMap, OrderedSet } from 'immutable';
 
+// TODO: use generic "node keys" instead of string
+
 /**
  * An immutable tree where each node requires a unique reference.
  * Represented as an immutable map.