diff --git a/src/bp-groups/admin/css/admin.css b/src/bp-groups/admin/css/admin.css
index c802127..d32bd31 100644
--- a/src/bp-groups/admin/css/admin.css
+++ b/src/bp-groups/admin/css/admin.css
@@ -46,6 +46,9 @@ body.toplevel_page_bp-groups table.groups th#last_active {
 	line-height: 24px;
 	color: #666;
 }
+#bp-groups-permalink {
+	margin-right: 24px;
+}
 .bp-groups-member-type {
 	position: relative;
 }
diff --git a/src/bp-groups/bp-groups-activity.php b/src/bp-groups/bp-groups-activity.php
index c29a03c..cb7c69c 100644
--- a/src/bp-groups/bp-groups-activity.php
+++ b/src/bp-groups/bp-groups-activity.php
@@ -190,6 +190,9 @@ function bp_groups_format_activity_action_group_details_updated( $action, $activ
 	} elseif ( ! empty( $changed['description']['old'] ) && ! empty( $changed['description']['new'] ) ) {
 		$action = sprintf( __( '%1$s changed the description of the group %2$s from "%3$s" to "%4$s"', 'buddypress' ), $user_link, $group_link, esc_html( $changed['description']['old'] ), esc_html( $changed['description']['new'] ) );
 
+	} elseif ( ! empty( $changed['slug']['old'] ) && ! empty( $changed['slug']['new'] ) ) {
+		$action = sprintf( __( '%1$s changed the permalink of the group %2$s.', 'buddypress' ), $user_link, $group_link );
+
 	}
 
 	/**
@@ -461,7 +464,7 @@ function bp_groups_group_details_updated_add_activity( $group_id, $old_group, $n
 		return false;
 	}
 
-	if ( ! isset( $old_group->name ) || ! isset( $old_group->description ) ) {
+	if ( ! isset( $old_group->name ) || ! isset( $old_group->slug ) || ! isset( $old_group->description ) ) {
 		return false;
 	}
 
@@ -489,6 +492,13 @@ function bp_groups_group_details_updated_add_activity( $group_id, $old_group, $n
 		);
 	}
 
+	if ( $group->slug !== $old_group->slug ) {
+		$changed['slug'] = array(
+			'old' => $old_group->slug,
+			'new' => $group->slug,
+		);
+	}
+
 	if ( $group->description !== $old_group->description ) {
 		$changed['description'] = array(
 			'old' => $old_group->description,
diff --git a/src/bp-groups/bp-groups-admin.php b/src/bp-groups/bp-groups-admin.php
index 77f13e1..c3cdac9 100644
--- a/src/bp-groups/bp-groups-admin.php
+++ b/src/bp-groups/bp-groups-admin.php
@@ -236,19 +236,29 @@ function bp_groups_admin_load() {
 		$error = 0;
 		$success_new = $error_new = $success_modified = $error_modified = array();
 
-		// Group name and description are handled with
-		// groups_edit_base_group_details().
-		if ( !groups_edit_base_group_details( $group_id, $_POST['bp-groups-name'], $_POST['bp-groups-description'], 0 ) ) {
-			$error = $group_id;
+		// Name, description and slug must not be empty.
+		if ( empty( $_POST['bp-groups-name'] ) ) {
+			$error = $error - 1;
+		}
+		if ( empty( $_POST['bp-groups-description'] ) ) {
+			$error = $error - 2;
+		}
+		if ( empty( $_POST['bp-groups-slug'] ) ) {
+			$error = $error - 4;
+		}
 
-			// Using negative integers for different error messages... eek!
-			if ( empty( $_POST['bp-groups-name'] ) && empty( $_POST['bp-groups-description'] ) ) {
-				$error = -3;
-			} elseif ( empty( $_POST['bp-groups-name'] ) ) {
-				$error = -1;
-			} elseif ( empty( $_POST['bp-groups-description'] ) ) {
-				$error = -2;
-			}
+		/*
+		 * Group name, slug, and description are handled with
+		 * groups_edit_base_group_details().
+		 */
+		if ( ! $error && ! groups_edit_base_group_details( array(
+				'group_id'       => $group_id,
+				'name'           => $_POST['bp-groups-name'],
+				'slug'           => $_POST['bp-groups-slug'],
+				'description'    => $_POST['bp-groups-description'],
+				'notify_members' => false,
+			) ) ) {
+			$error = $group_id;
 		}
 
 		// Enable discussion forum.
