You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2015/08/18 12:46:28 UTC

[2/3] incubator-brooklyn git commit: [BROOKLYN-162] Package renames in ./core/internal

[BROOKLYN-162] Package renames in ./core/internal


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/3230e730
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/3230e730
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/3230e730

Branch: refs/heads/master
Commit: 3230e730188920d015eb5e79951afe433f6b1e9d
Parents: 5dfe944
Author: Hadrian Zbarcea <ha...@apache.org>
Authored: Tue Aug 18 03:51:39 2015 -0400
Committer: Hadrian Zbarcea <ha...@apache.org>
Committed: Tue Aug 18 03:51:39 2015 -0400

----------------------------------------------------------------------
 .../brooklyn/entity/basic/AbstractEntity.java   |   8 +-
 .../brooklyn/event/basic/ListConfigKey.java     |   2 +-
 .../internal/storage/BrooklynStorage.java       | 114 --------
 .../brooklyn/internal/storage/DataGrid.java     |  52 ----
 .../internal/storage/DataGridFactory.java       |  38 ---
 .../brooklyn/internal/storage/Reference.java    |  50 ----
 .../internal/storage/impl/BackedReference.java  |  73 -----
 .../internal/storage/impl/BasicReference.java   |  67 -----
 .../storage/impl/BrooklynStorageImpl.java       | 139 ---------
 .../impl/ConcurrentMapAcceptingNullVals.java    | 272 ------------------
 .../impl/inmemory/InMemoryDataGridFactory.java  |  41 ---
 .../storage/impl/inmemory/InmemoryDatagrid.java |  93 ------
 .../internal/BrooklynFeatureEnablement.java     |   2 +-
 .../core/internal/storage/BrooklynStorage.java  | 114 ++++++++
 .../core/internal/storage/DataGrid.java         |  52 ++++
 .../core/internal/storage/DataGridFactory.java  |  38 +++
 .../core/internal/storage/Reference.java        |  50 ++++
 .../internal/storage/impl/BackedReference.java  |  73 +++++
 .../internal/storage/impl/BasicReference.java   |  67 +++++
 .../storage/impl/BrooklynStorageImpl.java       | 139 +++++++++
 .../impl/ConcurrentMapAcceptingNullVals.java    | 272 ++++++++++++++++++
 .../impl/inmemory/InMemoryDataGridFactory.java  |  40 +++
 .../storage/impl/inmemory/InmemoryDatagrid.java |  93 ++++++
 .../internal/AbstractManagementContext.java     |  10 +-
 .../internal/BrooklynGarbageCollector.java      |   2 +-
 .../management/internal/LocalEntityManager.java |   2 +-
 .../internal/LocalLocationManager.java          |   2 +-
 .../internal/LocalManagementContext.java        |   2 +-
 .../management/internal/LocalUsageManager.java  |   2 +-
 .../internal/ManagementContextInternal.java     |   2 +-
 .../NonDeploymentManagementContext.java         |   2 +-
 .../location/basic/AbstractLocation.java        |   8 +-
 .../storage/impl/BrooklynStorageImplTest.java   | 287 -------------------
 .../ConcurrentMapAcceptingNullValsTest.java     | 114 --------
 .../EntityCleanupLongevityTestFixture.java      |   6 +-
 .../storage/impl/BrooklynStorageImplTest.java   | 287 +++++++++++++++++++
 .../ConcurrentMapAcceptingNullValsTest.java     | 115 ++++++++
 .../impl/hazelcast/HazelcastDataGrid.java       |   3 +-
 .../hazelcast/HazelcastDataGridFactory.java     |   5 +-
 .../impl/hazelcast/HazelcastStorageTest.java    |   8 +-
 40 files changed, 1372 insertions(+), 1374 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
index 3e619b0..c62010c 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
@@ -56,6 +56,9 @@ import org.apache.brooklyn.api.policy.PolicySpec;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.internal.BrooklynFeatureEnablement;
 import org.apache.brooklyn.core.internal.BrooklynInitialization;
+import org.apache.brooklyn.core.internal.storage.BrooklynStorage;
+import org.apache.brooklyn.core.internal.storage.Reference;
+import org.apache.brooklyn.core.internal.storage.impl.BasicReference;
 import org.apache.brooklyn.core.management.internal.EffectorUtils;
 import org.apache.brooklyn.core.management.internal.EntityManagementSupport;
 import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
@@ -70,8 +73,8 @@ import org.apache.brooklyn.core.util.task.DeferredSupplier;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import org.apache.brooklyn.basic.AbstractBrooklynObject;
+
 import brooklyn.config.BrooklynLogging;
 import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;
@@ -85,9 +88,6 @@ import brooklyn.event.basic.BasicNotificationSensor;
 import brooklyn.event.basic.Sensors;
 import brooklyn.event.feed.AbstractFeed;
 import brooklyn.event.feed.ConfigToAttributes;
-import brooklyn.internal.storage.BrooklynStorage;
-import brooklyn.internal.storage.Reference;
-import brooklyn.internal.storage.impl.BasicReference;
 
 import org.apache.brooklyn.location.basic.Locations;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/brooklyn/event/basic/ListConfigKey.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/basic/ListConfigKey.java b/core/src/main/java/brooklyn/event/basic/ListConfigKey.java
