[dart][inspect] Final API changes

Rename Value->Property
configInspect() -> config()

PS1: File rename: value.dart->property.dart, value_test.dart
->property_test.dart

PS2: Search and replace "value" -> "property"

PS3: configInspect() -> config()

PS4: Search-and-replace bugfix; ArgumentError on bad VMO size; comment change.

Test: fx run-host-tests fuchsia_inspect_package_unittests
CF-597 #progress

Change-Id: Ia3c271df30c9d3ab33c3b01ca485f8dcf9e6a713
diff --git a/public/dart/fuchsia_inspect/BUILD.gn b/public/dart/fuchsia_inspect/BUILD.gn
index 45da0e4..dde9b6a 100644
--- a/public/dart/fuchsia_inspect/BUILD.gn
+++ b/public/dart/fuchsia_inspect/BUILD.gn
@@ -17,7 +17,7 @@
     "src/inspect/inspect.dart",
     "src/inspect/internal/_inspect_impl.dart",
     "src/inspect/node.dart",
-    "src/inspect/value.dart",
+    "src/inspect/property.dart",
     "src/vmo/bitfield64.dart",
     "src/vmo/block.dart",
     "src/vmo/heap.dart",
@@ -42,7 +42,7 @@
     "inspect/internal/inspect_impl_test.dart",
     "inspect/inspect_test.dart",
     "inspect/node_test.dart",
-    "inspect/value_test.dart",
+    "inspect/property_test.dart",
     "integration/writer.dart",
     "util.dart",
     "vmo/bitfield64_test.dart",
diff --git a/public/dart/fuchsia_inspect/examples/inspect_mod/lib/src/inspect_example_app.dart b/public/dart/fuchsia_inspect/examples/inspect_mod/lib/src/inspect_example_app.dart
index a8e2396..0d6973b 100644
--- a/public/dart/fuchsia_inspect/examples/inspect_mod/lib/src/inspect_example_app.dart
+++ b/public/dart/fuchsia_inspect/examples/inspect_mod/lib/src/inspect_example_app.dart
@@ -12,7 +12,7 @@
   final inspect.Node _inspectNode;
 
   InspectExampleApp(this._inspectNode) {
-    _initValues();
+    _initProperties();
   }
 
   @override
@@ -28,9 +28,9 @@
     );
   }
 
-  /// Initializes the [Inspect] values for this widget.
-  void _initValues() {
-    _inspectNode.stringValue('app-color').setValue('$_appColor');
+  /// Initializes the [Inspect] properties for this widget.
+  void _initProperties() {
+    _inspectNode.stringProperty('app-color').setValue('$_appColor');
   }
 }
 
@@ -39,7 +39,7 @@
   final inspect.Node inspectNode;
 
   _InspectHomePage({Key key, this.title, this.inspectNode}) : super(key: key) {
-    inspectNode.stringValue('title').setValue(title);
+    inspectNode.stringProperty('title').setValue(title);
   }
 
   @override
@@ -56,17 +56,17 @@
 
   final inspect.Node _inspectNode;
 
-  /// A value that tracks [_counter].
-  final inspect.IntValue _counterValue;
+  /// A property that tracks [_counter].
+  final inspect.IntProperty _counterProperty;
 
-  inspect.StringValue _backgroundValue;
+  inspect.StringProperty _backgroundProperty;
 
   int _counter = 0;
   int _colorIndex = 0;
 
   _InspectHomePageState(this._inspectNode)
-      : _counterValue = _inspectNode.intValue('counter') {
-    _backgroundValue = _inspectNode.stringValue('background-color')
+      : _counterProperty = _inspectNode.intProperty('counter') {
+    _backgroundProperty = _inspectNode.stringProperty('background-color')
       ..setValue('$_backgroundColor');
   }
 
@@ -76,18 +76,18 @@
     setState(() {
       _counter++;
 
-      // Note: an alternate approach that is also valid is to set the value to
-      // the new value:
+      // Note: an alternate approach that is also valid is to set the property
+      // to the new value:
       //
-      //     _counterValue.value = _counter;
-      _counterValue.add(1);
+      //     _counterProperty.setValue(_counter);
+      _counterProperty.add(1);
     });
   }
 
   void _decrementCounter() {
     setState(() {
       _counter--;
-      _counterValue.subtract(1);
+      _counterProperty.subtract(1);
     });
   }
 
@@ -101,16 +101,18 @@
       if (_colorIndex >= _colors.length) {
         _colorIndex = 0;
 
-        // Contrived example of removing an Inspect value:
-        // Once we've looped through the colors once, delete the value.
+        // Contrived example of removing an Inspect property:
+        // Once we've looped through the colors once, delete the  to.
         //
         // A more realistic example would be if something were being removed
         // from the UI, but this is intended to be super simple.
-        _backgroundValue.delete();
-        _backgroundValue = null;
+        _backgroundProperty.delete();
+        // Setting _backgroundProperty to null is optional; it's fine to
+        // call setValue() on a deleted property - it will just have no effect.
+        _backgroundProperty = null;
       }
 
-      _backgroundValue?.setValue('$_backgroundColor');
+      _backgroundProperty?.setValue('$_backgroundColor');
     });
   }
 
diff --git a/public/dart/fuchsia_inspect/lib/inspect.dart b/public/dart/fuchsia_inspect/lib/inspect.dart
index 2f8c855..8918cf3 100644
--- a/public/dart/fuchsia_inspect/lib/inspect.dart
+++ b/public/dart/fuchsia_inspect/lib/inspect.dart
@@ -8,7 +8,7 @@
         Inspect,
         InspectStateError,
         Node,
-        IntValue,
-        DoubleValue,
-        StringValue,
-        ByteDataValue;
+        IntProperty,
+        DoubleProperty,
+        StringProperty,
+        ByteDataProperty;
diff --git a/public/dart/fuchsia_inspect/lib/src/inspect/inspect.dart b/public/dart/fuchsia_inspect/lib/src/inspect/inspect.dart
index 4f33144..ac74ef6 100644
--- a/public/dart/fuchsia_inspect/lib/src/inspect/inspect.dart
+++ b/public/dart/fuchsia_inspect/lib/src/inspect/inspect.dart
@@ -13,7 +13,7 @@
 import 'internal/_inspect_impl.dart';
 
 part 'node.dart';
-part 'value.dart';
+part 'property.dart';
 
 /// Unless reconfigured, the VMO will be this size.
 /// @nodoc
@@ -60,9 +60,9 @@
   /// used to store inspection data for this program.
   /// Must be at least 64 bytes.
   ///
