Update the KVM resource endpoints to be more client friendly.
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
index 87a8649..489ffdf 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
@@ -290,8 +290,11 @@
     public <A extends Entity> A create( String entityType, Class<A> entityClass, Map<String, Object> properties )
             throws Exception {
 
-        if ( ( entityType != null ) && ( entityType.startsWith( TYPE_ENTITY ) || entityType
-                .startsWith( "entities" ) ) ) {
+        if ( ( entityType != null ) &&
+            ( entityType.startsWith( TYPE_ENTITY ) || entityType.startsWith( "entities" )
+                // safeguard against creating entities with type keyvaluemaps since we have specific Usergrid
+                // keyvaluemap implementation
+                || entityType.startsWith( "keyvaluemaps" ) || entityType.startsWith( "keyvaluemap" )) ) {
             throw new IllegalArgumentException( "Invalid entity type" );
         }
         A e = null;
diff --git a/stack/core/src/main/java/org/apache/usergrid/system/UsergridFeatures.java b/stack/core/src/main/java/org/apache/usergrid/system/UsergridFeatures.java
index 22ba48c..2826f66 100644
--- a/stack/core/src/main/java/org/apache/usergrid/system/UsergridFeatures.java
+++ b/stack/core/src/main/java/org/apache/usergrid/system/UsergridFeatures.java
@@ -63,7 +63,7 @@
 
     public static boolean isKvmFeatureEnabled(){
 
-        return  getFeaturesEnabled().contains(Feature.KVM);
+        return true;
 
     }
 }
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java
index 228598c..e73277c 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ApplicationResource.java
@@ -148,8 +148,8 @@
         return getEventsResource( ui );
     }
 
-    //@RequireApplicationAccess
-    @Path("maps")
+    @RequireApplicationAccess
+    @Path("keyvaluemaps")
     public KvmResource getKvmResource(@Context UriInfo ui ) throws Exception {
         return getSubResource( KvmResource.class );
     }
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/kvm/KvmResource.java b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/kvm/KvmResource.java
index 264f968..4d6107e 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/kvm/KvmResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/kvm/KvmResource.java
@@ -43,9 +43,7 @@
 
 @Component("org.apache.usergrid.rest.applications.kvm.KvmResource")
 @Scope("prototype")
-@Produces({ MediaType.APPLICATION_JSON, "application/javascript", "application/x-javascript", "text/ecmascript",
-    "application/ecmascript", "text/jscript"
-})
+@Produces(MediaType.APPLICATION_JSON)
 public class KvmResource extends AbstractContextResource {
 
     private static final Logger logger = LoggerFactory.getLogger( KvmResource.class );
@@ -87,26 +85,34 @@
             throw new IllegalArgumentException("Only 1 map can be created at a time.");
         }
 
+        enforceQueryFeature(ui);
+
         final String mapName = json.keySet().iterator().next();
-        final Object meta = json.get(mapName);
-        if( !(meta instanceof Map) ){
+
+        if( !(json.get(mapName) instanceof Map) ){
             throw new IllegalArgumentException("New map details must be provided as a JSON object.");
         }
+        final Map<String, Object> meta = (Map<String, Object>)json.get(mapName);
 
         if(StringUtils.isEmpty(mapName)){
             throw new IllegalArgumentException("Property mapName is required.");
         }
 
+        if( json.containsKey("metadata") ){
+            json.remove("metadata");
+        }
+
         final String appMap = services.getApplicationId().toString();
         final MapScope mapScope = new MapScopeImpl(services.getApplication().asId(), appMap);
         final MapManagerFactory mmf = injector.getInstance(MapManagerFactory.class);
         final MapManager mapManager = mmf.createMapManager(mapScope);
 
         final Map<String, Object> mapDetails = new HashMap<String, Object>(){{
-
-            put("active", true);
-            put("modified", System.currentTimeMillis() );
-            put("details", meta);
+            put("metadata", new HashMap<String, Object>(){{
+                put("active", true);
+                put("modified", System.currentTimeMillis() );
+            }});
+            putAll(meta);
 
         }};
 
@@ -121,7 +127,7 @@
         response.setAction( "post" );
         response.setApplication( services.getApplication() );
         response.setParams( ui.getQueryParameters() );
-        response.setProperty("maps", Collections.singletonList(map));
+        response.setProperty("maps", map);
 
         return response;
 
@@ -135,6 +141,7 @@
                                 @QueryParam("cursor") String cursor) {
 
         limit = validateLimit(limit);
+        enforceQueryFeature(ui);
 
         final String appMap = services.getApplicationId().toString();
 
@@ -144,14 +151,12 @@
 
         MapKeyResults mapKeyResults = mapManager.getKeys(cursor, limit );
 
-        List<Map<String, Object>> results = new ArrayList<>();
+        Map<String, Object> results = new HashMap<>();
 
         Observable.from(mapKeyResults.getKeys()).flatMap(key -> {
-            return Observable.just(new HashMap<String, Object>() {{
-                put(key, JsonUtils.parse(mapManager.getString(key)));
-            }});
+            return Observable.just(results.put(key, JsonUtils.parse(mapManager.getString(key))));
 
-        }).doOnNext(entry -> results.add(entry)).toBlocking().lastOrDefault(null);
+        }).toBlocking().lastOrDefault(null);
 
 
         ApiResponse response = createApiResponse();