index 0ad4d54..dadbd9e 100644
--- a/core/src/main/java/brooklyn/event/basic/ListConfigKey.java
+++ b/core/src/main/java/brooklyn/event/basic/ListConfigKey.java
@@ -24,10 +24,10 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.brooklyn.core.internal.storage.impl.ConcurrentMapAcceptingNullVals;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.internal.storage.impl.ConcurrentMapAcceptingNullVals;
 import brooklyn.util.collections.MutableList;
 
 /** A config key representing a list of values. 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/brooklyn/internal/storage/BrooklynStorage.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/internal/storage/BrooklynStorage.java b/core/src/main/java/brooklyn/internal/storage/BrooklynStorage.java
deleted file mode 100644
index 6ecabd3..0000000
--- a/core/src/main/java/brooklyn/internal/storage/BrooklynStorage.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.internal.storage;
-
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentMap;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-
-public interface BrooklynStorage {
-
-    /**
-     * Creates a reference to a value, backed by the storage-medium. If a reference with this 
-     * name has already been created, then that existing reference will be returned.
-     * 
-     * The returned reference is a live view: changes made to the reference will be persisted, 
-     * and changes that others make will be reflected in the reference.
-     * 
-     * The reference is thread-safe. No additional synchronization is required when getting/setting
-     * the reference.
-     * 
-     * @param id
-     */
-    <T> Reference<T> getReference(String id);
-
-    /**
-     * Creates a list backed by the storage-medium. If a list with this name has already been
-     * created, then that existing list will be returned.
-     * 
-     * The returned list is not a live view. Changes are made by calling reference.set(), and
-     * the view is refreshed by calling reference.get(). Changes are thread-safe, but callers
-     * must be careful not to overwrite other's changes. For example, the code below could overwrite
-     * another threads changes that are made to the map between the call to get() and the subsequent
-     * call to set().
-     * 
-     * <pre>
-     * {@code
-     * Reference<List<String>> ref = storage.<String>createNonConcurrentList("myid");
-     * List<String> newval = ImmutableList.<String>builder().addAll(ref.get()).add("another").builder();
-     * ref.set(newval);
-     * }
-     * </pre>
-     * 
-     * TODO Aled says: Is getNonConcurrentList necessary?
-     *   The purpose of this method, rather than just using
-     *   {@code Reference ref = getReference(id); ref.set(ImmutableList.of())}
-     *   is to allow control of the serialization of the things inside the list 
-     *   (e.g. switching the Location object to serialize a proxy object of some sort). 
-     *   I don't want us to have to do deep inspection of every object being added to any map/ref. 
-     *   Feels like we can use normal serialization unless the top-level object matches an 
-     *   instanceof for special things like Entity, Location, etc.
-     * 
-     * Peter responds:
-     *   What I'm a bit scared of is that we need to write some kind of meta serialization mechanism 
-     *   on top of the mechanisms provided by e.g. Hazelcast or Infinispan. Hazelcast has a very 
-     *   extensive serialization library where you can plug in all kinds of serialization mechanisms.
-     * 
-     * @param id
-     */
-    @Beta
-    <T> Reference<List<T>> getNonConcurrentList(String id);
-    
-    /**
-     * Creates a map backed by the storage-medium. If a map with this name has already been
-     * created, then that existing map will be returned.
-     * 
-     * The returned map is a live view: changes made to the map will be persisted, and changes 
-     * that others make will be reflected in the map.
-     * 
-     * The map is thread-safe: {@link Map#keySet()} etc will iterate over a snapshot view of the
-     * contents.
-     * 
-     * @param id
-     */
-    <K,V> ConcurrentMap<K,V> getMap(String id);
-
-    /**
-     * Removes the data stored against this id, whether it is a map, ref or whatever.
-     */
-    void remove(String id);
-
-    /**
-     * Terminates the BrooklynStorage.
-     */
-    void terminate();
-
-    /** asserts that some of the storage containers which should be empty are empty; 
-     * this could do more thorough checks, but as it is it is useful to catch many leaks,
-     * and the things which aren't empty it's much harder to check whether they should be empty!
-     * <p>
-     * not meant for use outwith tests */
-    @VisibleForTesting
-    public boolean isMostlyEmpty();
-    
-    Map<String, Object> getStorageMetrics();
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/brooklyn/internal/storage/DataGrid.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/internal/storage/DataGrid.java b/core/src/main/java/brooklyn/internal/storage/DataGrid.java
deleted file mode 100644
index de6d5fc..0000000
--- a/core/src/main/java/brooklyn/internal/storage/DataGrid.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.internal.storage;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-
-import com.google.common.annotations.VisibleForTesting;
-
-public interface DataGrid {
-
-    /**
-     * If a map already exists with this id, returns it; otherwise creates a new map stored
-     * in the datagrid.
-     */
-    <K,V> ConcurrentMap<K,V> getMap(String id);
-
-    /**
-     * Deletes the map for this id, if it exists; otherwise a no-op.
-     */
-    void remove(String id);
-
-    /**
-     * Terminates the DataGrid. If there is a real datagrid with multiple machines running, it doesn't mean that the
-     * datagrid is going to be terminated; it only means that all local resources of the datagrid are released.
-     */
-    void terminate();
-    
-    Map<String, Object> getDatagridMetrics();
-
-    /** Returns snapshot of known keys at this datagrid */
-    @VisibleForTesting
-    Set<String> getKeys();
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/brooklyn/internal/storage/DataGridFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/internal/storage/DataGridFactory.java b/core/src/main/java/brooklyn/internal/storage/DataGridFactory.java
deleted file mode 100644
index d5264c1..0000000
--- a/core/src/main/java/brooklyn/internal/storage/DataGridFactory.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.internal.storage;
-
-import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
-
-/**
- * A factory for creating a {@link DataGrid}.
- *
- * Implementations of this interface should have a public no arg constructor; this constructor will be
- * called through reflection in the {@link org.apache.brooklyn.core.management.internal.LocalManagementContext}.
- */
-public interface DataGridFactory {
-
-    /**
-     * Creates a {@link BrooklynStorage} instance.
-     *
-     * @param managementContext the ManagementContextInternal
-     * @return the created BrooklynStorage.
-     */
-    DataGrid newDataGrid(ManagementContextInternal managementContext);
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/brooklyn/internal/storage/Reference.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/internal/storage/Reference.java b/core/src/main/java/brooklyn/internal/storage/Reference.java
deleted file mode 100644
index 14b3877..0000000
--- a/core/src/main/java/brooklyn/internal/storage/Reference.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.internal.storage;
-
-/**
- * A reference to a value, backed by the storage-medium.
- * 
- * @see BrooklynStorage#getReference(String)
- * 
- * @author aled
- */
-public interface Reference<T> {
-
-    // TODO We can add compareAndSet(T,T) as and when required
-    
-    T get();
-    
-    T set(T val);
-    
-    /**
-     * @return true if the value is null; false otherwise.
-     */
-    boolean isNull();
-    
-    /**
-     * Sets the value back to null. Similar to {@code set(null)}.
-     */
-    void clear();
-    
-    /**
-     * @return true if the value equals the given parameter; false otherwise
-     */
-    boolean contains(Object other);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/brooklyn/internal/storage/impl/BackedReference.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/internal/storage/impl/BackedReference.java b/core/src/main/java/brooklyn/internal/storage/impl/BackedReference.java
deleted file mode 100644
index d1261ab..0000000
--- a/core/src/main/java/brooklyn/internal/storage/impl/BackedReference.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.internal.storage.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Map;
-
-import brooklyn.internal.storage.Reference;
-
-import com.google.common.base.Objects;
-
-class BackedReference<T> implements Reference<T> {
-    private final Map<String,? super T> backingMap;
-    private final String key;
-    
-    BackedReference(Map<String,? super T> backingMap, String key) {
-        this.backingMap = checkNotNull(backingMap, "backingMap");
-        this.key = key;
-    }
-    
-    @Override
-    public T get() {
-        // For happens-before (for different threads calling get and set), relies on 
-        // underlying map (e.g. from datagrid) having some synchronization
-        return (T) backingMap.get(key);
-    }
-    
-    @Override
-    public T set(T val) {
-        if (val == null) {
-            return (T) backingMap.remove(key);
-        } else {
-            return (T) backingMap.put(key, val);
-        }
-    }
-    
-    @Override
-    public String toString() {
-        return ""+get();
-    }
-    
-    @Override
-    public boolean isNull() {
-        return get() == null;
-    }
-    
-    @Override
-    public void clear() {
-        set(null);
-    }
-    
-    @Override
-    public boolean contains(Object other) {
-        return Objects.equal(get(), other);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/brooklyn/internal/storage/impl/BasicReference.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/internal/storage/impl/BasicReference.java b/core/src/main/java/brooklyn/internal/storage/impl/BasicReference.java
deleted file mode 100644
index ce40cf2..0000000
--- a/core/src/main/java/brooklyn/internal/storage/impl/BasicReference.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.internal.storage.impl;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-import brooklyn.internal.storage.Reference;
-
-import com.google.common.base.Objects;
-
-public class BasicReference<T> implements Reference<T >{
-
-    private final AtomicReference<T> ref = new AtomicReference<T>();
-    
-    public BasicReference() {
-    }
-    
-    public BasicReference(T val) {
-        set(val);
-    }
-    
-    @Override
-    public T get() {
-        return ref.get();
-    }
-
-    @Override
-    public T set(T val) {
-        return ref.getAndSet(val);
-    }
-
-    @Override
-    public boolean isNull() {
-        return get() == null;
-    }
-
-    @Override
-    public void clear() {
-        set(null);
-    }
-
-    @Override
-    public boolean contains(Object other) {
-        return Objects.equal(get(), other);
-    }
-    
-    @Override
-    public String toString() {
-        return ""+get();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/brooklyn/internal/storage/impl/BrooklynStorageImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/internal/storage/impl/BrooklynStorageImpl.java b/core/src/main/java/brooklyn/internal/storage/impl/BrooklynStorageImpl.java
deleted file mode 100644
index 2fbe411..0000000
--- a/core/src/main/java/brooklyn/internal/storage/impl/BrooklynStorageImpl.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.internal.storage.impl;
-
-import java.lang.ref.WeakReference;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentMap;
-
-import brooklyn.internal.storage.BrooklynStorage;
-import brooklyn.internal.storage.DataGrid;
-import brooklyn.internal.storage.Reference;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-
-public class BrooklynStorageImpl implements BrooklynStorage {
-
-    private final DataGrid datagrid;
-    private final ConcurrentMap<String, Object> refsMap;
-    private final ConcurrentMap<String, Object> listsMap;
-    private final ConcurrentMap<String, WeakReference<Reference<?>>> refsCache;
-    private final ConcurrentMap<String, WeakReference<Reference<?>>> listRefsCache;
-    
-    public BrooklynStorageImpl(DataGrid datagrid) {
-        this.datagrid = datagrid;
-        this.refsMap = datagrid.getMap("refs");
-        this.listsMap = datagrid.getMap("lists");
-        this.refsCache = Maps.newConcurrentMap();
-        this.listRefsCache = Maps.newConcurrentMap();
-    }
-
-    /**
-     * Returns the DataGrid used by this  BrooklynStorageImpl
-     *
-     * @return the DataGrid.
-     */
-    @VisibleForTesting
-    public DataGrid getDataGrid() {
-        return datagrid;
-    }
-
-    @Override
-    public <T> Reference<T> getReference(final String id) {
-        // Can use different ref instances; no need to always return same one. Caching is an
-        // optimisation to just avoid extra object creation.
-        WeakReference<Reference<?>> weakRef = refsCache.get(id);
-        Reference<?> ref = (weakRef != null) ? weakRef.get() : null;
-        if (ref == null) {
-            ref = new BackedReference<T>(refsMap, id) {
-                @Override protected void finalize() {
-                    // TODO Don't like using finalize due to performance overhead, but not
-                    // optimising yet. Could use PhantomReference instead; see
-                    // http://java.dzone.com/articles/finalization-and-phantom
-                    refsCache.remove(id);
-                }
-            };
-            refsCache.putIfAbsent(id, new WeakReference<Reference<?>>(ref));
-        }
-        return (Reference<T>) ref;
-    }
-    
-    @Override
-    public <T> Reference<List<T>> getNonConcurrentList(final String id) {
-        WeakReference<Reference<?>> weakRef = listRefsCache.get(id);
-        Reference<?> ref = (weakRef != null) ? weakRef.get() : null;
-        if (ref == null) {
-            ref = new BackedReference<List<T>>(listsMap, id) {
-                @Override public List<T> get() {
-                    List<T> result = super.get();
-                    return (result == null ? ImmutableList.<T>of() : Collections.unmodifiableList(result));
-                }
-                @Override protected void finalize() {
-                    listRefsCache.remove(id);
-                }
-            };
-            listRefsCache.putIfAbsent(id, new WeakReference<Reference<?>>(ref));
-        }
-        return (Reference<List<T>>) ref;
-    }
-
-    @Override
-    public <K, V> ConcurrentMap<K, V> getMap(final String id) {
-        return datagrid.<K,V>getMap(id);
-    }
-    
-    @Override
-    public void remove(String id) {
-        datagrid.remove(id);
-        refsMap.remove(id);
-        listsMap.remove(id);
-        refsCache.remove(id);
-        listRefsCache.remove(id);
-    }
-
-    @Override
-    public void terminate() {
-        datagrid.terminate();
-    }
-    
-    public boolean isMostlyEmpty() {
-        if (!refsMap.isEmpty() || !listsMap.isEmpty()) 
-            return false;
-        // the datagrid may have some standard bookkeeping entries
-        return true;
-    }
-    
-    @Override
-    public Map<String, Object> getStorageMetrics() {
-        return ImmutableMap.of(
-                "datagrid", datagrid.getDatagridMetrics(),
-                "refsMapSize", ""+refsMap.size(),
-                "listsMapSize", ""+listsMap.size());
-    }
-    
-    @Override
-    public String toString() {
-        return super.toString() + getStorageMetrics();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/brooklyn/internal/storage/impl/ConcurrentMapAcceptingNullVals.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/internal/storage/impl/ConcurrentMapAcceptingNullVals.java b/core/src/main/java/brooklyn/internal/storage/impl/ConcurrentMapAcceptingNullVals.java
deleted file mode 100644
index ee998df..0000000
--- a/core/src/main/java/brooklyn/internal/storage/impl/ConcurrentMapAcceptingNullVals.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.internal.storage.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.AbstractMap;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-
-import javax.annotation.Nullable;
-
-/**
- * A decorator for a ConcurrentMap that allows null values to be used.
- * 
- * However, {@link #values()} and {@link #entrySet()} return immutable snapshots
- * of the map's contents. This may be revisited in a future version.
- * 
- * @author aled
- */
-public class ConcurrentMapAcceptingNullVals<K, V> implements ConcurrentMap<K, V> {
-
-    private static enum Marker {
-        NULL;
-    }
-    
-    private final ConcurrentMap<K, V> delegate;
-
-    public ConcurrentMapAcceptingNullVals(ConcurrentMap<K,V> delegate) {
-        this.delegate = checkNotNull(delegate, "delegate");
-    }
-    
-    @Override
-    public void clear() {
-        delegate.clear();
-    }
-
-    @Override
-    public boolean containsKey(Object key) {
-        return delegate.containsKey(key);
-    }
-
-    @Override
-    public boolean containsValue(Object value) {
-        return delegate.containsValue(toNonNullValue(value));
-    }
-
-    @Override
-    public Set<Map.Entry<K, V>> entrySet() {
-        // Note that returns an immutable snapshot
-        Set<Map.Entry<K, V>> result = new LinkedHashSet<Map.Entry<K, V>>(delegate.size());
-        for (Map.Entry<K, V> entry : delegate.entrySet()) {
-            result.add(new AbstractMap.SimpleEntry<K,V>(entry.getKey(), (V)fromNonNullValue(entry.getValue())));
-        }
-        return Collections.unmodifiableSet(result);
-    }
-
-    @Override
-    public Collection<V> values() {
-        // Note that returns an immutable snapshot
-        List<V> result = new ArrayList<V>(delegate.size());
-        for (V v : delegate.values()) {
-            result.add((V)fromNonNullValue(v));
-        }
-        return Collections.unmodifiableCollection(result);
-    }
-
-    @Override
-    public Set<K> keySet() {
-        return delegate.keySet();
-    }
-
-    @Override
-    public V get(Object key) {
-        return (V) fromNonNullValue(delegate.get(key));
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return delegate.isEmpty();
-    }
-
-    @Override
-    public V put(K key, V value) {
-        return (V) fromNonNullValue(delegate.put(key, (V) toNonNullValue(value)));
-    }
-
-    @Override
-    public void putAll(Map<? extends K, ? extends V> vals) {
-        for (Map.Entry<? extends K, ? extends V> entry : vals.entrySet()) {
-            put(entry.getKey(), entry.getValue());
-        }
-    }
-
-    @Override
-    public V remove(Object key) {
-        return (V) fromNonNullValue(delegate.remove(key));
-    }
-
-    @Override
-    public int size() {
-        return delegate.size();
-    }
-
-    @Override
-    public V putIfAbsent(K key, V value) {
-        return (V) fromNonNullValue(delegate.putIfAbsent(key, (V) toNonNullValue(value)));
-    }
-
-    @Override
-    public boolean remove(Object key, Object value) {
-        return delegate.remove(key, (V) toNonNullValue(value));
-    }
-
-    @Override
-    public V replace(K key, V value) {
-        return (V) fromNonNullValue(delegate.replace(key, (V) toNonNullValue(value)));
-    }
-
-    @Override
-    public boolean replace(K key, V oldValue, V newValue) {
-        return delegate.replace(key, (V) toNonNullValue(oldValue), (V) toNonNullValue(newValue));
-    }
-    
-    private static class SetWithNullVals<T> implements Set<T> {
-
-        private final Set<T> delegate;
-        
-        public SetWithNullVals(Set<T> delegate) {
-            this.delegate = delegate;
-        }
-        
-        @Override
-        public boolean add(T e) {
-            return delegate.add(e); // unsupported; let delegate give exception
-        }
-
-        @Override
-        public boolean addAll(Collection<? extends T> c) {
-            return delegate.addAll(c); // unsupported; let delegate give exception
-        }
-
-        @Override
-        public void clear() {
-            delegate.clear();
-        }
-
-        @Override
-        public boolean contains(Object o) {
-            return delegate.contains(toNonNullValue(o));
-        }
-
-        @Override
-        public boolean containsAll(Collection<?> c) {
-            for (Object e : c) {
-                if (!delegate.contains(toNonNullValue(e))) return false;
-            }
-            return true;
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return delegate.isEmpty();
-        }
-
-        @Override
-        public Iterator<T> iterator() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public boolean remove(Object o) {
-            return delegate.remove(toNonNullValue(o));
-        }
-
-        @Override
-        public boolean removeAll(Collection<?> c) {
-            boolean result = false;
-            for (Object e : c) {
-                result = result & delegate.remove(toNonNullValue(e));
-            }
-            return result;
-        }
-
-        @Override
-        public boolean retainAll(Collection<?> c) {
-            boolean result = false;
-            for (Iterator<T> iter = delegate.iterator(); iter.hasNext();) {
-                T e = iter.next();
-                if (!c.contains(fromNonNullValue(e))) {
-                    iter.remove();
-                    result = true;
-                }
-            }
-            return result;
-        }
-
-        @Override
-        public int size() {
-            return delegate.size();
-        }
-
-        @Override
-        public Object[] toArray() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public <T> T[] toArray(T[] a) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-    }
-    
-    private static Object toNonNullValue(Object value) {
-        return (value != null) ? value : Marker.NULL;
-    }
-
-    private static Object fromNonNullValue(Object value) {
-        return (value == Marker.NULL) ? null : value; 
-    }
-    
-    @Override
-    public boolean equals(@Nullable Object object) {
-        // copied from guava's non-public method Maps.equalsImpl
-        if (this == object) {
-            return true;
-        }
-        if (object instanceof Map) {
-            Map<?, ?> o = (Map<?, ?>) object;
-            return entrySet().equals(o.entrySet());
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        // copied from guava's ImmutableMap.hashCode
-        return entrySet().hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return delegate.toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/brooklyn/internal/storage/impl/inmemory/InMemoryDataGridFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/internal/storage/impl/inmemory/InMemoryDataGridFactory.java b/core/src/main/java/brooklyn/internal/storage/impl/inmemory/InMemoryDataGridFactory.java
deleted file mode 100644
index 4f0fbac..0000000
--- a/core/src/main/java/brooklyn/internal/storage/impl/inmemory/InMemoryDataGridFactory.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.internal.storage.impl.inmemory;
-
-import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
-
-import brooklyn.internal.storage.DataGrid;
-import brooklyn.internal.storage.DataGridFactory;
-
-public class InMemoryDataGridFactory implements DataGridFactory {
-    
-    public static DataGridFactory ofInstance(final DataGrid datagrid) {
-        return new DataGridFactory() {
-            @Override
-            public DataGrid newDataGrid(ManagementContextInternal managementContext) {
-                return datagrid;
-            }
-        };
-    }
-    
-    @Override
-    public DataGrid newDataGrid(ManagementContextInternal managementContext) {
-        return new InmemoryDatagrid();
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/brooklyn/internal/storage/impl/inmemory/InmemoryDatagrid.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/internal/storage/impl/inmemory/InmemoryDatagrid.java b/core/src/main/java/brooklyn/internal/storage/impl/inmemory/InmemoryDatagrid.java
deleted file mode 100644
index 3cfb7c7..0000000
--- a/core/src/main/java/brooklyn/internal/storage/impl/inmemory/InmemoryDatagrid.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.internal.storage.impl.inmemory;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import brooklyn.internal.storage.DataGrid;
-import brooklyn.internal.storage.impl.ConcurrentMapAcceptingNullVals;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-
-/**
- * A simple implementation of datagrid backed by in-memory (unpersisted) maps, within a single JVM.
- * 
- * @author aled
- */
-public class InmemoryDatagrid implements DataGrid {
-
-    private final Map<String,Map<?,?>> maps = Maps.newLinkedHashMap();
-    private final AtomicInteger creationCounter = new AtomicInteger();
-    
-    @SuppressWarnings("unchecked")
-    @Override
-    public <K, V> ConcurrentMap<K, V> getMap(String id) {
-        synchronized (maps) {
-            ConcurrentMap<K, V> result = (ConcurrentMap<K, V>) maps.get(id);
-            if (result == null) {
-                result = newMap();
-                maps.put(id, result);
-                creationCounter.incrementAndGet();
-            }
-            return result;
-        }
-    }
-    
-    // TODO Not doing Maps.newConcurrentMap() because needs to store null values.
-    // Easy to avoid for Refererence<?> but harder for entity ConfigMap where the user
-    // can insert null values.
-    // 
-    // Could write a decorator that switches null values for a null marker, and back again.
-    //
-    private <K,V> ConcurrentMap<K,V> newMap() {
-        //return Collections.synchronizedMap(new HashMap<K, V>());
-        return new ConcurrentMapAcceptingNullVals<K,V>(Maps.<K,V>newConcurrentMap());
-    }
-
-    @Override
-    public void remove(String id) {
-        synchronized (maps) {
-            maps.remove(id);
-        }
-    }
-
-    @Override
-    public void terminate() {
-        synchronized (maps) {
-            maps.clear();
-        }
-    }
-
-    @Override
-    public Map<String, Object> getDatagridMetrics() {
-        synchronized (maps) {
-            return ImmutableMap.<String, Object>of("size", maps.size(), "createCount", creationCounter.get());
-        }
-    }
-
-    @Override
-    public Set<String> getKeys() {
-        return maps.keySet();
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynFeatureEnablement.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynFeatureEnablement.java b/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynFeatureEnablement.java
index 686fd35..047e3a8 100644
--- a/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynFeatureEnablement.java
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynFeatureEnablement.java
@@ -21,12 +21,12 @@ package org.apache.brooklyn.core.internal;
 import java.util.Map;
 
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
+import org.apache.brooklyn.core.internal.storage.BrooklynStorage;
 import org.apache.brooklyn.core.util.internal.ssh.ShellTool;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.config.BrooklynProperties;
-import brooklyn.internal.storage.BrooklynStorage;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.Maps;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/internal/storage/BrooklynStorage.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/BrooklynStorage.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/BrooklynStorage.java
new file mode 100644
index 0000000..b1f9cdf
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/storage/BrooklynStorage.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.internal.storage;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.VisibleForTesting;
+
+public interface BrooklynStorage {
+
+    /**
+     * Creates a reference to a value, backed by the storage-medium. If a reference with this 
+     * name has already been created, then that existing reference will be returned.
+     * 
+     * The returned reference is a live view: changes made to the reference will be persisted, 
+     * and changes that others make will be reflected in the reference.
+     * 
+     * The reference is thread-safe. No additional synchronization is required when getting/setting
+     * the reference.
+     * 
+     * @param id
+     */
+    <T> Reference<T> getReference(String id);
+
+    /**
+     * Creates a list backed by the storage-medium. If a list with this name has already been
+     * created, then that existing list will be returned.
+     * 
+     * The returned list is not a live view. Changes are made by calling reference.set(), and
+     * the view is refreshed by calling reference.get(). Changes are thread-safe, but callers
+     * must be careful not to overwrite other's changes. For example, the code below could overwrite
+     * another threads changes that are made to the map between the call to get() and the subsequent
+     * call to set().
+     * 
+     * <pre>
+     * {@code
+     * Reference<List<String>> ref = storage.<String>createNonConcurrentList("myid");
+     * List<String> newval = ImmutableList.<String>builder().addAll(ref.get()).add("another").builder();
+     * ref.set(newval);
+     * }
+     * </pre>
+     * 
+     * TODO Aled says: Is getNonConcurrentList necessary?
+     *   The purpose of this method, rather than just using
+     *   {@code Reference ref = getReference(id); ref.set(ImmutableList.of())}
+     *   is to allow control of the serialization of the things inside the list 
+     *   (e.g. switching the Location object to serialize a proxy object of some sort). 
+     *   I don't want us to have to do deep inspection of every object being added to any map/ref. 
+     *   Feels like we can use normal serialization unless the top-level object matches an 
+     *   instanceof for special things like Entity, Location, etc.
+     * 
+     * Peter responds:
+     *   What I'm a bit scared of is that we need to write some kind of meta serialization mechanism 
+     *   on top of the mechanisms provided by e.g. Hazelcast or Infinispan. Hazelcast has a very 
+     *   extensive serialization library where you can plug in all kinds of serialization mechanisms.
+     * 
+     * @param id
+     */
+    @Beta
+    <T> Reference<List<T>> getNonConcurrentList(String id);
+    
+    /**
+     * Creates a map backed by the storage-medium. If a map with this name has already been
+     * created, then that existing map will be returned.
+     * 
+     * The returned map is a live view: changes made to the map will be persisted, and changes 
+     * that others make will be reflected in the map.
+     * 
+     * The map is thread-safe: {@link Map#keySet()} etc will iterate over a snapshot view of the
+     * contents.
+     * 
+     * @param id
+     */
+    <K,V> ConcurrentMap<K,V> getMap(String id);
+
+    /**
+     * Removes the data stored against this id, whether it is a map, ref or whatever.
+     */
+    void remove(String id);
+
+    /**
+     * Terminates the BrooklynStorage.
+     */
+    void terminate();
+
+    /** asserts that some of the storage containers which should be empty are empty; 
+     * this could do more thorough checks, but as it is it is useful to catch many leaks,
+     * and the things which aren't empty it's much harder to check whether they should be empty!
+     * <p>
+     * not meant for use outwith tests */
+    @VisibleForTesting
+    public boolean isMostlyEmpty();
+    
+    Map<String, Object> getStorageMetrics();
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGrid.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGrid.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGrid.java
new file mode 100644
index 0000000..09f50fb
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGrid.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.internal.storage;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import com.google.common.annotations.VisibleForTesting;
+
+public interface DataGrid {
+
+    /**
+     * If a map already exists with this id, returns it; otherwise creates a new map stored
+     * in the datagrid.
+     */
+    <K,V> ConcurrentMap<K,V> getMap(String id);
+
+    /**
+     * Deletes the map for this id, if it exists; otherwise a no-op.
+     */
+    void remove(String id);
+
+    /**
+     * Terminates the DataGrid. If there is a real datagrid with multiple machines running, it doesn't mean that the
+     * datagrid is going to be terminated; it only means that all local resources of the datagrid are released.
+     */
+    void terminate();
+    
+    Map<String, Object> getDatagridMetrics();
+
+    /** Returns snapshot of known keys at this datagrid */
+    @VisibleForTesting
+    Set<String> getKeys();
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGridFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGridFactory.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGridFactory.java
new file mode 100644
index 0000000..c055efa
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGridFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.internal.storage;
+
+import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
+
+/**
+ * A factory for creating a {@link DataGrid}.
+ *
+ * Implementations of this interface should have a public no arg constructor; this constructor will be
+ * called through reflection in the {@link org.apache.brooklyn.core.management.internal.LocalManagementContext}.
+ */
+public interface DataGridFactory {
+
+    /**
+     * Creates a {@link BrooklynStorage} instance.
+     *
+     * @param managementContext the ManagementContextInternal
+     * @return the created BrooklynStorage.
+     */
+    DataGrid newDataGrid(ManagementContextInternal managementContext);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/internal/storage/Reference.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/Reference.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/Reference.java
new file mode 100644
index 0000000..3f2d846
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/storage/Reference.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.internal.storage;
+
+/**
+ * A reference to a value, backed by the storage-medium.
+ * 
+ * @see BrooklynStorage#getReference(String)
+ * 
+ * @author aled
+ */
+public interface Reference<T> {
+
+    // TODO We can add compareAndSet(T,T) as and when required
+    
+    T get();
+    
+    T set(T val);
+    
+    /**
+     * @return true if the value is null; false otherwise.
+     */
+    boolean isNull();
+    
+    /**
+     * Sets the value back to null. Similar to {@code set(null)}.
+     */
+    void clear();
+    
+    /**
+     * @return true if the value equals the given parameter; false otherwise
+     */
+    boolean contains(Object other);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BackedReference.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BackedReference.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BackedReference.java
new file mode 100644
index 0000000..e51e782
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BackedReference.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.internal.storage.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+
+import org.apache.brooklyn.core.internal.storage.Reference;
+
+import com.google.common.base.Objects;
+
+class BackedReference<T> implements Reference<T> {
+    private final Map<String,? super T> backingMap;
+    private final String key;
+    
+    BackedReference(Map<String,? super T> backingMap, String key) {
+        this.backingMap = checkNotNull(backingMap, "backingMap");
+        this.key = key;
+    }
+    
+    @Override
+    public T get() {
+        // For happens-before (for different threads calling get and set), relies on 
+        // underlying map (e.g. from datagrid) having some synchronization
+        return (T) backingMap.get(key);
+    }
+    
+    @Override
+    public T set(T val) {
+        if (val == null) {
+            return (T) backingMap.remove(key);
+        } else {
+            return (T) backingMap.put(key, val);
+        }
+    }
+    
+    @Override
+    public String toString() {
+        return ""+get();
+    }
+    
+    @Override
+    public boolean isNull() {
+        return get() == null;
+    }
+    
+    @Override
+    public void clear() {
+        set(null);
+    }
+    
+    @Override
+    public boolean contains(Object other) {
+        return Objects.equal(get(), other);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BasicReference.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BasicReference.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BasicReference.java
new file mode 100644
index 0000000..a01d61c
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BasicReference.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.internal.storage.impl;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.brooklyn.core.internal.storage.Reference;
+
+import com.google.common.base.Objects;
+
+public class BasicReference<T> implements Reference<T >{
+
+    private final AtomicReference<T> ref = new AtomicReference<T>();
+    
+    public BasicReference() {
+    }
+    
+    public BasicReference(T val) {
+        set(val);
+    }
+    
+    @Override
+    public T get() {
+        return ref.get();
+    }
+
+    @Override
+    public T set(T val) {
+        return ref.getAndSet(val);
+    }
+
+    @Override
+    public boolean isNull() {
+        return get() == null;
+    }
+
+    @Override
+    public void clear() {
+        set(null);
+    }
+
+    @Override
+    public boolean contains(Object other) {
+        return Objects.equal(get(), other);
+    }
+    
+    @Override
+    public String toString() {
+        return ""+get();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImpl.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImpl.java
new file mode 100644
index 0000000..188955a
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImpl.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.internal.storage.impl;
+
+import java.lang.ref.WeakReference;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.brooklyn.core.internal.storage.BrooklynStorage;
+import org.apache.brooklyn.core.internal.storage.DataGrid;
+import org.apache.brooklyn.core.internal.storage.Reference;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+public class BrooklynStorageImpl implements BrooklynStorage {
+
+    private final DataGrid datagrid;
+    private final ConcurrentMap<String, Object> refsMap;
+    private final ConcurrentMap<String, Object> listsMap;
+    private final ConcurrentMap<String, WeakReference<Reference<?>>> refsCache;
+    private final ConcurrentMap<String, WeakReference<Reference<?>>> listRefsCache;
+    
+    public BrooklynStorageImpl(DataGrid datagrid) {
+        this.datagrid = datagrid;
+        this.refsMap = datagrid.getMap("refs");
+        this.listsMap = datagrid.getMap("lists");
+        this.refsCache = Maps.newConcurrentMap();
+        this.listRefsCache = Maps.newConcurrentMap();
+    }
+
+    /**
+     * Returns the DataGrid used by this  BrooklynStorageImpl
+     *
+     * @return the DataGrid.
+     */
+    @VisibleForTesting
+    public DataGrid getDataGrid() {
+        return datagrid;
+    }
+
+    @Override
+    public <T> Reference<T> getReference(final String id) {
+        // Can use different ref instances; no need to always return same one. Caching is an
+        // optimisation to just avoid extra object creation.
+        WeakReference<Reference<?>> weakRef = refsCache.get(id);
+        Reference<?> ref = (weakRef != null) ? weakRef.get() : null;
+        if (ref == null) {
+            ref = new BackedReference<T>(refsMap, id) {
+                @Override protected void finalize() {
+                    // TODO Don't like using finalize due to performance overhead, but not
+                    // optimising yet. Could use PhantomReference instead; see
+                    // http://java.dzone.com/articles/finalization-and-phantom
+                    refsCache.remove(id);
+                }
+            };
+            refsCache.putIfAbsent(id, new WeakReference<Reference<?>>(ref));
+        }
+        return (Reference<T>) ref;
+    }
+    
+    @Override
+    public <T> Reference<List<T>> getNonConcurrentList(final String id) {
+        WeakReference<Reference<?>> weakRef = listRefsCache.get(id);
+        Reference<?> ref = (weakRef != null) ? weakRef.get() : null;
+        if (ref == null) {
+            ref = new BackedReference<List<T>>(listsMap, id) {
+                @Override public List<T> get() {
+                    List<T> result = super.get();
+                    return (result == null ? ImmutableList.<T>of() : Collections.unmodifiableList(result));
+                }
+                @Override protected void finalize() {
+                    listRefsCache.remove(id);
+                }
+            };
+            listRefsCache.putIfAbsent(id, new WeakReference<Reference<?>>(ref));
+        }
+        return (Reference<List<T>>) ref;
+    }
+
+    @Override
+    public <K, V> ConcurrentMap<K, V> getMap(final String id) {
+        return datagrid.<K,V>getMap(id);
+    }
+    
+    @Override
+    public void remove(String id) {
+        datagrid.remove(id);
+        refsMap.remove(id);
+        listsMap.remove(id);
+        refsCache.remove(id);
+        listRefsCache.remove(id);
+    }
+
+    @Override
+    public void terminate() {
+        datagrid.terminate();
+    }
+    
+    public boolean isMostlyEmpty() {
+        if (!refsMap.isEmpty() || !listsMap.isEmpty()) 
+            return false;
+        // the datagrid may have some standard bookkeeping entries
+        return true;
+    }
+    
+    @Override
+    public Map<String, Object> getStorageMetrics() {
+        return ImmutableMap.of(
+                "datagrid", datagrid.getDatagridMetrics(),
+                "refsMapSize", ""+refsMap.size(),
+                "listsMapSize", ""+listsMap.size());
+    }
+    
+    @Override
+    public String toString() {
+        return super.toString() + getStorageMetrics();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/ConcurrentMapAcceptingNullVals.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/ConcurrentMapAcceptingNullVals.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/ConcurrentMapAcceptingNullVals.java
new file mode 100644
index 0000000..c0d02c2
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/ConcurrentMapAcceptingNullVals.java
@@ -0,0 +1,272 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.internal.storage.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.annotation.Nullable;
+
+/**
+ * A decorator for a ConcurrentMap that allows null values to be used.
+ * 
+ * However, {@link #values()} and {@link #entrySet()} return immutable snapshots
+ * of the map's contents. This may be revisited in a future version.
+ * 
+ * @author aled
+ */
+public class ConcurrentMapAcceptingNullVals<K, V> implements ConcurrentMap<K, V> {
+
+    private static enum Marker {
+        NULL;
+    }
+    
+    private final ConcurrentMap<K, V> delegate;
+
+    public ConcurrentMapAcceptingNullVals(ConcurrentMap<K,V> delegate) {
+        this.delegate = checkNotNull(delegate, "delegate");
+    }
+    
+    @Override
+    public void clear() {
+        delegate.clear();
+    }
+
+    @Override
+    public boolean containsKey(Object key) {
+        return delegate.containsKey(key);
+    }
+
+    @Override
+    public boolean containsValue(Object value) {
+        return delegate.containsValue(toNonNullValue(value));
+    }
+
+    @Override
+    public Set<Map.Entry<K, V>> entrySet() {
+        // Note that returns an immutable snapshot
+        Set<Map.Entry<K, V>> result = new LinkedHashSet<Map.Entry<K, V>>(delegate.size());
+        for (Map.Entry<K, V> entry : delegate.entrySet()) {
+            result.add(new AbstractMap.SimpleEntry<K,V>(entry.getKey(), (V)fromNonNullValue(entry.getValue())));
+        }
+        return Collections.unmodifiableSet(result);
+    }
+
+    @Override
+    public Collection<V> values() {
+        // Note that returns an immutable snapshot
+        List<V> result = new ArrayList<V>(delegate.size());
+        for (V v : delegate.values()) {
+            result.add((V)fromNonNullValue(v));
+        }
+        return Collections.unmodifiableCollection(result);
+    }
+
+    @Override
+    public Set<K> keySet() {
+        return delegate.keySet();
+    }
+
+    @Override
+    public V get(Object key) {
+        return (V) fromNonNullValue(delegate.get(key));
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return delegate.isEmpty();
+    }
+
+    @Override
+    public V put(K key, V value) {
+        return (V) fromNonNullValue(delegate.put(key, (V) toNonNullValue(value)));
+    }
+
+    @Override
+    public void putAll(Map<? extends K, ? extends V> vals) {
+        for (Map.Entry<? extends K, ? extends V> entry : vals.entrySet()) {
+            put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    @Override
+    public V remove(Object key) {
+        return (V) fromNonNullValue(delegate.remove(key));
+    }
+
+    @Override
+    public int size() {
+        return delegate.size();
+    }
+
+    @Override
+    public V putIfAbsent(K key, V value) {
+        return (V) fromNonNullValue(delegate.putIfAbsent(key, (V) toNonNullValue(value)));
+    }
+
+    @Override
+    public boolean remove(Object key, Object value) {
+        return delegate.remove(key, (V) toNonNullValue(value));
+    }
+
+    @Override
+    public V replace(K key, V value) {
+        return (V) fromNonNullValue(delegate.replace(key, (V) toNonNullValue(value)));
+    }
+
+    @Override
+    public boolean replace(K key, V oldValue, V newValue) {
+        return delegate.replace(key, (V) toNonNullValue(oldValue), (V) toNonNullValue(newValue));
+    }
+    
+    private static class SetWithNullVals<T> implements Set<T> {
+
+        private final Set<T> delegate;
+        
+        public SetWithNullVals(Set<T> delegate) {
+            this.delegate = delegate;
+        }
+        
+        @Override
+        public boolean add(T e) {
+            return delegate.add(e); // unsupported; let delegate give exception
+        }
+
+        @Override
+        public boolean addAll(Collection<? extends T> c) {
+            return delegate.addAll(c); // unsupported; let delegate give exception
+        }
+
+        @Override
+        public void clear() {
+            delegate.clear();
+        }
+
+        @Override
+        public boolean contains(Object o) {
+            return delegate.contains(toNonNullValue(o));
+        }
+
+        @Override
+        public boolean containsAll(Collection<?> c) {
+            for (Object e : c) {
+                if (!delegate.contains(toNonNullValue(e))) return false;
+            }
+            return true;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return delegate.isEmpty();
+        }
+
+        @Override
+        public Iterator<T> iterator() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public boolean remove(Object o) {
+            return delegate.remove(toNonNullValue(o));
+        }
+
+        @Override
+        public boolean removeAll(Collection<?> c) {
+            boolean result = false;
+            for (Object e : c) {
+                result = result & delegate.remove(toNonNullValue(e));
+            }
+            return result;
+        }
+
+        @Override
+        public boolean retainAll(Collection<?> c) {
+            boolean result = false;
+            for (Iterator<T> iter = delegate.iterator(); iter.hasNext();) {
+                T e = iter.next();
+                if (!c.contains(fromNonNullValue(e))) {
+                    iter.remove();
+                    result = true;
+                }
+            }
+            return result;
+        }
+
+        @Override
+        public int size() {
+            return delegate.size();
+        }
+
+        @Override
+        public Object[] toArray() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public <T> T[] toArray(T[] a) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+    }
+    
+    private static Object toNonNullValue(Object value) {
+        return (value != null) ? value : Marker.NULL;
+    }
+
+    private static Object fromNonNullValue(Object value) {
+        return (value == Marker.NULL) ? null : value; 
+    }
+    
+    @Override
+    public boolean equals(@Nullable Object object) {
+        // copied from guava's non-public method Maps.equalsImpl
+        if (this == object) {
+            return true;
+        }
+        if (object instanceof Map) {
+            Map<?, ?> o = (Map<?, ?>) object;
+            return entrySet().equals(o.entrySet());
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        // copied from guava's ImmutableMap.hashCode
+        return entrySet().hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return delegate.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/inmemory/InMemoryDataGridFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/inmemory/InMemoryDataGridFactory.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/inmemory/InMemoryDataGridFactory.java
new file mode 100644
index 0000000..dec70ba
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/inmemory/InMemoryDataGridFactory.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.internal.storage.impl.inmemory;
+
+import org.apache.brooklyn.core.internal.storage.DataGrid;
+import org.apache.brooklyn.core.internal.storage.DataGridFactory;
+import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
+
+public class InMemoryDataGridFactory implements DataGridFactory {
+    
+    public static DataGridFactory ofInstance(final DataGrid datagrid) {
+        return new DataGridFactory() {
+            @Override
+            public DataGrid newDataGrid(ManagementContextInternal managementContext) {
+                return datagrid;
+            }
+        };
+    }
+    
+    @Override
+    public DataGrid newDataGrid(ManagementContextInternal managementContext) {
+        return new InmemoryDatagrid();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/inmemory/InmemoryDatagrid.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/inmemory/InmemoryDatagrid.java b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/inmemory/InmemoryDatagrid.java
new file mode 100644
index 0000000..48600d9
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/inmemory/InmemoryDatagrid.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.internal.storage.impl.inmemory;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.brooklyn.core.internal.storage.DataGrid;
+import org.apache.brooklyn.core.internal.storage.impl.ConcurrentMapAcceptingNullVals;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+/**
+ * A simple implementation of datagrid backed by in-memory (unpersisted) maps, within a single JVM.
+ * 
+ * @author aled
+ */
+public class InmemoryDatagrid implements DataGrid {
+
+    private final Map<String,Map<?,?>> maps = Maps.newLinkedHashMap();
+    private final AtomicInteger creationCounter = new AtomicInteger();
+    
+    @SuppressWarnings("unchecked")
+    @Override
+    public <K, V> ConcurrentMap<K, V> getMap(String id) {
+        synchronized (maps) {
+            ConcurrentMap<K, V> result = (ConcurrentMap<K, V>) maps.get(id);
+            if (result == null) {
+                result = newMap();
+                maps.put(id, result);
+                creationCounter.incrementAndGet();
+            }
+            return result;
+        }
+    }
+    
+    // TODO Not doing Maps.newConcurrentMap() because needs to store null values.
+    // Easy to avoid for Refererence<?> but harder for entity ConfigMap where the user
+    // can insert null values.
+    // 
+    // Could write a decorator that switches null values for a null marker, and back again.
+    //
+    private <K,V> ConcurrentMap<K,V> newMap() {
+        //return Collections.synchronizedMap(new HashMap<K, V>());
+        return new ConcurrentMapAcceptingNullVals<K,V>(Maps.<K,V>newConcurrentMap());
+    }
+
+    @Override
+    public void remove(String id) {
+        synchronized (maps) {
+            maps.remove(id);
+        }
+    }
+
+    @Override
+    public void terminate() {
+        synchronized (maps) {
+            maps.clear();
+        }
+    }
+
+    @Override
+    public Map<String, Object> getDatagridMetrics() {
+        synchronized (maps) {
+            return ImmutableMap.<String, Object>of("size", maps.size(), "createCount", creationCounter.get());
+        }
+    }
+
+    @Override
+    public Set<String> getKeys() {
+        return maps.keySet();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/management/internal/AbstractManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/AbstractManagementContext.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/AbstractManagementContext.java
index 7c1e473..0936bb2 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/AbstractManagementContext.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/AbstractManagementContext.java
@@ -53,6 +53,11 @@ import org.apache.brooklyn.api.management.ha.HighAvailabilityManager;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
 import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
+import org.apache.brooklyn.core.internal.storage.BrooklynStorage;
+import org.apache.brooklyn.core.internal.storage.DataGrid;
+import org.apache.brooklyn.core.internal.storage.DataGridFactory;
+import org.apache.brooklyn.core.internal.storage.impl.BrooklynStorageImpl;
+import org.apache.brooklyn.core.internal.storage.impl.inmemory.InMemoryDataGridFactory;
 import org.apache.brooklyn.core.management.classloading.JavaBrooklynClassLoadingContext;
 import org.apache.brooklyn.core.management.entitlement.Entitlements;
 import org.apache.brooklyn.core.management.ha.HighAvailabilityManagerImpl;
@@ -69,11 +74,6 @@ import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.drivers.BasicEntityDriverManager;
 import brooklyn.entity.drivers.downloads.BasicDownloadsManager;
 import brooklyn.entity.rebind.RebindManagerImpl;
-import brooklyn.internal.storage.BrooklynStorage;
-import brooklyn.internal.storage.DataGrid;
-import brooklyn.internal.storage.DataGridFactory;
-import brooklyn.internal.storage.impl.BrooklynStorageImpl;
-import brooklyn.internal.storage.impl.inmemory.InMemoryDataGridFactory;
 
 import org.apache.brooklyn.location.basic.BasicLocationRegistry;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/management/internal/BrooklynGarbageCollector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/BrooklynGarbageCollector.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/BrooklynGarbageCollector.java
index 45876c5..ad13d42 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/BrooklynGarbageCollector.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/BrooklynGarbageCollector.java
@@ -39,6 +39,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.HasTaskChildren;
 import org.apache.brooklyn.api.management.Task;
+import org.apache.brooklyn.core.internal.storage.BrooklynStorage;
 import org.apache.brooklyn.core.util.task.BasicExecutionManager;
 import org.apache.brooklyn.core.util.task.ExecutionListener;
 import org.apache.brooklyn.core.util.task.Tasks;
@@ -52,7 +53,6 @@ import brooklyn.entity.basic.BrooklynTaskTags.WrappedEntity;
 import brooklyn.entity.basic.BrooklynTaskTags.WrappedStream;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Entities;
-import brooklyn.internal.storage.BrooklynStorage;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalEntityManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalEntityManager.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalEntityManager.java
index 23039ba..84afdba 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalEntityManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalEntityManager.java
@@ -43,6 +43,7 @@ import org.apache.brooklyn.api.policy.Enricher;
 import org.apache.brooklyn.api.policy.EnricherSpec;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.policy.PolicySpec;
+import org.apache.brooklyn.core.internal.storage.BrooklynStorage;
 import org.apache.brooklyn.core.util.task.Tasks;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -59,7 +60,6 @@ import brooklyn.entity.proxying.EntityProxyImpl;
 import brooklyn.entity.proxying.InternalEntityFactory;
 import brooklyn.entity.proxying.InternalPolicyFactory;
 import brooklyn.entity.trait.Startable;
-import brooklyn.internal.storage.BrooklynStorage;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.collections.SetFromLiveMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3230e730/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalLocationManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalLocationManager.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalLocationManager.java
index f3e6aef..b22c5aa 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalLocationManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalLocationManager.java
@@ -29,6 +29,7 @@ import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.location.ProvisioningLocation;
 import org.apache.brooklyn.api.management.AccessController;
+import org.apache.brooklyn.core.internal.storage.BrooklynStorage;
 import org.apache.brooklyn.core.management.entitlement.Entitlements;
 import org.apache.brooklyn.core.util.config.ConfigBag;
 import org.apache.brooklyn.core.util.task.Tasks;
@@ -41,7 +42,6 @@ import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.proxying.InternalLocationFactory;
-import brooklyn.internal.storage.BrooklynStorage;
 
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.location.basic.LocationInternal;