-  /// Throws [InspectStateError] if called after Inspect() or with an
-  /// invalid vmoSizeBytes.
-  static void configureInspect({int vmoSizeBytes}) {
+  /// Throws [InspectStateError] if called after Inspect(), or [ArgumentError]
+  /// if called with an invalid vmoSizeBytes.
+  static void configure({int vmoSizeBytes}) {
 // TODO(cphoenix): In integration, test that we throw if called after
 // the factory is run.
     if (_singleton != null) {
@@ -72,7 +72,7 @@
 // TODO(cphoenix): In integration, test that the VMO is the specified size.
     if (vmoSizeBytes != null) {
       if (vmoSizeBytes < 64) {
-        throw InspectStateError('VMO size must be at least 64 bytes.');
+        throw ArgumentError('VMO size must be at least 64 bytes.');
       }
       vmoSize = vmoSizeBytes;
     }
diff --git a/public/dart/fuchsia_inspect/lib/src/inspect/node.dart b/public/dart/fuchsia_inspect/lib/src/inspect/node.dart
index 42375d5..a3ec10c 100644
--- a/public/dart/fuchsia_inspect/lib/src/inspect/node.dart
+++ b/public/dart/fuchsia_inspect/lib/src/inspect/node.dart
@@ -5,7 +5,7 @@
 part of 'inspect.dart';
 
 /// A named node in the Inspect tree that can have [Node]s and
-/// values under it.
+/// properties under it.
 class Node {
   /// The VMO index of this node.
   /// @nodoc
@@ -19,7 +19,7 @@
   /// If so, all actions on this Node should be no-ops and not throw.
   VmoWriter _writer;
 
-  final _values = <String, Value>{};
+  final _properties = <String, Property>{};
   final _children = <String, Node>{};
 
   /// Creates a [Node] with [name] under the [parentIndex].
@@ -66,13 +66,13 @@
   ///
   /// After a node has been deleted, all calls on it and its children have
   /// no effect and do not result in an error. Calls on a deleted node that
-  /// return a Node or Value return an already-deleted object.
+  /// return a Node or property return an already-deleted object.
   void delete() {
     if (_writer == null) {
       return;
     }
-    _values
-      ..forEach((_, value) => value.delete())
+    _properties
+      ..forEach((_, property) => property.delete())
       ..clear();
     _children
       ..forEach((_, node) => node.delete())
@@ -82,97 +82,97 @@
     _writer = null;
   }
 
-  /// Returns a [StringValue] with [name] on this node.
+  /// Returns a [StringProperty] with [name] on this node.
   ///
-  /// If a [StringValue] with [name] already exists and is not deleted,
+  /// If a [StringProperty] with [name] already exists and is not deleted,
   /// this method returns it.
   ///
-  /// Otherwise, it creates a new value initialized to the empty string.
+  /// Otherwise, it creates a new property initialized to the empty string.
   ///
-  /// Throws [InspectStateError] if a non-deleted value with [name] already
-  /// exists but it is not a [StringValue].
-  StringValue stringValue(String name) {
+  /// Throws [InspectStateError] if a non-deleted property with [name] already
+  /// exists but it is not a [StringProperty].
+  StringProperty stringProperty(String name) {
     if (_writer == null) {
-      return StringValue._deleted();
+      return StringProperty._deleted();
     }
-    if (_values.containsKey(name) && !_values[name]._isDeleted) {
-      if (_values[name] is! StringValue) {
-        throw InspectStateError("Can't create StringValue named $name;"
+    if (_properties.containsKey(name) && !_properties[name]._isDeleted) {
+      if (_properties[name] is! StringProperty) {
+        throw InspectStateError("Can't create StringProperty named $name;"
             ' a different type exists.');
       }
-      return _values[name];
+      return _properties[name];
     }
-    return _values[name] = StringValue._(name, index, _writer);
+    return _properties[name] = StringProperty._(name, index, _writer);
   }
 
-  /// Returns a [ByteDataValue] with [name] on this node.
+  /// Returns a [ByteDataProperty] with [name] on this node.
   ///
-  /// If a [ByteDataValue] with [name] already exists and is not deleted,
+  /// If a [ByteDataProperty] with [name] already exists and is not deleted,
   /// this method returns it.
   ///
-  /// Otherwise, it creates a new value initialized to the empty
+  /// Otherwise, it creates a new property initialized to the empty
   /// byte data container.
   ///
-  /// Throws [InspectStateError] if a non-deleted value with [name] already exists
-  /// but it is not a [ByteDataValue].
-  ByteDataValue byteDataValue(String name) {
+  /// Throws [InspectStateError] if a non-deleted property with [name] already exists
+  /// but it is not a [ByteDataProperty].
+  ByteDataProperty byteDataProperty(String name) {
     if (_writer == null) {
-      return ByteDataValue._deleted();
+      return ByteDataProperty._deleted();
     }
-    if (_values.containsKey(name) && !_values[name]._isDeleted) {
-      if (_values[name] is! ByteDataValue) {
-        throw InspectStateError("Can't create ByteDataValue named $name;"
+    if (_properties.containsKey(name) && !_properties[name]._isDeleted) {
+      if (_properties[name] is! ByteDataProperty) {
+        throw InspectStateError("Can't create ByteDataProperty named $name;"
             ' a different type exists.');
       }
-      return _values[name];
+      return _properties[name];
     }
-    return _values[name] = ByteDataValue._(name, index, _writer);
+    return _properties[name] = ByteDataProperty._(name, index, _writer);
   }
 
-  /// Returns an [IntValue] with [name] on this node.
+  /// Returns an [IntProperty] with [name] on this node.
   ///
-  /// If an [IntValue] with [name] already exists and is not
+  /// If an [IntProperty] with [name] already exists and is not
   /// deleted, this method returns it.
   ///
-  /// Otherwise, it creates a new value initialized to 0.
+  /// Otherwise, it creates a new property initialized to 0.
   ///
-  /// Throws [InspectStateError] if a non-deleted value with [name]
-  /// already exists but it is not an [IntValue].
-  IntValue intValue(String name) {
+  /// Throws [InspectStateError] if a non-deleted property with [name]
+  /// already exists but it is not an [IntProperty].
+  IntProperty intProperty(String name) {
     if (_writer == null) {
-      return IntValue._deleted();
+      return IntProperty._deleted();
     }
-    if (_values.containsKey(name) && !_values[name]._isDeleted) {
-      if (_values[name] is! IntValue) {
+    if (_properties.containsKey(name) && !_properties[name]._isDeleted) {
+      if (_properties[name] is! IntProperty) {
         throw InspectStateError(
-            "Can't create IntValue named $name; a different type exists.");
+            "Can't create IntProperty named $name; a different type exists.");
       }
-      return _values[name];
+      return _properties[name];
     }
-    return _values[name] = IntValue._(name, index, _writer);
+    return _properties[name] = IntProperty._(name, index, _writer);
   }
 
-  /// Returns a [DoubleValue] with [name] on this node.
+  /// Returns a [DoubleProperty] with [name] on this node.
   ///
-  /// If a [DoubleValue] with [name] already exists and is not
+  /// If a [DoubleProperty] with [name] already exists and is not
   /// deleted, this method returns it.
   ///
-  /// Otherwise, it creates a new value initialized to 0.0.
+  /// Otherwise, it creates a new property initialized to 0.0.
   ///
-  /// Throws [InspectStateError] if a non-deleted value with [name]
-  /// already exists but it is not a [DoubleValue].
-  DoubleValue doubleValue(String name) {
+  /// Throws [InspectStateError] if a non-deleted property with [name]
+  /// already exists but it is not a [DoubleProperty].
+  DoubleProperty doubleProperty(String name) {
     if (_writer == null) {
-      return DoubleValue._deleted();
+      return DoubleProperty._deleted();
     }
-    if (_values.containsKey(name) && !_values[name]._isDeleted) {
-      if (_values[name] is! DoubleValue) {
-        throw InspectStateError("Can't create DoubleValue named $name;"
+    if (_properties.containsKey(name) && !_properties[name]._isDeleted) {
+      if (_properties[name] is! DoubleProperty) {
+        throw InspectStateError("Can't create DoubleProperty named $name;"
             ' a different type exists.');
       }
-      return _values[name];
+      return _properties[name];
     }
-    return _values[name] = DoubleValue._(name, index, _writer);
+    return _properties[name] = DoubleProperty._(name, index, _writer);
   }
 }
 
diff --git a/public/dart/fuchsia_inspect/lib/src/inspect/property.dart b/public/dart/fuchsia_inspect/lib/src/inspect/property.dart
new file mode 100644
index 0000000..b68f0d6
--- /dev/null
+++ b/public/dart/fuchsia_inspect/lib/src/inspect/property.dart
@@ -0,0 +1,113 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+part of 'inspect.dart';
+
+/// A key-value pair with a [String] key and a typed value.
+abstract class Property<T> {
+  /// The VMO index for this property.
+  /// @nodoc
+  @visibleForTesting
+  final int index;
+
+  /// The writer for the underlying VMO.
+  ///
+  /// Will be set to null if the [Property] has been deleted or could not be
+  /// created in the VMO.
+  /// If so, all actions on this [Property] should be no-ops and not throw.
+  VmoWriter _writer;
+
+  /// Creates a modifiable [Property].
+  Property._(this.index, this._writer) {
+    if (index == invalidIndex) {
+      _writer = null;
+    }
+  }
+
+  /// Creates a property that never does anything.
+  ///
+  /// These are returned when calling methods on a deleted Node,
+  /// or if there is no space for a newly created property in underlying storage.
+  Property.deleted()
+      : _writer = null,
+        index = invalidIndex;
+
+  bool get _isDeleted => _writer == null;
+
+  /// Sets the value of this property.
+  void setValue(T value);
+
+  /// Deletes this property from underlying storage.
+  /// Calls on a deleted property have no effect and do not result in an error.
+  void delete() {
+    _writer?.deleteEntity(index);
+    _writer = null;
+  }
+}
+
+/// Sets value on properties which store a byte-vector.
+mixin BytesProperty<T> on Property<T> {
+  @override
+  void setValue(T value) {
+    _writer?.setProperty(index, value);
+  }
+}
+
+/// Operations on "Metric" type properties - those which store a number.
+mixin Arithmetic<T extends num> on Property<T> {
+  /// Adds [delta] to the value of this metric.
+  void add(T delta) {
+    _writer?.addMetric(index, delta);
+  }
+
+  /// Subtracts [delta] from the value of this metric.
+  void subtract(T delta) {
+    _writer?.subMetric(index, delta);
+  }
+
+  @override
+  void setValue(T value) {
+    _writer?.setMetric(index, value);
+  }
+}
+
+/// A property holding an [int].
+///
+/// Only [Node.intProperty()] can create this object.
+class IntProperty extends Property<int> with Arithmetic<int> {
+  IntProperty._(String name, int parentIndex, VmoWriter writer)
+      : super._(writer.createMetric(parentIndex, name, 0), writer);
+
+  IntProperty._deleted() : super.deleted();
+}
+
+/// A property holding a [double].
+///
+/// Only [Node.doubleProperty()] can create this object.
+class DoubleProperty extends Property<double> with Arithmetic<double> {
+  DoubleProperty._(String name, int parentIndex, VmoWriter writer)
+      : super._(writer.createMetric(parentIndex, name, 0.0), writer);
+
+  DoubleProperty._deleted() : super.deleted();
+}
+
+/// A property holding a [String].
+///
+/// Only [Node.stringProperty()] can create this object.
+class StringProperty extends Property<String> with BytesProperty<String> {
+  StringProperty._(String name, int parentIndex, VmoWriter writer)
+      : super._(writer.createProperty(parentIndex, name), writer);
+
+  StringProperty._deleted() : super.deleted();
+}
+
+/// A property holding a [ByteData].
+///
+/// Only [Node.byteDataProperty()] can create this object.
+class ByteDataProperty extends Property<ByteData> with BytesProperty<ByteData> {
+  ByteDataProperty._(String name, int parentIndex, VmoWriter writer)
+      : super._(writer.createProperty(parentIndex, name), writer);
+
+  ByteDataProperty._deleted() : super.deleted();
+}
diff --git a/public/dart/fuchsia_inspect/lib/src/inspect/value.dart b/public/dart/fuchsia_inspect/lib/src/inspect/value.dart
deleted file mode 100644
index da3835f..0000000
--- a/public/dart/fuchsia_inspect/lib/src/inspect/value.dart
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-part of 'inspect.dart';
-
-/// A VMO-backed key-value pair with a [String] key and a typed value.
-abstract class Value<T> {
-  /// The VMO index for this value.
-  /// @nodoc
-  @visibleForTesting
-  final int index;
-
-  /// The writer for the underlying VMO.
-  ///
-  /// Will be set to null if the [Value] has been deleted or could not be
-  /// created in the VMO.
-  /// If so, all actions on this [Value] should be no-ops and not throw.
-  VmoWriter _writer;
-
-  /// Creates a modifiable [Value].
-  Value._(this.index, this._writer) {
-    if (index == invalidIndex) {
-      _writer = null;
-    }
-  }
-
-  /// Creates a [Value] that never does anything.
-  ///
-  /// These are returned when calling methods on a deleted Node,
-  /// or if there is no space for a newly created value in underlying storage.
-  Value.deleted()
-      : _writer = null,
-        index = invalidIndex;
-
-  bool get _isDeleted => _writer == null;
-
-  /// Sets the value of this [Value].
-  void setValue(T value);
-
-  /// Deletes this value from underlying storage.
-  /// Calls on a deleted value have no effect and do not result in an error.
-  void delete() {
-    _writer?.deleteEntity(index);
-    _writer = null;
-  }
-}
-
-/// Sets value on "Property" type values - those which store a byte-vector.
-mixin Property<T> on Value<T> {
-  @override
-  void setValue(T value) {
-    _writer?.setProperty(index, value);
-  }
-}
-
-/// Operations on "Metric" type values - those which store a number.
-mixin Arithmetic<T extends num> on Value<T> {
-  /// Adds [delta] to the value of this metric.
-  void add(T delta) {
-    _writer?.addMetric(index, delta);
-  }
-
-  /// Subtracts [delta] from the value of this metric.
-  void subtract(T delta) {
-    _writer?.subMetric(index, delta);
-  }
-
-  @override
-  void setValue(T value) {
-    _writer?.setMetric(index, value);
-  }
-}
-
-/// A value holding an [int].
-///
-/// Only [Node.intValue()] can create this object.
-class IntValue extends Value<int> with Arithmetic<int> {
-  IntValue._(String name, int parentIndex, VmoWriter writer)
-      : super._(writer.createMetric(parentIndex, name, 0), writer);
-
-  IntValue._deleted() : super.deleted();
-}
-
-/// A value holding a [double].
-///
-/// Only [Node.doubleValue()] can create this object.
-class DoubleValue extends Value<double> with Arithmetic<double> {
-  DoubleValue._(String name, int parentIndex, VmoWriter writer)
-      : super._(writer.createMetric(parentIndex, name, 0.0), writer);
-
-  DoubleValue._deleted() : super.deleted();
-}
-
-/// A value holding a [String].
-///
-/// Only [Node.stringValue()] can create this object.
-class StringValue extends Value<String> with Property<String> {
-  StringValue._(String name, int parentIndex, VmoWriter writer)
-      : super._(writer.createProperty(parentIndex, name), writer);
-
-  StringValue._deleted() : super.deleted();
-}
-
-/// A value holding a [ByteData].
-///
-/// Only [Node.byteDataValue()] can create this object.
-class ByteDataValue extends Value<ByteData> with Property<ByteData> {
-  ByteDataValue._(String name, int parentIndex, VmoWriter writer)
-      : super._(writer.createProperty(parentIndex, name), writer);
-
-  ByteDataValue._deleted() : super.deleted();
-}
diff --git a/public/dart/fuchsia_inspect/test/inspect/inspect_test.dart b/public/dart/fuchsia_inspect/test/inspect/inspect_test.dart
index b7f3b2f..6de1d7e 100644
--- a/public/dart/fuchsia_inspect/test/inspect/inspect_test.dart
+++ b/public/dart/fuchsia_inspect/test/inspect/inspect_test.dart
@@ -7,24 +7,26 @@
 
 void main() {
   test('configureInspect changes the VMO size each time', () {
-    Inspect.configureInspect(vmoSizeBytes: 1024);
+    Inspect.configure(vmoSizeBytes: 1024);
     expect(Inspect.vmoSize, 1024);
-    Inspect.configureInspect(vmoSizeBytes: 2048);
+    Inspect.configure(vmoSizeBytes: 2048);
     expect(Inspect.vmoSize, 2048);
   });
 
   test('configureInspect rejects negative or too-small VMO size', () {
-    expect(
-        () => Inspect.configureInspect(vmoSizeBytes: -1024), throwsA(anything));
-    expect(() => Inspect.configureInspect(vmoSizeBytes: 0), throwsA(anything));
-    expect(() => Inspect.configureInspect(vmoSizeBytes: 16), throwsA(anything));
+    expect(() => Inspect.configure(vmoSizeBytes: -1024),
+        throwsA(const TypeMatcher<ArgumentError>()));
+    expect(() => Inspect.configure(vmoSizeBytes: 0),
+        throwsA(const TypeMatcher<ArgumentError>()));
+    expect(() => Inspect.configure(vmoSizeBytes: 16),
+        throwsA(const TypeMatcher<ArgumentError>()));
     expect(Inspect.vmoSize, greaterThanOrEqualTo(64));
   });
 
   test('configureInspect does nothing if called with no parameters', () {
-    Inspect.configureInspect(vmoSizeBytes: 2048);
+    Inspect.configure(vmoSizeBytes: 2048);
     expect(Inspect.vmoSize, 2048);
-    Inspect.configureInspect();
+    Inspect.configure();
     expect(Inspect.vmoSize, 2048);
   });
 }
diff --git a/public/dart/fuchsia_inspect/test/inspect/node_test.dart b/public/dart/fuchsia_inspect/test/inspect/node_test.dart
index e21d3b7..2d765d9 100644
--- a/public/dart/fuchsia_inspect/test/inspect/node_test.dart
+++ b/public/dart/fuchsia_inspect/test/inspect/node_test.dart
@@ -89,35 +89,39 @@
           reason: 'cannot read VMO values from a deleted node');
     });
 
-    test('Creating an IntValue on an already deleted node is a no-op', () {
-      IntValue value;
-      expect(() => value = deletedNode.intValue('404'), returnsNormally);
-      expect(() => value.setValue(404), returnsNormally);
-      expect(() => readInt(vmo, value), throwsA(anything),
+    test('Creating an IntProperty on an already deleted node is a no-op', () {
+      IntProperty property;
+      expect(() => property = deletedNode.intProperty('404'), returnsNormally);
+      expect(() => property.setValue(404), returnsNormally);
+      expect(() => readInt(vmo, property), throwsA(anything),
           reason: 'cannot read VMO values from a deleted node');
     });
 
-    test('Creating a DoubleValue on an already deleted node is a no-op', () {
-      DoubleValue value;
-      expect(() => value = deletedNode.doubleValue('404'), returnsNormally);
-      expect(() => value.setValue(404), returnsNormally);
-      expect(() => readDouble(vmo, value), throwsA(anything),
+    test('Creating a DoubleProperty on an already deleted node is a no-op', () {
+      DoubleProperty property;
+      expect(
+          () => property = deletedNode.doubleProperty('404'), returnsNormally);
+      expect(() => property.setValue(404), returnsNormally);
+      expect(() => readDouble(vmo, property), throwsA(anything),
           reason: 'cannot read VMO values from a deleted node');
     });
 
-    test('Creating a StringValue on an already deleted node is a no-op', () {
-      StringValue value;
-      expect(() => value = deletedNode.stringValue('404'), returnsNormally);
-      expect(() => value.setValue('404'), returnsNormally);
-      expect(() => readProperty(vmo, value.index), throwsA(anything),
+    test('Creating a StringProperty on an already deleted node is a no-op', () {
+      StringProperty property;
+      expect(
+          () => property = deletedNode.stringProperty('404'), returnsNormally);
+      expect(() => property.setValue('404'), returnsNormally);
+      expect(() => readProperty(vmo, property.index), throwsA(anything),
           reason: 'cannot read VMO values from a deleted property');
     });
 
-    test('Creating a ByteDataValue on an already deleted node is a no-op', () {
-      ByteDataValue value;
-      expect(() => value = deletedNode.byteDataValue('404'), returnsNormally);
-      expect(() => value.setValue(toByteData('fuchsia')), returnsNormally);
-      expect(() => readProperty(vmo, value.index), throwsA(anything),
+    test('Creating a ByteDataProperty on an already deleted node is a no-op',
+        () {
+      ByteDataProperty property;
+      expect(() => property = deletedNode.byteDataProperty('404'),
+          returnsNormally);
+      expect(() => property.setValue(toByteData('fuchsia')), returnsNormally);
+      expect(() => readProperty(vmo, property.index), throwsA(anything),
           reason: 'cannot read VMO values from a deleted property');
     });
   });
@@ -136,32 +140,32 @@
           reason: 'child Node of deleted Node should be deleted');
     });
 
-    test('child IntValue of deleted Node is deleted', () {
-      var intValue = normalNode.intValue('llamas');
+    test('child IntProperty of deleted Node is deleted', () {
+      var intProperty = normalNode.intProperty('llamas');
       normalNode.delete();
-      expect(() => readInt(vmo, intValue), throwsA(anything),
-          reason: 'child IntValue of deleted Node should be deleted');
+      expect(() => readInt(vmo, intProperty), throwsA(anything),
+          reason: 'child IntProperty of deleted Node should be deleted');
     });
 
-    test('child DoubleValue of deleted Node is deleted', () {
-      var doubleValue = normalNode.doubleValue('emus');
+    test('child DoubleProperty of deleted Node is deleted', () {
+      var doubleProperty = normalNode.doubleProperty('emus');
       normalNode.delete();
-      expect(() => readDouble(vmo, doubleValue), throwsA(anything),
-          reason: 'child DoubleValue of deleted Node should be deleted');
+      expect(() => readDouble(vmo, doubleProperty), throwsA(anything),
+          reason: 'child DoubleProperty of deleted Node should be deleted');
     });
 
-    test('child StringValue of deleted Node is deleted', () {
-      var stringValue = normalNode.stringValue('okapis');
+    test('child StringProperty of deleted Node is deleted', () {
+      var stringProperty = normalNode.stringProperty('okapis');
       normalNode.delete();
-      expect(() => readProperty(vmo, stringValue.index), throwsA(anything),
-          reason: 'child StringValue of deleted Node should be deleted');
+      expect(() => readProperty(vmo, stringProperty.index), throwsA(anything),
+          reason: 'child StringProperty of deleted Node should be deleted');
     });
 
-    test('child ByteDataValue of deleted Node is deleted', () {
-      var byteDataValue = normalNode.byteDataValue('capybaras');
+    test('child ByteDataProperty of deleted Node is deleted', () {
+      var byteDataProperty = normalNode.byteDataProperty('capybaras');
       normalNode.delete();
-      expect(() => readProperty(vmo, byteDataValue.index), throwsA(anything),
-          reason: 'child ByteDataValue of deleted Node should be deleted');
+      expect(() => readProperty(vmo, byteDataProperty.index), throwsA(anything),
+          reason: 'child ByteDataProperty of deleted Node should be deleted');
     });
   });
 
@@ -182,32 +186,32 @@
           reason: 'cannot read VMO values from a deleted node');
     });
 
-    test('If no space, creation gives a deleted IntValue', () {
-      var missingValue = tinyRoot.intValue('missing');
-      expect(() => missingValue.setValue(1), returnsNormally);
-      expect(() => readInt(vmo, missingValue), throwsA(anything),
+    test('If no space, creation gives a deleted IntProperty', () {
+      var missingProperty = tinyRoot.intProperty('missing');
+      expect(() => missingProperty.setValue(1), returnsNormally);
+      expect(() => readInt(vmo, missingProperty), throwsA(anything),
           reason: 'cannot read VMO values from a deleted metric');
     });
 
-    test('If no space, creation gives a deleted DoubleValue', () {
-      var missingValue = tinyRoot.doubleValue('missing');
-      expect(() => missingValue.setValue(1.0), returnsNormally);
-      expect(() => readDouble(vmo, missingValue), throwsA(anything),
+    test('If no space, creation gives a deleted DoubleProperty', () {
+      var missingProperty = tinyRoot.doubleProperty('missing');
+      expect(() => missingProperty.setValue(1.0), returnsNormally);
+      expect(() => readDouble(vmo, missingProperty), throwsA(anything),
           reason: 'cannot read VMO values from a deleted metric');
     });
 
-    test('If no space, creation gives a deleted StringValue', () {
-      var missingValue = tinyRoot.stringValue('missing');
-      expect(() => missingValue.setValue('something'), returnsNormally);
-      expect(() => readProperty(vmo, missingValue.index), throwsA(anything),
+    test('If no space, creation gives a deleted StringProperty', () {
+      var missingProperty = tinyRoot.stringProperty('missing');
+      expect(() => missingProperty.setValue('something'), returnsNormally);
+      expect(() => readProperty(vmo, missingProperty.index), throwsA(anything),
           reason: 'cannot read VMO values from a deleted property');
     });
 
-    test('If no space, creation gives a deleted ByteDataValue', () {
+    test('If no space, creation gives a deleted ByteDataProperty', () {
       var bytes = toByteData('this will not set');
-      var missingValue = tinyRoot.byteDataValue('missing');
-      expect(() => missingValue.setValue(bytes), returnsNormally);
-      expect(() => readProperty(vmo, missingValue.index), throwsA(anything),
+      var missingProperty = tinyRoot.byteDataProperty('missing');
+      expect(() => missingProperty.setValue(bytes), returnsNormally);
+      expect(() => readProperty(vmo, missingProperty.index), throwsA(anything),
           reason: 'cannot read VMO values from a deleted property');
     });
   });
diff --git a/public/dart/fuchsia_inspect/test/inspect/property_test.dart b/public/dart/fuchsia_inspect/test/inspect/property_test.dart
new file mode 100644
index 0000000..cbdc6f6
--- /dev/null
+++ b/public/dart/fuchsia_inspect/test/inspect/property_test.dart
@@ -0,0 +1,457 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// ignore_for_file: implementation_imports
+
+import 'package:fuchsia_inspect/inspect.dart';
+import 'package:fuchsia_inspect/src/inspect/internal/_inspect_impl.dart';
+import 'package:fuchsia_inspect/src/vmo/util.dart';
+import 'package:fuchsia_inspect/src/vmo/vmo_holder.dart';
+import 'package:fuchsia_inspect/src/vmo/vmo_writer.dart';
+import 'package:fuchsia_services/services.dart';
+import 'package:test/test.dart';
+
+import '../util.dart';
+
+void main() {
+  VmoHolder vmo;
+  Node node;
+
+  setUp(() {
+    var context = StartupContext.fromStartupInfo();
+    vmo = FakeVmo(512);
+    var writer = VmoWriter(vmo);
+    Inspect inspect = InspectImpl(context, writer);
+    node = inspect.root;
+  });
+
+  group('String properties', () {
+    test('are written to the VMO when the value is set', () {
+      var property = node.stringProperty('color')..setValue('fuchsia');
+
+      expect(readProperty(vmo, property.index),
+          equalsByteData(toByteData('fuchsia')));
+    });
+
+    test('can be mutated', () {
+      var property = node.stringProperty('breakfast')..setValue('pancakes');
+
+      expect(readProperty(vmo, property.index),
+          equalsByteData(toByteData('pancakes')));
+
+      property.setValue('waffles');
+      expect(readProperty(vmo, property.index),
+          equalsByteData(toByteData('waffles')));
+    });
+
+    test('can be deleted', () {
+      var property = node.stringProperty('scallops');
+      var index = property.index;
+
+      property.delete();
+
+      expect(() => readProperty(vmo, index),
+          throwsA(const TypeMatcher<StateError>()),
+          reason: 'cannot read VMO values from a deleted property');
+    });
+
+    test('setting a value on an already deleted property is a no-op', () {
+      var property = node.stringProperty('paella');
+      var index = property.index;
+      property.delete();
+
+      expect(() => property.setValue('this will not set'), returnsNormally);
+      expect(() => readProperty(vmo, index),
+          throwsA(const TypeMatcher<StateError>()),
+          reason: 'cannot read VMO values from a deleted property');
+    });
+
+    test('removing an already deleted property is a no-op', () {
+      var property = node.stringProperty('nothing-here')..delete();
+
+      expect(() => property.delete(), returnsNormally);
+    });
+  });
+
+  group('ByteData properties', () {
+    test('are written to the VMO when the property is set', () {
+      var bytes = toByteData('fuchsia');
+      var property = node.byteDataProperty('color')..setValue(bytes);
+
+      expect(readProperty(vmo, property.index), equalsByteData(bytes));
+    });
+
+    test('can be mutated', () {
+      var pancakes = toByteData('pancakes');
+      var property = node.byteDataProperty('breakfast')..setValue(pancakes);
+
+      expect(readProperty(vmo, property.index), equalsByteData(pancakes));
+
+      var waffles = toByteData('waffles');
+      property.setValue(waffles);
+      expect(readProperty(vmo, property.index), equalsByteData(waffles));
+    });
+
+    test('can be deleted', () {
+      var property = node.byteDataProperty('scallops');
+      var index = property.index;
+
+      property.delete();
+
+      expect(() => readProperty(vmo, index),
+          throwsA(const TypeMatcher<StateError>()),
+          reason: 'cannot read VMO values from a deleted property');
+    });
+
+    test('setting a value on an already deleted property is a no-op', () {
+      var property = node.byteDataProperty('paella');
+      var index = property.index;
+      property.delete();
+
+      var bytes = toByteData('this will not set');
+      expect(() => property.setValue(bytes), returnsNormally);
+      expect(() => readProperty(vmo, index),
+          throwsA(const TypeMatcher<StateError>()),
+          reason: 'cannot read VMO values from a deleted property');
+    });
+
+    test('removing an already deleted property is a no-op', () {
+      var property = node.byteDataProperty('nothing-here')..delete();
+
+      expect(() => property.delete(), returnsNormally);
+    });
+  });
+
+  group('Property creation (byte-vector properties)', () {
+    test('StringProperties created twice return the same object', () {
+      var childProperty = node.stringProperty('banana');
+      var childProperty2 = node.stringProperty('banana');
+
+      expect(childProperty, isNotNull);
+      expect(childProperty2, isNotNull);
+      expect(childProperty, same(childProperty2));
+    });
+
+    test('StringProperties created after deletion return different objects',
+        () {
+      var childProperty = node.stringProperty('banana')..delete();
+      var childProperty2 = node.stringProperty('banana');
+
+      expect(childProperty, isNotNull);
+      expect(childProperty2, isNotNull);
+      expect(childProperty, isNot(equals(childProperty2)));
+    });
+
+    test('ByteDataProperties created twice return the same object', () {
+      var childProperty = node.byteDataProperty('banana');
+      var childProperty2 = node.byteDataProperty('banana');
+
+      expect(childProperty, isNotNull);
+      expect(childProperty2, isNotNull);
+      expect(childProperty, same(childProperty2));
+    });
+
+    test('ByteDataProperties created after deletion return different objects',
+        () {
+      var childProperty = node.byteDataProperty('banana')..delete();
+      var childProperty2 = node.byteDataProperty('banana');
+
+      expect(childProperty, isNotNull);
+      expect(childProperty2, isNotNull);
+      expect(childProperty, isNot(equals(childProperty2)));
+    });
+
+    test('Changing StringProperty to ByteDataProperty throws', () {
+      node.stringProperty('banana');
+      expect(() => node.byteDataProperty('banana'),
+          throwsA(const TypeMatcher<InspectStateError>()));
+    });
+
+    test('Changing StringProperty to IntProperty throws', () {
+      node.stringProperty('banana');
+      expect(() => node.intProperty('banana'),
+          throwsA(const TypeMatcher<InspectStateError>()));
+    });
+
+    test('Changing StringProperty to DoubleProperty throws', () {
+      node.stringProperty('banana');
+      expect(() => node.doubleProperty('banana'),
+          throwsA(const TypeMatcher<InspectStateError>()));
+    });
+
+    test('Changing ByteDataProperty to StringProperty throws', () {
+      node.byteDataProperty('banana');
+      expect(() => node.stringProperty('banana'),
+          throwsA(const TypeMatcher<InspectStateError>()));
+    });
+
+    test('Changing ByteDataProperty to IntProperty throws', () {
+      node.byteDataProperty('banana');
+      expect(() => node.intProperty('banana'),
+          throwsA(const TypeMatcher<InspectStateError>()));
+    });
+
+    test('Changing ByteDataProperty to DoubleProperty throws', () {
+      node.byteDataProperty('banana');
+      expect(() => node.doubleProperty('banana'),
+          throwsA(const TypeMatcher<InspectStateError>()));
+    });
+
+    test('If no space, creation gives a deleted StringProperty', () {
+      var tinyVmo = FakeVmo(64);
+      var writer = VmoWriter(tinyVmo);
+      var context = StartupContext.fromStartupInfo();
+      Inspect inspect = InspectImpl(context, writer);
+      var tinyRoot = inspect.root;
+      var missingProperty = tinyRoot.stringProperty('missing');
+      expect(() => missingProperty.setValue('something'), returnsNormally);
+      expect(() => readProperty(vmo, missingProperty.index),
+          throwsA(const TypeMatcher<StateError>()),
+          reason: 'cannot read VMO values from a deleted property');
+    });
+
+    test('If no space, creation gives a deleted ByteDataProperty', () {
+      var tinyVmo = FakeVmo(64);
+      var writer = VmoWriter(tinyVmo);
+      var context = StartupContext.fromStartupInfo();
+      Inspect inspect = InspectImpl(context, writer);
+      var tinyRoot = inspect.root;
+      var bytes = toByteData('this will not set');
+      var missingProperty = tinyRoot.byteDataProperty('missing');
+      expect(() => missingProperty.setValue(bytes), returnsNormally);
+      expect(() => readProperty(vmo, missingProperty.index),
+          throwsA(const TypeMatcher<StateError>()),
+          reason: 'cannot read VMO values from a deleted property');
+    });
+  });
+
+  group('Int Properties', () {
+    test('are created with value 0', () {
+      var property = node.intProperty('foo');
+
+      expect(readInt(vmo, property), isZero);
+    });
+
+    test('are written to the VMO when the value is set', () {
+      var property = node.intProperty('eggs')..setValue(12);
+
+      expect(readInt(vmo, property), 12);
+    });
+
+    test('can be mutated', () {
+      var property = node.intProperty('locusts')..setValue(10);
+      expect(readInt(vmo, property), 10);
+
+      property.setValue(1000);
+
+      expect(readInt(vmo, property), 1000);
+    });
+
+    test('can add arbitrary values', () {
+      var property = node.intProperty('bagels')..setValue(13);
+      expect(readInt(vmo, property), 13);
+
+      property.add(13);
+
+      expect(readInt(vmo, property), 26);
+    });
+
+    test('can subtract arbitrary values', () {
+      var property = node.intProperty('bagels')..setValue(13);
+      expect(readInt(vmo, property), 13);
+
+      property.subtract(6);
+
+      expect(readInt(vmo, property), 7);
+    });
+
+    test('can be deleted', () {
+      var property = node.intProperty('sheep')..delete();
+
+      expect(() => readInt(vmo, property),
+          throwsA(const TypeMatcher<StateError>()),
+          reason: 'cannot read VMO values from a deleted property');
+    });
+
+    test('setting a value on an already deleted property is a no-op', () {
+      var property = node.intProperty('webpages')..delete();
+
+      expect(() => property.setValue(404), returnsNormally);
+      expect(() => readInt(vmo, property),
+          throwsA(const TypeMatcher<StateError>()),
+          reason: 'cannot read VMO values from a deleted property');
+    });
+
+    test('removing an already deleted property is a no-op', () {
+      var property = node.intProperty('nothing-here')..delete();
+
+      expect(() => property.delete(), returnsNormally);
+    });
+  });
+
+  group('DoubleProperties', () {
+    test('are created with value 0', () {
+      var property = node.doubleProperty('foo');
+
+      expect(readDouble(vmo, property), isZero);
+    });
+
+    test('are written to the VMO when the value is set', () {
+      var property = node.doubleProperty('foo')..setValue(2.5);
+
+      expect(readDouble(vmo, property), 2.5);
+    });
+
+    test('can be mutated', () {
+      var property = node.doubleProperty('bar')..setValue(3.0);
+      expect(readDouble(vmo, property), 3.0);
+
+      property.setValue(3.5);
+
+      expect(readDouble(vmo, property), 3.5);
+    });
+
+    test('can add arbitrary values', () {
+      var property = node.doubleProperty('cake')..setValue(1.5);
+      expect(readDouble(vmo, property), 1.5);
+
+      property.add(1.5);
+
+      expect(readDouble(vmo, property), 3);
+    });
+
+    test('can subtract arbitrary values', () {
+      var property = node.doubleProperty('cake')..setValue(5);
+      expect(readDouble(vmo, property), 5);
+
+      property.subtract(0.5);
+
+      expect(readDouble(vmo, property), 4.5);
+    });
+
+    test('can be deleted', () {
+      var property = node.doubleProperty('circumference')..delete();
+
+      expect(() => readDouble(vmo, property),
+          throwsA(const TypeMatcher<StateError>()),
+          reason: 'cannot read VMO values from a deleted property');
+    });
+
+    test('setting a value on an already deleted property is a no-op', () {
+      var property = node.doubleProperty('pounds')..delete();
+
+      expect(() => property.setValue(50.6), returnsNormally);
+      expect(() => readDouble(vmo, property),
+          throwsA(const TypeMatcher<StateError>()),
+          reason: 'cannot read VMO values from a deleted property');
+    });
+
+    test('removing an already deleted property is a no-op', () {
+      var property = node.doubleProperty('nothing-here')..delete();
+
+      expect(() => property.delete(), returnsNormally);
+    });
+  });
+
+  group('property creation', () {
+    test('IntProperties created twice return the same object', () {
+      var childProperty = node.intProperty('banana');
+      var childProperty2 = node.intProperty('banana');
+
+      expect(childProperty, isNotNull);
+      expect(childProperty2, isNotNull);
+      expect(childProperty, same(childProperty2));
+    });
+
+    test('IntProperties created after deletion return different objects', () {
+      var childProperty = node.intProperty('banana')..delete();
+      var childProperty2 = node.intProperty('banana');
+
+      expect(childProperty, isNotNull);
+      expect(childProperty2, isNotNull);
+      expect(childProperty, isNot(equals(childProperty2)));
+    });
+
+    test('DoubleProperties created twice return the same object', () {
+      var childProperty = node.doubleProperty('banana');
+      var childProperty2 = node.doubleProperty('banana');
+
+      expect(childProperty, isNotNull);
+      expect(childProperty2, isNotNull);
+      expect(childProperty, same(childProperty2));
+    });
+
+    test('DoubleProperties created after deletion return different objects',
+        () {
+      var childProperty = node.doubleProperty('banana')..delete();
+      var childProperty2 = node.doubleProperty('banana');
+
+      expect(childProperty, isNotNull);
+      expect(childProperty2, isNotNull);
+      expect(childProperty, isNot(equals(childProperty2)));
+    });
+
+    test('Changing IntProperty to DoubleProperty throws', () {
+      node.intProperty('banana');
+      expect(() => node.doubleProperty('banana'),
+          throwsA(const TypeMatcher<InspectStateError>()));
+    });
+
+    test('Changing IntProperty to StringProperty throws', () {
+      node.intProperty('banana');
+      expect(() => node.stringProperty('banana'),
+          throwsA(const TypeMatcher<InspectStateError>()));
+    });
+
+    test('Changing IntProperty to ByteDataProperty throws', () {
+      node.intProperty('banana');
+      expect(() => node.byteDataProperty('banana'),
+          throwsA(const TypeMatcher<InspectStateError>()));
+    });
+
+    test('Changing DoubleProperty to IntProperty throws', () {
+      node.doubleProperty('banana');
+      expect(() => node.intProperty('banana'),
+          throwsA(const TypeMatcher<InspectStateError>()));
+    });
+
+    test('Changing DoubleProperty to StringProperty throws', () {
+      node.doubleProperty('banana');
+      expect(() => node.stringProperty('banana'),
+          throwsA(const TypeMatcher<InspectStateError>()));
+    });
+
+    test('Changing DoubleProperty to ByteDataProperty throws', () {
+      node.doubleProperty('banana');
+      expect(() => node.byteDataProperty('banana'),
+          throwsA(const TypeMatcher<InspectStateError>()));
+    });
+
+    test('If no space, creation gives a deleted IntProperty', () {
+      var tinyVmo = FakeVmo(64);
+      var writer = VmoWriter(tinyVmo);
+      var context = StartupContext.fromStartupInfo();
+      Inspect inspect = InspectImpl(context, writer);
+      var tinyRoot = inspect.root;
+      var missingProperty = tinyRoot.intProperty('missing');
+      expect(() => missingProperty.setValue(1), returnsNormally);
+      expect(() => readInt(vmo, missingProperty),
+          throwsA(const TypeMatcher<StateError>()),
+          reason: 'cannot read VMO values from a deleted property');
+    });
+
+    test('If no space, creation gives a deleted DoubleProperty', () {
+      var tinyVmo = FakeVmo(64);
+      var writer = VmoWriter(tinyVmo);
+      var context = StartupContext.fromStartupInfo();
+      Inspect inspect = InspectImpl(context, writer);
+      var tinyRoot = inspect.root;
+      var missingProperty = tinyRoot.doubleProperty('missing');
+      expect(() => missingProperty.setValue(1.0), returnsNormally);
+      expect(() => readDouble(vmo, missingProperty),
+          throwsA(const TypeMatcher<StateError>()),
+          reason: 'cannot read VMO values from a deleted property');
+    });
+  });
+}
diff --git a/public/dart/fuchsia_inspect/test/inspect/value_test.dart b/public/dart/fuchsia_inspect/test/inspect/value_test.dart
deleted file mode 100644
index 6fcad60..0000000
--- a/public/dart/fuchsia_inspect/test/inspect/value_test.dart
+++ /dev/null
@@ -1,454 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// ignore_for_file: implementation_imports
-
-import 'package:fuchsia_inspect/inspect.dart';
-import 'package:fuchsia_inspect/src/inspect/internal/_inspect_impl.dart';
-import 'package:fuchsia_inspect/src/vmo/util.dart';
-import 'package:fuchsia_inspect/src/vmo/vmo_holder.dart';
-import 'package:fuchsia_inspect/src/vmo/vmo_writer.dart';
-import 'package:fuchsia_services/services.dart';
-import 'package:test/test.dart';
-
-import '../util.dart';
-
-void main() {
-  VmoHolder vmo;
-  Node node;
-
-  setUp(() {
-    var context = StartupContext.fromStartupInfo();
-    vmo = FakeVmo(512);
-    var writer = VmoWriter(vmo);
-    Inspect inspect = InspectImpl(context, writer);
-    node = inspect.root;
-  });
-
-  group('String values', () {
-    test('are written to the VMO when the value is set', () {
-      var value = node.stringValue('color')..setValue('fuchsia');
-
-      expect(readProperty(vmo, value.index),
-          equalsByteData(toByteData('fuchsia')));
-    });
-
-    test('can be mutated', () {
-      var value = node.stringValue('breakfast')..setValue('pancakes');
-
-      expect(readProperty(vmo, value.index),
-          equalsByteData(toByteData('pancakes')));
-
-      value.setValue('waffles');
-      expect(readProperty(vmo, value.index),
-          equalsByteData(toByteData('waffles')));
-    });
-
-    test('can be deleted', () {
-      var value = node.stringValue('scallops');
-      var index = value.index;
-
-      value.delete();
-
-      expect(() => readProperty(vmo, index),
-          throwsA(const TypeMatcher<StateError>()),
-          reason: 'cannot read VMO values from a deleted property');
-    });
-
-    test('setting a value on an already deleted value is a no-op', () {
-      var value = node.stringValue('paella');
-      var index = value.index;
-      value.delete();
-
-      expect(() => value.setValue('this will not set'), returnsNormally);
-      expect(() => readProperty(vmo, index),
-          throwsA(const TypeMatcher<StateError>()),
-          reason: 'cannot read VMO values from a deleted property');
-    });
-
-    test('removing an already deleted value is a no-op', () {
-      var value = node.stringValue('nothing-here')..delete();
-
-      expect(() => value.delete(), returnsNormally);
-    });
-  });
-
-  group('ByteData values', () {
-    test('are written to the VMO when the value is set', () {
-      var bytes = toByteData('fuchsia');
-      var value = node.byteDataValue('color')..setValue(bytes);
-
-      expect(readProperty(vmo, value.index), equalsByteData(bytes));
-    });
-
-    test('can be mutated', () {
-      var pancakes = toByteData('pancakes');
-      var value = node.byteDataValue('breakfast')..setValue(pancakes);
-
-      expect(readProperty(vmo, value.index), equalsByteData(pancakes));
-
-      var waffles = toByteData('waffles');
-      value.setValue(waffles);
-      expect(readProperty(vmo, value.index), equalsByteData(waffles));
-    });
-
-    test('can be deleted', () {
-      var value = node.byteDataValue('scallops');
-      var index = value.index;
-
-      value.delete();
-
-      expect(() => readProperty(vmo, index),
-          throwsA(const TypeMatcher<StateError>()),
-          reason: 'cannot read VMO values from a deleted property');
-    });
-
-    test('setting a value on an already deleted value is a no-op', () {
-      var value = node.byteDataValue('paella');
-      var index = value.index;
-      value.delete();
-
-      var bytes = toByteData('this will not set');
-      expect(() => value.setValue(bytes), returnsNormally);
-      expect(() => readProperty(vmo, index),
-          throwsA(const TypeMatcher<StateError>()),
-          reason: 'cannot read VMO values from a deleted property');
-    });
-
-    test('removing an already deleted value is a no-op', () {
-      var value = node.byteDataValue('nothing-here')..delete();
-
-      expect(() => value.delete(), returnsNormally);
-    });
-  });
-
-  group('Property creation (byte-vector Values)', () {
-    test('StringValues created twice return the same object', () {
-      var childValue = node.stringValue('banana');
-      var childValue2 = node.stringValue('banana');
-
-      expect(childValue, isNotNull);
-      expect(childValue2, isNotNull);
-      expect(childValue, same(childValue2));
-    });
-
-    test('StringValues created after deletion return different objects', () {
-      var childValue = node.stringValue('banana')..delete();
-      var childValue2 = node.stringValue('banana');
-
-      expect(childValue, isNotNull);
-      expect(childValue2, isNotNull);
-      expect(childValue, isNot(equals(childValue2)));
-    });
-
-    test('ByteDataValues created twice return the same object', () {
-      var childValue = node.byteDataValue('banana');
-      var childValue2 = node.byteDataValue('banana');
-
-      expect(childValue, isNotNull);
-      expect(childValue2, isNotNull);
-      expect(childValue, same(childValue2));
-    });
-
-    test('ByteDataValues created after deletion return different objects', () {
-      var childValue = node.byteDataValue('banana')..delete();
-      var childValue2 = node.byteDataValue('banana');
-
-      expect(childValue, isNotNull);
-      expect(childValue2, isNotNull);
-      expect(childValue, isNot(equals(childValue2)));
-    });
-
-    test('Changing StringValue to ByteDataValue throws', () {
-      node.stringValue('banana');
-      expect(() => node.byteDataValue('banana'),
-          throwsA(const TypeMatcher<InspectStateError>()));
-    });
-
-    test('Changing StringValue to IntValue throws', () {
-      node.stringValue('banana');
-      expect(() => node.intValue('banana'),
-          throwsA(const TypeMatcher<InspectStateError>()));
-    });
-
-    test('Changing StringValue to DoubleValue throws', () {
-      node.stringValue('banana');
-      expect(() => node.doubleValue('banana'),
-          throwsA(const TypeMatcher<InspectStateError>()));
-    });
-
-    test('Changing ByteDataValue to StringValue throws', () {
-      node.byteDataValue('banana');
-      expect(() => node.stringValue('banana'),
-          throwsA(const TypeMatcher<InspectStateError>()));
-    });
-
-    test('Changing ByteDataValue to IntValue throws', () {
-      node.byteDataValue('banana');
-      expect(() => node.intValue('banana'),
-          throwsA(const TypeMatcher<InspectStateError>()));
-    });
-
-    test('Changing ByteDataValue to DoubleValue throws', () {
-      node.byteDataValue('banana');
-      expect(() => node.doubleValue('banana'),
-          throwsA(const TypeMatcher<InspectStateError>()));
-    });
-
-    test('If no space, creation gives a deleted StringValue', () {
-      var tinyVmo = FakeVmo(64);
-      var writer = VmoWriter(tinyVmo);
-      var context = StartupContext.fromStartupInfo();
-      Inspect inspect = InspectImpl(context, writer);
-      var tinyRoot = inspect.root;
-      var missingValue = tinyRoot.stringValue('missing');
-      expect(() => missingValue.setValue('something'), returnsNormally);
-      expect(() => readProperty(vmo, missingValue.index),
-          throwsA(const TypeMatcher<StateError>()),
-          reason: 'cannot read VMO values from a deleted property');
-    });
-
-    test('If no space, creation gives a deleted ByteDataValue', () {
-      var tinyVmo = FakeVmo(64);
-      var writer = VmoWriter(tinyVmo);
-      var context = StartupContext.fromStartupInfo();
-      Inspect inspect = InspectImpl(context, writer);
-      var tinyRoot = inspect.root;
-      var bytes = toByteData('this will not set');
-      var missingValue = tinyRoot.byteDataValue('missing');
-      expect(() => missingValue.setValue(bytes), returnsNormally);
-      expect(() => readProperty(vmo, missingValue.index),
-          throwsA(const TypeMatcher<StateError>()),
-          reason: 'cannot read VMO values from a deleted property');
-    });
-  });
-
-  group('Int Values', () {
-    test('are created with value 0', () {
-      var value = node.intValue('foo');
-
-      expect(readInt(vmo, value), isZero);
-    });
-
-    test('are written to the VMO when the value is set', () {
-      var value = node.intValue('eggs')..setValue(12);
-
-      expect(readInt(vmo, value), 12);
-    });
-
-    test('can be mutated', () {
-      var value = node.intValue('locusts')..setValue(10);
-      expect(readInt(vmo, value), 10);
-
-      value.setValue(1000);
-
-      expect(readInt(vmo, value), 1000);
-    });
-
-    test('can add arbitrary values', () {
-      var value = node.intValue('bagels')..setValue(13);
-      expect(readInt(vmo, value), 13);
-
-      value.add(13);
-
-      expect(readInt(vmo, value), 26);
-    });
-
-    test('can subtract arbitrary values', () {
-      var value = node.intValue('bagels')..setValue(13);
-      expect(readInt(vmo, value), 13);
-
-      value.subtract(6);
-
-      expect(readInt(vmo, value), 7);
-    });
-
-    test('can be deleted', () {
-      var value = node.intValue('sheep')..delete();
-
-      expect(
-          () => readInt(vmo, value), throwsA(const TypeMatcher<StateError>()),
-          reason: 'cannot read VMO values from a deleted value');
-    });
-
-    test('setting a value on an already deleted value is a no-op', () {
-      var value = node.intValue('webpages')..delete();
-
-      expect(() => value.setValue(404), returnsNormally);
-      expect(
-          () => readInt(vmo, value), throwsA(const TypeMatcher<StateError>()),
-          reason: 'cannot read VMO values from a deleted value');
-    });
-
-    test('removing an already deleted value is a no-op', () {
-      var value = node.intValue('nothing-here')..delete();
-
-      expect(() => value.delete(), returnsNormally);
-    });
-  });
-
-  group('DoubleValues', () {
-    test('are created with value 0', () {
-      var value = node.doubleValue('foo');
-
-      expect(readDouble(vmo, value), isZero);
-    });
-
-    test('are written to the VMO when the value is set', () {
-      var value = node.doubleValue('foo')..setValue(2.5);
-
-      expect(readDouble(vmo, value), 2.5);
-    });
-
-    test('can be mutated', () {
-      var value = node.doubleValue('bar')..setValue(3.0);
-      expect(readDouble(vmo, value), 3.0);
-
-      value.setValue(3.5);
-
-      expect(readDouble(vmo, value), 3.5);
-    });
-
-    test('can add arbitrary values', () {
-      var value = node.doubleValue('cake')..setValue(1.5);
-      expect(readDouble(vmo, value), 1.5);
-
-      value.add(1.5);
-
-      expect(readDouble(vmo, value), 3);
-    });
-
-    test('can subtract arbitrary values', () {
-      var value = node.doubleValue('cake')..setValue(5);
-      expect(readDouble(vmo, value), 5);
-
-      value.subtract(0.5);
-
-      expect(readDouble(vmo, value), 4.5);
-    });
-
-    test('can be deleted', () {
-      var value = node.doubleValue('circumference')..delete();
-
-      expect(() => readDouble(vmo, value),
-          throwsA(const TypeMatcher<StateError>()),
-          reason: 'cannot read VMO values from a deleted value');
-    });
-
-    test('setting a value on an already deleted value is a no-op', () {
-      var value = node.doubleValue('pounds')..delete();
-
-      expect(() => value.setValue(50.6), returnsNormally);
-      expect(() => readDouble(vmo, value),
-          throwsA(const TypeMatcher<StateError>()),
-          reason: 'cannot read VMO values from a deleted value');
-    });
-
-    test('removing an already deleted value is a no-op', () {
-      var value = node.doubleValue('nothing-here')..delete();
-
-      expect(() => value.delete(), returnsNormally);
-    });
-  });
-
-  group('value creation', () {
-    test('IntValues created twice return the same object', () {
-      var childValue = node.intValue('banana');
-      var childValue2 = node.intValue('banana');
-
-      expect(childValue, isNotNull);
-      expect(childValue2, isNotNull);
-      expect(childValue, same(childValue2));
-    });
-
-    test('IntValues created after deletion return different objects', () {
-      var childValue = node.intValue('banana')..delete();
-      var childValue2 = node.intValue('banana');
-
-      expect(childValue, isNotNull);
-      expect(childValue2, isNotNull);
-      expect(childValue, isNot(equals(childValue2)));
-    });
-
-    test('DoubleValues created twice return the same object', () {
-      var childValue = node.doubleValue('banana');
-      var childValue2 = node.doubleValue('banana');
-
-      expect(childValue, isNotNull);
-      expect(childValue2, isNotNull);
-      expect(childValue, same(childValue2));
-    });
-
-    test('DoubleValues created after deletion return different objects', () {
-      var childValue = node.doubleValue('banana')..delete();
-      var childValue2 = node.doubleValue('banana');
-
-      expect(childValue, isNotNull);
-      expect(childValue2, isNotNull);
-      expect(childValue, isNot(equals(childValue2)));
-    });
-
-    test('Changing IntValue to DoubleValue throws', () {
-      node.intValue('banana');
-      expect(() => node.doubleValue('banana'),
-          throwsA(const TypeMatcher<InspectStateError>()));
-    });
-
-    test('Changing IntValue to StringValue throws', () {
-      node.intValue('banana');
-      expect(() => node.stringValue('banana'),
-          throwsA(const TypeMatcher<InspectStateError>()));
-    });
-
-    test('Changing IntValue to ByteDataValue throws', () {
-      node.intValue('banana');
-      expect(() => node.byteDataValue('banana'),
-          throwsA(const TypeMatcher<InspectStateError>()));
-    });
-
-    test('Changing DoubleValue to IntValue throws', () {
-      node.doubleValue('banana');
-      expect(() => node.intValue('banana'),
-          throwsA(const TypeMatcher<InspectStateError>()));
-    });
-
-    test('Changing DoubleValue to StringValue throws', () {
-      node.doubleValue('banana');
-      expect(() => node.stringValue('banana'),
-          throwsA(const TypeMatcher<InspectStateError>()));
-    });
-
-    test('Changing DoubleValue to ByteDataValue throws', () {
-      node.doubleValue('banana');
-      expect(() => node.byteDataValue('banana'),
-          throwsA(const TypeMatcher<InspectStateError>()));
-    });
-
-    test('If no space, creation gives a deleted IntValue', () {
-      var tinyVmo = FakeVmo(64);
-      var writer = VmoWriter(tinyVmo);
-      var context = StartupContext.fromStartupInfo();
-      Inspect inspect = InspectImpl(context, writer);
-      var tinyRoot = inspect.root;
-      var missingValue = tinyRoot.intValue('missing');
-      expect(() => missingValue.setValue(1), returnsNormally);
-      expect(() => readInt(vmo, missingValue),
-          throwsA(const TypeMatcher<StateError>()),
-          reason: 'cannot read VMO values from a deleted property');
-    });
-
-    test('If no space, creation gives a deleted DoubleValue', () {
-      var tinyVmo = FakeVmo(64);
-      var writer = VmoWriter(tinyVmo);
-      var context = StartupContext.fromStartupInfo();
-      Inspect inspect = InspectImpl(context, writer);
-      var tinyRoot = inspect.root;
-      var missingValue = tinyRoot.doubleValue('missing');
-      expect(() => missingValue.setValue(1.0), returnsNormally);
-      expect(() => readDouble(vmo, missingValue),
-          throwsA(const TypeMatcher<StateError>()),
-          reason: 'cannot read VMO values from a deleted property');
-    });
-  });
-}
diff --git a/public/dart/fuchsia_inspect/test/util.dart b/public/dart/fuchsia_inspect/test/util.dart
index 68aa058..0a587cc 100644
--- a/public/dart/fuchsia_inspect/test/util.dart
+++ b/public/dart/fuchsia_inspect/test/util.dart
@@ -189,15 +189,15 @@
 int readNameIndex(FakeVmo vmo, Node node) =>
     Block.read(vmo, node.index).nameIndex;
 
-/// Returns the int value of [value] in [vmo].
-int readInt(FakeVmo vmo, IntValue value) =>
-    Block.read(vmo, value.index).intValue;
+/// Returns the int value of [property] in [vmo].
+int readInt(FakeVmo vmo, IntProperty property) =>
+    Block.read(vmo, property.index).intValue;
 
-/// Returns the double value of [value] in [vmo].
-double readDouble(FakeVmo vmo, DoubleValue value) =>
-    Block.read(vmo, value.index).doubleValue;
+/// Returns the double value of [property] in [vmo].
+double readDouble(FakeVmo vmo, DoubleProperty property) =>
+    Block.read(vmo, property.index).doubleValue;
 
-/// A matcher that matches ByteData values as unit8 lists.
+/// A matcher that matches ByteData properties as unit8 lists.
 Matcher equalsByteData(ByteData data) => _EqualsByteData(data);
 
 class _EqualsByteData extends Matcher {