allow params with events and views
diff --git a/lib/src/usage_impl.dart b/lib/src/usage_impl.dart
index 563f14e..3b972b4 100644
--- a/lib/src/usage_impl.dart
+++ b/lib/src/usage_impl.dart
@@ -123,7 +123,7 @@
     properties['enabled'] = value;
   }
 
-  Future sendScreenView(String viewName, { Map<String, String> parameters }) {
+  Future sendScreenView(String viewName, {Map<String, String> parameters}) {
     Map<String, dynamic> args = {'cd': viewName};
     if (parameters != null) {
       args.addAll(parameters);
@@ -131,10 +131,14 @@
     return _sendPayload('screenview', args);
   }
 
-  Future sendEvent(String category, String action, {String label, int value}) {
+  Future sendEvent(String category, String action, {String label, int value,
+      Map<String, String> parameters}) {
     Map<String, dynamic> args = {'ec': category, 'ea': action};
     if (label != null) args['el'] = label;
     if (value != null) args['ev'] = value;
+    if (parameters != null) {
+      args.addAll(parameters);
+    }
     return _sendPayload('event', args);
   }
 
diff --git a/lib/usage.dart b/lib/usage.dart
index 8e5a808..c5d2ed8 100644
--- a/lib/usage.dart
+++ b/lib/usage.dart
@@ -81,13 +81,17 @@
    * [parameters] can be any analytics key/value pair. Useful
    * for custom dimensions, etc.
    */
-  Future sendScreenView(String viewName, { Map<String, String> parameters });
+  Future sendScreenView(String viewName, {Map<String, String> parameters});
 
   /**
    * Sends an Event hit to Google Analytics. [label] specifies the event label.
    * [value] specifies the event value. Values must be non-negative.
+   * 
+   * [parameters] can be any analytics key/value pair. Useful
+   * for custom dimensions, etc.
    */
-  Future sendEvent(String category, String action, {String label, int value});
+  Future sendEvent(String category, String action, {String label, int value,
+      Map<String, String> parameters});
 
   /**
    * Sends a Social hit to Google Analytics. [network] specifies the social
@@ -239,21 +243,25 @@
   @override
   String get clientId => '00000000-0000-4000-0000-000000000000';
 
-  Future sendScreenView(String viewName, { Map<String, String> parameters }) {
+  Future sendScreenView(String viewName, {Map<String, String> parameters}) {
     if (parameters == null) {
       parameters = <String, String>{};
     }
     parameters['viewName'] = viewName;
-    _log('screenView', parameters);
+    return _log('screenView', parameters);
   }
 
-  Future sendEvent(String category, String action, {String label, int value}) {
+  Future sendEvent(String category, String action, {String label, int value,
+      Map<String, String> parameters}) {
+    if (parameters == null) {
+      parameters = <String, String>{};
+    }
     return _log('event', {
       'category': category,
       'action': action,
       'label': label,
       'value': value
-    });
+    }..addAll(parameters));
   }
 
   Future sendSocial(String network, String action, String target) =>
diff --git a/readme.md b/readme.md
index b348773..c9a92c7 100644
--- a/readme.md
+++ b/readme.md
@@ -110,6 +110,12 @@
 For more information, please see the Google Analytics Measurement Protocol
 [Policy](https://developers.google.com/analytics/devguides/collection/protocol/policy).
 
+## Contributing
+
+Run the tests with `pub run test`.
+
+Analyze the code with `dartanalyzer lib/*.dart test/*.dart`.
+
 ## Issues and bugs
 
 Please file reports on the
diff --git a/test/hit_types_test.dart b/test/hit_types_test.dart
index 7aab2d3..e8bf241 100644
--- a/test/hit_types_test.dart
+++ b/test/hit_types_test.dart
@@ -21,6 +21,13 @@
       expect(mock.mockProperties['clientId'], isNotNull);
       expect(mock.mockPostHandler.sentValues, isNot(isEmpty));
     });
+    test('with parameters', () {
+      AnalyticsImplMock mock = createMock();
+      mock.sendScreenView('withParams', parameters: {'cd1': 'foo'});
+      expect(mock.mockProperties['clientId'], isNotNull);
+      expect(mock.mockPostHandler.sentValues, isNot(isEmpty));
+      has(mock.last, 'cd1');
+    });
   });
 
   group('event', () {
@@ -33,6 +40,16 @@
       has(mock.last, 'ea');
     });
 
+    test('with parameters', () {
+      AnalyticsImplMock mock = createMock();
+      mock.sendEvent('withParams', 'save', parameters: {'cd1': 'foo'});
+      expect(mock.mockPostHandler.sentValues, isNot(isEmpty));
+      was(mock.last, 'event');
+      has(mock.last, 'ec');
+      has(mock.last, 'ea');
+      has(mock.last, 'cd1');
+    });
+
     test('optional args', () {
       AnalyticsImplMock mock = createMock();
       mock.sendEvent('files', 'save', label: 'File Save', value: 23);
diff --git a/test/usage_test.dart b/test/usage_test.dart
index 6137a29..9d2a4e0 100644
--- a/test/usage_test.dart
+++ b/test/usage_test.dart
@@ -16,6 +16,7 @@
       mock.sendScreenView('main');
       mock.sendScreenView('withParameters', parameters: {'cd1': 'custom'});
       mock.sendEvent('files', 'save');
+      mock.sendEvent('eventWithParameters', 'save', parameters: {'cd1': 'custom'});
       mock.sendSocial('g+', 'plus', 'userid');
       mock.sendTiming('compile', 123);
       mock.startTimer('compile').finish();