@@ -177,6 +182,7 @@
                                 @PathParam("mapName") String mapName ) {
 
         limit = validateLimit(limit);
+        enforceQueryFeature(ui);
 
         final String appMap = services.getApplicationId().toString();
 
@@ -193,7 +199,7 @@
         response.setAction( "get" );
         response.setApplication( services.getApplication() );
         response.setParams( ui.getQueryParameters() );
-        response.setProperty("maps", Collections.singletonList(map));
+        response.setProperty("maps", map);
 
         return response;
 
@@ -205,7 +211,7 @@
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
     public ApiResponse createEntries( @Context UriInfo ui,
-                                      List<Map<String,Object>> json,
+                                      Map<String,Object> json,
                                       @PathParam("mapName") String mapName ) {
 
         if ( json.size() > BATCH_SIZE_MAX ){
@@ -216,19 +222,17 @@
             throw new IllegalArgumentException("Property mapName is required.");
         }
 
+        enforceQueryFeature(ui);
+
         final MapScope mapScope = new MapScopeImpl(services.getApplication().asId(), mapName);
         final MapManagerFactory mmf = injector.getInstance(MapManagerFactory.class);
         final MapManager mapManager = mmf.createMapManager(mapScope);
 
         //TODO maybe RX flatmap this or parallel stream
-        json.forEach( item -> {
-
-            String key = item.keySet().iterator().next();
-            Object value = item.get(key);
+        json.forEach( (key, value) -> {
 
             mapManager.putString(key, value.toString());
 
-
         });
 
 
@@ -236,7 +240,6 @@
         response.setAction( "post" );
         response.setApplication( services.getApplication() );
         response.setParams( ui.getQueryParameters() );
-        response.setProperty("mapName", mapName);
         response.setProperty("entries", json);
 
         return response;
@@ -257,6 +260,7 @@
         }
 
         limit = validateLimit(limit);
+        enforceQueryFeature(ui);
 
         final MapScope mapScope = new MapScopeImpl(services.getApplication().asId(), mapName);
         final MapManagerFactory mmf = injector.getInstance(MapManagerFactory.class);
@@ -264,7 +268,6 @@
 
         MapKeyResults mapKeyResults = mapManager.getKeys(cursor, limit );
 
-
         ApiResponse response = createApiResponse();
         response.setAction( "get" );
         response.setApplication( services.getApplication() );
@@ -292,6 +295,7 @@
         }
 
         limit = validateLimit(limit);
+        enforceQueryFeature(ui);
 
         final MapScope mapScope = new MapScopeImpl(services.getApplication().asId(), mapName);
         final MapManagerFactory mmf = injector.getInstance(MapManagerFactory.class);
@@ -299,11 +303,10 @@
 
         MapKeyResults mapKeyResults = mapManager.getKeys(cursor, limit );
 
-        List<Map<String, String>> results = new ArrayList<>();
+        Map<String, Object> results = new HashMap<>();
         Observable.from(mapKeyResults.getKeys()).flatMap(key ->{
-            return Observable.just(new HashMap<String, String>(){{put(key, mapManager.getString(key));}});
-
-        }).doOnNext(entry -> results.add(entry)).toBlocking().lastOrDefault(null);
+            return Observable.just(results.put(key, mapManager.getString(key)));
+        }).toBlocking().lastOrDefault(null);
 
 
         ApiResponse response = createApiResponse();
@@ -323,27 +326,34 @@
     @GET
     @Path("{mapName}/entries/{keyName}")
     @Produces(MediaType.APPLICATION_JSON)
-    public ApiResponse getEntry( @Context UriInfo ui,
+    public Object getEntry( @Context UriInfo ui,
                                    @PathParam("mapName") String mapName,
-                                   @PathParam("keyName") String keyName ) {
+                                   @PathParam("keyName") String keyName,
+                                   @QueryParam("rawData") @DefaultValue("false") boolean rawData) {
 
+        enforceQueryFeature(ui);
 
         final MapScope mapScope = new MapScopeImpl(services.getApplication().asId(), mapName);
         final MapManagerFactory mmf = injector.getInstance(MapManagerFactory.class);
         final MapManager mapManager = mmf.createMapManager(mapScope);
 
 
-        List<Map<String, String>> results = new ArrayList<>();
-        results.add(new HashMap<String, String>(){{put(keyName, mapManager.getString(keyName));}});
+        Map<String, Object> results = new HashMap<>();
+        Object value = mapManager.getString(keyName);
+        results.put(keyName, value);
+
+        if( !rawData ) {
+            ApiResponse response = createApiResponse();
+            response.setAction("get");
+            response.setApplication(services.getApplication());
+            response.setParams(ui.getQueryParameters());
+            response.setProperty("entries", results);
+            return response;
+        }else{
+            return value;
+        }
 
 
-        ApiResponse response = createApiResponse();
-        response.setAction( "get" );
-        response.setApplication( services.getApplication() );
-        response.setParams( ui.getQueryParameters() );
-        response.setProperty("entries", results);
-
-        return response;
 
     }
 
@@ -354,5 +364,15 @@
 
     }
 
+    private void enforceQueryFeature(UriInfo ui) {
+
+        if( StringUtils.isNotEmpty(ui.getQueryParameters().getFirst("ql"))){
+
+            throw new IllegalArgumentException("Query feature not supported for keyvaluemaps");
+
+        }
+
+    }
+
 
 }