diff --git a/constraints/constraint_consecutive.inc b/constraints/constraint_consecutive.inc
new file mode 100644
index 0000000..1c11b78
--- /dev/null
+++ b/constraints/constraint_consecutive.inc
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Password policy constraint callbacks.
+ */
+
+/****************************************************************************/
+/* Constraint API                                                           */
+/****************************************************************************/
+
+/**
+ * Description of the constraint.
+ */
+function password_policy_constraint_consecutive_description() {
+  return array('name' => t('Consecutive Characters'), 'description' => t('Password must not contain the specified number of consecutive occurrences of a character (case insensitive).'));
+}
+
+/**
+ * Error message of the constraint.
+ */
+function password_policy_constraint_consecutive_error($constraint) {
+  return t('Password must not contain @count consecutive occurrences of a character.', array('@count' => $constraint));
+}
+
+/**
+ * Password validation.
+ */
+function password_policy_constraint_consecutive_validate($password, $constraint, $account) {
+  $pattern = '/(.)\1{' . ($constraint - 1) . '}/';
+  return !preg_match($pattern, $password);
+}
+
+/**
+ * Javascript portion.
+ */
+function password_policy_constraint_consecutive_js($constraint, $account) {
+  return <<<JS
+
+    var repetitions = $constraint - 1;
+    var pattern = '(.)\\\\1{' + repetitions + '}';
+    var re = new RegExp(pattern);
+    if (re.test(value)) {
+      strength = 'low';
+      msg.push(translate.constraint_consecutive);
+    }
+JS;
+}
