diff --git a/res/values/config.xml b/res/values/config.xml
index 9f8cc81..a296254 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -317,4 +317,8 @@
     <!-- The package names which can request thermal mitigation. -->
     <string-array name="thermal_mitigation_allowlisted_packages" translatable="false">
     </string-array>
+
+    <!-- The package name of the app which hosts the
+         {@link TelecomManager#ACTION_SHOW_CALL_SETTINGS} settings screen. -->
+    <string name="call_settings_package_name">com.android.phone</string>
 </resources>
diff --git a/src/com/android/phone/ImsRcsController.java b/src/com/android/phone/ImsRcsController.java
index bd6ba6b..31059e7 100644
--- a/src/com/android/phone/ImsRcsController.java
+++ b/src/com/android/phone/ImsRcsController.java
@@ -17,7 +17,6 @@
 package com.android.phone;
 
 import android.Manifest;
-import android.app.ActivityManager;
 import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Binder;
@@ -276,9 +275,6 @@
             List<Uri> contactNumbers, IRcsUceControllerCallback c) {
         enforceAccessUserCapabilityExchangePermission("requestCapabilities");
         enforceReadContactsPermission("requestCapabilities");
-        if (!isCallingProcessInForeground(Binder.getCallingUid())) {
-            throw new SecurityException("The caller is not in the foreground.");
-        }
         final long token = Binder.clearCallingIdentity();
         try {
             UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
@@ -300,9 +296,6 @@
             String callingFeatureId, Uri contactNumber, IRcsUceControllerCallback c) {
         enforceAccessUserCapabilityExchangePermission("requestAvailability");
         enforceReadContactsPermission("requestAvailability");
-        if (!isCallingProcessInForeground(Binder.getCallingUid())) {
-            throw new SecurityException("The caller is not in the foreground.");
-        }
         final long token = Binder.clearCallingIdentity();
         try {
             UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
@@ -668,19 +661,6 @@
     }
 
     /**
-     * Check if the calling process is in the foreground.
-     *
-     * @return true if the caller is in the foreground.
-     */
-    private boolean isCallingProcessInForeground(int uid) {
-        ActivityManager am = mApp.getSystemService(ActivityManager.class);
-        boolean isCallingProcessForeground = am != null
-                && am.getUidImportance(uid)
-                        == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
-        return isCallingProcessForeground;
-    }
-
-    /**
      * Retrieve ImsPhone instance.
      *
      * @param subId the subscription ID
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 4fb61f0..fb45f4c 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -565,9 +565,10 @@
                     .setChannelId(NotificationChannelController.CHANNEL_ID_CALL_FORWARD)
                     .setOnlyAlertOnce(isRefresh);
 
-            Intent intent = new Intent(Intent.ACTION_MAIN);
+            Intent intent = new Intent(TelecomManager.ACTION_SHOW_CALL_SETTINGS);
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            intent.setClassName("com.android.phone", "com.android.phone.CallFeaturesSetting");
+            intent.setPackage(mContext.getResources().getString(
+                    R.string.call_settings_package_name));
             SubscriptionInfoHelper.addExtrasToIntent(
                     intent, mSubscriptionManager.getActiveSubscriptionInfo(subId));
             builder.setContentIntent(PendingIntent.getActivity(mContext, subId /* requestCode */,
diff --git a/src/com/android/services/telephony/rcs/MessageTransportWrapper.java b/src/com/android/services/telephony/rcs/MessageTransportWrapper.java
index c4edf49..0d4265a 100644
--- a/src/com/android/services/telephony/rcs/MessageTransportWrapper.java
+++ b/src/com/android/services/telephony/rcs/MessageTransportWrapper.java
@@ -38,7 +38,6 @@
 import com.android.services.telephony.rcs.validator.ValidationResult;
 
 import java.io.PrintWriter;
-import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ScheduledExecutorService;
@@ -130,8 +129,8 @@
                             mSipSessionTracker.verifyOutgoingMessage(sipMessage, configVersion);
                     result = maybeOverrideValidationForTesting(result);
                     if (!result.isValidated) {
-                        notifyDelegateSendError("Outgoing messages restricted", sipMessage,
-                                result.restrictedReason);
+                        notifyDelegateSendError("Outgoing - " + result.logReason,
+                                sipMessage, result.restrictedReason);
                         return;
                     }
                     try {
@@ -186,7 +185,7 @@
                 mExecutor.execute(() -> {
                     ValidationResult result = mSipSessionTracker.verifyIncomingMessage(message);
                     if (!result.isValidated) {
-                        notifyAppReceiveError("Incoming messages restricted", message,
+                        notifyAppReceiveError("Incoming - " + result.logReason, message,
                                 result.restrictedReason);
                         return;
                     }
@@ -304,7 +303,7 @@
 
     @Override
     public void onRegistrationStateChanged(DelegateRegistrationState registrationState) {
-        mSipSessionTracker.onRegistrationStateChanged((List<String> callIds) -> {
+        mSipSessionTracker.onRegistrationStateChanged((callIds) -> {
             for (String id : callIds)  {
                 cleanupSessionInternal(id);
             }
@@ -371,13 +370,14 @@
     }
 
     /**
-     * Gradually close all SIP Dialogs by:
+     * Gradually close all SIP Sessions by:
      * 1) denying all new outgoing SIP Dialog requests with the reason specified and
-     * 2) only allowing existing SIP Dialogs to continue.
+     * 2) only allowing existing SIP Sessions to continue.
      * <p>
-     * This will allow traffic to continue on existing SIP Dialogs until a BYE is sent and the
-     * SIP Dialogs are closed or a timeout is hit and {@link SipDelegate#closeDialog(String)} is
-     * forcefully called on all open SIP Dialogs.
+     * This will allow traffic to continue on existing SIP Sessions until a BYE is sent and the
+     * corresponding SIP Dialogs are closed or a timeout is hit and
+     * {@link SipDelegate#cleanupSession(String)} (String)} is forcefully called on all open SIP
+     * sessions.
      * <p>
      * Any outgoing out-of-dialog traffic on this transport will be denied with the provided reason.
      * <p>
@@ -408,19 +408,19 @@
     }
 
     /**
-     * Close all ongoing SIP Dialogs immediately and respond to any incoming/outgoing messages with
+     * Close all ongoing SIP sessions immediately and respond to any incoming/outgoing messages with
      * the provided reason.
      * @param closedReason The failure reason to provide to incoming/outgoing SIP messages
      *         if an attempt is made to send/receive a message after this method is called.
      */
     public void close(int closedReason) {
-        List<String> openDialogs = mSipSessionTracker.closeSessionsForcefully(closedReason);
-        logi("close: closedReason=" + closedReason + "open call IDs:{" + openDialogs + "}");
-        closeTransport(openDialogs);
+        Set<String> openSessions = mSipSessionTracker.closeSessions(closedReason);
+        logi("close: closedReason=" + closedReason + "open call IDs:{" + openSessions + "}");
+        closeTransport(openSessions);
     }
 
     // Clean up all state related to the existing SipDelegate immediately.
-    private void closeTransport(List<String> openCallIds) {
+    private void closeTransport(Set<String> openCallIds) {
         for (String id : openCallIds) {
             cleanupSessionInternal(id);
         }
@@ -428,20 +428,19 @@
     }
 
     private void cleanupSessionInternal(String callId) {
-        logi("cleanupSessionInternal: closing session with callId: " + callId);
-        mSipSessionTracker.onSipSessionCleanup(callId);
-
-        if (mSipDelegate == null) {
-            logw("cleanupSession called when SipDelegate is not associated, callId: "
-                    + callId);
-            return;
-        }
+        logi("cleanupSessionInternal: clean up session with callId: " + callId);
         try {
-            mSipDelegate.cleanupSession(callId);
+            if (mSipDelegate == null) {
+                logw("cleanupSessionInternal: SipDelegate is not associated, callId: " + callId);
+            } else {
+                // This will close the transport, so call cleanup on ImsService first.
+                mSipDelegate.cleanupSession(callId);
+            }
         } catch (RemoteException e) {
-            logw("SipDelegate not available when cleanupSession was called "
+            logw("cleanupSessionInternal: remote not available when cleanupSession was called "
                     + "for call id: " + callId);
         }
+        mSipSessionTracker.onSipSessionCleanup(callId);
     }
 
     private ValidationResult maybeOverrideValidationForTesting(ValidationResult result) {
@@ -454,7 +453,8 @@
         } else if (result.isValidated) {
             // if override is set to false and the original result was validated, return a new
             // restricted result with UNKNOWN reason.
-            return new ValidationResult(SipDelegateManager.MESSAGE_FAILURE_REASON_UNKNOWN);
+            return new ValidationResult(SipDelegateManager.MESSAGE_FAILURE_REASON_UNKNOWN,
+                    "validation failed due to a testing override being set");
         }
         return result;
     }
diff --git a/src/com/android/services/telephony/rcs/SipDelegateController.java b/src/com/android/services/telephony/rcs/SipDelegateController.java
index c2e5e67..30edca1 100644
--- a/src/com/android/services/telephony/rcs/SipDelegateController.java
+++ b/src/com/android/services/telephony/rcs/SipDelegateController.java
@@ -269,7 +269,7 @@
                         DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING,
                         destroyReason);
         return pendingOperationComplete.thenApplyAsync((reasonFromDelegate) -> {
-            logi("destroy, operation complete, notifying trackers, reason" + reasonFromDelegate);
+            logi("destroy, operation complete, notifying trackers, reason " + reasonFromDelegate);
             mDelegateStateTracker.sipDelegateDestroyed(reasonFromDelegate);
             return reasonFromDelegate;
         }, mExecutorService);
diff --git a/src/com/android/services/telephony/rcs/SipDialog.java b/src/com/android/services/telephony/rcs/SipDialog.java
new file mode 100644
index 0000000..508d515
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/SipDialog.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.rcs;
+
+import android.telephony.ims.SipMessage;
+import android.text.TextUtils;
+
+import com.android.internal.telephony.SipMessageParsingUtils;
+
+import java.time.Instant;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Track the state of a SIP Dialog.
+ * <p>
+ * SIP Dialogs follow the following initialization flow:
+ * <pre>
+ * (INVITE) ---> EARLY -(2XX)-> CONFIRMED -(BYE)-----> CLOSED
+ *          ^     |   \                           ^
+ *          |--(1XX)   -(3XX-7XX) ----------------|
+ * </pre>
+ * <p> A special note on forking INVITE requests:
+ * During the EARLY phase, a 1XX or 2XX response can carry a To header tag param. This To header
+ * tag param will be set once a INVITE reaches the remote and responds. If the proxy has multiple
+ * endpoints available for the same contact, the INVITE may fork and multiple responses may be
+ * received for the same INVITE request, each with a different To header tag parameter (but the
+ * same call-id). This will generate another SIP dialog within the same SIP session.
+ */
+public class SipDialog {
+
+    /**
+     * The device has sent out a dialog starting event and is awaiting a confirmation.
+     */
+    public static final int STATE_EARLY = 0;
+
+    /**
+     * The device has received a 2XX response to the early dialog.
+     */
+    public static final int STATE_CONFIRMED = 1;
+
+    /**
+     * The device has received either a 3XX+ response to a pending dialog request or a BYE
+     * request has been sent on this dialog.
+     */
+    public static final int STATE_CLOSED = 2;
+
+    private final String mBranchId;
+    private final String mCallId;
+    private final String mFromTag;
+    private final Set<String> mAcceptContactFeatureTags;
+    private String mToTag;
+    private int mState = STATE_EARLY;
+    private Instant mLastInteraction;
+
+    /**
+     * @return A SipDialog instance representing the SIP request.
+     */
+    public static SipDialog fromSipMessage(SipMessage m) {
+        if (!SipMessageParsingUtils.isSipRequest(m.getStartLine())) return null;
+        String fromTag = SipMessageParsingUtils.getFromTag(m.getHeaderSection());
+        Set<String> acceptContactTags = SipMessageParsingUtils.getAcceptContactFeatureTags(
+                m.getHeaderSection());
+        return new SipDialog(m.getViaBranchParameter(), m.getCallIdParameter(), fromTag,
+                acceptContactTags);
+    }
+
+    /**
+     * Track a new SIP dialog, which will be starting in {@link #STATE_EARLY}.
+     *
+     * @param branchId The via branch param of the INVITE request, which is used to match
+     *                 responses.
+     * @param callId   The callId of the SIP dialog.
+     * @param fromTag  The from header's tag parameter.
+     */
+    private SipDialog(String branchId, String callId, String fromTag, Set<String> featureTags) {
+        mBranchId = branchId;
+        mCallId = callId;
+        mFromTag = fromTag;
+        mAcceptContactFeatureTags = featureTags;
+        mLastInteraction = Instant.now();
+    }
+
+    /**
+     * @return The call id associated with the SIP dialog.
+     */
+    public String getCallId() {
+        return mCallId;
+    }
+
+    /**
+     * @return the state of the SIP dialog, either {@link #STATE_EARLY},
+     * {@link #STATE_CONFIRMED}, {@link #STATE_CLOSED}.
+     */
+    public int getState() {
+        return mState;
+    }
+
+    /**
+     * @return The to header's tag parameter if this dialog has gotten a response from the remote
+     * party or {@code null} if it has not.
+     */
+    public String getToTag() {
+        return mToTag;
+    }
+
+    /**
+     * @return The feature tags contained in the "Accept-Contact" header.
+     */
+    public Set<String> getAcceptContactFeatureTags() {
+        return mAcceptContactFeatureTags;
+    }
+
+    /**
+     * @return A new instance with branch param, call-id value, and from tag param populated.
+     */
+    public SipDialog forkDialog() {
+        return new SipDialog(mBranchId, mCallId, mFromTag, mAcceptContactFeatureTags);
+    }
+
+    /**
+     * A early response has been received (101-199) and contains a to tag, which will create a
+     * dialog.
+     * @param toTag The to tag of the SIP response.
+     */
+    public void earlyResponse(String toTag) {
+        if (TextUtils.isEmpty(toTag) || mState != STATE_EARLY) {
+            // invalid state
+            return;
+        }
+        mLastInteraction = Instant.now();
+        // Only accept To tag if one has not been assigned yet.
+        if (mToTag == null) {
+            mToTag = toTag;
+        }
+    }
+
+    /**
+     * The early dialog has been confirmed and
+     * @param toTag The To header's tag parameter.
+     */
+    public void confirm(String toTag) {
+        if (mState != STATE_EARLY) {
+            // Invalid state
+            return;
+        }
+        mLastInteraction = Instant.now();
+        mState = STATE_CONFIRMED;
+        // Only accept a To tag if one has not been assigned yet.
+        if (mToTag == null) {
+            mToTag = toTag;
+        }
+    }
+
+    /**
+     * Close the SIP dialog
+     */
+    public void close() {
+        mLastInteraction = Instant.now();
+        mState = STATE_CLOSED;
+    }
+
+    /**
+     * @return {@code true} if a SIP response's branch, call-id, and from tags match this dialog,
+     * {@code false} if it does not. This may match multiple Dialogs in the case of SIP INVITE
+     * forking.
+     */
+    public boolean isResponseAssociatedWithDialog(SipMessage m) {
+        if (!mBranchId.equals(m.getViaBranchParameter())) return false;
+        if (!mCallId.equals(m.getCallIdParameter())) return false;
+        String fromTag = SipMessageParsingUtils.getFromTag(m.getHeaderSection());
+        return mFromTag.equals(fromTag);
+    }
+
+    /**
+     * @return {@code true} if the SIP request is part of the SIP Dialog, {@code false} if it is
+     * not.
+     */
+    public boolean isRequestAssociatedWithDialog(SipMessage m) {
+        if (!mCallId.equals(m.getCallIdParameter())) return false;
+        String fromTag = SipMessageParsingUtils.getFromTag(m.getHeaderSection());
+        String toTag = SipMessageParsingUtils.getToTag(m.getHeaderSection());
+        // Requests can only be associated if both to and from tag of message are populated. The
+        // dialog's to tag must also be non-null meaning we got a response from the remote.
+        if (fromTag == null || toTag == null || mToTag == null) return false;
+        // For outgoing requests, recorded from tag will match their from tag and for incoming
+        // requests recorded from tag will match their to tag. Same with our recorded to tag.
+        return (mFromTag.equals(fromTag) || mFromTag.equals(toTag))
+                && (mToTag.equals(toTag) || mToTag.equals(fromTag));
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder("SipDialog[");
+        switch (mState) {
+            case STATE_EARLY:
+                b.append("early");
+                break;
+            case STATE_CONFIRMED:
+                b.append("confirmed");
+                break;
+            case STATE_CLOSED:
+                b.append("closed");
+                break;
+            default:
+                b.append(mState);
+        }
+        b.append("] bId=");
+        b.append(mBranchId);
+        b.append(", cId=");
+        b.append(mCallId);
+        b.append(", f=");
+        b.append(mFromTag);
+        b.append(", t=");
+        b.append(mToTag);
+        b.append(", Last Interaction: ");
+        b.append(mLastInteraction);
+        return b.toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        SipDialog sipDialog = (SipDialog) o;
+        // Does not include mState and last interaction time, as a dialog is only the same if
+        // its branch, callId, and to/from tags are equal.
+        return mBranchId.equals(sipDialog.mBranchId)
+                && Objects.equals(mCallId, sipDialog.mCallId)
+                && Objects.equals(mFromTag, sipDialog.mFromTag)
+                && Objects.equals(mToTag, sipDialog.mToTag);
+    }
+
+    @Override
+    public int hashCode() {
+        // Does not include mState and last interaction time, as a dialog is only the same if
+        // its branch, callId, and to/from tags are equal.
+        return Objects.hash(mBranchId, mCallId, mFromTag, mToTag);
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/SipSessionTracker.java b/src/com/android/services/telephony/rcs/SipSessionTracker.java
new file mode 100644
index 0000000..77bf3f3
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/SipSessionTracker.java
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.rcs;
+
+import android.telephony.ims.SipMessage;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.LocalLog;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.SipMessageParsingUtils;
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Tracks the state of SIP sessions started by a SIP INVITE (see RFC 3261)
+ * <p>
+ * Each SIP session created will consist of one or more SIP with, each dialog in the session
+ * having the same call-ID. Each SIP dialog will be in one of three states: EARLY, CONFIRMED, and
+ * CLOSED.
+ * <p>
+ * The SIP session will be closed once all of the associated dialogs are closed.
+ */
+public class SipSessionTracker {
+    private static final String TAG = "SessionT";
+
+    /**
+     * SIP request methods that will start a new SIP Dialog and move it into the PENDING state
+     * while we wait for a response. Note: INVITE is not the only SIP dialog that will create a
+     * dialog, however it is the only one that we wish to track for this use case.
+     */
+    public static final String[] SIP_REQUEST_DIALOG_START_METHODS = new String[] { "invite" };
+
+    /**
+     * The SIP request method that will close a SIP Dialog in the ACTIVE state with the same
+     * Call-Id.
+     */
+    private static final String SIP_CLOSE_DIALOG_REQUEST_METHOD = "bye";
+
+    private final LocalLog mLocalLog = new LocalLog(SipTransportController.LOG_SIZE);
+    private final ArrayList<SipDialog> mTrackedDialogs = new ArrayList<>();
+    // Operations that are pending an ack from the remote application processing the message before
+    // they can be applied here. Maps the via header branch parameter of the message to the
+    // associated pending operation.
+    private final ArrayMap<String, Runnable> mPendingAck = new ArrayMap<>();
+
+    /**
+     * Filter a SIP message to determine if it will result in a new SIP dialog. This will need to be
+     * successfully acknowledged by the remote IMS stack using
+     * {@link #acknowledgePendingMessage(String)} before we do any further processing.
+     *
+     * @param message The Incoming SIP message.
+     */
+    public void filterSipMessage(SipMessage message) {
+        final Runnable r;
+        if (startsEarlyDialog(message)) {
+            r = getCreateDialogRunnable(message);
+        } else if (closesDialog(message)) {
+            r = getCloseDialogRunnable(message);
+        } else if (SipMessageParsingUtils.isSipResponse(message.getStartLine())) {
+            r = getDialogStateChangeRunnable(message);
+        } else {
+            r = null;
+        }
+
+        if (r != null) {
+            if (mPendingAck.containsKey(message.getViaBranchParameter())) {
+                Runnable lastEvent = mPendingAck.get(message.getViaBranchParameter());
+                logw("Adding new message when there was already a pending event for branch: "
+                        + message.getViaBranchParameter());
+                Runnable concatRunnable = () -> {
+                    // No choice but to concatenate the Runnables together.
+                    if (lastEvent != null) lastEvent.run();
+                    r.run();
+                };
+                mPendingAck.put(message.getViaBranchParameter(), concatRunnable);
+            } else {
+                mPendingAck.put(message.getViaBranchParameter(), r);
+            }
+        }
+    }
+
+    /**
+     * The pending SIP message has been received by the remote IMS stack. We can now track dialogs
+     * associated with this message.
+     * message.
+     * @param viaBranchId The SIP message's Via header's branch parameter, which is used as a
+     *                    unique token.
+     */
+    public void acknowledgePendingMessage(String viaBranchId) {
+        Runnable r = mPendingAck.get(viaBranchId);
+        if (r != null) {
+            mPendingAck.remove(viaBranchId);
+            r.run();
+        }
+    }
+
+    /**
+     * The pending SIP message has failed to be sent to the remote so remove the pending task.
+     * @param viaBranchId The failed message's Via header's branch parameter.
+     */
+    public void pendingMessageFailed(String viaBranchId) {
+        mPendingAck.remove(viaBranchId);
+    }
+
+    /**
+     * A SIP session tracked by the remote application's IMS stack has been closed, so we can stop
+     * tracking it.
+     * @param callId The callId of the SIP session that has been closed.
+     */
+    public void cleanupSession(String callId) {
+        List<SipDialog> dialogsToCleanup = mTrackedDialogs.stream()
+                .filter(d -> d.getCallId().equals(callId))
+                .collect(Collectors.toList());
+        if (dialogsToCleanup.isEmpty()) return;
+        logi("Cleanup dialogs associated with call id: " + callId);
+        for (SipDialog d : dialogsToCleanup) {
+            d.close();
+            logi("Dialog closed: " + d);
+        }
+        mTrackedDialogs.removeAll(dialogsToCleanup);
+    }
+
+    /**
+     * @return the call IDs of the dialogs associated with the provided feature tags.
+     */
+    public Set<String> getCallIdsAssociatedWithFeatureTag(Set<String> featureTags) {
+        if (featureTags.isEmpty()) return Collections.emptySet();
+        Set<String> associatedIds = new ArraySet<>();
+        for (String featureTag : featureTags) {
+            for (SipDialog dialog : mTrackedDialogs) {
+                boolean isAssociated = dialog.getAcceptContactFeatureTags().stream().anyMatch(
+                        d -> d.equalsIgnoreCase(featureTag));
+                if (isAssociated) associatedIds.add(dialog.getCallId());
+            }
+        }
+        return associatedIds;
+    }
+
+    /**
+     * @return All dialogs that have not received a final response yet 2XX or 3XX+.
+     */
+    public Set<SipDialog> getEarlyDialogs() {
+        return mTrackedDialogs.stream().filter(d -> d.getState() == SipDialog.STATE_EARLY)
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * @return All confirmed dialogs that have received a 2XX response and are active.
+     */
+    public Set<SipDialog> getConfirmedDialogs() {
+        return mTrackedDialogs.stream().filter(d -> d.getState() == SipDialog.STATE_CONFIRMED)
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * @return Dialogs that have been closed via a BYE or 3XX+ response and
+     * {@link #cleanupSession(String)} has not been called yet.
+     */
+    @VisibleForTesting
+    public Set<SipDialog> getClosedDialogs() {
+        return mTrackedDialogs.stream().filter(d -> d.getState() == SipDialog.STATE_CLOSED)
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * @return All of the tracked dialogs, even the ones that have been closed but
+     * {@link #cleanupSession(String)} has not been called.
+     */
+    public Set<SipDialog> getTrackedDialogs() {
+        return new ArraySet<>(mTrackedDialogs);
+    }
+
+    /**
+     * Clears all tracked sessions.
+     */
+    public void clearAllSessions() {
+        mTrackedDialogs.clear();
+        mPendingAck.clear();
+    }
+
+    /**
+     * Dump the state of this tracker to the provided PrintWriter.
+     */
+    public void dump(PrintWriter printWriter) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("SipSessionTracker:");
+        pw.increaseIndent();
+        pw.print("Early Call IDs: ");
+        pw.println(getEarlyDialogs().stream().map(SipDialog::getCallId)
+                .collect(Collectors.toSet()));
+        pw.print("Confirmed Call IDs: ");
+        pw.println(getConfirmedDialogs().stream().map(SipDialog::getCallId)
+                .collect(Collectors.toSet()));
+        pw.print("Closed Call IDs: ");
+        pw.println(getClosedDialogs().stream().map(SipDialog::getCallId)
+                .collect(Collectors.toSet()));
+        pw.println("Tracked Dialogs:");
+        pw.increaseIndent();
+        for (SipDialog d : mTrackedDialogs) {
+            pw.println(d);
+        }
+        pw.decreaseIndent();
+        pw.println();
+        pw.println("Local Logs");
+        mLocalLog.dump(pw);
+        pw.decreaseIndent();
+    }
+
+    /**
+     * @return {@code true}, if the SipMessage passed in should start a new SIP dialog,
+     * {@code false} if it should not.
+     */
+    private boolean startsEarlyDialog(SipMessage m) {
+        if (!SipMessageParsingUtils.isSipRequest(m.getStartLine())) {
+            return false;
+        }
+        String[] startLineSegments = SipMessageParsingUtils.splitStartLineAndVerify(
+                m.getStartLine());
+        if (startLineSegments == null) {
+            return false;
+        }
+        return Arrays.stream(SIP_REQUEST_DIALOG_START_METHODS)
+                .anyMatch(r -> r.equalsIgnoreCase(startLineSegments[0]));
+    }
+
+    /**
+     * @return {@code true}, if the SipMessage passed in should close a confirmed dialog,
+     * {@code false} if it should not.
+     */
+    private boolean closesDialog(SipMessage m) {
+        if (!SipMessageParsingUtils.isSipRequest(m.getStartLine())) {
+            return false;
+        }
+        String[] startLineSegments = SipMessageParsingUtils.splitStartLineAndVerify(
+                m.getStartLine());
+        if (startLineSegments == null) {
+            return false;
+        }
+        return SIP_CLOSE_DIALOG_REQUEST_METHOD.equalsIgnoreCase(startLineSegments[0]);
+    }
+
+    private Runnable getCreateDialogRunnable(SipMessage m) {
+        return () -> {
+            List<SipDialog> duplicateDialogs = mTrackedDialogs.stream()
+                    .filter(d -> d.getCallId().equals(m.getCallIdParameter()))
+                    .collect(Collectors.toList());
+            if (duplicateDialogs.size() > 0) {
+                logi("trying to create a dialog for a call ID that already exists, skip: "
+                        + duplicateDialogs);
+                return;
+            }
+            SipDialog dialog = SipDialog.fromSipMessage(m);
+            logi("Starting new SipDialog: " + dialog);
+            mTrackedDialogs.add(dialog);
+        };
+    }
+
+    private Runnable getCloseDialogRunnable(SipMessage m) {
+        return () -> {
+            List<SipDialog> dialogsToClose = mTrackedDialogs.stream()
+                    .filter(d -> d.isRequestAssociatedWithDialog(m))
+                    .collect(Collectors.toList());
+            if (dialogsToClose.isEmpty()) return;
+            logi("Closing dialogs associated with: " + m);
+            for (SipDialog d : dialogsToClose) {
+                d.close();
+                logi("Dialog closed: " + d);
+            }
+        };
+    }
+
+    private Runnable getDialogStateChangeRunnable(SipMessage m) {
+        return () -> {
+            // This will return a dialog and all of its potential forks
+            List<SipDialog> associatedDialogs = mTrackedDialogs.stream()
+                    .filter(d -> d.isResponseAssociatedWithDialog(m))
+                    .collect(Collectors.toList());
+            if (associatedDialogs.isEmpty()) return;
+            String messageToTag = SipMessageParsingUtils.getToTag(m.getHeaderSection());
+            // If the to tag matches (or message to tag doesn't exist in dialog yet because this is
+            // the first response), then we are done.
+            SipDialog match = associatedDialogs.stream()
+                    .filter(d -> d.getToTag() == null || d.getToTag().equals(messageToTag))
+                    .findFirst().orElse(null);
+            if (match == null) {
+                // If it doesn't then we have a situation where we need to fork the existing dialog.
+                // The dialog used to fork doesn't matter, since the required params are the same,
+                // so simply use the first one in the returned list.
+                logi("Dialog forked");
+                match = associatedDialogs.get(0).forkDialog();
+                mTrackedDialogs.add(match);
+            }
+            if (match != null) {
+                logi("Dialog: " + match + " is associated with: " + m);
+                updateSipDialogState(match, m);
+                logi("Dialog state updated to " + match);
+            } else {
+                logi("No Dialogs are associated with: " + m);
+            }
+        };
+    }
+
+    private void updateSipDialogState(SipDialog d, SipMessage m) {
+        String[] startLineSegments = SipMessageParsingUtils.splitStartLineAndVerify(
+                m.getStartLine());
+        if (startLineSegments == null) {
+            logw("Could not parse start line for SIP message: " + m.getStartLine());
+            return;
+        }
+        int statusCode = 0;
+        try {
+            statusCode = Integer.parseInt(startLineSegments[1]);
+        } catch (NumberFormatException e) {
+            logw("Could not parse status code for SIP message: " + m.getStartLine());
+            return;
+        }
+        String toTag = SipMessageParsingUtils.getToTag(m.getHeaderSection());
+        logi("updateSipDialogState: message has statusCode: " + statusCode + ", and to tag: "
+                + toTag);
+        // If specifically 100 Trying, then do not do anything.
+        if (statusCode <= 100) return;
+        // If 300+, then this dialog has received an error response and should move to closed state.
+        if (statusCode >= 300) {
+            d.close();
+            return;
+        }
+        if (toTag == null) logw("updateSipDialogState: No to tag for message: " + m);
+        if (statusCode >= 200) {
+            d.confirm(toTag);
+            return;
+        }
+        // 1XX responses still require updates to dialogs.
+        d.earlyResponse(toTag);
+    }
+
+    private void logi(String log) {
+        Log.w(SipTransportController.LOG_TAG, TAG + ": " + log);
+        mLocalLog.log("[I] " + log);
+    }
+
+    private void logw(String log) {
+        Log.w(SipTransportController.LOG_TAG, TAG + ": " + log);
+        mLocalLog.log("[W] " + log);
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/SipTransportController.java b/src/com/android/services/telephony/rcs/SipTransportController.java
index 6ffffaf..f37c360 100644
--- a/src/com/android/services/telephony/rcs/SipTransportController.java
+++ b/src/com/android/services/telephony/rcs/SipTransportController.java
@@ -85,8 +85,8 @@
  */
 public class SipTransportController implements RcsFeatureController.Feature,
         OnRoleHoldersChangedListener {
+    public static final String LOG_TAG = "SipTransportC";
     static final int LOG_SIZE = 50;
-    static final String LOG_TAG = "SipTransportC";
 
     /**See {@link TimerAdapter#getReevaluateThrottleTimerMilliseconds()}.*/
     private static final int REEVALUATE_THROTTLE_DEFAULT_MS = 1000;
diff --git a/src/com/android/services/telephony/rcs/TransportSipMessageValidator.java b/src/com/android/services/telephony/rcs/TransportSipMessageValidator.java
index 66dea85..777026c 100644
--- a/src/com/android/services/telephony/rcs/TransportSipMessageValidator.java
+++ b/src/com/android/services/telephony/rcs/TransportSipMessageValidator.java
@@ -26,6 +26,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.services.telephony.rcs.validator.IncomingTransportStateValidator;
 import com.android.services.telephony.rcs.validator.MalformedSipMessageValidator;
 import com.android.services.telephony.rcs.validator.OutgoingTransportStateValidator;
@@ -36,17 +37,21 @@
 
 import java.io.PrintWriter;
 import java.util.Collections;
-import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * Track incoming and outgoing SIP messages passing through this delegate and verify these messages
  * by doing the following:
  *  <ul>
  *    <li>Track the SipDelegate's registration state to ensure that a registration event has
- *    occurred before allowing outgoing messages.</li>
+ *    occurred before allowing outgoing messages. Once it has occurred, filter outgoing SIP messages
+ *    based on the open/restricted feature tag registration state.</li>
  *    <li>Track the SipDelegate's IMS configuration version and deny any outgoing SipMessages
  *    associated with a stale IMS configuration version.</li>
  *    <li>Track the SipDelegate open/close state to allow/deny outgoing messages based on the
@@ -59,9 +64,74 @@
 
     private static final String LOG_TAG = "SipMessageV";
 
+    /**
+     * the time in milliseconds that we will wait for SIP sessions to close before we will timeout
+     * and force the sessions to be cleaned up.
+     */
+    private static final int PENDING_CLOSE_TIMEOUT_MS = 1000;
+    /**
+     * time in milliseconds that we will wait for SIP sessions to be closed before we timeout and
+     * force the sessions associated with the deregistering feature tags to be cleaned up.
+     */
+    private static final int PENDING_REGISTRATION_CHANGE_TIMEOUT_MS = 1000;
+
+    /**
+     * Timeouts used in this class that are visible for testing.
+     */
+    @VisibleForTesting
+    public interface Timeouts {
+        /**
+         * @return the time in milliseconds that we will wait for SIP sessions to close before we
+         * will timeout and force the sessions to be cleaned up.
+         */
+        int getPendingCloseTimeoutMs();
+
+        /**
+         * @return the time in milliseconds that we will wait for SIP sessions to be closed before
+         * we timeout and force the sessions associated with the deregistering feature tags to be
+         * cleaned up.
+         */
+        int getPendingRegistrationChangeTimeoutMs();
+    }
+
+    /**
+     * Tracks a pending task that has been scheduled on the associated Executor.
+     */
+    private abstract static class PendingTask implements Runnable {
+
+        private ScheduledFuture<?> mFuture;
+
+        public void scheduleDelayed(ScheduledExecutorService executor, int timeMs) {
+            mFuture = executor.schedule(this, timeMs, TimeUnit.MILLISECONDS);
+        }
+
+        public boolean isDone() {
+            return mFuture != null && mFuture.isDone();
+        }
+
+        public void cancel() {
+            if (mFuture == null) return;
+            mFuture.cancel(false /*interrupt*/);
+        }
+    }
+
+    /**
+     * Tracks a pending reg cleanup task that has been scheduled on the associated Executor.
+     */
+    private abstract static class PendingRegCleanupTask extends PendingTask {
+        public final Set<String> pendingCallIds;
+        public final Set<String> featureTags;
+
+        PendingRegCleanupTask(Set<String> tags, Set<String> callIds) {
+            featureTags = tags;
+            pendingCallIds = callIds;
+        }
+    }
+
     private final int mSubId;
     private final ScheduledExecutorService mExecutor;
     private final LocalLog mLocalLog = new LocalLog(SipTransportController.LOG_SIZE);
+    private final SipSessionTracker mSipSessionTracker;
     // Validators
     private final IncomingTransportStateValidator mIncomingTransportStateValidator;
     private final OutgoingTransportStateValidator mOutgoingTransportStateValidator;
@@ -71,29 +141,35 @@
     private Set<String> mSupportedFeatureTags;
     private Set<FeatureTagState> mDeniedFeatureTags;
     private long mConfigVersion = -1;
-    private DelegateRegistrationState mLatestRegistrationState;
-    private Consumer<List<String>> mClosingCompleteConsumer;
-    private Consumer<List<String>> mRegistrationAppliedConsumer;
+    private Consumer<Set<String>> mClosingCompleteConsumer;
+    private PendingTask mPendingClose;
+    private PendingRegCleanupTask mPendingRegCleanup;
+    private Consumer<Set<String>> mRegistrationAppliedConsumer;
 
     public TransportSipMessageValidator(int subId, ScheduledExecutorService executor) {
-        this(subId, executor, new OutgoingTransportStateValidator(),
-                new IncomingTransportStateValidator(), new MalformedSipMessageValidator().andThen(
+        mSubId = subId;
+        mExecutor = executor;
+        mSipSessionTracker = new SipSessionTracker();
+        mOutgoingTransportStateValidator = new OutgoingTransportStateValidator(mSipSessionTracker);
+        mIncomingTransportStateValidator = new IncomingTransportStateValidator();
+        mOutgoingMessageValidator = new MalformedSipMessageValidator().andThen(
                 new RestrictedOutgoingSipRequestValidator()).andThen(
-                new RestrictedOutgoingSubscribeValidator()));
+                new RestrictedOutgoingSubscribeValidator()).andThen(
+                        mOutgoingTransportStateValidator);
+        mIncomingMessageValidator = mIncomingTransportStateValidator;
     }
 
-
     @VisibleForTesting
     public TransportSipMessageValidator(int subId, ScheduledExecutorService executor,
+            SipSessionTracker sipSessionTracker,
             OutgoingTransportStateValidator outgoingStateValidator,
-            IncomingTransportStateValidator incomingStateValidator,
-            SipMessageValidator statelessMessageValidator) {
+            IncomingTransportStateValidator incomingStateValidator) {
         mSubId = subId;
         mExecutor = executor;
+        mSipSessionTracker = sipSessionTracker;
         mOutgoingTransportStateValidator = outgoingStateValidator;
         mIncomingTransportStateValidator = incomingStateValidator;
-        mOutgoingMessageValidator = mOutgoingTransportStateValidator.andThen(
-                statelessMessageValidator);
+        mOutgoingMessageValidator = mOutgoingTransportStateValidator;
         mIncomingMessageValidator = mIncomingTransportStateValidator;
     }
 
@@ -115,30 +191,27 @@
      *         changes.
      * @param regState The new registration state.
      */
-    public void onRegistrationStateChanged(Consumer<List<String>> stateChangeComplete,
+    public void onRegistrationStateChanged(Consumer<Set<String>> stateChangeComplete,
             DelegateRegistrationState regState) {
         if (mRegistrationAppliedConsumer != null) {
             logw("onRegistrationStateChanged: pending registration change, completing now.");
             // complete the pending consumer with no dialogs pending, this will be re-evaluated
             // and new configuration will be applied.
-            mRegistrationAppliedConsumer.accept(Collections.emptyList());
+            cleanupAndNotifyRegistrationAppliedConsumer(Collections.emptySet());
         }
-        mLatestRegistrationState = regState;
-        // evaluate if this needs to be set based on reg state.
+        Set<String> restrictedTags = Stream.concat(
+                regState.getDeregisteringFeatureTags().stream(),
+                regState.getDeregisteredFeatureTags().stream()).map(FeatureTagState::getFeatureTag)
+                .collect(Collectors.toSet());
+        mOutgoingTransportStateValidator.restrictFeatureTags(restrictedTags);
         mRegistrationAppliedConsumer = stateChangeComplete;
-        // notify stateChangeComplete when reg state applied
-        mExecutor.execute(() -> {
-            // TODO: Track open regState & signal dialogs to close if required.
-            // Collect open dialogs associated with features that regState is signalling as
-            // DEREGISTERING. When PENDING_DIALOG_CLOSING_TIMEOUT_MS occurs, these dialogs need to
-            // close so that the features can move to DEREGISTERED.
-
-            // For now, just pass back an empty list and complete the Consumer.
-            if (mRegistrationAppliedConsumer != null) {
-                mRegistrationAppliedConsumer.accept(Collections.emptyList());
-                mRegistrationAppliedConsumer = null;
-            }
-        });
+        if (mPendingClose == null || mPendingClose.isDone()) {
+            // Only update the pending registration cleanup task if we do not already have a pending
+            // close in progress.
+            updatePendingRegCleanupTask(restrictedTags);
+        } else {
+            logi("skipping update reg cleanup due to pending close task.");
+        }
     }
 
     /**
@@ -184,7 +257,8 @@
         logi("onTransportOpened: moving to open state");
         mSupportedFeatureTags = supportedFeatureTags;
         mDeniedFeatureTags = deniedFeatureTags;
-        mOutgoingTransportStateValidator.open();
+        mOutgoingTransportStateValidator.open(supportedFeatureTags, deniedFeatureTags.stream().map(
+                FeatureTagState::getFeatureTag).collect(Collectors.toSet()));
         mIncomingTransportStateValidator.open();
     }
 
@@ -193,7 +267,8 @@
      * @param callId The call ID associated with the SIP session.
      */
     public void onSipSessionCleanup(String callId) {
-        //TODO track SIP sessions.
+        mSipSessionTracker.cleanupSession(callId);
+        onCallIdsChanged();
     }
 
     /**
@@ -213,54 +288,66 @@
      * @param closedReason The reason that will be provided if any outgoing SIP message is sent
      *         once the transport is closed.
      */
-    public void closeSessionsGracefully(Consumer<List<String>> closingCompleteConsumer,
+    public void closeSessionsGracefully(Consumer<Set<String>> closingCompleteConsumer,
             int closingReason, int closedReason) {
-        if (mClosingCompleteConsumer != null) {
-            logw("closeSessionsGracefully: already pending close, completing consumer to unblock");
-            closingCompleteConsumer.accept(Collections.emptyList());
+        if (closingCompleteConsumer == null) {
+            logw("closeSessionsGracefully: unexpected - called with null consumer... closing now");
+            closeSessions(closedReason);
             return;
         }
+        if (mClosingCompleteConsumer != null) {
+            // In this case, all we can do is combine the consumers and wait for the other pending
+            // close to complete, finishing both.
+            logw("closeSessionsGracefully: unexpected - existing close pending, combining"
+                    + " consumers.");
+            mClosingCompleteConsumer = callIds -> {
+                mClosingCompleteConsumer.accept(callIds);
+                closingCompleteConsumer.accept(callIds);
+            };
+            return;
+        } else {
+            mClosingCompleteConsumer = closingCompleteConsumer;
+        }
+        if (getTrackedSipSessionCallIds().isEmpty()) {
+            logi("closeSessionsGracefully: moving to closed state now, reason=" + closedReason);
+            closeSessionsInternal(closedReason);
+            cancelClosingTimeoutAndSendComplete(Collections.emptySet());
+            return;
+        }
+        cancelPendingRegCleanupTask();
         logi("closeSessionsGracefully: moving to restricted state, reason=" + closingReason);
-        mClosingCompleteConsumer = closingCompleteConsumer;
         mOutgoingTransportStateValidator.restrict(closingReason);
-        mExecutor.execute(() -> {
-            logi("closeSessionsGracefully: moving to closed state, reason=" + closedReason);
-            mOutgoingTransportStateValidator.close(closedReason);
-            mIncomingTransportStateValidator.close(closedReason);
-            if (mClosingCompleteConsumer != null) {
-                // TODO: Track SIP sessions and complete when there are no SIP dialogs open anymore
-                //  or the timeout occurs.
-                mClosingCompleteConsumer.accept(Collections.emptyList());
-                mClosingCompleteConsumer = null;
+        mPendingClose = new PendingTask() {
+            @Override
+            public void run() {
+                closeSessions(closingReason);
             }
-        });
+        };
+        mPendingClose.scheduleDelayed(mExecutor, PENDING_CLOSE_TIMEOUT_MS);
     }
 
     /**
-     * The message transport must close now due to a configuration change (SIM subscription change,
-     * user disabled RCS, the service is dead, etc...).
+     * Close the transport now. If there are any open SIP sessions and this is closed due to a
+     * configuration change (SIM subscription change, user disabled RCS, the service is dead,
+     * etc...) then we will return the call IDs of all open sessions and ask them to be closed.
      * @param closedReason The error reason for why the message transport was closed that will be
      *         sent back to the caller if a new SIP message is sent.
      * @return A List of call IDs associated with sessions that were still open at the time that the
      * tracker closed the transport.
      */
-    public List<String> closeSessionsForcefully(int closedReason) {
-        logi("closeSessionsForcefully: moving to closed state, reason=" + closedReason);
-        mOutgoingTransportStateValidator.close(closedReason);
-        mIncomingTransportStateValidator.close(closedReason);
-        // TODO: add logic to collect open SIP dialogs to be forcefully closed once they are being
-        //  tracked.
-        List<String> openCallIds = Collections.emptyList();
-        if (mClosingCompleteConsumer != null) {
-            logi("closeSessionsForcefully: sending pending call ids through close consumer");
-            // send the call ID through the pending complete mechanism to unblock any previous
-            // graceful close command.
-            mClosingCompleteConsumer.accept(openCallIds);
-            mClosingCompleteConsumer = null;
-            return Collections.emptyList();
-        } else {
-            return openCallIds;
+    public Set<String> closeSessions(int closedReason) {
+        Set<String> openCallIds = getTrackedSipSessionCallIds();
+        logi("closeSessions: moving to closed state, reason=" + closedReason + ", open call ids: "
+                + openCallIds);
+        closeSessionsInternal(closedReason);
+        boolean consumerHandledPendingSessions = cancelClosingTimeoutAndSendComplete(openCallIds);
+        if (consumerHandledPendingSessions) {
+            logw("closeSessions: call ID closure handled through consumer");
+            // sent the open call IDs through the pending complete mechanism to unblock any previous
+            // graceful close command and close them early.
+            return Collections.emptySet();
         }
+        return openCallIds;
     }
 
     /**
@@ -270,20 +357,15 @@
      */
 
     public ValidationResult verifyOutgoingMessage(SipMessage message, long configVersion) {
-        ValidationResult result = mOutgoingMessageValidator.validate(message);
-        if (!result.isValidated) return result;
-
         if (mConfigVersion != configVersion) {
-            logi("VerifyOutgoingMessage failed: for message: " + message + ", due to stale IMS "
-                    + "configuration: " + configVersion + ", expected: " + mConfigVersion);
             return new ValidationResult(
-                    SipDelegateManager.MESSAGE_FAILURE_REASON_STALE_IMS_CONFIGURATION);
+                    SipDelegateManager.MESSAGE_FAILURE_REASON_STALE_IMS_CONFIGURATION,
+                    "stale IMS configuration: "  + configVersion + ", expected: "
+                            + mConfigVersion);
         }
-        if (mLatestRegistrationState == null) {
-            result = new ValidationResult(
-                    SipDelegateManager.MESSAGE_FAILURE_REASON_NOT_REGISTERED);
-        }
-        logi("VerifyOutgoingMessage: " + result + ", message=" + message);
+        ValidationResult result = mOutgoingMessageValidator.validate(message);
+        logi("verifyOutgoingMessage: " + result + ", message=" + message);
+        if (result.isValidated) mSipSessionTracker.filterSipMessage(message);
         return result;
     }
 
@@ -294,7 +376,10 @@
      * @return The result of verifying the incoming message.
      */
     public ValidationResult verifyIncomingMessage(SipMessage message) {
-        return mIncomingMessageValidator.validate(message);
+        ValidationResult result = mIncomingMessageValidator.validate(message);
+        logi("verifyIncomingMessage: " + result + ", message=" + message);
+        if (result.isValidated) mSipSessionTracker.filterSipMessage(message);
+        return result;
     }
 
     /**
@@ -304,33 +389,158 @@
      */
     public void acknowledgePendingMessage(String transactionId) {
         logi("acknowledgePendingMessage: id=" + transactionId);
-        //TODO: keep track of pending messages to add to SIP session candidates.
+        mSipSessionTracker.acknowledgePendingMessage(transactionId);
+        onCallIdsChanged();
     }
 
     /**
      * A pending incoming or outgoing SIP message has failed and should not be tracked.
-     * @param transactionId
+     * @param transactionId The transaction ID associated with the message.
      */
     public void notifyPendingMessageFailed(String transactionId) {
         logi("notifyPendingMessageFailed: id=" + transactionId);
-        //TODO: keep track of pending messages to remove from SIP session candidates.
+        mSipSessionTracker.pendingMessageFailed(transactionId);
     }
 
     /** Dump state about this tracker that should be included in the dumpsys */
     public void dump(PrintWriter printWriter) {
-        printWriter.println("Supported Tags:" + mSupportedFeatureTags);
-        printWriter.println("Denied Tags:" + mDeniedFeatureTags);
-        printWriter.println(mOutgoingTransportStateValidator);
-        printWriter.println(mIncomingTransportStateValidator);
-        printWriter.println("Reg consumer pending: " + (mRegistrationAppliedConsumer != null));
-        printWriter.println("Close consumer pending: " + (mClosingCompleteConsumer != null));
-        printWriter.println();
-        printWriter.println("Most recent logs:");
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("Supported Tags:" + mSupportedFeatureTags);
+        pw.println("Denied Tags:" + mDeniedFeatureTags);
+        pw.println(mOutgoingTransportStateValidator);
+        pw.println(mIncomingTransportStateValidator);
+        pw.println("Reg consumer pending: " + (mRegistrationAppliedConsumer != null));
+        pw.println("Close consumer pending: " + (mClosingCompleteConsumer != null));
+        pw.println();
+        mSipSessionTracker.dump(pw);
+        pw.println();
+        pw.println("Most recent logs:");
         mLocalLog.dump(printWriter);
     }
 
+    /**
+     * A event has occurred that can change the list of active call IDs.
+     */
+    private void onCallIdsChanged() {
+        if (getTrackedSipSessionCallIds().isEmpty() && mPendingClose != null
+                && !mPendingClose.isDone()) {
+            logi("onCallIdsChanged: no open sessions, completing any pending close events.");
+            // do not wait for timeout if pending sessions closed.
+            mPendingClose.cancel();
+            mPendingClose.run();
+        }
+        if (mPendingRegCleanup != null && !mPendingRegCleanup.isDone()) {
+            logi("onCallIdsChanged: updating pending reg cleanup task.");
+            // Recalculate the open call IDs based on the same feature tag set in the case that the
+            // call ID change has caused a change in pending reg cleanup task.
+            updatePendingRegCleanupTask(mPendingRegCleanup.featureTags);
+        }
+    }
+
+    /**
+     * If there are any pending registration clean up tasks, cancel them and clean up consumers.
+     */
+    private void cancelPendingRegCleanupTask() {
+        if (mPendingRegCleanup != null && !mPendingRegCleanup.isDone()) {
+            logi("cancelPendingRegCleanupTask: cancelling...");
+            mPendingRegCleanup.cancel();
+        }
+        cleanupAndNotifyRegistrationAppliedConsumer(Collections.emptySet());
+    }
+
+    /**
+     * Update the pending registration change clean up task based on the new set of restricted
+     * feature tags generated from the deregistering/deregistered feature tags.
+     *
+     * <p>
+     * This set of restricted tags will generate a set of call IDs associated to dialogs that
+     * are active and associated with the restricted tags. If there is no pending cleanup task, it
+     * will create a new one. If there was already a pending reg cleanup task, it will compare them
+     * and create a new one and cancel the old one if the new set of call ids is different from the
+     * old one.
+     */
+    private void updatePendingRegCleanupTask(Set<String> restrictedTags) {
+        Set<String> pendingCallIds = mSipSessionTracker.getCallIdsAssociatedWithFeatureTag(
+                restrictedTags);
+        if (pendingCallIds.isEmpty()) {
+            if (mPendingRegCleanup != null && !mPendingRegCleanup.isDone()) {
+                logi("updatePendingRegCleanupTask: no remaining call ids, finish cleanup task "
+                        + "now.");
+                mPendingRegCleanup.cancel();
+                mPendingRegCleanup.run();
+            } else {
+                if (mRegistrationAppliedConsumer != null) {
+                    logi("updatePendingRegCleanupTask: notify no pending call ids.");
+                    cleanupAndNotifyRegistrationAppliedConsumer(Collections.emptySet());
+                }
+            }
+            return;
+        }
+        if (mPendingRegCleanup != null && !mPendingRegCleanup.isDone()) {
+            if (mPendingRegCleanup.pendingCallIds.equals(pendingCallIds)) {
+                logi("updatePendingRegCleanupTask: pending reg change has same set of pending call"
+                        + " IDs, so keeping pending task");
+                return;
+            }
+            logi("updatePendingRegCleanupTask: cancelling, call ids have changed.");
+            mPendingRegCleanup.cancel();
+        }
+        mPendingRegCleanup = new PendingRegCleanupTask(restrictedTags, pendingCallIds) {
+            @Override
+            public void run() {
+                cleanupAndNotifyRegistrationAppliedConsumer(pendingCallIds);
+            }
+        };
+        logi("updatePendingRegCleanupTask: scheduling for call ids: " + pendingCallIds);
+        mPendingRegCleanup.scheduleDelayed(mExecutor, PENDING_REGISTRATION_CHANGE_TIMEOUT_MS);
+    }
+
+    /**
+     * Notify the pending registration applied consumer of the call ids that need to be cleaned up.
+     */
+    private void cleanupAndNotifyRegistrationAppliedConsumer(Set<String> pendingCallIds) {
+        if (mRegistrationAppliedConsumer != null) {
+            mRegistrationAppliedConsumer.accept(pendingCallIds);
+            mRegistrationAppliedConsumer = null;
+        }
+    }
+
+    /**
+     * Cancel any pending timeout to close pending sessions and send the provided call IDs to any
+     * pending closing complete consumer.
+     * @return {@code true} if a consumer was notified, {@code false} if there were no consumers.
+     */
+    private boolean cancelClosingTimeoutAndSendComplete(Set<String> openCallIds) {
+        if (mPendingClose != null && !mPendingClose.isDone()) {
+            logi("completing pending close consumer");
+            mPendingClose.cancel();
+        }
+        // Complete the pending consumer with no open sessions.
+        if (mClosingCompleteConsumer != null) {
+            mClosingCompleteConsumer.accept(openCallIds);
+            mClosingCompleteConsumer = null;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Close and clear all stateful trackers and validators.
+     */
+    private void closeSessionsInternal(int closedReason) {
+        cancelPendingRegCleanupTask();
+        mOutgoingTransportStateValidator.close(closedReason);
+        mIncomingTransportStateValidator.close(closedReason);
+        mSipSessionTracker.clearAllSessions();
+    }
+
+    private Set<String> getTrackedSipSessionCallIds() {
+        return mSipSessionTracker.getTrackedDialogs().stream().map(SipDialog::getCallId)
+                .collect(Collectors.toSet());
+    }
+
     private void logi(String log) {
-        Log.w(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + log);
+        Log.i(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + log);
         mLocalLog.log("[I] " + log);
     }
 
diff --git a/src/com/android/services/telephony/rcs/validator/IncomingTransportStateValidator.java b/src/com/android/services/telephony/rcs/validator/IncomingTransportStateValidator.java
index 2ab4bbe..24ab45e 100644
--- a/src/com/android/services/telephony/rcs/validator/IncomingTransportStateValidator.java
+++ b/src/com/android/services/telephony/rcs/validator/IncomingTransportStateValidator.java
@@ -65,7 +65,8 @@
     @Override
     public ValidationResult validate(SipMessage message) {
         if (mState != STATE_OPEN) {
-            return new ValidationResult(mReason);
+            return new ValidationResult(mReason,
+                    "incoming transport closed");
         }
         return ValidationResult.SUCCESS;
     }
diff --git a/src/com/android/services/telephony/rcs/validator/MalformedSipMessageValidator.java b/src/com/android/services/telephony/rcs/validator/MalformedSipMessageValidator.java
index 3ac461d..a76ac3e 100644
--- a/src/com/android/services/telephony/rcs/validator/MalformedSipMessageValidator.java
+++ b/src/com/android/services/telephony/rcs/validator/MalformedSipMessageValidator.java
@@ -34,7 +34,8 @@
         if (!SipMessageParsingUtils.isSipRequest(message.getStartLine())
                 && !SipMessageParsingUtils.isSipResponse(message.getStartLine())) {
             return new ValidationResult(
-                    SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE);
+                    SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE,
+                    "malformed start line: " + message.getStartLine());
         }
         return ValidationResult.SUCCESS;
     }
diff --git a/src/com/android/services/telephony/rcs/validator/OutgoingTransportStateValidator.java b/src/com/android/services/telephony/rcs/validator/OutgoingTransportStateValidator.java
index 348c213..72d22f8 100644
--- a/src/com/android/services/telephony/rcs/validator/OutgoingTransportStateValidator.java
+++ b/src/com/android/services/telephony/rcs/validator/OutgoingTransportStateValidator.java
@@ -18,7 +18,20 @@
 
 import android.telephony.ims.SipDelegateManager;
 import android.telephony.ims.SipMessage;
+import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.telephony.SipMessageParsingUtils;
+import com.android.services.telephony.rcs.SipDialog;
+import com.android.services.telephony.rcs.SipSessionTracker;
+import com.android.services.telephony.rcs.SipTransportController;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * Tracks the state of the outgoing SIP message transport from the remote IMS application to the
@@ -48,16 +61,42 @@
         ENUM_TO_STRING_MAP.append(STATE_OPEN, "OPEN");
     }
 
+    private final SipSessionTracker mSipSessionTracker;
     private int mState = STATE_CLOSED;
     private int mReason = SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED;
+    private Set<String> mAllowedTags = Collections.emptySet();
+    private Set<String> mDeniedTags = Collections.emptySet();
+    private Set<String> mRestrictedFeatureTags;
+
+    public OutgoingTransportStateValidator(SipSessionTracker sessionTracker) {
+        mSipSessionTracker = sessionTracker;
+    }
 
     /**
      * The SIP message transport is open and will successfully validate both in and out of dialog
      * SIP messages.
      */
-    public void open() {
+    public void open(Set<String> allowedFeatureTags, Set<String> deniedFeatureTags) {
         mState = STATE_OPEN;
         mReason = -1;
+        // This is for validation, so try to reduce matching errors due to upper/lower case.
+        mAllowedTags = allowedFeatureTags.stream().map(String::trim).map(String::toLowerCase)
+                .collect(Collectors.toSet());
+        mDeniedTags = deniedFeatureTags.stream().map(String::trim).map(String::toLowerCase)
+                .collect(Collectors.toSet());
+        mRestrictedFeatureTags = null;
+    }
+
+    /**
+     * Restrict the starting of dialogs for specific feature tags, excluding requests associated
+     * with ongoing sessions.
+     * @param restrictedFeatureTags The feature tags that are deregistering or deregistered and can
+     *                              not have new dialogs associated with them.
+     */
+    public void restrictFeatureTags(Set<String> restrictedFeatureTags) {
+        // This is for validation, so try to reduce matching errors due to upper/lower case.
+        mRestrictedFeatureTags = restrictedFeatureTags.stream().map(String::trim)
+                .map(String::toLowerCase).collect(Collectors.toSet());
     }
 
     /**
@@ -77,15 +116,28 @@
     public void close(int reason) {
         mState = STATE_CLOSED;
         mReason = reason;
+        mAllowedTags = Collections.emptySet();
     }
 
     @Override
     public ValidationResult validate(SipMessage message) {
-        // TODO: integrate in and out-of-dialog message detection as well as supported & denied tags
-        if (mState != STATE_OPEN) {
-            return new ValidationResult(mReason);
+        switch (mState) {
+            case STATE_CLOSED:
+                return new ValidationResult(mReason, "outgoing transport closed.");
+            case STATE_RESTRICTED:
+                return verifyRestrictedMessage(message);
+            case STATE_OPEN:
+                return verifyOpenMessage(message);
+            default:
+                Log.w(SipTransportController.LOG_TAG, "OutgoingTSV - warning, unexpected state");
+                return ValidationResult.SUCCESS;
         }
-        return ValidationResult.SUCCESS;
+    }
+
+    public Set<String> getAllowedCallIds() {
+        return Stream.concat(mSipSessionTracker.getEarlyDialogs().stream(),
+                mSipSessionTracker.getConfirmedDialogs().stream()).map(SipDialog::getCallId)
+                .collect(Collectors.toSet());
     }
 
     @Override
@@ -93,6 +145,91 @@
         return "Outgoing Transport State: " + ENUM_TO_STRING_MAP.getOrDefault(mState,
                 String.valueOf(mState)) + ", reason: "
                 + SipDelegateManager.MESSAGE_FAILURE_REASON_STRING_MAP.getOrDefault(mReason,
-                String.valueOf(mReason));
+                String.valueOf(mReason)) + ", allowed tags: " + mAllowedTags + ", restricted tags: "
+                + mRestrictedFeatureTags + ", denied tags: " + mDeniedTags;
+    }
+
+    private ValidationResult verifyOpenMessage(SipMessage m) {
+        // No need to validate responses to requests.
+        if (!SipMessageParsingUtils.isSipRequest(m.getStartLine())) {
+            return ValidationResult.SUCCESS;
+        }
+        if (mRestrictedFeatureTags == null) {
+            return new ValidationResult(SipDelegateManager.MESSAGE_FAILURE_REASON_NOT_REGISTERED,
+                    "no reg state from vendor");
+        }
+        String[] segments = SipMessageParsingUtils.splitStartLineAndVerify(m.getStartLine());
+        if (segments == null) {
+            return new ValidationResult(
+                    SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE,
+                    "couldn't parse start line: " + m.getStartLine());
+        }
+        // Only need to validate requests that start dialogs.
+        boolean startsDialog = Arrays.stream(SipSessionTracker.SIP_REQUEST_DIALOG_START_METHODS)
+                .anyMatch(req -> req.equals(segments[0].trim().toLowerCase()));
+        // If part of an existing dialog, then no need to validate.
+        boolean needsFeatureValidation = startsDialog && !getAllowedCallIds()
+                .contains(m.getCallIdParameter());
+        if (needsFeatureValidation) {
+            return validateMessageFeatureTag(m);
+        }
+        return ValidationResult.SUCCESS;
+    }
+
+    /**
+     * Compares the "Accept-Contact" header against the supported/denied feature tags and ensures
+     * that there are no restricted or denied tags included.
+     */
+    private ValidationResult validateMessageFeatureTag(SipMessage m) {
+        Set<String> featureTags = SipMessageParsingUtils.getAcceptContactFeatureTags(
+                m.getHeaderSection());
+        // Get rid of potential formatting issues first.
+        featureTags = featureTags.stream().map(String::toLowerCase).map(String::trim)
+                .collect(Collectors.toSet());
+        long acceptedFeatureTagCount = featureTags.stream()
+                .filter(f -> mAllowedTags.contains(f)).count();
+        long deniedFeatureTagCount = featureTags.stream()
+                .filter(f -> mDeniedTags.contains(f)).count();
+        long restrictedFeatureTagCount = featureTags.stream()
+                .filter(f -> mRestrictedFeatureTags.contains(f)).count();
+        // we should not have any feature tags that are denied/restricted and there should be at
+        // least one accepted tag
+        if (deniedFeatureTagCount > 0) {
+            return new ValidationResult(
+                    SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_FEATURE_TAG,
+                    "contains denied tags in Accept-Contact: " + featureTags);
+        }
+        if (restrictedFeatureTagCount > 0) {
+            return new ValidationResult(
+                    SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_FEATURE_TAG,
+                    "contains restricted tags in Accept-Contact: " + featureTags);
+        }
+
+        if (acceptedFeatureTagCount == 0) {
+            return new ValidationResult(
+                    SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_FEATURE_TAG,
+                    "No Accept-Contact feature tags are in accepted feature tag list: "
+                            + featureTags);
+        }
+
+        return ValidationResult.SUCCESS;
+    }
+
+    private ValidationResult verifyRestrictedMessage(SipMessage m) {
+        // The validator is in the restricted state, so only in dialog requests and all responses
+        // are allowed.
+        if (!SipMessageParsingUtils.isSipRequest(m.getStartLine())) {
+            return ValidationResult.SUCCESS;
+        }
+        String callId = m.getCallIdParameter();
+        if (TextUtils.isEmpty(callId)) {
+            return new ValidationResult(mReason, "empty call id");
+        }
+        Set<String> mAllowedCallIds = getAllowedCallIds();
+        if (!mAllowedCallIds.contains(callId)) {
+            return new ValidationResult(mReason, "call id " + callId + " is not associated with"
+                    + " any active sessions");
+        }
+        return ValidationResult.SUCCESS;
     }
 }
diff --git a/src/com/android/services/telephony/rcs/validator/RestrictedOutgoingSipRequestValidator.java b/src/com/android/services/telephony/rcs/validator/RestrictedOutgoingSipRequestValidator.java
index e3aba25..2c2632f 100644
--- a/src/com/android/services/telephony/rcs/validator/RestrictedOutgoingSipRequestValidator.java
+++ b/src/com/android/services/telephony/rcs/validator/RestrictedOutgoingSipRequestValidator.java
@@ -43,12 +43,14 @@
             String[] segments = SipMessageParsingUtils.splitStartLineAndVerify(startLine);
             if (segments == null) {
                 return new ValidationResult(
-                        SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE);
+                        SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE,
+                        "malformed start line: " + message.getStartLine());
             }
             if (Arrays.stream(IMS_SERVICE_HANDLED_REQUEST_METHODS).anyMatch(
                     s -> segments[0].toLowerCase().contains(s))) {
                 return new ValidationResult(
-                        SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE);
+                        SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE,
+                        "restricted method: " + segments[0]);
             }
         }
         return ValidationResult.SUCCESS;
diff --git a/src/com/android/services/telephony/rcs/validator/RestrictedOutgoingSubscribeValidator.java b/src/com/android/services/telephony/rcs/validator/RestrictedOutgoingSubscribeValidator.java
index 0db3381..41074ed 100644
--- a/src/com/android/services/telephony/rcs/validator/RestrictedOutgoingSubscribeValidator.java
+++ b/src/com/android/services/telephony/rcs/validator/RestrictedOutgoingSubscribeValidator.java
@@ -24,6 +24,7 @@
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * Ensure that if there is an outgoing SUBSCRIBE request, that it does not contain the "Event"
@@ -45,7 +46,8 @@
                 message.getStartLine());
         if (requestSegments == null) {
             return new ValidationResult(
-                    SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE);
+                    SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_START_LINE,
+                    "malformed start line: " + message.getStartLine());
         }
         // Request-Line  =  Method SP Request-URI SP SIP-Version CRLF, verify Method
         if (!requestSegments[0].equalsIgnoreCase(SUBSCRIBE_REQUEST)) {
@@ -61,7 +63,9 @@
                 .anyMatch(e -> Arrays.asList(RESTRICTED_EVENTS).contains(e.trim().toLowerCase()));
 
         return isRestricted ? new ValidationResult(
-                SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_HEADER_FIELDS) :
+                SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_HEADER_FIELDS,
+                "matched a restricted header field: " + eventHeaders.stream().map(e -> e.second)
+                        .collect(Collectors.toSet())) :
                 ValidationResult.SUCCESS;
     }
 }
diff --git a/src/com/android/services/telephony/rcs/validator/ValidationResult.java b/src/com/android/services/telephony/rcs/validator/ValidationResult.java
index f3f6470..e434163 100644
--- a/src/com/android/services/telephony/rcs/validator/ValidationResult.java
+++ b/src/com/android/services/telephony/rcs/validator/ValidationResult.java
@@ -41,11 +41,17 @@
     public final int restrictedReason;
 
     /**
+     * The human readable reason for why the validation failed for logging.
+     */
+    public final String logReason;
+
+    /**
      * Communicates a validated result of success. Use {@link #SUCCESS} instead.
      */
     private ValidationResult() {
         isValidated = true;
         restrictedReason = SipDelegateManager.MESSAGE_FAILURE_REASON_UNKNOWN;
+        logReason = "";
     }
 
     /**
@@ -54,9 +60,10 @@
      * @param reason The reason associated with why the SIP message was not validated and
      *               generated a {@code false} result for {@link #isValidated}.
      */
-    public ValidationResult(@SipDelegateManager.MessageFailureReason int reason) {
+    public ValidationResult(@SipDelegateManager.MessageFailureReason int reason, String log) {
         isValidated = false;
         restrictedReason = reason;
+        logReason = log;
     }
 
     @Override
@@ -68,6 +75,8 @@
         if (!isValidated) {
             b.append(", restrictedReason=");
             b.append(restrictedReason);
+            b.append(", logReason=");
+            b.append(logReason);
         }
         b.append('}');
         return b.toString();
diff --git a/tests/src/com/android/services/telephony/rcs/MessageTransportWrapperTest.java b/tests/src/com/android/services/telephony/rcs/MessageTransportWrapperTest.java
index 3542cc1..5ced75c 100644
--- a/tests/src/com/android/services/telephony/rcs/MessageTransportWrapperTest.java
+++ b/tests/src/com/android/services/telephony/rcs/MessageTransportWrapperTest.java
@@ -38,6 +38,7 @@
 import android.telephony.ims.SipMessage;
 import android.telephony.ims.aidl.ISipDelegate;
 import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.util.ArraySet;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -57,7 +58,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.List;
+import java.util.Set;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.function.Consumer;
 
@@ -76,7 +77,6 @@
     @Mock private ISipDelegateMessageCallback mDelegateMessageCallback;
     @Mock private TransportSipMessageValidator mTransportSipSessionValidator;
     @Mock private ISipDelegate mISipDelegate;
-    @Mock private Consumer<Boolean> mMockCloseConsumer;
 
     // Test executor that just calls run on the Runnable provided in execute.
     private ScheduledExecutorService mExecutor = new TestExecutorService();
@@ -123,7 +123,7 @@
     @SmallTest
     @Test
     public void testRegistrationStateChanged() throws Exception {
-        ArrayList<String> callIds = new ArrayList<>(2);
+        ArraySet<String> callIds = new ArraySet<>(2);
         callIds.add("callId1");
         callIds.add("callId2");
         // empty registration state for testing
@@ -131,7 +131,7 @@
         MessageTransportWrapper tracker = createTestMessageTransportWrapper();
         tracker.openTransport(mISipDelegate, Collections.emptySet(), Collections.emptySet());
 
-        Consumer<List<String>> callIdConsumer = trackerRegStateChanged(tracker, state);
+        Consumer<Set<String>> callIdConsumer = trackerRegStateChanged(tracker, state);
         callIdConsumer.accept(callIds);
         // Verify that the pending call IDs are closed properly.
         for (String callId : callIds) {
@@ -148,9 +148,9 @@
         MessageTransportWrapper tracker = createTestMessageTransportWrapper();
 
         Boolean[] result = new Boolean[1];
-        Consumer<List<String>> callIdConsumer = closeTrackerGracefully(tracker, closingReason,
+        Consumer<Set<String>> callIdConsumer = closeTrackerGracefully(tracker, closingReason,
                 closedReason, (r) -> result[0] = r);
-        callIdConsumer.accept(Collections.emptyList());
+        callIdConsumer.accept(Collections.emptySet());
         // Verify that the pending call IDs are closed properly.
         verify(mTransportSipSessionValidator, never()).onSipSessionCleanup(anyString());
         verify(mISipDelegate, never()).cleanupSession(anyString());
@@ -161,7 +161,7 @@
     @SmallTest
     @Test
     public void testCloseGracefullyForceCloseCallIds() throws Exception {
-        ArrayList<String> callIds = new ArrayList<>(2);
+        ArraySet<String> callIds = new ArraySet<>(2);
         callIds.add("callId1");
         callIds.add("callId2");
         int closingReason = DelegateRegistrationState.DEREGISTERING_REASON_PROVISIONING_CHANGE;
@@ -170,7 +170,7 @@
         tracker.openTransport(mISipDelegate, Collections.emptySet(), Collections.emptySet());
 
         Boolean[] result = new Boolean[1];
-        Consumer<List<String>> callIdConsumer = closeTrackerGracefully(tracker, closingReason,
+        Consumer<Set<String>> callIdConsumer = closeTrackerGracefully(tracker, closingReason,
                 closedReason, (r) -> result[0] = r);
         callIdConsumer.accept(callIds);
         // Verify that the pending call IDs are closed properly.
@@ -186,11 +186,11 @@
     @SmallTest
     @Test
     public void testClose() throws Exception {
-        ArrayList<String> callIds = new ArrayList<>(2);
+        ArraySet<String> callIds = new ArraySet<>(2);
         callIds.add("callId1");
         callIds.add("callId2");
         int closedReason = SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED;
-        doReturn(callIds).when(mTransportSipSessionValidator).closeSessionsForcefully(closedReason);
+        doReturn(callIds).when(mTransportSipSessionValidator).closeSessions(closedReason);
         MessageTransportWrapper tracker = createTestMessageTransportWrapper();
         tracker.openTransport(mISipDelegate, Collections.emptySet(), Collections.emptySet());
 
@@ -220,7 +220,7 @@
                 eq(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD));
 
         doReturn(new ValidationResult(
-                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED))
+                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED, ""))
                 .when(mTransportSipSessionValidator)
                 .verifyOutgoingMessage(TEST_MESSAGE, 1 /*version*/);
         tracker.getDelegateConnection().sendMessage(TEST_MESSAGE, 1 /*version*/);
@@ -277,7 +277,7 @@
                 SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD);
 
         doReturn(new ValidationResult(
-                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD))
+                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD, ""))
                 .when(mTransportSipSessionValidator).verifyIncomingMessage(TEST_MESSAGE);
         tracker.getMessageCallback().onMessageReceived(TEST_MESSAGE);
         verify(mISipDelegate, times(2)).notifyMessageReceiveError(TEST_TRANSACTION_ID,
@@ -311,9 +311,9 @@
                 mExecutor, mDelegateMessageCallback, mTransportSipSessionValidator);
     }
 
-    private Consumer<List<String>> trackerRegStateChanged(MessageTransportWrapper tracker,
+    private Consumer<Set<String>> trackerRegStateChanged(MessageTransportWrapper tracker,
             DelegateRegistrationState state) {
-        ArrayList<Consumer<List<String>>> consumerCaptor = new ArrayList<>(1);
+        ArrayList<Consumer<Set<String>>> consumerCaptor = new ArrayList<>(1);
         Mockito.doAnswer(it -> {
             // Capture the consumer here.
             consumerCaptor.add(it.getArgument(0));
@@ -325,9 +325,9 @@
         return consumerCaptor.get(0);
     }
 
-    private Consumer<List<String>> closeTrackerGracefully(MessageTransportWrapper tracker,
+    private Consumer<Set<String>> closeTrackerGracefully(MessageTransportWrapper tracker,
             int closingReason, int closedReason, Consumer<Boolean> resultConsumer) {
-        ArrayList<Consumer<List<String>>> consumerCaptor = new ArrayList<>(1);
+        ArrayList<Consumer<Set<String>>> consumerCaptor = new ArrayList<>(1);
         Mockito.doAnswer(it -> {
             // Capture the consumer here.
             consumerCaptor.add(it.getArgument(0));
diff --git a/tests/src/com/android/services/telephony/rcs/SipDialogTest.java b/tests/src/com/android/services/telephony/rcs/SipDialogTest.java
new file mode 100644
index 0000000..17830c5
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/SipDialogTest.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.rcs;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+import android.telephony.ims.SipMessage;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class SipDialogTest {
+
+    private static final String SIP_URI_ALICE = "sip:alice@client.example.com";
+    private static final String BASE_CONTACT_URI_ALICE = "Alice <" + SIP_URI_ALICE + ">";
+    private static final String SIP_URI_BOB = "sip:bob@client.example.com";
+    private static final String BASE_CONTACT_URI_BOB = "Bob <" + SIP_URI_BOB + ">";
+
+    @Test
+    public void testCreateEarlyDialog() {
+        String branchId = "testBranchId";
+        String fromTag = "abcd";
+        String callId = "testCallId";
+        SipMessage inviteRequest = SipMessageUtils.generateSipRequest(
+                SipMessageUtils.INVITE_SIP_METHOD,
+                BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB, SIP_URI_BOB, branchId, callId,
+                fromTag, null /*toTag*/);
+        SipDialog dialog = SipDialog.fromSipMessage(inviteRequest);
+        assertNotNull(dialog);
+        assertEquals(SipDialog.STATE_EARLY, dialog.getState());
+        assertEquals(callId, dialog.getCallId());
+        assertNull(dialog.getToTag());
+        // receive an earlyResponse
+        String toTag = "testToTag";
+        dialog.earlyResponse(toTag);
+        assertEquals(toTag, dialog.getToTag());
+    }
+
+    @Test
+    public void testIsResponseAssociated() {
+        String branchId = "testBranchId";
+        String fromTag = "abcd";
+        String callId = "testCallId";
+        SipMessage inviteRequest = SipMessageUtils.generateSipRequest(
+                SipMessageUtils.INVITE_SIP_METHOD,
+                BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB, SIP_URI_BOB, branchId, callId,
+                fromTag, null /*toTag*/);
+        SipDialog dialog = SipDialog.fromSipMessage(inviteRequest);
+        assertNotNull(dialog);
+
+        // A response with no to tag should match
+        SipMessage inviteTrying = SipMessageUtils.generateSipResponse("100", "Trying",
+                BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB, branchId, callId, fromTag,
+                null /*toTag*/);
+        assertTrue(dialog.isResponseAssociatedWithDialog(inviteTrying));
+        // A response with a different to tag should match
+        inviteTrying = SipMessageUtils.generateSipResponse("100", "Trying",
+                BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB, branchId, callId, fromTag,
+                "testToTag");
+        assertTrue(dialog.isResponseAssociatedWithDialog(inviteTrying));
+        // A response with a different from tag shouldn't match.
+        String fromTag2 = "testFromTag2";
+        inviteTrying = SipMessageUtils.generateSipResponse("100", "Trying",
+                BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB, branchId, callId, fromTag2,
+                null /*toTag*/);
+        assertFalse(dialog.isResponseAssociatedWithDialog(inviteTrying));
+        // A response with a different branch ID shouldn't match.
+        String branchId2 = "testBranchId2";
+        inviteTrying = SipMessageUtils.generateSipResponse("100", "Trying",
+                BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB, branchId2, callId, fromTag,
+                null /*toTag*/);
+        assertFalse(dialog.isResponseAssociatedWithDialog(inviteTrying));
+        // A response with a different call id shouldn't match.
+        String callId2 = "testCallId2";
+        inviteTrying = SipMessageUtils.generateSipResponse("100", "Trying",
+                BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB, branchId, callId2, fromTag,
+                null /*toTag*/);
+        assertFalse(dialog.isResponseAssociatedWithDialog(inviteTrying));
+    }
+
+    @Test
+    public void testFork() {
+        String branchId = "testBranchId";
+        String fromTag = "abcd";
+        String callId = "testCallId";
+        SipMessage inviteRequest = SipMessageUtils.generateSipRequest(
+                SipMessageUtils.INVITE_SIP_METHOD,
+                BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB, SIP_URI_BOB, branchId, callId,
+                fromTag, null /*toTag*/);
+        SipDialog dialog = SipDialog.fromSipMessage(inviteRequest);
+        assertNotNull(dialog);
+        assertEquals(SipDialog.STATE_EARLY, dialog.getState());
+        assertEquals(callId, dialog.getCallId());
+        // receive an earlyResponse
+        dialog.earlyResponse("testToTag");
+        assertEquals(SipDialog.STATE_EARLY, dialog.getState());
+        // fork dialog
+        SipDialog dialogFork = dialog.forkDialog();
+        assertEquals(SipDialog.STATE_EARLY, dialogFork.getState());
+        assertEquals(callId, dialogFork.getCallId());
+        assertNull(dialogFork.getToTag());
+    }
+
+    @Test
+    public void testConfirmDialog() {
+        String branchId = "testBranchId";
+        String fromTag = "abcd";
+        String callId = "testCallId";
+        SipMessage inviteRequest = SipMessageUtils.generateSipRequest(
+                SipMessageUtils.INVITE_SIP_METHOD,
+                BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB, SIP_URI_BOB, branchId, callId,
+                fromTag, null /*toTag*/);
+        SipDialog dialog = SipDialog.fromSipMessage(inviteRequest);
+        assertNotNull(dialog);
+        assertEquals(SipDialog.STATE_EARLY, dialog.getState());
+        assertEquals(callId, dialog.getCallId());
+        // receive a confirm response
+        dialog.confirm("testToTag");
+        assertEquals(SipDialog.STATE_CONFIRMED, dialog.getState());
+        assertEquals(callId, dialog.getCallId());
+    }
+
+    @Test
+    public void testIsRequestAssociated() {
+        String branchId = "testBranchId";
+        String fromTag = "testFromTag";
+        String callId = "testCallId";
+        String toTag = "testToTag";
+        SipMessage inviteRequest = SipMessageUtils.generateSipRequest(
+                SipMessageUtils.INVITE_SIP_METHOD,
+                BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB, SIP_URI_BOB, branchId, callId,
+                fromTag, null /*toTag*/);
+        SipDialog dialog = SipDialog.fromSipMessage(inviteRequest);
+        assertNotNull(dialog);
+        dialog.earlyResponse(toTag);
+
+        SipMessage cancelRequest = SipMessageUtils.generateSipRequest(
+                SipMessageUtils.CANCEL_SIP_METHOD, BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB,
+                SIP_URI_BOB, branchId, callId, fromTag, toTag);
+        assertTrue(dialog.isRequestAssociatedWithDialog(cancelRequest));
+        // cancel request with no toTag should fail
+        cancelRequest = SipMessageUtils.generateSipRequest(
+                SipMessageUtils.INVITE_SIP_METHOD, BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB,
+                SIP_URI_BOB, branchId, callId, fromTag, null /*toTag*/);
+        assertFalse(dialog.isRequestAssociatedWithDialog(cancelRequest));
+        // cancel request to a different dialog in the same session should fail
+        String toTag2 = "testToTag2";
+        cancelRequest = SipMessageUtils.generateSipRequest(
+                SipMessageUtils.INVITE_SIP_METHOD, BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB,
+                SIP_URI_BOB, branchId, callId, fromTag, toTag2);
+        assertFalse(dialog.isRequestAssociatedWithDialog(cancelRequest));
+        // cancel request to a different session should fail (even with the same from/to)
+        String callId2 = "testCallId2";
+        cancelRequest = SipMessageUtils.generateSipRequest(
+                SipMessageUtils.INVITE_SIP_METHOD, BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB,
+                SIP_URI_BOB, branchId, callId2, fromTag, toTag);
+        assertFalse(dialog.isRequestAssociatedWithDialog(cancelRequest));
+        // Same call id but different from and to (although not really possible) should fail.
+        String fromTag3 = "testFromTag3";
+        String toTag3 = "testToTag3";
+        cancelRequest = SipMessageUtils.generateSipRequest(
+                SipMessageUtils.INVITE_SIP_METHOD, BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB,
+                SIP_URI_BOB, branchId, callId, fromTag3, toTag3);
+        assertFalse(dialog.isRequestAssociatedWithDialog(cancelRequest));
+    }
+
+    @Test
+    public void testCloseDialog() {
+        String branchId = "testBranchId";
+        String fromTag = "abcd";
+        String callId = "testCallId";
+        SipMessage inviteRequest = SipMessageUtils.generateSipRequest(
+                SipMessageUtils.INVITE_SIP_METHOD,
+                BASE_CONTACT_URI_ALICE, BASE_CONTACT_URI_BOB, SIP_URI_BOB, branchId, callId,
+                fromTag, null /*toTag*/);
+        SipDialog dialog = SipDialog.fromSipMessage(inviteRequest);
+        assertNotNull(dialog);
+        assertEquals(SipDialog.STATE_EARLY, dialog.getState());
+        assertEquals(callId, dialog.getCallId());
+
+        // receive a confirm response
+        dialog.confirm("testToTag");
+        assertEquals(SipDialog.STATE_CONFIRMED, dialog.getState());
+
+        dialog.close();
+        assertEquals(SipDialog.STATE_CLOSED, dialog.getState());
+    }
+}
diff --git a/tests/src/com/android/services/telephony/rcs/SipMessageParsingUtilsTest.java b/tests/src/com/android/services/telephony/rcs/SipMessageParsingUtilsTest.java
new file mode 100644
index 0000000..ff96eb6
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/SipMessageParsingUtilsTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.rcs;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+
+import android.util.ArraySet;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.telephony.SipMessageParsingUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+public class SipMessageParsingUtilsTest {
+
+    @Test
+    public void testNoAcceptContactHeader() {
+        String header = "Via: SIP/2.0/UDP ex.place.com;branch=z9hG4bK776asdhds";
+        assertTrue(SipMessageParsingUtils.getAcceptContactFeatureTags(header).isEmpty());
+    }
+
+    @Test
+    public void testAcceptContactHeaderMultipleValues() {
+        Set<String> testFeatures = new ArraySet<>(2);
+        // "+a="b,c" should be split into +a="b" and +a="c"
+        testFeatures.add("+a=\"b,c\"");
+        testFeatures.add("+d");
+        testFeatures.add("+e=\"f\"");
+        // These non-feature tags should be filtered out.
+        testFeatures.add("video");
+        testFeatures.add("blah=BLAH");
+        String header = "Via: SIP/2.0/UDP ex.place.com;branch=z9hG4bK776asdhds";
+        header = addFeatures(header, testFeatures);
+        Set<String> features = SipMessageParsingUtils.getAcceptContactFeatureTags(header);
+        assertNotNull(features);
+        assertEquals(4, features.size());
+        assertTrue(features.containsAll(Arrays.asList("+a=\"b\"", "+a=\"c\"", "+d", "+e=\"f\"")));
+    }
+
+    private String addFeatures(String headers, Set<String> features) {
+        StringBuilder newHeader = new StringBuilder(headers + "\n");
+        newHeader.append("Accept-Contact:*");
+        for (String feature : features) {
+            newHeader.append(";").append(feature);
+        }
+        return newHeader.toString();
+    }
+}
diff --git a/tests/src/com/android/services/telephony/rcs/SipMessageUtils.java b/tests/src/com/android/services/telephony/rcs/SipMessageUtils.java
new file mode 100644
index 0000000..8ad0f2a
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/SipMessageUtils.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.rcs;
+
+import android.telephony.ims.SipMessage;
+
+public class SipMessageUtils {
+
+    public static final String INVITE_SIP_METHOD = "INVITE";
+    public static final String CANCEL_SIP_METHOD = "CANCEL";
+    public static final String BYE_SIP_METHOD = "BYE";
+    public static final String ACK_SIP_METHOD = "ACK";
+    public static final String BASE_ADDRESS = "client.example.com";
+
+    private static final String PARAM_SEPARATOR = ";";
+    private static final String PARAM_KEY_VALUE_SEPARATOR = "=";
+    private static final String BASE_VIA_HEADER_VALUE = "SIP/2.0/TCP " + BASE_ADDRESS + ":5060";
+
+    /**
+     * @return A new SIP request from the given parameters.
+     */
+    public static SipMessage generateSipRequest(String requestMethod, String fromContact,
+            String toContact, String toUri, String branchId, String callId, String fromTag,
+            String toTag) {
+        String header = "Via: " + addParamToHeader(BASE_VIA_HEADER_VALUE, "branch", branchId);
+        header += "\n";
+        header += "From: " + addParamToHeader(fromContact, "tag", fromTag);
+        header += "\n";
+        // To tag is optional
+        header += "To: " + ((toTag != null)
+                ? addParamToHeader(toContact, "tag", toTag) : toContact);
+        header += "\n";
+        header += "Call-ID: " + callId;
+        return new SipMessage(requestMethod + " " + toUri + " SIP/2.0", header, new byte[0]);
+    }
+
+    /**
+     * @return Generates a SIP response.
+     */
+    public static SipMessage generateSipResponse(String statusCode, String statusString,
+            String fromContact, String toContact, String branchId, String callId, String fromTag,
+            String toTag) {
+        String header = "Via: " + addParamToHeader(BASE_VIA_HEADER_VALUE, "branch", branchId);
+        header += "\n";
+        header += "From: " + addParamToHeader(fromContact, "tag", fromTag);
+        header += "\n";
+        // To tag is optional
+        header += "To: " + ((toTag != null)
+                ? addParamToHeader(toContact, "tag", toTag) : toContact);
+        header += "\n";
+        header += "Call-ID: " + callId;
+        return new SipMessage("SIP/2.0 " + statusCode + " " + statusString, header,
+                new byte[0]);
+    }
+
+    private static String addParamToHeader(String headerValue, String paramKey, String paramValue) {
+        headerValue += PARAM_SEPARATOR + paramKey.trim() + PARAM_KEY_VALUE_SEPARATOR
+                + paramValue.trim();
+        return headerValue;
+    }
+}
diff --git a/tests/src/com/android/services/telephony/rcs/SipSessionTrackerTest.java b/tests/src/com/android/services/telephony/rcs/SipSessionTrackerTest.java
new file mode 100644
index 0000000..823a8be
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/SipSessionTrackerTest.java
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.rcs;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+
+import android.net.Uri;
+import android.telephony.ims.SipMessage;
+import android.util.Base64;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@RunWith(AndroidJUnit4.class)
+public class SipSessionTrackerTest {
+
+    private class DialogAttributes {
+        public final String branchId;
+        public final String callId;
+        public final String fromHeader;
+        public final String fromTag;
+        public final String toUri;
+        public final String toHeader;
+        private final String mFromUri;
+        // This may be populated later.
+        public String toTag;
+
+        DialogAttributes() {
+            branchId = getNextString();
+            callId = getNextString();
+            mFromUri = generateRandomSipUri();
+            fromHeader = generateContactUri(mFromUri);
+            fromTag = getNextString();
+            toUri = generateRandomSipUri();
+            toHeader = generateContactUri(toUri);
+        }
+
+        private DialogAttributes(String branchId, String callId, String fromUri,
+                String fromTag, String toUri, String toTag) {
+            this.branchId = branchId;
+            this.callId = callId;
+            this.mFromUri = fromUri;
+            this.fromHeader = generateContactUri(fromUri);
+            this.fromTag = fromTag;
+            this.toUri = toUri;
+            this.toHeader = generateContactUri(toUri);
+            this.toTag = toTag;
+        }
+
+        public void setToTag() {
+            if (toTag == null) {
+                toTag = getNextString();
+            }
+        }
+
+        public DialogAttributes fromExisting() {
+            return new DialogAttributes(branchId, callId, mFromUri, fromTag, toUri, null);
+        }
+
+        public DialogAttributes invertFromTo() {
+            return new DialogAttributes(branchId, callId, toUri, fromTag, mFromUri, toTag);
+        }
+    }
+
+    // Keep track of the string entry so we can generate unique strings.
+    private int mStringEntryCounter = 0;
+    private SipSessionTracker mTrackerUT;
+
+    @Before
+    public void setUp() {
+        mStringEntryCounter = 0;
+        mTrackerUT = new SipSessionTracker();
+    }
+
+    @Test
+    public void testEarlyDialogToConfirmed() {
+        DialogAttributes attr = new DialogAttributes();
+        // INVITE A -> B
+        SipMessage inviteRequest = generateSipRequest(SipMessageUtils.INVITE_SIP_METHOD, attr);
+        filterMessage(inviteRequest, attr);
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getEarlyDialogs(), attr);
+        // 100 TRYING A <- proxy
+        SipMessage inviteTrying = generateSipResponse("100", "Trying", attr);
+        filterMessage(inviteTrying, attr);
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getEarlyDialogs(), attr);
+        // INVITE proxy -> B
+        // (BOB generates To tag)
+        attr.setToTag();
+        // 180 RINGING proxy <- B
+        // 180 RINGING A <- proxy
+        SipMessage inviteRinging = generateSipResponse("180", "Ringing", attr);
+        filterMessage(inviteRinging, attr);
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getEarlyDialogs(), attr);
+        // User answers phone
+        // 200 OK proxy <- B
+        // 200 OK A <- proxy
+        SipMessage inviteConfirm = generateSipResponse("200", "OK", attr);
+        filterMessage(inviteConfirm, attr);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getConfirmedDialogs(), attr);
+    }
+
+    @Test
+    public void testForkDialog() {
+        DialogAttributes attrB1 = new DialogAttributes();
+        // INVITE A -> B
+        SipMessage inviteRequest = generateSipRequest(SipMessageUtils.INVITE_SIP_METHOD, attrB1);
+        filterMessage(inviteRequest, attrB1);
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getEarlyDialogs(), attrB1);
+        // INVITE proxy -> B
+        // (BOB generates To tag)
+        attrB1.setToTag();
+        // 180 RINGING proxy <- B1
+        // 180 RINGING A <- proxy
+        SipMessage inviteRingingB1 = generateSipResponse("180", "Ringing", attrB1);
+        filterMessage(inviteRingingB1, attrB1);
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getEarlyDialogs(), attrB1);
+        // Now get another RINGING indication from another device associated with the same user.
+        // 180 RINGING proxy <- B2
+        // 180 RINGING A <- proxy
+        DialogAttributes attrB2 = attrB1.fromExisting();
+        // set different To tag
+        attrB2.setToTag();
+        SipMessage inviteRingingB2 = generateSipResponse("180", "Ringing", attrB2);
+        filterMessage(inviteRingingB2, attrB2);
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getEarlyDialogs(), attrB1, attrB2);
+        // User answers B1
+        // 200 OK proxy <- B1
+        // 200 OK A <- proxy
+        SipMessage inviteConfirm = generateSipResponse("200", "OK", attrB1);
+        filterMessage(inviteConfirm, attrB1);
+        verifyContainsCallIds(mTrackerUT.getEarlyDialogs(), attrB2);
+        verifyContainsCallIds(mTrackerUT.getConfirmedDialogs(), attrB1);
+        // Receive indication that B2 is terminated because user answered on B1
+        // 487 A <- proxy
+        SipMessage terminatedResponse = generateSipResponse("487",
+                "Request Terminated", attrB2);
+        filterMessage(terminatedResponse, attrB2);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getConfirmedDialogs(), attrB1);
+        verifyContainsCallIds(mTrackerUT.getClosedDialogs(), attrB2);
+        SipMessage byeRequest = generateSipRequest(SipMessageUtils.BYE_SIP_METHOD, attrB1);
+        // Send BYE request for the open dialog.
+        filterMessage(byeRequest, attrB1);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getClosedDialogs(), attrB1, attrB2);
+        // Clean up the session and ensure the close dialog is completely removed from the tracker.
+        mTrackerUT.cleanupSession(attrB1.callId);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        assertTrue(mTrackerUT.getClosedDialogs().isEmpty());
+    }
+
+    @Test
+    public void testCloseLocalDialog() {
+        DialogAttributes attr = new DialogAttributes();
+        attr.setToTag();
+        createConfirmedDialog(attr);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getConfirmedDialogs(), attr);
+
+        // Send BYE request for a dialog that was started locally and ensure that we see the call id
+        // move to the closed list.
+        SipMessage byeRequest = generateSipRequest(SipMessageUtils.BYE_SIP_METHOD, attr);
+        filterMessage(byeRequest, attr);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getClosedDialogs(), attr);
+        // Clean up the session and ensure the close dialog is completely removed from the tracker.
+        mTrackerUT.cleanupSession(attr.callId);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        assertTrue(mTrackerUT.getClosedDialogs().isEmpty());
+    }
+
+    @Test
+    public void testAcceptContactFts() {
+        DialogAttributes attr = new DialogAttributes();
+        attr.setToTag();
+        SipMessage inviteRequest = generateSipRequest(
+                SipMessageUtils.INVITE_SIP_METHOD,
+                attr);
+        // add accept contact header
+        inviteRequest = new SipMessage(inviteRequest.getStartLine(),
+                inviteRequest.getHeaderSection() + "\nAccept-Contact:*;+test",
+                new byte[0]);
+        filterMessage(inviteRequest, attr);
+        assertTrue(mTrackerUT.getCallIdsAssociatedWithFeatureTag(Collections.singleton("+test"))
+                .contains(attr.callId));
+    }
+
+    @Test
+    public void testCloseRemoteDialog() {
+        DialogAttributes remoteAttr = new DialogAttributes();
+        remoteAttr.setToTag();
+        createConfirmedDialog(remoteAttr);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getConfirmedDialogs(), remoteAttr);
+
+        // Send BYE request on a dialog that was started from the remote party.
+        DialogAttributes localAttr = remoteAttr.invertFromTo();
+        SipMessage byeRequest = generateSipRequest(SipMessageUtils.BYE_SIP_METHOD, localAttr);
+        filterMessage(byeRequest, localAttr);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getClosedDialogs(), remoteAttr);
+        // Clean up the session and ensure the dialog is completely removed from the tracker.
+        mTrackerUT.cleanupSession(remoteAttr.callId);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        assertTrue(mTrackerUT.getClosedDialogs().isEmpty());
+    }
+
+    @Test
+    public void testCleanupConfirmedDialog() {
+        DialogAttributes attr = new DialogAttributes();
+        attr.setToTag();
+        createConfirmedDialog(attr);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getConfirmedDialogs(), attr);
+        // Clean up the session and ensure the dialog is completely removed from the tracker.
+        mTrackerUT.cleanupSession(attr.callId);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        assertTrue(mTrackerUT.getClosedDialogs().isEmpty());
+    }
+
+    @Test
+    public void testMultipleDialogs() {
+        DialogAttributes attr1 = new DialogAttributes();
+        createConfirmedDialog(attr1);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getConfirmedDialogs(), attr1);
+        // add a second dialog
+        DialogAttributes attr2 = new DialogAttributes();
+        createConfirmedDialog(attr2);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getConfirmedDialogs(), attr1, attr2);
+        // Send BYE request on dialogs
+        SipMessage byeRequest = generateSipRequest(SipMessageUtils.BYE_SIP_METHOD, attr1);
+        filterMessage(byeRequest, attr1);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getConfirmedDialogs(), attr2);
+        verifyContainsCallIds(mTrackerUT.getClosedDialogs(), attr1);
+        mTrackerUT.cleanupSession(attr1.callId);
+        // Send BYE request on dialogs
+        byeRequest = generateSipRequest(SipMessageUtils.BYE_SIP_METHOD, attr2);
+        filterMessage(byeRequest, attr2);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getClosedDialogs(), attr2);
+        mTrackerUT.cleanupSession(attr2.callId);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        assertTrue(mTrackerUT.getClosedDialogs().isEmpty());
+    }
+
+    @Test
+    public void testAcknowledgeMessageFailed() {
+        DialogAttributes attr = new DialogAttributes();
+        SipMessage inviteRequest = generateSipRequest(SipMessageUtils.INVITE_SIP_METHOD, attr);
+        mTrackerUT.filterSipMessage(inviteRequest);
+        // Do not acknowledge the request and ensure that the operation has not been applied yet.
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        // send message ack failed event, the operation shouldn't have been applied
+        mTrackerUT.pendingMessageFailed(attr.branchId);
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+    }
+
+    @Test
+    public void testAcknowledgeBatchEvents() {
+        DialogAttributes attr = new DialogAttributes();
+        SipMessage inviteRequest = generateSipRequest(SipMessageUtils.INVITE_SIP_METHOD, attr);
+        attr.setToTag();
+        SipMessage inviteConfirm = generateSipResponse("200", "OK", attr);
+        // We unexpectedly received two filter requests for the same branchId without
+        // acknowledgePendingMessage being called in between. Ensure that when it is called, it
+        // applies both operations.
+        mTrackerUT.filterSipMessage(inviteRequest);
+        mTrackerUT.filterSipMessage(inviteConfirm);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        assertTrue(mTrackerUT.getConfirmedDialogs().isEmpty());
+        // we should skip right to confirmed as both operations run back-to-back
+        mTrackerUT.acknowledgePendingMessage(attr.branchId);
+        assertTrue(mTrackerUT.getEarlyDialogs().isEmpty());
+        verifyContainsCallIds(mTrackerUT.getConfirmedDialogs(), attr);
+    }
+
+    private void filterMessage(SipMessage m, DialogAttributes attr) {
+        mTrackerUT.filterSipMessage(m);
+        mTrackerUT.acknowledgePendingMessage(attr.branchId);
+    }
+    private void verifyContainsCallIds(Set<SipDialog> callIdSet, DialogAttributes... attrs) {
+        Set<String> callIds = Arrays.stream(attrs).map(a -> a.callId).collect(
+                Collectors.toSet());
+        assertTrue(callIdSet.stream().map(SipDialog::getCallId).collect(Collectors.toSet())
+                .containsAll(callIds));
+    }
+
+    private SipMessage generateSipRequest(String requestMethod,
+            DialogAttributes attr) {
+        return SipMessageUtils.generateSipRequest(requestMethod, attr.fromHeader, attr.toHeader,
+                attr.toUri, attr.branchId, attr.callId, attr.fromTag, attr.toTag);
+    }
+    private SipMessage generateSipResponse(String statusCode, String statusString,
+            DialogAttributes attr) {
+        return SipMessageUtils.generateSipResponse(statusCode, statusString, attr.fromHeader,
+                attr.toHeader, attr.branchId, attr.callId, attr.fromTag, attr.toTag);
+    }
+
+    private String generateContactUri(String sipUri) {
+        Uri uri = Uri.parse(sipUri);
+        assertNotNull(uri);
+        String[] user = uri.getSchemeSpecificPart().split("@", 2);
+        assertNotNull(user);
+        assertEquals(2, user.length);
+        return user[0] + " <" + sipUri + ">";
+    }
+
+    private String generateRandomSipUri() {
+        return "sip:" + getNextString() + "@" + SipMessageUtils.BASE_ADDRESS;
+    }
+
+    private void createConfirmedDialog(DialogAttributes attr) {
+        // INVITE ALICE -> BOB
+        SipMessage inviteRequest = generateSipRequest(
+                SipMessageUtils.INVITE_SIP_METHOD,
+                attr);
+        filterMessage(inviteRequest, attr);
+        attr.setToTag();
+        // skip to confirmed state for test.
+        SipMessage inviteConfirm = generateSipResponse("200", "OK",
+                attr);
+        filterMessage(inviteConfirm, attr);
+    }
+
+    private String getNextString() {
+        // Get a string representation of the entry counter
+        byte[] idByteArray = ByteBuffer.allocate(4).putInt(mStringEntryCounter++).array();
+        return Base64.encodeToString(idByteArray,
+                Base64.NO_WRAP | Base64.NO_PADDING | Base64.URL_SAFE);
+    }
+}
diff --git a/tests/src/com/android/services/telephony/rcs/TransportSipMessageValidatorTest.java b/tests/src/com/android/services/telephony/rcs/TransportSipMessageValidatorTest.java
index c991a8c..4d222e3 100644
--- a/tests/src/com/android/services/telephony/rcs/TransportSipMessageValidatorTest.java
+++ b/tests/src/com/android/services/telephony/rcs/TransportSipMessageValidatorTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.net.InetAddresses;
@@ -30,6 +31,7 @@
 import android.telephony.ims.SipDelegateConfiguration;
 import android.telephony.ims.SipDelegateManager;
 import android.telephony.ims.SipMessage;
+import android.util.ArraySet;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -37,7 +39,6 @@
 import com.android.TestExecutorService;
 import com.android.services.telephony.rcs.validator.IncomingTransportStateValidator;
 import com.android.services.telephony.rcs.validator.OutgoingTransportStateValidator;
-import com.android.services.telephony.rcs.validator.SipMessageValidator;
 import com.android.services.telephony.rcs.validator.ValidationResult;
 
 import org.junit.After;
@@ -48,6 +49,7 @@
 
 import java.net.InetSocketAddress;
 import java.util.Collections;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ScheduledExecutorService;
 
 @RunWith(AndroidJUnit4.class)
@@ -61,7 +63,7 @@
                     + "Max-Forwards: 70\n"
                     + "To: Bob <sip:bob@biloxi.com>\n"
                     + "From: Alice <sip:alice@atlanta.com>;tag=1928301774\n"
-                    + "Call-ID: a84b4c76e66710@pc33.atlanta.com\n"
+                    + "Call-ID: testid\n"
                     + "CSeq: 314159 INVITE\n"
                     + "Contact: <sip:alice@pc33.atlanta.com>\n"
                     + "Content-Type: application/sdp\n"
@@ -69,11 +71,11 @@
             new byte[0]);
 
     @Mock
+    private SipSessionTracker mSipSessionTracker;
+    @Mock
     private IncomingTransportStateValidator mIncomingStateValidator;
     @Mock
     private OutgoingTransportStateValidator mOutgoingStateValidator;
-    @Mock
-    private SipMessageValidator mStatelessValidator;
 
     @Before
     public void setUp() throws Exception {
@@ -90,19 +92,15 @@
         TestExecutorService executor = new TestExecutorService();
         TransportSipMessageValidator tracker = getTestTracker(executor);
         tracker.onTransportOpened(Collections.emptySet(), Collections.emptySet());
-        verify(mOutgoingStateValidator).open();
+        verify(mOutgoingStateValidator).open(Collections.emptySet(), Collections.emptySet());
         verify(mIncomingStateValidator).open();
         // Incoming messages are already verified
         assertTrue(isIncomingTransportOpen(tracker));
-        // IMS config and registration state needs to be sent before outgoing messages can be
-        // verified.
+        // IMS config needs to be sent before outgoing messages can be verified.
         assertFalse(isOutgoingTransportOpen(tracker));
         tracker.onConfigurationChanged(getConfigBuilder(TEST_CONFIG_VERSION).build());
         // Incoming messages are already verified
-        assertTrue(isIncomingTransportOpen(tracker));
-        assertFalse(isOutgoingTransportOpen(tracker));
-        tracker.onRegistrationStateChanged((ignore) -> {}, getTestRegistrationState());
-        // Config set + IMS reg state sent, transport is now open.
+        // Config set, transport is now open.
         assertTrue(isIncomingTransportOpen(tracker));
         assertTrue(isOutgoingTransportOpen(tracker));
     }
@@ -110,13 +108,7 @@
     @Test
     public void testTransportOpenConfigChange() {
         TestExecutorService executor = new TestExecutorService();
-        TransportSipMessageValidator tracker = getTestTracker(executor);
-        tracker.onTransportOpened(Collections.emptySet(), Collections.emptySet());
-        tracker.onConfigurationChanged(getConfigBuilder(TEST_CONFIG_VERSION).build());
-        tracker.onRegistrationStateChanged((ignore) -> {}, getTestRegistrationState());
-        // Config set + IMS reg state sent, transport is now open.
-        assertTrue(isIncomingTransportOpen(tracker));
-        assertTrue(isOutgoingTransportOpen(tracker));
+        TransportSipMessageValidator tracker = openTransport(executor);
 
         // Update IMS config version and send a message with an outdated version.
         tracker.onConfigurationChanged(getConfigBuilder(TEST_CONFIG_VERSION + 1).build());
@@ -125,25 +117,165 @@
     }
 
     @Test
-    public void testTransportClosingGracefully() {
+    public void testSessionTrackerFiltering() {
+        TestExecutorService executor = new TestExecutorService();
+        TransportSipMessageValidator tracker = openTransport(executor);
+        // Since the incoming/outgoing messages were verified, there should have been two calls
+        // to filter the message.
+        verify(mSipSessionTracker, times(2)).filterSipMessage(TEST_MESSAGE);
+        // ensure pass through methods are working
+        tracker.acknowledgePendingMessage("abc");
+        verify(mSipSessionTracker).acknowledgePendingMessage("abc");
+        tracker.notifyPendingMessageFailed("abc");
+        verify(mSipSessionTracker).pendingMessageFailed("abc");
+        tracker.onSipSessionCleanup("abc");
+        verify(mSipSessionTracker).cleanupSession("abc");
+        // Now have validators return a non-successful result for validation and the tracker should
+        // not get the indication to filter the message.
+        doReturn(new ValidationResult(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED,
+                "")).when(mOutgoingStateValidator).validate(any());
+        doReturn(new ValidationResult(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED,
+                "")).when(mIncomingStateValidator).validate(any());
+        assertFalse(tracker.verifyIncomingMessage(TEST_MESSAGE).isValidated);
+        assertFalse(tracker.verifyOutgoingMessage(TEST_MESSAGE, TEST_CONFIG_VERSION).isValidated);
+        // The number of times the filter method was called should still only be two after these
+        // messages were not validated.
+        verify(mSipSessionTracker, times(2)).filterSipMessage(TEST_MESSAGE);
+    }
+
+
+    @Test
+    public void testTransportClosingGracefullyNoPendingSessions() {
         TestExecutorService executor = new TestExecutorService(true /*wait*/);
-        TransportSipMessageValidator tracker = getTestTracker(executor);
-        tracker.onTransportOpened(Collections.emptySet(), Collections.emptySet());
-        tracker.onConfigurationChanged(getConfigBuilder(TEST_CONFIG_VERSION).build());
-        tracker.onRegistrationStateChanged((ignore) -> {}, getTestRegistrationState());
-        // Config set + IMS reg state sent, transport is now open.
-        assertTrue(isIncomingTransportOpen(tracker));
-        assertTrue(isOutgoingTransportOpen(tracker));
+        TransportSipMessageValidator tracker = openTransport(executor);
 
-        tracker.closeSessionsGracefully((ignore) -> {},
-                SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
+        doReturn(Collections.emptySet()).when(mSipSessionTracker).getTrackedDialogs();
+        ArraySet<String> pendingCallIds = new ArraySet<>();
+        CountDownLatch l = new CountDownLatch(1);
+        tracker.closeSessionsGracefully((ids) -> {
+            pendingCallIds.addAll(ids);
+            l.countDown();
+        }, SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
                 SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED);
+        // Since there are no pending call ids, this should be completed with no call ids pending.
+        assertEquals(0, l.getCount());
+        assertTrue(pendingCallIds.isEmpty());
+        verify(mOutgoingStateValidator).close(anyInt());
+        verify(mIncomingStateValidator).close(anyInt());
+    }
 
-        // Before executor executes, outgoing messages will be restricted.
+    @Test
+    public void testTransportClosingGracefullyCloseCallIds() {
+        TestExecutorService executor = new TestExecutorService(true /*wait*/);
+        TransportSipMessageValidator tracker = openTransport(executor);
+
+        ArraySet<SipDialog> dialogs = new ArraySet<>();
+        dialogs.add(SipDialog.fromSipMessage(TEST_MESSAGE));
+        doReturn(dialogs).when(mSipSessionTracker).getTrackedDialogs();
+        ArraySet<String> pendingCallIds = new ArraySet<>();
+        CountDownLatch l = new CountDownLatch(1);
+        tracker.closeSessionsGracefully((ids) -> {
+            pendingCallIds.addAll(ids);
+            l.countDown();
+        }, SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
+                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED);
+        // Before executor executes, outgoing messages will be restricted due to pending call ids.
+        assertTrue(l.getCount() >= 1);
+        assertTrue(pendingCallIds.isEmpty());
         assertTrue(isIncomingTransportOpen(tracker));
         verify(mOutgoingStateValidator).restrict(anyInt());
+        // pretend a sip message has been acknowledged, which closed pending call id. Since there
+        // are no more pending call ids, the transport should move to closed.
+        dialogs.clear();
+        tracker.acknowledgePendingMessage("blah");
+        assertEquals(0, l.getCount());
+        assertTrue(pendingCallIds.isEmpty());
+        verify(mOutgoingStateValidator).close(anyInt());
+        verify(mIncomingStateValidator).close(anyInt());
+    }
+
+    @Test
+    public void testTransportClosingGracefullyThenForceClose() {
+        TestExecutorService executor = new TestExecutorService(true /*wait*/);
+        TransportSipMessageValidator tracker = openTransport(executor);
+
+        ArraySet<SipDialog> dialogs = new ArraySet<>();
+        dialogs.add(SipDialog.fromSipMessage(TEST_MESSAGE));
+        doReturn(dialogs).when(mSipSessionTracker).getTrackedDialogs();
+        ArraySet<String> pendingCallIds = new ArraySet<>();
+        CountDownLatch l = new CountDownLatch(1);
+        tracker.closeSessionsGracefully((ids) -> {
+            pendingCallIds.addAll(ids);
+            l.countDown();
+        }, SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
+                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED);
+        // Before executor executes, outgoing messages will be restricted due to pending call ids.
+        assertTrue(l.getCount() >= 1);
+        assertTrue(pendingCallIds.isEmpty());
+        assertTrue(isIncomingTransportOpen(tracker));
+        verify(mOutgoingStateValidator).restrict(anyInt());
+        // force close amd ensure pending close is
+        assertTrue(tracker.closeSessions(
+                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED).isEmpty());
+        assertEquals(0, l.getCount());
+        assertEquals(pendingCallIds, pendingCallIds);
+        verify(mOutgoingStateValidator).close(anyInt());
+        verify(mIncomingStateValidator).close(anyInt());
+    }
+
+    @Test
+    public void testTransportClosingGracefullyTimeout() {
+        TestExecutorService executor = new TestExecutorService(true /*wait*/);
+        TransportSipMessageValidator tracker = openTransport(executor);
+
+        ArraySet<SipDialog> dialogs = new ArraySet<>();
+        dialogs.add(SipDialog.fromSipMessage(TEST_MESSAGE));
+        doReturn(dialogs).when(mSipSessionTracker).getTrackedDialogs();
+        ArraySet<String> pendingCallIds = new ArraySet<>();
+        CountDownLatch l = new CountDownLatch(1);
+        tracker.closeSessionsGracefully((ids) -> {
+            pendingCallIds.addAll(ids);
+            l.countDown();
+        }, SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
+                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED);
+        // Before executor executes, outgoing messages will be restricted due to pending call ids.
+        assertTrue(l.getCount() >= 1);
+        assertTrue(pendingCallIds.isEmpty());
+        assertTrue(isIncomingTransportOpen(tracker));
+        verify(mOutgoingStateValidator).restrict(anyInt());
+        // Process timeout event - pending call id should be passed to transport.
         executor.executePending();
-        // After Executor executes, all messages will be rejected.
+        assertEquals(0, l.getCount());
+        assertTrue(pendingCallIds.contains("testid"));
+        verify(mOutgoingStateValidator).close(anyInt());
+        verify(mIncomingStateValidator).close(anyInt());
+    }
+
+    @Test
+    public void testTransportClosingGracefullyCleanup() {
+        TestExecutorService executor = new TestExecutorService(true /*wait*/);
+        TransportSipMessageValidator tracker = openTransport(executor);
+
+        ArraySet<SipDialog> dialogs = new ArraySet<>();
+        dialogs.add(SipDialog.fromSipMessage(TEST_MESSAGE));
+        doReturn(dialogs).when(mSipSessionTracker).getTrackedDialogs();
+        ArraySet<String> pendingCallIds = new ArraySet<>();
+        CountDownLatch l = new CountDownLatch(1);
+        tracker.closeSessionsGracefully((ids) -> {
+            pendingCallIds.addAll(ids);
+            l.countDown();
+        }, SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
+                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED);
+        // Before executor executes, outgoing messages will be restricted due to pending call ids.
+        assertTrue(l.getCount() >= 1);
+        assertTrue(pendingCallIds.isEmpty());
+        assertTrue(isIncomingTransportOpen(tracker));
+        verify(mOutgoingStateValidator).restrict(anyInt());
+        // Mock cleanupSession event was called for pending callId
+        dialogs.clear();
+        tracker.onSipSessionCleanup("abc");
+        assertEquals(0, l.getCount());
+        assertTrue(pendingCallIds.isEmpty());
         verify(mOutgoingStateValidator).close(anyInt());
         verify(mIncomingStateValidator).close(anyInt());
     }
@@ -151,22 +283,162 @@
     @Test
     public void testTransportClosingForcefully() {
         TestExecutorService executor = new TestExecutorService();
-        TransportSipMessageValidator tracker = getTestTracker(executor);
-        tracker.onTransportOpened(Collections.emptySet(), Collections.emptySet());
-        tracker.onConfigurationChanged(getConfigBuilder(TEST_CONFIG_VERSION).build());
-        tracker.onRegistrationStateChanged((ignore) -> {}, getTestRegistrationState());
-        // Config set + IMS reg state sent, transport is now open.
-        assertTrue(isIncomingTransportOpen(tracker));
-        assertTrue(isOutgoingTransportOpen(tracker));
+        TransportSipMessageValidator tracker = openTransport(executor);
 
-        tracker.closeSessionsForcefully(
-                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED);
+        tracker.closeSessions(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED);
 
         // All messages will be rejected.
         verify(mOutgoingStateValidator).close(anyInt());
         verify(mIncomingStateValidator).close(anyInt());
     }
 
+    @Test
+    public void setRegStateChangedNoPendingCallIds() {
+        TestExecutorService executor = new TestExecutorService(true /*wait*/);
+        TransportSipMessageValidator tracker = openTransport(executor);
+
+        doReturn(Collections.emptySet()).when(mSipSessionTracker)
+                .getCallIdsAssociatedWithFeatureTag(any());
+        ArraySet<String> pendingCallIds = new ArraySet<>();
+        CountDownLatch l = new CountDownLatch(1);
+        // no feature tags are deregistering/deregistered, should return immediately
+        tracker.onRegistrationStateChanged((ids) -> {
+            pendingCallIds.addAll(ids);
+            l.countDown();
+        }, getTestRegistrationState());
+        verify(mOutgoingStateValidator, times(2)).restrictFeatureTags(Collections.emptySet());
+        assertTrue(pendingCallIds.isEmpty());
+        assertEquals(0, l.getCount());
+    }
+
+    @Test
+    public void setRegStateChangedPendingCallIdsMultipleCalls() {
+        TestExecutorService executor = new TestExecutorService(true /*wait*/);
+        TransportSipMessageValidator tracker = openTransport(executor);
+
+        ArraySet<String> callIds = new ArraySet<>(1);
+        callIds.add("abc");
+        doReturn(callIds).when(mSipSessionTracker)
+                .getCallIdsAssociatedWithFeatureTag(any());
+        ArraySet<String> pendingCallIds = new ArraySet<>();
+        CountDownLatch l = new CountDownLatch(2);
+        tracker.onRegistrationStateChanged((ids) -> {
+            pendingCallIds.addAll(ids);
+            l.countDown();
+        }, getTestRegistrationState());
+        assertEquals(2, l.getCount());
+        // If called again, the previous request will complete with no call ids
+        tracker.onRegistrationStateChanged((ids) -> {
+            pendingCallIds.addAll(ids);
+            l.countDown();
+        }, getTestRegistrationState());
+        assertEquals(1, l.getCount());
+        assertTrue(pendingCallIds.isEmpty());
+        // Simulate timeout - we should get callback with the pending call ids.
+        executor.executePending();
+        assertEquals(0, l.getCount());
+        assertEquals(callIds, pendingCallIds);
+    }
+
+    @Test
+    public void setRegStateChangedPendingCallIdsTimeout() {
+        TestExecutorService executor = new TestExecutorService(true /*wait*/);
+        TransportSipMessageValidator tracker = openTransport(executor);
+
+        ArraySet<String> callIds = new ArraySet<>(1);
+        callIds.add("abc");
+        doReturn(callIds).when(mSipSessionTracker)
+                .getCallIdsAssociatedWithFeatureTag(any());
+        ArraySet<String> pendingCallIds = new ArraySet<>();
+        CountDownLatch l = new CountDownLatch(1);
+        tracker.onRegistrationStateChanged((ids) -> {
+            pendingCallIds.addAll(ids);
+            l.countDown();
+        }, getTestRegistrationState());
+        assertEquals(1, l.getCount());
+        assertTrue(pendingCallIds.isEmpty());
+        // Simulate timeout - we should get callback with the pending call ids.
+        executor.executePending();
+        assertEquals(0, l.getCount());
+        assertEquals(callIds, pendingCallIds);
+    }
+
+    @Test
+    public void setRegStateChangedPendingCallIdsResolved() {
+        TestExecutorService executor = new TestExecutorService(true /*wait*/);
+        TransportSipMessageValidator tracker = openTransport(executor);
+
+        ArraySet<String> callIds = new ArraySet<>(1);
+        callIds.add("abc");
+        doReturn(callIds).when(mSipSessionTracker)
+                .getCallIdsAssociatedWithFeatureTag(any());
+        ArraySet<String> pendingCallIds = new ArraySet<>();
+        CountDownLatch l = new CountDownLatch(1);
+        tracker.onRegistrationStateChanged((ids) -> {
+            pendingCallIds.addAll(ids);
+            l.countDown();
+        }, getTestRegistrationState());
+        assertEquals(1, l.getCount());
+        assertTrue(pendingCallIds.isEmpty());
+        // Simulate ack pending SIP session, which has cleared pending call id
+        doReturn(Collections.emptySet()).when(mSipSessionTracker)
+                .getCallIdsAssociatedWithFeatureTag(any());
+        tracker.acknowledgePendingMessage("blah");
+        assertEquals(0, l.getCount());
+        assertEquals(callIds, pendingCallIds);
+    }
+
+    @Test
+    public void setRegStateChangedPendingCallIdsChanged() {
+        TestExecutorService executor = new TestExecutorService(true /*wait*/);
+        TransportSipMessageValidator tracker = openTransport(executor);
+
+        ArraySet<String> callIds = new ArraySet<>(1);
+        callIds.add("abc");
+        doReturn(callIds).when(mSipSessionTracker)
+                .getCallIdsAssociatedWithFeatureTag(any());
+        ArraySet<String> pendingCallIds = new ArraySet<>();
+        CountDownLatch l = new CountDownLatch(1);
+        tracker.onRegistrationStateChanged((ids) -> {
+            pendingCallIds.addAll(ids);
+            l.countDown();
+        }, getTestRegistrationState());
+        assertEquals(1, l.getCount());
+        assertTrue(pendingCallIds.isEmpty());
+        // Simulate pending callIds changed to add another session.
+        callIds.add("def");
+        executor.executePending();
+        assertEquals(0, l.getCount());
+        assertEquals(callIds, pendingCallIds);
+    }
+
+    @Test
+    public void setRegStateRegThenClose() {
+        TestExecutorService executor = new TestExecutorService(true /*wait*/);
+        TransportSipMessageValidator tracker = openTransport(executor);
+
+        ArraySet<String> callIds = new ArraySet<>(1);
+        callIds.add("abc");
+        doReturn(callIds).when(mSipSessionTracker)
+                .getCallIdsAssociatedWithFeatureTag(any());
+        ArraySet<String> pendingCallIds = new ArraySet<>();
+        CountDownLatch l = new CountDownLatch(1);
+        tracker.onRegistrationStateChanged((ids) -> {
+            pendingCallIds.addAll(ids);
+            l.countDown();
+        }, getTestRegistrationState());
+        assertEquals(1, l.getCount());
+        assertTrue(pendingCallIds.isEmpty());
+        // If close is called during pending reg state change, it should be completed with no
+        // pending call IDs (close will take care of closing everything).
+        ArraySet<SipDialog> dialogs = new ArraySet<>();
+        dialogs.add(SipDialog.fromSipMessage(TEST_MESSAGE));
+        doReturn(dialogs).when(mSipSessionTracker).getTrackedDialogs();
+        tracker.closeSessions(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD);
+        assertEquals(0, l.getCount());
+        assertEquals(Collections.emptySet(), pendingCallIds);
+    }
+
     private SipDelegateConfiguration.Builder getConfigBuilder(int version) {
         InetSocketAddress localAddr = new InetSocketAddress(
                 InetAddresses.parseNumericAddress("1.1.1.1"), 80);
@@ -176,7 +448,6 @@
                 SipDelegateConfiguration.SIP_TRANSPORT_TCP, localAddr, serverAddr);
     }
 
-
     private boolean isIncomingTransportOpen(TransportSipMessageValidator tracker) {
         return tracker.verifyIncomingMessage(TEST_MESSAGE).isValidated;
     }
@@ -195,15 +466,22 @@
         return new DelegateRegistrationState.Builder().build();
     }
 
+    private TransportSipMessageValidator openTransport(ScheduledExecutorService executor) {
+        TransportSipMessageValidator tracker = getTestTracker(executor);
+        tracker.onTransportOpened(Collections.emptySet(), Collections.emptySet());
+        tracker.onConfigurationChanged(getConfigBuilder(TEST_CONFIG_VERSION).build());
+        tracker.onRegistrationStateChanged((ignore) -> {}, getTestRegistrationState());
+        // Config set + IMS reg state sent, transport is now open.
+        assertTrue(isIncomingTransportOpen(tracker));
+        assertTrue(isOutgoingTransportOpen(tracker));
+        return tracker;
+    }
+
     private TransportSipMessageValidator getTestTracker(ScheduledExecutorService executor) {
-        doReturn(ValidationResult.SUCCESS).when(mStatelessValidator).validate(any());
-        doReturn(mStatelessValidator).when(mStatelessValidator).andThen(any());
         doReturn(ValidationResult.SUCCESS).when(mOutgoingStateValidator).validate(any());
-        // recreate chain for mocked instances.
-        doReturn(mStatelessValidator).when(mOutgoingStateValidator).andThen(any());
         doReturn(ValidationResult.SUCCESS).when(mIncomingStateValidator).validate(any());
         doReturn(mIncomingStateValidator).when(mIncomingStateValidator).andThen(any());
-        return new TransportSipMessageValidator(TEST_SUB_ID, executor, mOutgoingStateValidator,
-                mIncomingStateValidator, mStatelessValidator);
+        return new TransportSipMessageValidator(TEST_SUB_ID, executor, mSipSessionTracker,
+                mOutgoingStateValidator, mIncomingStateValidator);
     }
 }
diff --git a/tests/src/com/android/services/telephony/rcs/validator/OutgoingTransportStateValidatorTest.java b/tests/src/com/android/services/telephony/rcs/validator/OutgoingTransportStateValidatorTest.java
index e54e5ff..8dbeb9b 100644
--- a/tests/src/com/android/services/telephony/rcs/validator/OutgoingTransportStateValidatorTest.java
+++ b/tests/src/com/android/services/telephony/rcs/validator/OutgoingTransportStateValidatorTest.java
@@ -20,53 +20,211 @@
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
+import static org.mockito.Mockito.doReturn;
+
 import android.telephony.ims.SipDelegateManager;
 import android.telephony.ims.SipMessage;
+import android.util.ArraySet;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import com.android.TelephonyTestBase;
+import com.android.services.telephony.rcs.SipDialog;
+import com.android.services.telephony.rcs.SipSessionTracker;
+
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+import java.util.Collections;
+import java.util.Random;
 
 @RunWith(AndroidJUnit4.class)
-public class OutgoingTransportStateValidatorTest {
+public class OutgoingTransportStateValidatorTest  extends TelephonyTestBase {
 
-    private static final SipMessage TEST_MESSAGE = new SipMessage(
-            "INVITE sip:bob@biloxi.com SIP/2.0",
-            "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds\n"
-                    + "Max-Forwards: 70\n"
-                    + "To: Bob <sip:bob@biloxi.com>\n"
-                    + "From: Alice <sip:alice@atlanta.com>;tag=1928301774\n"
-                    + "Call-ID: a84b4c76e66710@pc33.atlanta.com\n"
-                    + "CSeq: 314159 INVITE\n"
-                    + "Contact: <sip:alice@pc33.atlanta.com>\n"
-                    + "Content-Type: application/sdp\n"
-                    + "Content-Length: 142",
-            new byte[0]);
+    @Mock
+    private SipSessionTracker mMockSessionTracker;
+    private final Random mRandom = new Random();
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
 
     @Test
-    public void testVerifyMessageAndUpdateState() {
-        OutgoingTransportStateValidator validator = new OutgoingTransportStateValidator();
-        ValidationResult result = validator.validate(TEST_MESSAGE);
+    public void testVerifyMessageInOpenCloseState() {
+        SipMessage testMessage = generateSipRequestForCallId("callId1");
+        OutgoingTransportStateValidator validator =
+                new OutgoingTransportStateValidator(mMockSessionTracker);
+        ValidationResult result = validator.validate(testMessage);
         assertFalse(result.isValidated);
         assertEquals(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED,
                 result.restrictedReason);
 
-        validator.open();
-        result = validator.validate(TEST_MESSAGE);
+        validator.open(Collections.singleton("+tag"), Collections.emptySet());
+        validator.restrictFeatureTags(Collections.emptySet());
+        result = validator.validate(testMessage);
         assertTrue(result.isValidated);
 
+        validator.close(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED);
+        result = validator.validate(testMessage);
+        assertFalse(result.isValidated);
+        assertEquals(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED,
+                result.restrictedReason);
+    }
+
+    @Test
+    public void testVerifyMessageRestricted() {
+        String callId1 = "callId1";
+        String callId2 = "callId2";
+        String callId3 = "callId3";
+        SipMessage testInDialogEarlyMessage = generateSipRequestForCallId(callId1);
+        SipMessage testInDialogConfirmedMessage = generateSipRequestForCallId(callId2);
+        SipMessage testOutOfDialogInvite = generateSipRequestForCallId(callId3);
+        SipMessage testStatelessRequest = generateMessageRequest();
+        ArraySet<SipDialog> inDialogEarlyCallIds = new ArraySet<>(1);
+        inDialogEarlyCallIds.add(SipDialog.fromSipMessage(testInDialogEarlyMessage));
+        ArraySet<String> inDialogConfirmedCallIds = new ArraySet<>();
+        inDialogEarlyCallIds.add(SipDialog.fromSipMessage(testInDialogConfirmedMessage));
+        // For the sake of testing, add the same call id to early and confirmed dialogs, since we
+        // will accept requests for both right now.
+        doReturn(inDialogEarlyCallIds).when(mMockSessionTracker).getEarlyDialogs();
+        doReturn(inDialogConfirmedCallIds).when(mMockSessionTracker).getConfirmedDialogs();
+        OutgoingTransportStateValidator validator =
+                new OutgoingTransportStateValidator(mMockSessionTracker);
         validator.restrict(
                 SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION);
-        result = validator.validate(TEST_MESSAGE);
+
+        // ensure a response to a pending request is not restricted, even if it is not for a tracked
+        // call ID.
+        ValidationResult result = validator.validate(generate200OkResponse("callId4"));
+        assertTrue(result.isValidated);
+
+        // confirm in dialog messages are not restricted
+        result = validator.validate(testInDialogEarlyMessage);
+        assertTrue(result.isValidated);
+        result = validator.validate(testInDialogConfirmedMessage);
+        assertTrue(result.isValidated);
+
+        // confirm out-of-dialog requests are restricted.
+        result = validator.validate(testOutOfDialogInvite);
         assertFalse(result.isValidated);
         assertEquals(SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
                 result.restrictedReason);
+        result = validator.validate(testStatelessRequest);
+        assertFalse(result.isValidated);
+        assertEquals(SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
+                result.restrictedReason);
+    }
 
-        validator.close(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED);
-        result = validator.validate(TEST_MESSAGE);
+    @Test
+    public void testDeniedFeatureTag() {
+        SipMessage testMessage = generateSipRequestForCallId("callId1");
+        OutgoingTransportStateValidator validator =
+                new OutgoingTransportStateValidator(mMockSessionTracker);
+        ValidationResult result = validator.validate(testMessage);
         assertFalse(result.isValidated);
         assertEquals(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED,
                 result.restrictedReason);
+
+        // Assert that invites associated with denied tags are denied.
+        validator.open(Collections.emptySet(), Collections.singleton("+tag"));
+        validator.restrictFeatureTags(Collections.emptySet());
+        result = validator.validate(testMessage);
+        assertFalse(result.isValidated);
+        assertEquals(SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_FEATURE_TAG,
+                result.restrictedReason);
+    }
+
+    @Test
+    public void testRestrictedFeatureTag() {
+        SipMessage testMessage = generateSipRequestForCallId("callId1");
+        OutgoingTransportStateValidator validator =
+                new OutgoingTransportStateValidator(mMockSessionTracker);
+        ValidationResult result = validator.validate(testMessage);
+        assertFalse(result.isValidated);
+        assertEquals(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED,
+                result.restrictedReason);
+
+        validator.open(Collections.singleton("+tag"), Collections.emptySet());
+        // Ensure that when supported tags are restricted, the message is not validated.
+        validator.restrictFeatureTags(Collections.singleton("+tag"));
+        result = validator.validate(testMessage);
+        assertFalse(result.isValidated);
+        assertEquals(SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_FEATURE_TAG,
+                result.restrictedReason);
+    }
+
+    @Test
+    public void testNoSupportedFeatureTag() {
+        SipMessage testMessage = generateSipRequestForCallId("callId1");
+        OutgoingTransportStateValidator validator =
+                new OutgoingTransportStateValidator(mMockSessionTracker);
+        ValidationResult result = validator.validate(testMessage);
+        assertFalse(result.isValidated);
+        assertEquals(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED,
+                result.restrictedReason);
+
+        // Assert if a message doesn't have any related supported tags, it should be denied
+        validator.open(Collections.emptySet(), Collections.emptySet());
+        validator.restrictFeatureTags(Collections.emptySet());
+        result = validator.validate(testMessage);
+        assertFalse(result.isValidated);
+        assertEquals(SipDelegateManager.MESSAGE_FAILURE_REASON_INVALID_FEATURE_TAG,
+                result.restrictedReason);
+
+        // responses and non-dialog starting messages do not matter
+        result = validator.validate(generate200OkResponse("callId2"));
+        assertTrue(result.isValidated);
+        result = validator.validate(generateMessageRequest());
+        assertTrue(result.isValidated);
+    }
+
+    /**
+     * @return A INVITE with the call ID specified. Note: this request is not technically valid, but
+     * only contains the relevant headers for testing.
+     */
+    private SipMessage generateSipRequestForCallId(String callId) {
+        return new SipMessage(
+                "INVITE sip:b@client.example.com SIP/2.0",
+                "Via: SIP/2.0/UDP client.example.com;branch=z9hG4bK776asdhds\n"
+                        + "To: B <sip:b@example.com>\n"
+                        + "From: A <sip:a@example.com>;tag=1928301774\n"
+                        + "Accept-Contact: *;+tag\n"
+                        + "Call-ID: " + callId,
+                new byte[0]);
+    }
+
+    /**
+     * @return A MESSAGE request. Note: this request is not technically valid, but only contains the
+     * relevant headers for testing.
+     */
+    private SipMessage generateMessageRequest() {
+        return new SipMessage(
+                "MESSAGE sip:b@client.example.com SIP/2.0",
+                "Via: SIP/2.0/UDP client.example.com;branch=z9hG4bK776asdhds\n"
+                        + "To: B <sip:b@example.com>\n"
+                        + "From: A <sip:a@example.com>;tag=1928301774\n",
+                new byte[0]);
+    }
+
+    /**
+     * @return A 200 OK associated with the supplied call ID.
+     */
+    private SipMessage generate200OkResponse(String callId) {
+        return new SipMessage(
+                "SIP/2.0 200 OK",
+                "Via: SIP/2.0/UDP client.example.com;branch=z9hG4bK776asdhds\n"
+                        + "To: B <sip:b@example.com>\n"
+                        + "From: A <sip:a@example.com>;tag=1928301774\n"
+                        + "Call-ID: " + callId,
+                new byte[0]);
     }
 }