@@ -518,22 +528,10 @@ function bp_groups_admin_edit() {
 		}
 
 		if ( ! empty( $errors ) ) {
-			switch ( $errors ) {
-				case -1 :
-					$messages[] = __( 'Group name cannot be empty.', 'buddypress' );
-					break;
-
-				case -2 :
-					$messages[] = __( 'Group description cannot be empty.', 'buddypress' );
-					break;
-
-				case -3 :
-					$messages[] = __( 'Group name and description cannot be empty.', 'buddypress' );
-					break;
-
-				default :
-					$messages[] = __( 'An error occurred when trying to update your group details.', 'buddypress' );
-					break;
+			if ( $errors < 0 ) {
+				$messages[] = __( 'Group name, slug, and description are all required fields.', 'buddypress' );
+			} else {
+				$messages[] = __( 'An error occurred when trying to update your group details.', 'buddypress' );
 			}
 
 		} elseif ( ! empty( $updated ) ) {
@@ -612,7 +610,11 @@ function bp_groups_admin_edit() {
 										?></label>
 										<input type="text" name="bp-groups-name" id="bp-groups-name" value="<?php echo esc_attr( stripslashes( $group_name ) ) ?>" />
 										<div id="bp-groups-permalink-box">
-											<strong><?php esc_html_e( 'Permalink:', 'buddypress' ) ?></strong> <span id="sample-permalink"><?php bp_group_permalink( $group ) ?></span> <a href="<?php echo bp_group_permalink( $group ) ?>" class="button button-small" id="bp-groups-visit-group"><?php esc_html_e( 'Visit Group', 'buddypress' ) ?></a>
+											<strong><?php esc_html_e( 'Permalink:', 'buddypress' ) ?></strong>
+											<span id="bp-groups-permalink">
+												<?php bp_groups_directory_permalink(); ?> <input type="text" id="bp-groups-slug" name="bp-groups-slug" value="<?php bp_group_slug( $group ); ?>" autocomplete="off"> /
+											</span>
+											<a href="<?php echo bp_group_permalink( $group ) ?>" class="button button-small" id="bp-groups-visit-group"><?php esc_html_e( 'Visit Group', 'buddypress' ) ?></a>
 										</div>
 
 										<label for="bp-groups-description" class="screen-reader-text"><?php
diff --git a/src/bp-groups/bp-groups-functions.php b/src/bp-groups/bp-groups-functions.php
index c65af89..1f316b1 100644
--- a/src/bp-groups/bp-groups-functions.php
+++ b/src/bp-groups/bp-groups-functions.php
@@ -218,28 +218,76 @@ function groups_create_group( $args = '' ) {
  *
  * @since 1.0.0
  *
- * @param int    $group_id       ID of the group.
- * @param string $group_name     Name of the group.
- * @param string $group_desc     Description of the group.
- * @param bool   $notify_members Whether to send an email notification to group
- *                               members about changes in these details.
+ * @param array $args {
+ *     An array of optional arguments.
+ *     @type int    $group_id       ID of the group.
+ *     @type string $name           Name of the group.
+ *     @type string $slug           Slug of the group.
+ *     @type string $description    Description of the group.
+ *     @type bool   $notify_members Whether to send an email notification to group
+ *                                  members about changes in these details.
+ * }
  * @return bool True on success, false on failure.
  */
-function groups_edit_base_group_details( $group_id, $group_name, $group_desc, $notify_members ) {
+function groups_edit_base_group_details( $args = array() ) {
 
-	if ( empty( $group_name ) || empty( $group_desc ) )
+	// Backward compatibility with old method of passing arguments.
+	if ( ! is_array( $args ) || func_num_args() > 1 ) {
+		_deprecated_argument( __METHOD__, '2.9.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
+
+		$old_args_keys = array(
+			0 => 'group_id',
+			1 => 'name',
+			2 => 'description',
+			3 => 'notify_members',
+		);
+
+		$args = bp_core_parse_args_array( $old_args_keys, func_get_args() );
+	}
+
+	$r = wp_parse_args( $args, array(
+		'group_id'       => bp_get_current_group_id(),
+		'name'           => null,
+		'slug'           => null,
+		'description'    => null,
+		'notify_members' => false,
+	) );
+
+	if ( ! $r['group_id'] ) {
 		return false;
+	}
 
-	$group     = groups_get_group( $group_id );
+	$group     = groups_get_group( $r['group_id'] );
 	$old_group = clone $group;
 
-	$group->name        = $group_name;
-	$group->description = $group_desc;
+	// Group name, slug and description can never be empty. Update only if provided.
+	if ( $r['name'] ) {
+		$group->name = $r['name'];
+	}
+	if ( $r['slug']  && $r['slug'] != $group->slug ) {
+		$group->slug = groups_check_slug( $r['slug'] );
+	}
+	if ( $r['description'] ) {
+		$group->description = $r['description'];
+	}
 
-	if ( !$group->save() )
+	if ( ! $group->save() ) {
 		return false;
+	}
+
+	// Maybe update the "previous_slug" groupmeta.
+	if ( $group->slug != $old_group->slug ) {
+		/*
+		 * If the old slug exists in this group's past, delete that entry.
+		 * Recent previous_slugs are preferred when selecting the current group
+		 * from an old group slug, so we want the previous slug to be
+		 * saved "now" in the groupmeta table and don't need the old record.
+		 */
+		groups_delete_groupmeta( $group->id, 'previous_slug', $old_group->slug );
+		groups_add_groupmeta( $group->id, 'previous_slug', $old_group->slug );
+	}
 
-	if ( $notify_members ) {
+	if ( $r['notify_members'] ) {
 		groups_notification_group_updated( $group->id, $old_group );
 	}
 
@@ -252,7 +300,7 @@ function groups_edit_base_group_details( $group_id, $group_name, $group_desc, $n
 	 * @param BP_Groups_Group $old_group      Group object, before being modified.
 	 * @param bool            $notify_members Whether to send an email notification to members about the change.
 	 */
-	do_action( 'groups_details_updated', $group->id, $old_group, $notify_members );
+	do_action( 'groups_details_updated', $group->id, $old_group, $r['notify_members'] );
 
 	return true;
 }
@@ -428,6 +476,18 @@ function groups_get_id( $group_slug ) {
 	return BP_Groups_Group::group_exists( $group_slug );
 }
 
+/**
+ * Get a group ID by checking against old (not currently active) slugs.
+ *
+ * @since 2.9.0
+ *
+ * @param string $group_slug The group's slug.
+ * @return int|null The group ID on success; null on failure.
+ */
+function groups_get_id_by_previous_slug( $group_slug ) {
+	return BP_Groups_Group::get_id_by_previous_slug( $group_slug );
+}
+
 /** User Actions **************************************************************/
 
 /**
diff --git a/src/bp-groups/bp-groups-notifications.php b/src/bp-groups/bp-groups-notifications.php
index fc8a052..5bf44fd 100644
--- a/src/bp-groups/bp-groups-notifications.php
+++ b/src/bp-groups/bp-groups-notifications.php
@@ -44,6 +44,14 @@ function groups_notification_group_updated( $group_id = 0, $old_group = null ) {
 				esc_html( $group->description )
 			);
 		}
+
+		if ( $group->slug !== $old_group->slug ) {
+			$changed[] = sprintf(
+				_x( '* Permalink changed from "%s" to "%s".', 'Group update email text', 'buddypress' ),
+				esc_url( bp_get_group_permalink( $old_group ) ),
+				esc_url( bp_get_group_permalink( $group ) )
+			);
+		}
 	}
 
 	/**
diff --git a/src/bp-groups/bp-groups-screens.php b/src/bp-groups/bp-groups-screens.php
index 17e139b..b02419f 100644
--- a/src/bp-groups/bp-groups-screens.php
+++ b/src/bp-groups/bp-groups-screens.php
@@ -839,7 +839,16 @@ function groups_screen_group_admin_edit_details() {
 
 			$group_notify_members = isset( $_POST['group-notify-members'] ) ? (int) $_POST['group-notify-members'] : 0;
 
-			if ( !groups_edit_base_group_details( $_POST['group-id'], $_POST['group-name'], $_POST['group-desc'], $group_notify_members ) ) {
+			// Name and description are required and may not be empty.
+			if ( empty( $_POST['group-name'] ) || empty( $_POST['group-desc'] ) ) {
+				bp_core_add_message( __( 'Groups must have a name and a description. Please try again.', 'buddypress' ), 'error' );
+			} elseif ( ! groups_edit_base_group_details( array(
+				'group_id'       => $_POST['group-id'],
+				'name'           => $_POST['group-name'],
+				'slug'           => null, // @TODO: Add to settings pane? If yes, editable by site admin only, or allow group admins to do this?
+				'description'    => $_POST['group-desc'],
+				'notify_members' => $group_notify_members,
+			) ) ) {
 				bp_core_add_message( __( 'There was an error updating group details. Please try again.', 'buddypress' ), 'error' );
 			} else {
 				bp_core_add_message( __( 'Group details were successfully updated.', 'buddypress' ) );
diff --git a/src/bp-groups/classes/class-bp-groups-component.php b/src/bp-groups/classes/class-bp-groups-component.php
index 8515a5b..e271ec0 100644
--- a/src/bp-groups/classes/class-bp-groups-component.php
+++ b/src/bp-groups/classes/class-bp-groups-component.php
@@ -196,8 +196,10 @@ class BP_Groups_Component extends BP_Component {
 		/* Single Group Globals **********************************************/
 
 		// Are we viewing a single group?
-		if ( bp_is_groups_component() && $group_id = BP_Groups_Group::group_exists( bp_current_action() ) ) {
-
+		if ( bp_is_groups_component()
+			&& ( ( $group_id = BP_Groups_Group::group_exists( bp_current_action() ) )
+				|| ( $group_id = BP_Groups_Group::get_id_by_previous_slug( bp_current_action() ) ) )
+			) {
 			$bp->is_single_item  = true;
 
 			/**
diff --git a/src/bp-groups/classes/class-bp-groups-group.php b/src/bp-groups/classes/class-bp-groups-group.php
index bd897d8..029093e 100644
--- a/src/bp-groups/classes/class-bp-groups-group.php
+++ b/src/bp-groups/classes/class-bp-groups-group.php
@@ -645,6 +645,46 @@ class BP_Groups_Group {
 	}
 
 	/**
+	 * Get whether a group exists for an old slug.
+	 *
+	 * @since 2.9.0
+	 *
+	 * @param string      $slug       Slug to check.
+	 *
+	 * @return int|null|false Group ID if found; null if not; false if missing parameters.
+	 */
+	public static function get_id_by_previous_slug( $slug ) {
+		global $wpdb;
+
+		if ( empty( $slug ) ) {
+			return false;
+		}
+
+		$args = array(
+			'meta_query'         => array(
+				array(
+					'key'   => 'previous_slug',
+					'value' => $slug
+				),
+			),
+			'orderby'           => 'meta_id',
+			'order'              => 'DESC',
+			'per_page'           => 1,
+			'page'               => 1,
+			'update_meta_cache'  => false,
+			'show_hidden'        => true,
+		);
+		$groups = BP_Groups_Group::get( $args );
+
+		$group_id = null;
+		if ( $groups['groups'] ) {
+			$group_id = current( $groups['groups'] )->id;
+		}
+
+		return $group_id;
+	}
+
+	/**
 	 * Get IDs of users with outstanding invites to a given group from a specified user.
 	 *
 	 * @since 1.6.0
@@ -1113,6 +1153,11 @@ class BP_Groups_Group {
 			$where_conditions['last_activity'] = "gm_last_activity.meta_key = 'last_activity'";
 		}
 
+		// If Meta ID is the requested order, and there's no meta query, fall back to the default.
+		if ( 'meta_id' === $orderby && empty( $meta_query_sql['join'] ) ) {
+			$orderby = 'date_created';
+		}
+
 		// Sanitize 'order'.
 		$order = bp_esc_sql_order( $order );
 
@@ -1415,6 +1460,10 @@ class BP_Groups_Group {
 			case 'random' :
 				$order_by_term = 'rand()';
 				break;
+
+			case 'meta_id' :
+				$order_by_term = buddypress()->groups->table_name_groupmeta . '.id';
+				break;
 		}
 
 		return $order_by_term;
diff --git a/tests/phpunit/testcases/groups/activity.php b/tests/phpunit/testcases/groups/activity.php
index 1946326..bfb4087 100644
--- a/tests/phpunit/testcases/groups/activity.php
+++ b/tests/phpunit/testcases/groups/activity.php
@@ -55,7 +55,13 @@ class BP_Tests_Groups_Activity extends BP_UnitTestCase {
 	 */
 	public function test_bp_groups_format_activity_action_group_details_updated_with_no_change() {
 		$group = $this->factory->group->create_and_get();
-		groups_edit_base_group_details( $group->id, $group->name, $group->description, true );
+		groups_edit_base_group_details( array(
+				'group_id'       => $group->id,
+				'name'           => $group->name,
+				'slug'           => $group->slug,
+				'description'    => $group->description,
+				'notify_members' => true,
+		) );
 
 		$a = bp_activity_get( array(
 			'component' => buddypress()->groups->id,
@@ -72,7 +78,13 @@ class BP_Tests_Groups_Activity extends BP_UnitTestCase {
 	 */
 	public function test_bp_groups_format_activity_action_group_details_updated_with_notify_members_false() {
 		$group = $this->factory->group->create_and_get();
-		groups_edit_base_group_details( $group->id, 'Foo', $group->description, false );
+		groups_edit_base_group_details( array(
+			'group_id'       => $group->id,
+			'name'           => 'Foo',
+			'slug'           => $group->slug,
+			'description'    => $group->description,
+			'notify_members' => false,
+		) );
 
 		$a = bp_activity_get( array(
 			'component' => buddypress()->groups->id,
@@ -93,7 +105,13 @@ class BP_Tests_Groups_Activity extends BP_UnitTestCase {
 		$this->set_current_user( $u );
 
 		$group = $this->factory->group->create_and_get();
-		groups_edit_base_group_details( $group->id, 'Foo', $group->description, true );
+		groups_edit_base_group_details( array(
+			'group_id'       => $group->id,
+			'name'           => 'Foo',
+			'slug'           => $group->slug,
+			'description'    => $group->description,
+			'notify_members' => true,
+		) );
 
 		$a = bp_activity_get( array(
 			'component' => buddypress()->groups->id,
@@ -119,7 +137,13 @@ class BP_Tests_Groups_Activity extends BP_UnitTestCase {
 		$this->set_current_user( $u );
 
 		$group = $this->factory->group->create_and_get();
-		groups_edit_base_group_details( $group->id, $group->name, 'Bar', true );
+		groups_edit_base_group_details( array(
+			'group_id'       => $group->id,
+			'name'           => $group->name,
+			'slug'           => $group->slug,
+			'description'    => 'Bar',
+			'notify_members' => true,
+		) );
 
 		$a = bp_activity_get( array(
 			'component' => buddypress()->groups->id,
@@ -139,13 +163,52 @@ class BP_Tests_Groups_Activity extends BP_UnitTestCase {
 	 * @group activity_action
 	 * @group bp_groups_format_activity_action_group_details_updated
 	 */
+	public function test_bp_groups_format_activity_action_group_details_updated_with_updated_slug() {
+		$old_user = get_current_user_id();
+		$u = $this->factory->user->create();
+		$this->set_current_user( $u );
+
+		$group = $this->factory->group->create_and_get();
+		groups_edit_base_group_details( array(
+			'group_id'       => $group->id,
+			'name'           => $group->name,
+			'slug'           => 'flaxen',
+			'description'    => $group->description,
+			'notify_members' => true,
+		) );
+		$new_group_details = groups_get_group( $group->id );
+
+		$a = bp_activity_get( array(
+			'component' => buddypress()->groups->id,
+			'action' => 'group_details_updated',
+			'item_id' => $group->id,
+		) );
+
+		$this->assertNotEmpty( $a['activities'] );
+
+		$expected = sprintf( __( '%s changed the permalink of the group %s.', 'buddypress' ), bp_core_get_userlink( $u ),  '<a href="' . bp_get_group_permalink( $new_group_details ) . '">' . $group->name . '</a>' );
+		$this->assertSame( $expected, $a['activities'][0]->action );
+
+		$this->set_current_user( $old_user );
+	}
+
+	/**
+	 * @group activity_action
+	 * @group bp_groups_format_activity_action_group_details_updated
+	 */
 	public function test_bp_groups_format_activity_action_group_details_updated_with_updated_name_and_description() {
 		$old_user = get_current_user_id();
 		$u = $this->factory->user->create();
 		$this->set_current_user( $u );
 
 		$group = $this->factory->group->create_and_get();
-		groups_edit_base_group_details( $group->id, 'Foo', 'Bar', true );
+		groups_edit_base_group_details( array(
+			'group_id'       => $group->id,
+			'name'           => 'Foo',
+			'slug'           => $group->slug,
+			'description'    => 'Bar',
+			'notify_members' => true,
+		) );
 
 		$a = bp_activity_get( array(
 			'component' => buddypress()->groups->id,
diff --git a/tests/phpunit/testcases/groups/class-bp-groups-group.php b/tests/phpunit/testcases/groups/class-bp-groups-group.php
index 0fcc1d5..5178354 100644
--- a/tests/phpunit/testcases/groups/class-bp-groups-group.php
+++ b/tests/phpunit/testcases/groups/class-bp-groups-group.php
@@ -956,6 +956,58 @@ class BP_Tests_BP_Groups_Group_TestCases extends BP_UnitTestCase {
 		$this->assertEquals( _BP_Groups_Group::_convert_orderby_to_order_by_term( 'date_created' ), _BP_Groups_Group::_convert_orderby_to_order_by_term( 'I am a bad boy' ) );
 	}
 
+	/**
+	 * @group groups_get_orderby_meta_id
+	 */
+	public function test_get_orderby_meta_id() {
+		$g1 = $this->factory->group->create();
+		$g2 = $this->factory->group->create();
+		$g3 = $this->factory->group->create();
+
+		groups_update_groupmeta( $g2, 'orderup', 'sammy' );
+		groups_update_groupmeta( $g1, 'orderup', 'sammy' );
+
+		$args = array(
+			'meta_query'         => array(
+				array(
+					'key'   => 'orderup',
+					'value' => 'sammy'
+				),
+			),
+			'orderby'           => 'meta_id',
+			'order'             => 'ASC',
+		);
+		$groups = BP_Groups_Group::get( $args );
+
+		$found = wp_list_pluck( $groups['groups'], 'id' );
+		$this->assertEquals( array( $g2, $g1 ), $found );
+	}
+
+	/**
+	 * @group groups_get_orderby_meta_id
+	 */
+	public function test_get_orderby_meta_id_invalid_fallback_to_date_created() {
+		$time = time();
+		$g1 = $this->factory->group->create( array(
+			'date_created' => gmdate( 'Y-m-d H:i:s', $time - 10000 ),
+		) );
+		$g2 = $this->factory->group->create( array(
+			'date_created' => gmdate( 'Y-m-d H:i:s', $time - 1000 ),
+		) );
+		$g3 = $this->factory->group->create( array(
+			'date_created' => gmdate( 'Y-m-d H:i:s', $time - 100 ),
+		) );
+
+		$args = array(
+			'orderby'           => 'meta_id',
+		);
+		$groups = BP_Groups_Group::get( $args );
+
+		// Orderby meta_id should be ignored if no meta query is present.
+		$found = wp_list_pluck( $groups['groups'], 'id' );
+		$this->assertEquals( array( $g3, $g2, $g1 ), $found );
+	}
+
 	public function test_filter_user_groups_normal_search() {
 		$g1 = $this->factory->group->create( array(
 			'name' => 'Cool Group',
diff --git a/tests/phpunit/testcases/groups/functions.php b/tests/phpunit/testcases/groups/functions.php
index 4a4c8ba..e08ea7c 100644
--- a/tests/phpunit/testcases/groups/functions.php
+++ b/tests/phpunit/testcases/groups/functions.php
@@ -711,4 +711,142 @@ Bar!';
 
 		$this->assertEquals( $g1, $group->id );
 	}
+
+	/**
+	 * @expectedDeprecated groups_edit_base_group_details
+	 * @group groups_edit_base_group_details
+	 */
+	public function test_groups_edit_base_group_details_test_backcompat_arguments() {
+		$g1 = $this->factory->group->create();
+		$name = 'Great Scott';
+		$description = 'A must-see in time for the holidays!';
+		groups_edit_base_group_details( $g1, $name, $description, false );
+
+		$expected = array(
+			'id'          => $g1,
+			'name'        => $name,
+			'description' => $description
+		);
+		$updated_group_object = groups_get_group( $g1 );
+		$updated = array(
+			'id'          => $updated_group_object->id,
+			'name'        => $updated_group_object->name,
+			'description' => $updated_group_object->description
+		);
+
+		$this->assertEqualSets( $expected, $updated );
+	}
+
+	/**
+	 * @group groups_edit_base_group_details
+	 */
+	public function test_groups_edit_base_group_details_test_new_arguments() {
+		$g1 = $this->factory->group->create();
+		$name = 'Great Scott';
+		$slug = 'what-about-it';
+		$description = 'A must-see in time for the holidays!';
+		groups_edit_base_group_details( array(
+				'group_id'       => $g1,
+				'name'           => $name,
+				'slug'           => $slug,
+				'description'    => $description,
+				'notify_members' => false,
+		) );
+
+		$expected = array(
+			'id'          => $g1,
+			'slug'        => $slug,
+			'name'        => $name,
+			'description' => $description
+		);
+		$updated_group_object = groups_get_group( $g1 );
+		$updated = array(
+			'id'          => $updated_group_object->id,
+			'slug'        => $updated_group_object->slug,
+			'name'        => $updated_group_object->name,
+			'description' => $updated_group_object->description
+		);
+
+		$this->assertEqualSets( $expected, $updated );
+	}
+
+	/**
+	 * @group groups_edit_base_group_details
+	 */
+	public function test_groups_edit_base_group_details_avoid_slug_collisions() {
+		$slug = 'circe';
+		$g1 = $this->factory->group->create( array( 'slug' => $slug ) );
+		$g2 = $this->factory->group->create( array( 'slug' => 'loom' ) );
+
+		// Attempt to use a duplicate slug.
+		groups_edit_base_group_details( array(
+				'group_id'       => $g2,
+				'slug'           => $slug,
+		) );
+
+		$updated_group_object = groups_get_group( $g2 );
+
+		$this->assertNotEquals( $slug, $updated_group_object->slug );
+	}
+
+	/**
+	 * @group groups_edit_base_group_details
+	 */
+	public function test_groups_edit_base_group_details_slug_no_change() {
+		$slug = 'circe';
+		$g1 = $this->factory->group->create( array( 'slug' => $slug ) );
+
+		// Make sure the slug doesn't get incremented when there's no change.
+		groups_edit_base_group_details( array(
+				'group_id'       => $g1,
+				'slug'           => $slug,
+		) );
+
+		$updated_group_object = groups_get_group( $g1 );
+
+		$this->assertEquals( $slug, $updated_group_object->slug );
+	}
+
+	/**
+	 * @group groups_edit_base_group_details
+	 */
+	public function test_groups_edit_base_group_details_slug_null_value() {
+		$slug = 'circe';
+		$g1 = $this->factory->group->create( array( 'slug' => $slug ) );
+
+		// Make sure the slug doesn't get changed when null is passed.
+		groups_edit_base_group_details( array(
+				'group_id'       => $g1,
+				'slug'           => null,
+		) );
+
+		$updated_group_object = groups_get_group( $g1 );
+
+		$this->assertEquals( $slug, $updated_group_object->slug );
+	}
+
+	/**
+	 * @group groups_get_id_by_previous_slug
+	 */
+	public function test_groups_get_id_by_previous_slug() {
+		$slug = 'circe';
+		$g1 = $this->factory->group->create( array( 'slug' => $slug ) );
+		$g2 = $this->factory->group->create( array( 'slug' => 'loom' ) );
+
+		groups_edit_base_group_details( array(
+			'group_id'       => $g1,
+			'slug'           => 'newslug',
+		) );
+
+		// Function should return the group ID as an integer.
+		$this->assertSame( $g1, groups_get_id_by_previous_slug( $slug ) );
+	}
+
+	/**
+	 * @group groups_get_id_by_previous_slug
+	 */
+	public function test_groups_get_id_by_previous_slug_null_no_results() {
+		$this->assertNull( groups_get_id_by_previous_slug( 'woohoo' ) );
+	}
+
 }
diff --git a/tests/phpunit/testcases/routing/groups.php b/tests/phpunit/testcases/routing/groups.php
index f4cbb5f..b89c39f 100644
--- a/tests/phpunit/testcases/routing/groups.php
+++ b/tests/phpunit/testcases/routing/groups.php
@@ -63,4 +63,65 @@ class BP_Tests_Routing_Groups extends BP_UnitTestCase {
 		$this->go_to( bp_get_members_directory_permalink() . 'type/foo/' );
 		$this->assertTrue( is_404() );
 	}
+
+	/**
+	 * @group group_previous_slug
+	 */
+	public function test_group_previous_slug_current_slug_should_resolve() {
+		$g1 = $this->factory->group->create( array(
+			'slug' => 'george',
+		) );
+		groups_edit_base_group_details( array(
+			'group_id' => $g1,
+			'slug'     => 'ralph',
+		) );
+
+		$this->go_to( bp_get_groups_directory_permalink() . 'ralph' );
+
+		$this->assertEquals( $g1, bp_get_current_group_id() );
+	}
+
+	/**
+	 * @group group_previous_slug
+	 */
+	public function test_group_previous_slug_should_resolve() {
+		$g1 = $this->factory->group->create( array(
+			'slug' => 'george',
+		) );
+
+		groups_edit_base_group_details( array(
+			'group_id'       => $g1,
+			'slug'           => 'sam!',
+			'notify_members' => false,
+		) );
+		$this->go_to( bp_get_groups_directory_permalink() . 'george' );
+
+		$this->assertEquals( $g1, bp_get_current_group_id() );
+	}
+
+	/**
+	 * @group group_previous_slug
+	 */
+	public function test_group_previous_slug_most_recent_takes_precedence() {
+		$g1 = $this->factory->group->create( array(
+			'slug' => 'george',
+		) );
+		groups_edit_base_group_details( array(
+			'group_id'       => $g1,
+			'slug'           => 'ralph',
+			'notify_members' => false,
+		) );
+		$g2 = $this->factory->group->create( array(
+			'slug' => 'george',
+		) );
+		groups_edit_base_group_details( array(
+			'group_id'       => $g2,
+			'slug'           => 'sam',
+			'notify_members' => false,
+		) );
+
+		$this->go_to( bp_get_groups_directory_permalink() . 'george' );
+		$this->assertEquals( $g2, bp_get_current_group_id() );
+	}
+
 }
