diff --git a/src/com/android/phone/ImsRcsController.java b/src/com/android/phone/ImsRcsController.java
index 58f3646..52069b8 100644
--- a/src/com/android/phone/ImsRcsController.java
+++ b/src/com/android/phone/ImsRcsController.java
@@ -16,10 +16,12 @@
 
 package com.android.phone;
 
+import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
+import android.os.UserHandle;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.ims.DelegateRequest;
@@ -413,10 +415,22 @@
     }
 
     @Override
-    public void createSipDelegate(int subId, DelegateRequest request,
+    public void createSipDelegate(int subId, DelegateRequest request, String packageName,
             ISipDelegateConnectionStateCallback delegateState,
             ISipDelegateMessageCallback delegateMessage) {
         enforceModifyPermission();
+        if (!UserHandle.getUserHandleForUid(Binder.getCallingUid()).isSystem()) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "SipDelegate creation is only available to primary user.");
+        }
+        try {
+            int remoteUid = mApp.getPackageManager().getPackageUid(packageName, 0 /*flags*/);
+            if (Binder.getCallingUid() != remoteUid) {
+                throw new SecurityException("passed in packageName does not match the caller");
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new SecurityException("Passed in PackageName can not be found on device");
+        }
 
         final long identity = Binder.clearCallingIdentity();
         SipTransportController transport = getRcsFeatureController(subId).getFeature(
@@ -426,7 +440,8 @@
                     "This subscription does not support the creation of SIP delegates");
         }
         try {
-            transport.createSipDelegate(subId, request, delegateState, delegateMessage);
+            transport.createSipDelegate(subId, request, packageName, delegateState,
+                    delegateMessage);
         } catch (ImsException e) {
             throw new ServiceSpecificException(e.getCode(), e.getMessage());
         } finally {
@@ -440,7 +455,12 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            // Do nothing yet, we do not support this API yet.
+            SipTransportController transport = getRcsFeatureController(subId).getFeature(
+                    SipTransportController.class);
+            if (transport == null) {
+                return;
+            }
+            transport.destroySipDelegate(subId, connection, reason);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
diff --git a/src/com/android/services/telephony/rcs/DelegateBinderStateManager.java b/src/com/android/services/telephony/rcs/DelegateBinderStateManager.java
new file mode 100644
index 0000000..39e9965
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/DelegateBinderStateManager.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2020 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.DelegateRegistrationState;
+import android.telephony.ims.DelegateRequest;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateImsConfiguration;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.aidl.ISipTransport;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+/**
+ * Defines the interface to be used to manage the state of a SipDelegate on the ImsService side.
+ */
+public interface DelegateBinderStateManager {
+
+    /**
+     * Callback interface that allows listeners to listen to changes in registration or
+     * configuration state.
+     */
+    interface StateCallback {
+        /**
+         * The SipDelegate has notified telephony that the registration state has changed.
+         */
+        void onRegistrationStateChanged(DelegateRegistrationState registrationState);
+
+        /**
+         * The SipDelegate has notified telephony that the IMS configuration has changed.
+         */
+        void onImsConfigurationChanged(SipDelegateImsConfiguration config);
+    }
+
+    /** Allow for mocks to be created for testing. */
+    @VisibleForTesting
+    interface Factory {
+        /**
+         * Create a new instance of this interface, which may change depending on the tags being
+         * denied. See {@link SipDelegateBinderConnectionStub} and
+         * {@link SipDelegateBinderConnection}
+         */
+        DelegateBinderStateManager create(int subId, ISipTransport sipTransport,
+                DelegateRequest requestedConfig, Set<FeatureTagState> transportDeniedTags,
+                Executor executor, List<StateCallback> stateCallbacks);
+    }
+
+    /**
+     * Start the process to create a SipDelegate on the ImsService.
+     * @param cb The Binder interface that the SipDelegate should use to notify new incoming SIP
+     *         messages as well as acknowledge whether or not an outgoing SIP message was
+     *         successfully sent.
+     * @param createdConsumer The consumer that will be notified when the creation process has
+     *         completed. Contains the ISipDelegate interface to communicate with the SipDelegate
+     *         and the feature tags the SipDelegate itself denied.
+     * @return true if the creation process started, false if the remote process died. If false, the
+     * consumers will not be notified.
+     */
+    boolean create(ISipDelegateMessageCallback cb,
+            BiConsumer<ISipDelegate, Set<FeatureTagState>> createdConsumer);
+
+    /**
+     * Destroy the existing SipDelegate managed by this object.
+     * <p>
+     * This instance should be cleaned up after this call.
+     * @param reason The reason for why this delegate is being destroyed.
+     * @param destroyedConsumer The consumer that will be notified when this operation completes.
+     *         Contains the reason the SipDelegate reported it was destroyed.
+     */
+    void destroy(int reason, Consumer<Integer> destroyedConsumer);
+}
diff --git a/src/com/android/services/telephony/rcs/DelegateStateTracker.java b/src/com/android/services/telephony/rcs/DelegateStateTracker.java
new file mode 100644
index 0000000..e287813
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/DelegateStateTracker.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2020 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.os.RemoteException;
+import android.telephony.ims.DelegateRegistrationState;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateImsConfiguration;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
+import android.telephony.ims.stub.DelegateConnectionStateCallback;
+import android.util.LocalLog;
+import android.util.Log;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Manages the events sent back to the remote IMS application using the AIDL backing for the
+ * {@link DelegateConnectionStateCallback} interface.
+ */
+public class DelegateStateTracker implements DelegateBinderStateManager.StateCallback {
+    private static final String LOG_TAG = "DelegateST";
+
+    private final int mSubId;
+    private final ISipDelegateConnectionStateCallback mAppStateCallback;
+    private final ISipDelegate mLocalDelegateImpl;
+
+    private final LocalLog mLocalLog = new LocalLog(SipTransportController.LOG_SIZE);
+
+    private List<FeatureTagState> mDelegateDeniedTags;
+    private DelegateRegistrationState mLastRegState;
+    private boolean mCreatedCalled = false;
+    private int mRegistrationStateOverride = -1;
+
+    public DelegateStateTracker(int subId, ISipDelegateConnectionStateCallback appStateCallback,
+            ISipDelegate localDelegateImpl) {
+        mSubId = subId;
+        mAppStateCallback = appStateCallback;
+        mLocalDelegateImpl = localDelegateImpl;
+    }
+
+    /**
+     * Notify this state tracker that a new internal SipDelegate has been connected.
+     *
+     * Registration and state updates will be send via the
+     * {@link SipDelegateBinderConnection.StateCallback} callback implemented by this class as they
+     * arrive.
+     * @param deniedTags The tags denied by the SipTransportController and ImsService creating the
+     *         SipDelegate. These tags will need to be notified back to the IMS application.
+     */
+    public void sipDelegateConnected(Set<FeatureTagState> deniedTags) {
+        logi("SipDelegate connected with denied tags:" + deniedTags);
+        // From the IMS application perspective, we only call onCreated/onDestroyed once and
+        // provide the local implementation of ISipDelegate, which doesn't change, even though
+        // SipDelegates may be changing underneath.
+        if (!mCreatedCalled) {
+            mCreatedCalled = true;
+            notifySipDelegateCreated();
+        }
+        mRegistrationStateOverride = -1;
+        mDelegateDeniedTags = new ArrayList<>(deniedTags);
+    }
+
+    /**
+     * The underlying SipDelegate is changing due to a state change in the SipDelegateController.
+     *
+     * This will trigger an override of the IMS application's registration state. All feature tags
+     * in the REGISTERED state will be overridden to move to the deregistering state specified until
+     * a new SipDelegate was successfully created and {@link #sipDelegateConnected(Set)} was called
+     * or it was destroyed and {@link #sipDelegateDestroyed(int)} was called.
+     * @param deregisteringReason The new deregistering reason that all feature tags in the
+     *         registered state should now report.
+     */
+    public void sipDelegateChanging(int deregisteringReason) {
+        logi("SipDelegate Changing");
+        mRegistrationStateOverride = deregisteringReason;
+        if (mLastRegState == null) {
+            logw("sipDelegateChanging: invalid state, onRegistrationStateChanged never called.");
+            mLastRegState = new DelegateRegistrationState.Builder().build();
+        }
+        onRegistrationStateChanged(mLastRegState);
+    }
+
+    /**
+     * The underlying SipDelegate has been destroyed.
+     *
+     * This should only be called when the entire {@link SipDelegateController} is going down
+     * because the application has requested that the SipDelegate be destroyed.
+     *
+     * This can also be called in error conditions where the IMS application or ImsService has
+     * crashed.
+     * @param reason The reason that will be sent to the IMS application for why the SipDelegate
+     *         is being destroyed.
+     */
+    public void sipDelegateDestroyed(int reason) {
+        logi("SipDelegate destroyed:" + reason);
+        mRegistrationStateOverride = -1;
+        try {
+            mAppStateCallback.onDestroyed(reason);
+        } catch (RemoteException e) {
+            logw("sipDelegateDestroyed: IMS application is dead: " + e);
+        }
+    }
+
+    /**
+     * The underlying SipDelegate has reported that its registration state has changed.
+     * @param registrationState The RegistrationState reported by the SipDelegate to be sent to the
+     *         IMS application.
+     */
+    @Override
+    public void onRegistrationStateChanged(DelegateRegistrationState registrationState) {
+        mLastRegState = registrationState;
+        if (mRegistrationStateOverride > DelegateRegistrationState.DEREGISTERED_REASON_UNKNOWN) {
+            logi("onRegistrationStateChanged: overriding registered state to "
+                    + mRegistrationStateOverride);
+            registrationState = overrideRegistrationForDelegateChange(mRegistrationStateOverride,
+                    registrationState);
+        }
+        logi("onRegistrationStateChanged: sending reg state" + registrationState);
+        try {
+            mAppStateCallback.onFeatureTagStatusChanged(registrationState, mDelegateDeniedTags);
+        } catch (RemoteException e) {
+            logw("onRegistrationStateChanged: IMS application is dead: " + e);
+        }
+    }
+
+    /**
+     * THe underlying SipDelegate has reported that the IMS configuration has changed.
+     * @param config The config to be sent to the IMS application.
+     */
+    @Override
+    public void onImsConfigurationChanged(SipDelegateImsConfiguration config) {
+        logi("onImsConfigurationChanged: Sending new IMS configuration.");
+        try {
+            mAppStateCallback.onImsConfigurationChanged(config);
+        } catch (RemoteException e) {
+            logw("onImsConfigurationChanged: IMS application is dead: " + e);
+        }
+    }
+
+    /** Write state about this tracker into the PrintWriter to be included in the dumpsys */
+    public void dump(PrintWriter printWriter) {
+        printWriter.println("Last reg state: " + mLastRegState);
+        printWriter.println("Denied tags: " + mDelegateDeniedTags);
+        printWriter.println("Most recent logs: ");
+        printWriter.println();
+        mLocalLog.dump(printWriter);
+    }
+
+    private DelegateRegistrationState overrideRegistrationForDelegateChange(
+            int registerOverrideReason, DelegateRegistrationState state) {
+        Set<String> registeredFeatures = state.getRegisteredFeatureTags();
+        DelegateRegistrationState.Builder overriddenState = new DelegateRegistrationState.Builder();
+        // Override REGISTERED only
+        for (String ft : registeredFeatures) {
+            overriddenState.addDeregisteringFeatureTag(ft, registerOverrideReason);
+        }
+        // keep other deregistering/deregistered tags the same.
+        for (FeatureTagState dereging : state.getDeregisteringFeatureTags()) {
+            overriddenState.addDeregisteringFeatureTag(dereging.getFeatureTag(),
+                    dereging.getState());
+        }
+        for (FeatureTagState dereged : state.getDeregisteredFeatureTags()) {
+            overriddenState.addDeregisteredFeatureTag(dereged.getFeatureTag(),
+                    dereged.getState());
+        }
+        return overriddenState.build();
+    }
+
+    private void notifySipDelegateCreated() {
+        try {
+            mAppStateCallback.onCreated(mLocalDelegateImpl);
+        } catch (RemoteException e) {
+            logw("notifySipDelegateCreated: IMS application is dead: " + e);
+        }
+    }
+
+    private void logi(String log) {
+        Log.i(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[I] " + log);
+    }
+    private void logw(String log) {
+        Log.w(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[W] " + log);
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/MessageTransportStateTracker.java b/src/com/android/services/telephony/rcs/MessageTransportStateTracker.java
new file mode 100644
index 0000000..531ed7d
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/MessageTransportStateTracker.java
@@ -0,0 +1,478 @@
+/*
+ * Copyright (C) 2020 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.os.Binder;
+import android.os.RemoteException;
+import android.telephony.ims.DelegateMessageCallback;
+import android.telephony.ims.DelegateRegistrationState;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateImsConfiguration;
+import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.SipMessage;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.stub.SipDelegate;
+import android.util.LocalLog;
+import android.util.Log;
+
+import java.io.PrintWriter;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Tracks the SIP message path both from the IMS application to the SipDelegate and from the
+ * SipDelegate back to the IMS Application.
+ * <p>
+ * Responsibilities include:
+ * 1) Queue incoming and outgoing SIP messages and deliver to IMS application and SipDelegate in
+ *        order. If there is an error delivering the message, notify the caller.
+ * 2) TODO Perform basic validation of outgoing messages.
+ * 3) TODO Record the status of ongoing SIP Dialogs and trigger the completion of pending
+ *         consumers when they are finished or call closeDialog to clean up the SIP
+ *         dialogs that did not complete within the allotted timeout time.
+ * <p>
+ * Note: This handles incoming binder calls, so all calls from other processes should be handled on
+ * the provided Executor.
+ */
+public class MessageTransportStateTracker implements DelegateBinderStateManager.StateCallback {
+    private static final String TAG = "MessageST";
+
+    /**
+     * Communicates the result of verifying whether a SIP message should be sent based on the
+     * contents of the SIP message as well as if the transport is in an available state for the
+     * intended recipient of the message.
+     */
+    private static class VerificationResult {
+        public static final VerificationResult SUCCESS = new VerificationResult();
+
+        /**
+         * If {@code true}, the requested SIP message has been verified to be sent to the remote. If
+         * {@code false}, the SIP message has failed verification and should not be sent to the
+         * result. The {@link #restrictedReason} field will contain the reason for the verification
+         * failure.
+         */
+        public final boolean isVerified;
+
+        /**
+         * The reason associated with why the SIP message was not verified and generated a
+         * {@code false} result for {@link #isVerified}.
+         */
+        public final int restrictedReason;
+
+        /**
+         * Communicates a verified result of success. Use {@link #SUCCESS} instead.
+         */
+        private VerificationResult() {
+            isVerified = true;
+            restrictedReason = SipDelegateManager.MESSAGE_FAILURE_REASON_UNKNOWN;
+        }
+
+        /**
+         * The result of verifying that the SIP Message should be sent.
+         * @param reason The reason associated with why the SIP message was not verified and
+         *               generated a {@code false} result for {@link #isVerified}.
+         */
+        VerificationResult(@SipDelegateManager.MessageFailureReason int reason) {
+            isVerified = false;
+            restrictedReason = reason;
+        }
+    }
+
+    // SipDelegateConnection(IMS Application) -> SipDelegate(ImsService)
+    private final ISipDelegate.Stub mSipDelegateConnection = new ISipDelegate.Stub() {
+        /**
+         * The IMS application is acknowledging that it has successfully received and processed an
+         * incoming SIP message sent by the SipDelegate in
+         * {@link ISipDelegateMessageCallback#onMessageReceived(SipMessage)}.
+         */
+        @Override
+        public void notifyMessageReceived(String viaTransactionId) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    if (mSipDelegate == null) {
+                        logw("notifyMessageReceived called when SipDelegate is not associated for "
+                                + "transaction id: " + viaTransactionId);
+                        return;
+                    }
+                    try {
+                        // TODO track the SIP Dialogs created/destroyed on the associated
+                        // SipDelegate.
+                        mSipDelegate.notifyMessageReceived(viaTransactionId);
+                    } catch (RemoteException e) {
+                        logw("SipDelegate not available when notifyMessageReceived was called "
+                                + "for transaction id: " + viaTransactionId);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        /**
+         * The IMS application is acknowledging that it received an incoming SIP message sent by the
+         * SipDelegate in {@link ISipDelegateMessageCallback#onMessageReceived(SipMessage)} but it
+         * was unable to process it.
+         */
+        @Override
+        public void notifyMessageReceiveError(String viaTransactionId, int reason) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    if (mSipDelegate == null) {
+                        logw("notifyMessageReceiveError called when SipDelegate is not associated "
+                                + "for transaction id: " + viaTransactionId);
+                        return;
+                    }
+                    try {
+                        // TODO track the SIP Dialogs created/destroyed on the associated
+                        // SipDelegate.
+                        mSipDelegate.notifyMessageReceiveError(viaTransactionId, reason);
+                    } catch (RemoteException e) {
+                        logw("SipDelegate not available when notifyMessageReceiveError was called "
+                                + "for transaction id: " + viaTransactionId);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        /**
+         * The IMS application is sending an outgoing SIP message to the SipDelegate to be processed
+         * and sent over the network.
+         */
+        @Override
+        public void sendMessage(SipMessage sipMessage, int configVersion) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    VerificationResult result = verifyOutgoingMessage(sipMessage);
+                    if (!result.isVerified) {
+                        notifyDelegateSendError("Outgoing messages restricted", sipMessage,
+                                result.restrictedReason);
+                        return;
+                    }
+                    try {
+                        // TODO track the SIP Dialogs created/destroyed on the associated
+                        // SipDelegate.
+                        mSipDelegate.sendMessage(sipMessage, configVersion);
+                        logi("sendMessage: message sent - " + sipMessage + ", configVersion: "
+                                + configVersion);
+                    } catch (RemoteException e) {
+                        notifyDelegateSendError("RemoteException: " + e, sipMessage,
+                                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        /**
+         * The SipDelegateConnection is requesting that the resources associated with an ongoing SIP
+         * dialog be released as the SIP dialog is now closed.
+         */
+        @Override
+        public void closeDialog(String callId) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    if (mSipDelegate == null) {
+                        logw("closeDialog called when SipDelegate is not associated, callId: "
+                                + callId);
+                        return;
+                    }
+                    try {
+                        // TODO track the SIP Dialogs created/destroyed on the associated
+                        // SipDelegate.
+                        mSipDelegate.closeDialog(callId);
+                    } catch (RemoteException e) {
+                        logw("SipDelegate not available when closeDialog was called "
+                                + "for call id: " + callId);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+    };
+
+    // SipDelegate(ImsService) -> SipDelegateConnection(IMS Application)
+    private final ISipDelegateMessageCallback.Stub mDelegateConnectionMessageCallback =
+            new ISipDelegateMessageCallback.Stub() {
+        /**
+         * An Incoming SIP Message has been received by the SipDelegate and is being routed
+         * to the IMS application for processing.
+         * <p>
+         * IMS application will call {@link ISipDelegate#notifyMessageReceived(String)} to
+         * acknowledge receipt of this incoming message.
+         */
+        @Override
+        public void onMessageReceived(SipMessage message) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    VerificationResult result = verifyIncomingMessage(message);
+                    if (!result.isVerified) {
+                        notifyAppReceiveError("Incoming messages restricted", message,
+                                result.restrictedReason);
+                        return;
+                    }
+                    try {
+                        // TODO track the SIP Dialogs created/destroyed on the associated
+                        //  SipDelegate.
+                        mAppCallback.onMessageReceived(message);
+                        logi("onMessageReceived: received " + message);
+                    } catch (RemoteException e) {
+                        notifyAppReceiveError("RemoteException: " + e, message,
+                                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        /**
+         * An outgoing SIP message sent previously by the SipDelegateConnection to the SipDelegate
+         * using {@link ISipDelegate#sendMessage(SipMessage, int)} as been successfully sent.
+         */
+        @Override
+        public void onMessageSent(String viaTransactionId) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    if (mSipDelegate == null) {
+                        logw("Unexpected state, onMessageSent called when SipDelegate is not "
+                                + "associated");
+                    }
+                    try {
+                        mAppCallback.onMessageSent(viaTransactionId);
+                    } catch (RemoteException e) {
+                        logw("Error sending onMessageSent to SipDelegateConnection, remote not"
+                                + "available for transaction ID: " + viaTransactionId);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        /**
+         * An outgoing SIP message sent previously by the SipDelegateConnection to the SipDelegate
+         * using {@link ISipDelegate#sendMessage(SipMessage, int)} failed to be sent.
+         */
+        @Override
+        public void onMessageSendFailure(String viaTransactionId, int reason) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    if (mSipDelegate == null) {
+                        logw("Unexpected state, onMessageSendFailure called when SipDelegate is not"
+                                + "associated");
+                    }
+                    try {
+                        mAppCallback.onMessageSendFailure(viaTransactionId, reason);
+                    } catch (RemoteException e) {
+                        logw("Error sending onMessageSendFailure to SipDelegateConnection, remote"
+                                + " not available for transaction ID: " + viaTransactionId);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+    };
+
+    private final ISipDelegateMessageCallback mAppCallback;
+    private final Executor mExecutor;
+    private final int mSubId;
+    private final LocalLog mLocalLog = new LocalLog(SipTransportController.LOG_SIZE);
+
+    private ISipDelegate mSipDelegate;
+    private Consumer<Boolean> mPendingClosedConsumer;
+    private int mDelegateClosingReason = -1;
+    private int mDelegateClosedReason = -1;
+
+    public MessageTransportStateTracker(int subId, Executor executor,
+            ISipDelegateMessageCallback appMessageCallback) {
+        mSubId = subId;
+        mAppCallback = appMessageCallback;
+        mExecutor = executor;
+    }
+
+    @Override
+    public void onRegistrationStateChanged(DelegateRegistrationState registrationState) {
+        // TODO: integrate registration changes to SipMessage verification checks.
+    }
+
+    @Override
+    public void onImsConfigurationChanged(SipDelegateImsConfiguration config) {
+        // Not needed for this Tracker
+    }
+
+    /**
+     * Open the transport and allow SIP messages to be sent/received on the delegate specified.
+     * @param delegate The delegate connection to send SIP messages to on the ImsService.
+     * @param deniedFeatureTags Feature tags that have been denied. Outgoing SIP messages relating
+     *         to these tags will be denied.
+     */
+    public void openTransport(ISipDelegate delegate, Set<FeatureTagState> deniedFeatureTags) {
+        mSipDelegate = delegate;
+        mDelegateClosingReason = -1;
+        mDelegateClosedReason = -1;
+        // TODO: integrate denied tags to SipMessage verification checks.
+    }
+
+    /** Dump state about this tracker that should be included in the dumpsys */
+    public void dump(PrintWriter printWriter) {
+        mLocalLog.dump(printWriter);
+    }
+
+    /**
+     * @return SipDelegate implementation to be sent to IMS application.
+     */
+    public ISipDelegate getDelegateConnection() {
+        return mSipDelegateConnection;
+    }
+
+    /**
+     * @return MessageCallback implementation to be sent to the ImsService.
+     */
+    public ISipDelegateMessageCallback getMessageCallback() {
+        return mDelegateConnectionMessageCallback;
+    }
+
+    /**
+     * Gradually close all SIP Dialogs by:
+     * 1) denying all new outgoing SIP Dialog requests with the reason specified and
+     * 2) only allowing existing SIP Dialogs 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.
+     * <p>
+     * Any outgoing out-of-dialog traffic on this transport will be denied with the provided reason.
+     * <p>
+     * Incoming out-of-dialog traffic will continue to be set up until the SipDelegate is fully
+     * closed.
+     * @param delegateClosingReason The reason code to return to
+     * {@link DelegateMessageCallback#onMessageSendFailure(String, int)} if a new out-of-dialog SIP
+     *         message is received while waiting for existing Dialogs.
+     * @param closedReason reason to return to new outgoing SIP messages via
+     *         {@link SipDelegate#notifyMessageReceiveError(String, int)} once the transport
+     *         transitions to the fully closed state.
+     * @param resultConsumer The consumer called when the message transport has been closed. It will
+     *         return {@code true} if the procedure completed successfully or {@link false} if the
+     *         transport needed to be closed forcefully due to the application not responding before
+     *         a timeout occurred.
+     */
+    public void closeGracefully(int delegateClosingReason, int closedReason,
+            Consumer<Boolean> resultConsumer) {
+        mDelegateClosingReason = delegateClosingReason;
+        mPendingClosedConsumer = resultConsumer;
+        mExecutor.execute(() -> {
+            // TODO: Track SIP Dialogs and complete when there are no SIP dialogs open anymore or
+            //  the timeout occurs.
+            mPendingClosedConsumer.accept(true);
+            mPendingClosedConsumer = null;
+            closeTransport(closedReason);
+        });
+    }
+
+    /**
+     * Close all ongoing SIP Dialogs 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) {
+        closeTransport(closedReason);
+    }
+
+    // Clean up all state related to the existing SipDelegate immediately.
+    private void closeTransport(int closedReason) {
+        // TODO: add logic to forcefully close open SIP dialogs once they are being tracked.
+        mSipDelegate = null;
+        if (mPendingClosedConsumer != null) {
+            mExecutor.execute(() -> {
+                logw("closeTransport: transport close forced with pending consumer.");
+                mPendingClosedConsumer.accept(false /*closedGracefully*/);
+                mPendingClosedConsumer = null;
+            });
+        }
+        mDelegateClosingReason = -1;
+        mDelegateClosedReason = closedReason;
+    }
+
+    private VerificationResult verifyOutgoingMessage(SipMessage message) {
+        if (mDelegateClosingReason > -1) {
+            return new VerificationResult(mDelegateClosingReason);
+        }
+        if (mDelegateClosedReason > -1) {
+            return new VerificationResult(mDelegateClosedReason);
+        }
+        if (mSipDelegate == null) {
+            logw("sendMessage called when SipDelegate is not associated." + message);
+            return new VerificationResult(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD);
+        }
+        return VerificationResult.SUCCESS;
+    }
+
+    private VerificationResult verifyIncomingMessage(SipMessage message) {
+        // Do not restrict incoming based on closing reason.
+        if (mDelegateClosedReason > -1) {
+            return new VerificationResult(mDelegateClosedReason);
+        }
+        return VerificationResult.SUCCESS;
+    }
+
+    private void notifyDelegateSendError(String logReason, SipMessage message, int reasonCode) {
+        // TODO parse SipMessage header for viaTransactionId.
+        logw("Error sending SipMessage[id: " + null + ", code: " + reasonCode + "] -> SipDelegate "
+                + "for reason: " + logReason);
+        try {
+            mAppCallback.onMessageSendFailure(null, reasonCode);
+        } catch (RemoteException e) {
+            logw("notifyDelegateSendError, SipDelegate is not available: " + e);
+        }
+    }
+
+    private void notifyAppReceiveError(String logReason, SipMessage message, int reasonCode) {
+        // TODO parse SipMessage header for viaTransactionId.
+        logw("Error sending SipMessage[id: " + null + ", code: " + reasonCode + "] -> "
+                + "SipDelegateConnection for reason: " + logReason);
+        try {
+            mSipDelegate.notifyMessageReceiveError(null, reasonCode);
+        } catch (RemoteException e) {
+            logw("notifyAppReceiveError, SipDelegate is not available: " + e);
+        }
+    }
+
+    private void logi(String log) {
+        Log.w(SipTransportController.LOG_TAG, TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[I] " + log);
+    }
+
+    private void logw(String log) {
+        Log.w(SipTransportController.LOG_TAG, TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[W] " + log);
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/RcsFeatureController.java b/src/com/android/services/telephony/rcs/RcsFeatureController.java
index 8c6fce0..304a74d 100644
--- a/src/com/android/services/telephony/rcs/RcsFeatureController.java
+++ b/src/com/android/services/telephony/rcs/RcsFeatureController.java
@@ -74,6 +74,12 @@
          * Called when the feature should be destroyed.
          */
         void onDestroy();
+
+        /**
+         * Called when a dumpsys is being generated for this RcsFeatureController for all Features
+         * to report their status.
+         */
+        void dump(PrintWriter pw);
     }
 
     /**
@@ -427,6 +433,14 @@
         pw.print("connected=");
         synchronized (mLock) {
             pw.println(mFeatureManager != null);
+            pw.println();
+            pw.println("RcsFeatureControllers:");
+            pw.increaseIndent();
+            for (Feature f : mFeatures.values()) {
+                f.dump(pw);
+                pw.println();
+            }
+            pw.decreaseIndent();
         }
     }
 
diff --git a/src/com/android/services/telephony/rcs/SipDelegateBinderConnection.java b/src/com/android/services/telephony/rcs/SipDelegateBinderConnection.java
new file mode 100644
index 0000000..8ae1936
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/SipDelegateBinderConnection.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2020 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.os.Binder;
+import android.os.RemoteException;
+import android.telephony.ims.DelegateRegistrationState;
+import android.telephony.ims.DelegateRequest;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateImsConfiguration;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.aidl.ISipDelegateStateCallback;
+import android.telephony.ims.aidl.ISipTransport;
+import android.telephony.ims.stub.SipDelegate;
+import android.util.LocalLog;
+import android.util.Log;
+
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+/**
+ * Container for the active connection to the {@link SipDelegate} active on the ImsService.
+ * <p>
+ * New instances of this class will be created and destroyed new {@link SipDelegate}s are created
+ * and destroyed by the {@link SipDelegateController}.
+ */
+public class SipDelegateBinderConnection implements DelegateBinderStateManager {
+    private static final String LOG_TAG = "BinderConn";
+
+    protected final int mSubId;
+    protected final Set<FeatureTagState> mDeniedTags;
+    protected final Executor mExecutor;
+    protected final List<StateCallback> mStateCallbacks;
+
+    private final LocalLog mLocalLog = new LocalLog(SipTransportController.LOG_SIZE);
+
+    // Callback interface from ImsService to this Connection. State Events will be forwarded to IMS
+    // application through DelegateStateTracker.
+    private final ISipDelegateStateCallback mSipDelegateStateCallback =
+            new ISipDelegateStateCallback.Stub() {
+                @Override
+                public void onCreated(ISipDelegate delegate,
+                        List<FeatureTagState> deniedFeatureTags) {
+                    long token = Binder.clearCallingIdentity();
+                    try {
+                        mExecutor.execute(() ->
+                                notifySipDelegateCreated(delegate, deniedFeatureTags));
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+                }
+
+                @Override
+                public void onFeatureTagRegistrationChanged(
+                        DelegateRegistrationState registrationState) {
+                    long token = Binder.clearCallingIdentity();
+                    try {
+                        mExecutor.execute(() -> {
+                            logi("onFeatureTagRegistrationChanged:" + registrationState);
+                            for (StateCallback c : mStateCallbacks) {
+                                c.onRegistrationStateChanged(registrationState);
+                            }
+                        });
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+                }
+
+                @Override
+                public void onImsConfigurationChanged(
+                        SipDelegateImsConfiguration registeredSipConfig) {
+                    long token = Binder.clearCallingIdentity();
+                    try {
+                        mExecutor.execute(() -> {
+                            logi("onImsConfigurationChanged");
+                            for (StateCallback c : mStateCallbacks) {
+                                c.onImsConfigurationChanged(registeredSipConfig);
+                            }
+                        });
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+                }
+
+                @Override
+                public void onDestroyed(int reason) {
+                    long token = Binder.clearCallingIdentity();
+                    try {
+                        mExecutor.execute(() -> notifySipDelegateDestroyed(reason));
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+                }
+            };
+
+    private final ISipTransport mSipTransport;
+    private final DelegateRequest mRequestedConfig;
+
+    private ISipDelegate mDelegateBinder;
+    private BiConsumer<ISipDelegate, Set<FeatureTagState>> mPendingCreatedConsumer;
+    private Consumer<Integer> mPendingDestroyedConsumer;
+
+    /**
+     * Create a new Connection object to manage the creation and destruction of a
+     * {@link SipDelegate}.
+     * @param subId The subid that this SipDelegate is being created for.
+     * @param sipTransport The SipTransport implementation that will be used to manage SipDelegates.
+     * @param requestedConfig The DelegateRequest to be sent to the ImsService.
+     * @param transportDeniedTags The feature tags that have already been denied by the
+     *                            SipTransportController and should not be requested.
+     * @param executor The Executor that all binder calls from the remote process will be executed
+     *                on.
+     * @param stateCallbacks A list of callbacks that will each be called when the state of the
+     *                       SipDelegate changes. This will be called on the supplied executor.
+     */
+    public SipDelegateBinderConnection(int subId, ISipTransport sipTransport,
+            DelegateRequest requestedConfig, Set<FeatureTagState> transportDeniedTags,
+            Executor executor, List<StateCallback> stateCallbacks) {
+        mSubId = subId;
+        mSipTransport = sipTransport;
+        mRequestedConfig = requestedConfig;
+        mDeniedTags = transportDeniedTags;
+        mExecutor = executor;
+        mStateCallbacks = stateCallbacks;
+    }
+
+    @Override
+    public boolean create(ISipDelegateMessageCallback cb,
+            BiConsumer<ISipDelegate, Set<FeatureTagState>> createdConsumer) {
+        try {
+            mSipTransport.createSipDelegate(mSubId, mRequestedConfig, mSipDelegateStateCallback,
+                    cb);
+        } catch (RemoteException e) {
+            logw("create called on unreachable SipTransport:" + e);
+            return false;
+        }
+        mPendingCreatedConsumer = createdConsumer;
+        return true;
+    }
+
+    @Override
+    public void destroy(int reason, Consumer<Integer> destroyedConsumer) {
+        mPendingDestroyedConsumer = destroyedConsumer;
+        try {
+            if (mDelegateBinder != null) {
+                mSipTransport.destroySipDelegate(mDelegateBinder, reason);
+            } else {
+                mExecutor.execute(() -> notifySipDelegateDestroyed(reason));
+            }
+            mStateCallbacks.clear();
+        } catch (RemoteException e) {
+            logw("destroy called on unreachable SipTransport:" + e);
+            mExecutor.execute(() -> notifySipDelegateDestroyed(reason));
+        }
+    }
+
+    private void notifySipDelegateCreated(ISipDelegate delegate,
+            List<FeatureTagState> deniedFeatureTags) {
+        logi("Delegate Created: " + delegate + ", deniedTags:" + deniedFeatureTags);
+        if (delegate == null) {
+            logw("Invalid null delegate returned!");
+        }
+        mDelegateBinder = delegate;
+        // Add denied feature tags from SipDelegate to the ones denied by the transport
+        if (deniedFeatureTags != null) {
+            mDeniedTags.addAll(deniedFeatureTags);
+        }
+        if (mPendingCreatedConsumer == null) return;
+        mPendingCreatedConsumer.accept(delegate, mDeniedTags);
+        mPendingCreatedConsumer = null;
+    }
+
+    private void notifySipDelegateDestroyed(int reason) {
+        logi("Delegate Destroyed, reason: " + reason);
+        mDelegateBinder = null;
+        if (mPendingDestroyedConsumer == null) return;
+        mPendingDestroyedConsumer.accept(reason);
+        mPendingDestroyedConsumer = null;
+    }
+
+    /** Dump state about this binder connection that should be included in the dumpsys. */
+    public void dump(PrintWriter printWriter) {
+        mLocalLog.dump(printWriter);
+    }
+
+    protected final void logi(String log) {
+        Log.i(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[I] " + log);
+    }
+
+    protected final void logw(String log) {
+        Log.w(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[W] " + log);
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionStub.java b/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionStub.java
new file mode 100644
index 0000000..888af94
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionStub.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 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.DelegateRegistrationState;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.stub.SipDelegate;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+/**
+ * Stub implementation used when a SipDelegate needs to be set up in specific cases, but there
+ * is no underlying implementation in the ImsService.
+ *
+ * This is used in cases where all of the requested feature tags were denied for various reasons
+ * from the SipTransportController. In this case, we will "connect", send a update to include the
+ * denied feature tags, and then do nothing until this stub is torn down.
+ */
+public class SipDelegateBinderConnectionStub implements DelegateBinderStateManager {
+    protected final Set<FeatureTagState> mDeniedTags;
+    protected final Executor mExecutor;
+    protected final List<StateCallback> mStateCallbacks;
+
+    /**
+     * Create a new Connection object to manage the creation and destruction of a
+     * {@link SipDelegate}.
+     * @param transportDeniedTags The feature tags that have already been denied by the
+     *                            SipTransportController and should not be requested.
+     * @param executor The Executor that all binder calls from the remote process will be executed
+     *                on.
+     * @param stateCallbacks A list of callbacks that will each be called when the state of the
+     *                       SipDelegate changes. This will be called on the supplied executor.
+     */
+    public SipDelegateBinderConnectionStub(Set<FeatureTagState> transportDeniedTags,
+            Executor executor, List<StateCallback> stateCallbacks) {
+        mDeniedTags = transportDeniedTags;
+        mExecutor = executor;
+        mStateCallbacks = stateCallbacks;
+    }
+
+    @Override
+    public boolean create(ISipDelegateMessageCallback cb,
+            BiConsumer<ISipDelegate, Set<FeatureTagState>> createdConsumer) {
+        mExecutor.execute(() -> {
+            createdConsumer.accept(null, (mDeniedTags));
+            for (SipDelegateBinderConnection.StateCallback  c: mStateCallbacks) {
+                c.onRegistrationStateChanged(new DelegateRegistrationState.Builder().build());
+            }
+        });
+        return true;
+    }
+
+    @Override
+    public void destroy(int reason, Consumer<Integer> destroyedConsumer) {
+        mExecutor.execute(() -> {
+            mStateCallbacks.clear();
+            destroyedConsumer.accept(reason);
+        });
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/SipDelegateController.java b/src/com/android/services/telephony/rcs/SipDelegateController.java
new file mode 100644
index 0000000..ee9d4a7
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/SipDelegateController.java
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2020 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.DelegateRegistrationState;
+import android.telephony.ims.DelegateRequest;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateConnection;
+import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.aidl.ISipTransport;
+import android.telephony.ims.stub.DelegateConnectionStateCallback;
+import android.telephony.ims.stub.SipDelegate;
+import android.util.ArraySet;
+import android.util.LocalLog;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * Created when an IMS application wishes to open up a {@link SipDelegateConnection} and manages the
+ * resulting {@link SipDelegate} that may be created on the ImsService side.
+ */
+public class SipDelegateController {
+    static final String LOG_TAG = "SipDelegateC";
+
+    private DelegateBinderStateManager.Factory mBinderConnectionFactory =
+            new DelegateBinderStateManager.Factory() {
+        @Override
+        public DelegateBinderStateManager create(int subId, ISipTransport sipTransport,
+                DelegateRequest requestedConfig, Set<FeatureTagState> transportDeniedTags,
+                Executor executor, List<DelegateBinderStateManager.StateCallback> stateCallbacks) {
+            // We should not actually create a SipDelegate in this case.
+            if (requestedConfig.getFeatureTags().isEmpty()) {
+                return new SipDelegateBinderConnectionStub(transportDeniedTags, executor,
+                        stateCallbacks);
+            }
+            return new SipDelegateBinderConnection(mSubId, mSipTransportImpl, requestedConfig,
+                    transportDeniedTags, mExecutorService, stateCallbacks);
+        }
+    };
+
+    private final int mSubId;
+    private final String mPackageName;
+    private final DelegateRequest mInitialRequest;
+    private final ISipTransport mSipTransportImpl;
+    private final ScheduledExecutorService mExecutorService;
+    private final MessageTransportStateTracker mMessageTransportStateTracker;
+    private final DelegateStateTracker mDelegateStateTracker;
+    private final LocalLog mLocalLog = new LocalLog(SipTransportController.LOG_SIZE);
+
+    private DelegateBinderStateManager mBinderConnection;
+    private Set<String> mTrackedFeatureTags = new ArraySet<>();
+
+    public SipDelegateController(int subId, DelegateRequest initialRequest, String packageName,
+            ISipTransport sipTransportImpl, ScheduledExecutorService executorService,
+            ISipDelegateConnectionStateCallback stateCallback,
+            ISipDelegateMessageCallback messageCallback) {
+        mSubId = subId;
+        mPackageName = packageName;
+        mInitialRequest = initialRequest;
+        mSipTransportImpl = sipTransportImpl;
+        mExecutorService = executorService;
+
+        mMessageTransportStateTracker = new MessageTransportStateTracker(mSubId, executorService,
+                messageCallback);
+        mDelegateStateTracker = new DelegateStateTracker(mSubId, stateCallback,
+                mMessageTransportStateTracker.getDelegateConnection());
+    }
+
+    /**
+     * Inject dependencies for testing only.
+     */
+    @VisibleForTesting
+    public SipDelegateController(int subId, DelegateRequest initialRequest, String packageName,
+            ISipTransport sipTransportImpl, ScheduledExecutorService executorService,
+            MessageTransportStateTracker messageTransportStateTracker,
+            DelegateStateTracker delegateStateTracker,
+            DelegateBinderStateManager.Factory connectionFactory) {
+        mSubId = subId;
+        mInitialRequest = initialRequest;
+        mPackageName = packageName;
+        mSipTransportImpl = sipTransportImpl;
+        mExecutorService = executorService;
+        mMessageTransportStateTracker = messageTransportStateTracker;
+        mDelegateStateTracker = delegateStateTracker;
+        mBinderConnectionFactory = connectionFactory;
+    }
+
+    /**
+     * @return The InitialRequest from the IMS application. The feature tags that are actually set
+     * up may differ from this request based on the state of this controller.
+     */
+    public DelegateRequest getInitialRequest() {
+        return mInitialRequest;
+    }
+
+    /**
+     * @return The package name of the IMS application associated with this SipDelegateController.
+     */
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    public ISipDelegate getSipDelegateInterface() {
+        return mMessageTransportStateTracker.getDelegateConnection();
+    }
+
+    /**
+     * Create the underlying SipDelegate.
+     * <p>
+     * This may not happen instantly, The CompletableFuture returned will not complete until
+     * {@link DelegateConnectionStateCallback#onCreated(SipDelegateConnection)} is called by the
+     * SipDelegate or DelegateStateTracker state is updated in the case that all requested features
+     * were denied.
+     * @return A CompletableFuture that will complete once the SipDelegate has been created. If true
+     * is returned, the SipDelegate has been created successfully. If false, the ImsService is not
+     * reachable and the process should be aborted.
+     */
+    public CompletableFuture<Boolean> create(Set<String> supportedSet,
+            Set<FeatureTagState> deniedSet) {
+        logi("create, supported: " + supportedSet + ", denied: " + deniedSet);
+        mTrackedFeatureTags = supportedSet;
+        DelegateBinderStateManager connection =
+                createBinderConnection(supportedSet, deniedSet);
+        CompletableFuture<Pair<ISipDelegate, Set<FeatureTagState>>> pendingCreate =
+                createSipDelegate(connection);
+        // May need to implement special case handling where SipDelegate denies all in supportedSet,
+        // however that should be a very rare case. For now, if that happens, just keep the
+        // SipDelegate bound.
+        return pendingCreate.thenApplyAsync((resultPair) -> {
+            if (resultPair == null) {
+                logw("create: resultPair returned null");
+                return false;
+            }
+            mBinderConnection = connection;
+            logi("create: created, delegate denied: " + resultPair.second);
+            mMessageTransportStateTracker.openTransport(resultPair.first, resultPair.second);
+            mDelegateStateTracker.sipDelegateConnected(resultPair.second);
+            return true;
+        }, mExecutorService);
+    }
+
+    /**
+     * Modify the SipTransport to reflect the new Feature Tag set that the IMS application has
+     * access to.
+     * <p>
+     * This involves the following operations if the new supported tag set does not match the
+     * the existing set:
+     * 1) destroy the existing underlying SipDelegate. If there are SIP Dialogs that are active
+     * on the SipDelegate that is pending to be destroyed, we must move the feature tags into a
+     * deregistering state via
+     * {@link DelegateRegistrationState#DEREGISTERING_REASON_FEATURE_TAGS_CHANGING} to signal to the
+     * IMS application to close all dialogs before the operation can proceed. If any outgoing
+     * out-of-dialog messages are sent at this time, they will also fail with reason
+     * {@link SipDelegateManager#MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION}.
+     * 2) create a new underlying SipDelegate and notify trackers, allowing the transport to
+     * re-open.
+     * @param newSupportedSet The new supported set of feature tags that the SipDelegate should
+     *     be opened for.
+     * @param deniedSet The new set of tags that have been denied as well as the reason for the
+     *        denial to be reported back to the IMS Application.
+     * @return A CompletableFuture containing the pending operation that will change the supported
+     * feature tags. Any operations to change the supported feature tags of the associated
+     * SipDelegate after this should not happen until this pending operation completes. Will
+     * complete with {@code true} if the operation was successful or {@code false} if the
+     * IMS service was unreachable.
+     */
+    public CompletableFuture<Boolean> changeSupportedFeatureTags(Set<String> newSupportedSet,
+            Set<FeatureTagState> deniedSet) {
+        logi("Received feature tag set change, old: [" + mTrackedFeatureTags + "], new: "
+                + newSupportedSet + ",denied: [" + deniedSet + "]");
+        if (mTrackedFeatureTags.equals(newSupportedSet)) {
+            logi("changeSupportedFeatureTags: no change, returning");
+            return CompletableFuture.completedFuture(true);
+        }
+
+        mTrackedFeatureTags = newSupportedSet;
+        // Next perform the destroy operation.
+        CompletableFuture<Integer> pendingDestroy = destroySipDelegate(false/*force*/,
+                SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
+                SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
+                DelegateRegistrationState.DEREGISTERING_REASON_FEATURE_TAGS_CHANGING,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+
+        // Next perform the create operation with the new set of supported feature tags.
+        return pendingDestroy.thenComposeAsync((reasonFromService) -> {
+            logi("changeSupportedFeatureTags: destroy stage complete, reason reported: "
+                    + reasonFromService);
+            return create(newSupportedSet, deniedSet);
+        }, mExecutorService);
+    }
+
+    /**
+     * Destroy this SipDelegate. This controller should be disposed of after this method is
+     * called.
+     * <p>
+     * This may not happen instantly if there are SIP Dialogs that are active on this SipDelegate.
+     * In this case, the CompletableFuture will not complete until
+     * {@link DelegateConnectionStateCallback#onDestroyed(int)} is called by the SipDelegate.
+     * @param force If set true, we will close the transport immediately and call
+     * {@link SipDelegate#closeDialog(String)} on any open dialogs. If false, we will wait for the
+     *         SIP Dialogs to close or the close timer to timeout before destroying the underlying
+     *         SipDelegate.
+     * @param destroyReason The reason for why this SipDelegate is being destroyed.
+     * @return A CompletableFuture that will complete once the SipDelegate has been destroyed.
+     */
+    public CompletableFuture<Integer> destroy(boolean force, int destroyReason) {
+        logi("destroy, forced " + force + ", destroyReason: " + destroyReason);
+
+        CompletableFuture<Integer> pendingOperationComplete =
+                destroySipDelegate(force, SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED,
+                        getMessageFailReasonFromDestroyReason(destroyReason),
+                        DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING,
+                        destroyReason);
+        return pendingOperationComplete.thenApplyAsync((reasonFromDelegate) -> {
+            logi("destroy, operation complete, notifying trackers, reason" + reasonFromDelegate);
+            mDelegateStateTracker.sipDelegateDestroyed(reasonFromDelegate);
+            return reasonFromDelegate;
+        }, mExecutorService);
+    };
+
+    private static int getMessageFailReasonFromDestroyReason(int destroyReason) {
+        switch (destroyReason) {
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD:
+                return SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD;
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP:
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_USER_DISABLED_RCS:
+                return SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED;
+            default:
+                return SipDelegateManager.MESSAGE_FAILURE_REASON_UNKNOWN;
+        }
+    }
+
+    /**
+     * @param force If set true, we will close the transport immediately and call
+     * {@link SipDelegate#closeDialog(String)} on any open dialogs. If false, we will wait for the
+     *         SIP Dialogs to close or the close timer to timeout before destroying the underlying
+     *         SipDelegate.
+     * @param messageDestroyingReason The reason to send back to the IMS application in the case
+     *         that a new outgoing SIP message is sent that is out-of-dialog while the message
+     *         transport is closing.
+     * @param messageDestroyedReason The reason to send back to the IMS application in the case
+     *         that a new outgoing SIP message is sent once the underlying transport is closed.
+     * @param deregisteringReason The deregistering state reported to the IMS application for all
+     *         registered feature tags.
+     * @param delegateDestroyedReason The reason to send to the underlying SipDelegate that is being
+     *         destroyed.
+     * @return A CompletableFuture containing the reason from the SipDelegate for why it was
+     * destroyed.
+     */
+    private CompletableFuture<Integer> destroySipDelegate(boolean force,
+            int messageDestroyingReason, int messageDestroyedReason, int deregisteringReason,
+            int delegateDestroyedReason) {
+        if (mBinderConnection == null) {
+            logi("destroySipDelegate, called when binder connection is already null");
+            return CompletableFuture.completedFuture(delegateDestroyedReason);
+        }
+        // First, bring down the message transport.
+        CompletableFuture<Boolean> pendingTransportClosed = new CompletableFuture<>();
+        if (force) {
+            logi("destroySipDelegate, forced");
+            mMessageTransportStateTracker.close(messageDestroyedReason);
+            pendingTransportClosed.complete(true);
+        } else {
+            mMessageTransportStateTracker.closeGracefully(messageDestroyingReason,
+                    messageDestroyedReason, pendingTransportClosed::complete);
+        }
+
+        // Do not send an intermediate pending state to app if there are no open SIP dialogs to
+        // worry about.
+        if (!pendingTransportClosed.isDone()) {
+            mDelegateStateTracker.sipDelegateChanging(deregisteringReason);
+        } else {
+            logi("destroySipDelegate, skip DEREGISTERING_REASON_DESTROY_PENDING");
+        }
+
+        // Next, destroy the SipDelegate.
+        return pendingTransportClosed.thenComposeAsync((wasGraceful) -> {
+            logi("destroySipDelegate, transport gracefully closed = " + wasGraceful);
+            CompletableFuture<Integer> pendingDestroy = new CompletableFuture<>();
+            mBinderConnection.destroy(delegateDestroyedReason, pendingDestroy::complete);
+            return pendingDestroy;
+        }, mExecutorService);
+    }
+
+    /**
+     * @return a CompletableFuture that returns a Pair containing SipDelegate Binder interface as
+     * well as rejected feature tags or a {@code null} Pair instance if the ImsService is not
+     * available.
+     */
+    private CompletableFuture<Pair<ISipDelegate, Set<FeatureTagState>>> createSipDelegate(
+            DelegateBinderStateManager connection) {
+        CompletableFuture<Pair<ISipDelegate, Set<FeatureTagState>>> createdFuture =
+                new CompletableFuture<>();
+        boolean isStarted = connection.create(mMessageTransportStateTracker.getMessageCallback(),
+                (delegate, delegateDeniedTags) ->
+                        createdFuture.complete(new Pair<>(delegate, delegateDeniedTags)));
+        if (!isStarted) {
+            logw("Couldn't create binder connection, ImsService is not available.");
+            connection.destroy(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD, null);
+            return CompletableFuture.completedFuture(null);
+        }
+        return createdFuture;
+    }
+
+    private DelegateBinderStateManager createBinderConnection(Set<String> supportedSet,
+            Set<FeatureTagState> deniedSet) {
+
+        List<DelegateBinderStateManager.StateCallback> stateCallbacks = new ArrayList<>(2);
+        stateCallbacks.add(mDelegateStateTracker);
+        stateCallbacks.add(mMessageTransportStateTracker);
+
+        return mBinderConnectionFactory.create(mSubId, mSipTransportImpl,
+                new DelegateRequest(supportedSet), deniedSet, mExecutorService, stateCallbacks);
+    }
+
+    /**
+     * Write the current state of this controller in String format using the PrintWriter provided
+     * for dumpsys.
+     */
+    public void dump(PrintWriter printWriter) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("SipDelegateController" + "[" + mSubId + "]:");
+        pw.increaseIndent();
+        pw.println("DelegateStateTracker:");
+        pw.increaseIndent();
+        mDelegateStateTracker.dump(printWriter);
+        pw.decreaseIndent();
+        pw.println("MessageStateTracker:");
+        pw.increaseIndent();
+        mMessageTransportStateTracker.dump(printWriter);
+        pw.decreaseIndent();
+        pw.decreaseIndent();
+    }
+
+    private void logi(String log) {
+        Log.w(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[I] " + log);
+    }
+
+    private void logw(String log) {
+        Log.w(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + 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 813834a..dd06cc1 100644
--- a/src/com/android/services/telephony/rcs/SipTransportController.java
+++ b/src/com/android/services/telephony/rcs/SipTransportController.java
@@ -16,26 +16,51 @@
 
 package com.android.services.telephony.rcs;
 
+import android.app.role.OnRoleHoldersChangedListener;
+import android.app.role.RoleManager;
 import android.content.Context;
+import android.os.UserHandle;
 import android.telephony.ims.DelegateRequest;
+import android.telephony.ims.FeatureTagState;
 import android.telephony.ims.ImsException;
 import android.telephony.ims.ImsService;
+import android.telephony.ims.SipDelegateManager;
 import android.telephony.ims.aidl.ISipDelegate;
 import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
 import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.aidl.ISipTransport;
 import android.telephony.ims.stub.DelegateConnectionMessageCallback;
 import android.telephony.ims.stub.DelegateConnectionStateCallback;
 import android.telephony.ims.stub.SipDelegate;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.LocalLog;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+
 import com.android.ims.RcsFeatureManager;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
 
+import com.google.common.base.Objects;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 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;
 
 /**
  * Manages the creation and destruction of SipDelegates in response to an IMS application requesting
@@ -46,16 +71,179 @@
  * instead of requiring that the IMS application manage its own IMS registration over-the-top. This
  * is required for some cellular carriers, which mandate that all IMS SIP traffic must be sent
  * through a single IMS registration managed by the system IMS service.
+ *
+ * //TODO: Support other roles besides SMS
+ * //TODO: Bring in carrier provisioning to influence features that can be created.
+ * //TODO: Generate registration change events.
  */
-public class SipTransportController implements RcsFeatureController.Feature {
-    private static final String LOG_TAG = "SipTransportC";
+public class SipTransportController implements RcsFeatureController.Feature,
+        OnRoleHoldersChangedListener {
+    static final int LOG_SIZE = 50;
+    static final String LOG_TAG = "SipTransportC";
 
-    private final Context mContext;
+    /**See {@link TimerAdapter#getReevaluateThrottleTimerMilliseconds()}.*/
+    private static final int REEVALUATE_THROTTLE_DEFAULT_MS = 1000;
+    /**See {@link TimerAdapter#getUpdateRegistrationDelayMilliseconds()}.*/
+    private static final int TRIGGER_UPDATE_REGISTRATION_DELAY_DEFAULT_MS = 1000;
+
+    /**
+     * {@link RoleManager} is final so we have to wrap the implementation for testing.
+     */
+    @VisibleForTesting
+    public interface RoleManagerAdapter {
+        /** See {@link RoleManager#getRoleHolders(String)} */
+        List<String> getRoleHolders(String roleName);
+        /** See {@link RoleManager#addOnRoleHoldersChangedListenerAsUser} */
+        void addOnRoleHoldersChangedListenerAsUser(Executor executor,
+                OnRoleHoldersChangedListener listener, UserHandle user);
+        /** See {@link RoleManager#removeOnRoleHoldersChangedListenerAsUser} */
+        void removeOnRoleHoldersChangedListenerAsUser(OnRoleHoldersChangedListener listener,
+                UserHandle user);
+    }
+
+    /**
+     * Adapter for timers related to this class so they can be modified during testing.
+     */
+    @VisibleForTesting
+    public interface TimerAdapter {
+        /**
+         * Time we will delay after a {@link #createSipDelegate} or {@link #destroySipDelegate}
+         * command to re-evaluate and apply any changes to the list of tracked
+         * SipDelegateControllers.
+         * <p>
+         * Another create/destroy request sent during this time will not postpone re-evaluation
+         * again.
+         */
+        int getReevaluateThrottleTimerMilliseconds();
+
+        /**
+         * Time after re-evaluate we will wait to trigger the update of IMS registration.
+         * <p>
+         * Another re-evaluate while waiting to trigger a registration update will cause this
+         * controller to cancel and reschedule the event again, further delaying the trigger to send
+         * a registration update.
+         */
+        int getUpdateRegistrationDelayMilliseconds();
+    }
+
+    private static class TimerAdapterImpl implements TimerAdapter {
+
+        @Override
+        public int getReevaluateThrottleTimerMilliseconds() {
+            return REEVALUATE_THROTTLE_DEFAULT_MS;
+        }
+
+        @Override
+        public int getUpdateRegistrationDelayMilliseconds() {
+            return TRIGGER_UPDATE_REGISTRATION_DELAY_DEFAULT_MS;
+        }
+    }
+
+    private static class RoleManagerAdapterImpl implements RoleManagerAdapter {
+
+        private final RoleManager mRoleManager;
+
+        private RoleManagerAdapterImpl(Context context) {
+            mRoleManager = context.getSystemService(RoleManager.class);
+        }
+
+        @Override
+        public List<String> getRoleHolders(String roleName) {
+            return mRoleManager.getRoleHolders(roleName);
+        }
+
+        @Override
+        public void addOnRoleHoldersChangedListenerAsUser(Executor executor,
+                OnRoleHoldersChangedListener listener, UserHandle user) {
+            mRoleManager.addOnRoleHoldersChangedListenerAsUser(executor, listener, user);
+        }
+
+        @Override
+        public void removeOnRoleHoldersChangedListenerAsUser(OnRoleHoldersChangedListener listener,
+                UserHandle user) {
+            mRoleManager.removeOnRoleHoldersChangedListenerAsUser(listener, user);
+        }
+    }
+
+    /**
+     * Used in {@link #destroySipDelegate(int, ISipDelegate, int)} to store pending destroy
+     * requests.
+     */
+    private static final class DestroyRequest {
+        public final SipDelegateController controller;
+        public final int reason;
+
+        DestroyRequest(SipDelegateController c, int r) {
+            controller = c;
+            reason = r;
+        }
+
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            DestroyRequest that = (DestroyRequest) o;
+            return reason == that.reason
+                    && controller.equals(that.controller);
+        }
+
+        @Override
+        public int hashCode() {
+            return java.util.Objects.hash(controller, reason);
+        }
+
+        @Override
+        public String toString() {
+            return "DestroyRequest{" + "controller=" + controller + ", reason=" + reason + '}';
+        }
+    }
+
+    /**
+     * Allow the ability for tests to easily mock out the SipDelegateController for testing.
+     */
+    @VisibleForTesting
+    public interface SipDelegateControllerFactory {
+        /** See {@link SipDelegateController} */
+        SipDelegateController create(int subId, DelegateRequest initialRequest, String packageName,
+                ISipTransport sipTransportImpl, ScheduledExecutorService executorService,
+                ISipDelegateConnectionStateCallback stateCallback,
+                ISipDelegateMessageCallback messageCallback);
+    }
+
+    private SipDelegateControllerFactory mDelegateControllerFactory = SipDelegateController::new;
     private final int mSlotId;
     private final ScheduledExecutorService mExecutorService;
+    private final RoleManagerAdapter mRoleManagerAdapter;
+    private final TimerAdapter mTimerAdapter;
+    private final LocalLog mLocalLog = new LocalLog(LOG_SIZE);
 
+    // A priority queue of active SipDelegateControllers, where the oldest SipDelegate gets
+    // access to the feature tag if multiple apps are allowed to request the same feature tag.
+    private final List<SipDelegateController> mDelegatePriorityQueue = new ArrayList<>();
+    // SipDelegateControllers who have been created and are pending to be added to the priority
+    // queue. Will be added into the queue in the same order as they were added here.
+    private final List<SipDelegateController> mDelegatePendingCreate = new ArrayList<>();
+    // SipDelegateControllers that are pending to be destroyed.
+    private final List<DestroyRequest> mDelegatePendingDestroy = new ArrayList<>();
+
+    // Future scheduled for operations that require the list of SipDelegateControllers to
+    // be evaluated. When the timer expires and triggers the reevaluate method, this controller
+    // will iterate through mDelegatePriorityQueue and assign Feature Tags based on role+priority.
+    private ScheduledFuture<?> mScheduledEvaluateFuture;
+    // mPendingEvaluateFTFuture creates this CompletableFuture, exposed in order to stop other
+    // evaluates from occurring while another is waiting for a result on other threads.
+    private CompletableFuture<Void> mEvaluateCompleteFuture;
+    // Future scheduled that will trigger the ImsService to update the IMS registration for the
+    // SipDelegate configuration. Will be scheduled TRIGGER_UPDATE_REGISTRATION_DELAY_MS
+    // milliseconds after a pending evaluate completes.
+    private ScheduledFuture<?> mPendingUpdateRegistrationFuture;
+    // Subscription id will change as new subscriptions are loaded on the slot.
     private int mSubId;
+    // Will go up/down as the ImsService associated with this slotId goes up/down.
     private RcsFeatureManager mRcsManager;
+    // Cached package name of the app that is considered the default SMS app.
+    private String mCachedSmsRolePackageName = "";
 
     /**
      * Create an instance of SipTransportController.
@@ -64,10 +252,11 @@
      * @param subId The subscription ID associated with this controller when it was first created.
      */
     public SipTransportController(Context context, int slotId, int subId) {
-        mContext = context;
         mSlotId = slotId;
         mSubId = subId;
 
+        mRoleManagerAdapter = new RoleManagerAdapterImpl(context);
+        mTimerAdapter = new TimerAdapterImpl();
         mExecutorService = Executors.newSingleThreadScheduledExecutor();
     }
 
@@ -76,11 +265,14 @@
      */
     @VisibleForTesting
     public SipTransportController(Context context, int slotId, int subId,
-            ScheduledExecutorService executor) {
-        mContext = context;
+            SipDelegateControllerFactory delegateFactory, RoleManagerAdapter roleManagerAdapter,
+            TimerAdapter timerAdapter, ScheduledExecutorService executor) {
         mSlotId = slotId;
         mSubId = subId;
 
+        mRoleManagerAdapter = roleManagerAdapter;
+        mTimerAdapter = timerAdapter;
+        mDelegateControllerFactory = delegateFactory;
         mExecutorService = executor;
         logi("created");
     }
@@ -102,8 +294,14 @@
 
     @Override
     public void onDestroy() {
-        // Can be null in testing.
-        mExecutorService.shutdownNow();
+        mExecutorService.submit(()-> {
+            // Ensure new create/destroy requests are denied.
+            mSubId = -1;
+            triggerDeregistrationEvent();
+            scheduleDestroyDelegates(
+                    SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN)
+                    .thenRun(mExecutorService::shutdown);
+        });
     }
 
     /**
@@ -119,12 +317,24 @@
      * @param delegateMessage The {@link DelegateConnectionMessageCallback} Binder Connection
      * @throws ImsException if the request to create the {@link SipDelegate} did not complete.
      */
-    public void createSipDelegate(int subId, DelegateRequest request,
+    public void createSipDelegate(int subId, DelegateRequest request, String packageName,
             ISipDelegateConnectionStateCallback delegateState,
             ISipDelegateMessageCallback delegateMessage) throws ImsException {
-        // TODO implementation.
-        throw new ImsException("createSipDelegate is not supported yet",
-                ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
+        logi("createSipDelegate: request= " + request + ", packageName= " + packageName);
+        CompletableFuture<ImsException> result = new CompletableFuture<>();
+        mExecutorService.submit(() -> createSipDelegateInternal(subId, request, packageName,
+                delegateState,
+                // Capture any ImsExceptions generated during the process.
+                delegateMessage, result::complete));
+        try {
+            ImsException e = result.get();
+            logi("createSipDelegate: request finished");
+            if (e != null) {
+                throw e;
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            logw("createSipDelegate: exception completing future: " + e);
+        }
     }
 
     /**
@@ -134,7 +344,7 @@
      * @param reason The reason for why the {@link SipDelegate} was destroyed.
      */
     public void destroySipDelegate(int subId, ISipDelegate connection, int reason) {
-        // TODO implementation
+        mExecutorService.execute(() -> destroySipDelegateInternal(subId, connection, reason));
     }
 
     /**
@@ -151,6 +361,104 @@
         return result;
     }
 
+    private void createSipDelegateInternal(int subId, DelegateRequest request, String packageName,
+            ISipDelegateConnectionStateCallback delegateState,
+            ISipDelegateMessageCallback delegateMessage,
+            Consumer<ImsException> startedErrorConsumer) {
+        ISipTransport transport;
+        // Send back any errors via Consumer early in creation process if it is clear that the
+        // SipDelegate will never be created.
+        try {
+            checkStateOfController(subId);
+            transport = mRcsManager.getSipTransport();
+            if (transport == null) {
+                logw("createSipDelegateInternal, transport null during request.");
+                startedErrorConsumer.accept(new ImsException("SipTransport not supported",
+                        ImsException.CODE_ERROR_UNSUPPORTED_OPERATION));
+                return;
+            } else {
+                // Release the binder thread as there were no issues processing the initial request.
+                startedErrorConsumer.accept(null);
+            }
+        } catch (ImsException e) {
+            logw("createSipDelegateInternal, ImsException during create: " + e);
+            startedErrorConsumer.accept(e);
+            return;
+        }
+
+        SipDelegateController c = mDelegateControllerFactory.create(subId, request, packageName,
+                transport, mExecutorService, delegateState, delegateMessage);
+        logi("createSipDelegateInternal: request= " + request + ", packageName= " + packageName
+                + ", controller created: " + c);
+        addPendingCreateAndEvaluate(c);
+    }
+
+    private void destroySipDelegateInternal(int subId, ISipDelegate connection, int reason) {
+        if (subId != mSubId) {
+            logw("destroySipDelegateInternal: ignoring destroy, as this is about to be destroyed "
+                    + "anyway due to subId change, delegate=" + connection);
+            return;
+        }
+        if (connection == null) {
+            logw("destroySipDelegateInternal: ignoring destroy, null connection binder.");
+            return;
+        }
+        SipDelegateController match = null;
+        for (SipDelegateController controller : mDelegatePriorityQueue) {
+            if (Objects.equal(connection.asBinder(),
+                    controller.getSipDelegateInterface().asBinder())) {
+                match = controller;
+                break;
+            }
+        }
+        if (match == null) {
+            logw("destroySipDelegateInternal: could not find matching connection=" + connection);
+            return;
+        }
+
+        logi("destroySipDelegateInternal: destroy queued for connection= " + connection);
+        addPendingDestroyAndEvaluate(match, reason);
+    }
+
+    /**
+     * Cancel pending update IMS registration events if they exist and instead send a deregister
+     * event.
+     */
+    private void triggerDeregistrationEvent() {
+        if (mPendingUpdateRegistrationFuture != null
+                && !mPendingUpdateRegistrationFuture.isDone()) {
+            // Cancel pending update and replace with a call to deregister now.
+            mPendingUpdateRegistrationFuture.cancel(false);
+            logi("triggerDeregistrationEvent: cancelling existing reg update event: "
+                    + mPendingUpdateRegistrationFuture);
+        }
+        logi("triggerDeregistrationEvent: Sending deregister event to ImsService");
+        //TODO hook up registration apis
+    }
+
+    /**
+     * Schedule an update to the IMS registration. If there is an existing update scheduled, cancel
+     * it and reschedule.
+     */
+    private void scheduleUpdateRegistration() {
+        if (mPendingUpdateRegistrationFuture != null
+                && !mPendingUpdateRegistrationFuture.isDone()) {
+            // Cancel the old pending operation and reschedule again.
+            mPendingUpdateRegistrationFuture.cancel(false);
+            logi("scheduleUpdateRegistration: cancelling existing reg update event: "
+                    + mPendingUpdateRegistrationFuture);
+        }
+        ScheduledFuture<?> f = mExecutorService.schedule(this::triggerUpdateRegistrationEvent,
+                mTimerAdapter.getUpdateRegistrationDelayMilliseconds(), TimeUnit.MILLISECONDS);
+        logi("scheduleUpdateRegistration: scheduling new event: " + f);
+        mPendingUpdateRegistrationFuture = f;
+    }
+
+    private void triggerUpdateRegistrationEvent() {
+        logi("triggerUpdateRegistrationEvent: Sending update registration event to ImsService");
+        //TODO hook up registration apis
+    }
+
     /**
      * Returns whether or not the ImsService implementation associated with the supplied subId
      * supports the SipTransport APIs.
@@ -164,6 +472,277 @@
         return (mRcsManager.getSipTransport() != null);
     }
 
+    private boolean addPendingDestroy(SipDelegateController c, int reason) {
+        DestroyRequest request = new DestroyRequest(c, reason);
+        if (!mDelegatePendingDestroy.contains(request)) {
+            return mDelegatePendingDestroy.add(request);
+        }
+        return false;
+    }
+
+    /**
+     * The supplied SipDelegateController has been destroyed and associated feature tags have been
+     * released. Trigger the re-evaluation of the priority queue with the new configuration.
+     */
+    private void addPendingDestroyAndEvaluate(SipDelegateController c, int reason) {
+        if (addPendingDestroy(c, reason)) {
+            scheduleThrottledReevaluate();
+        }
+    }
+
+    /**
+     * A new SipDelegateController has been created, add to the back of the priority queue and
+     * trigger the re-evaluation of the priority queue with the new configuration.
+     */
+    private void addPendingCreateAndEvaluate(SipDelegateController c) {
+        mDelegatePendingCreate.add(c);
+        scheduleThrottledReevaluate();
+    }
+
+    /**
+     * The priority queue has changed, which will cause a re-evaluation of the feature tags granted
+     * to each SipDelegate.
+     * <p>
+     * Note: re-evaluations are throttled to happen at a minimum to occur every
+     * REEVALUATE_THROTTLE_MS seconds. We also do not reevaluate while another reevaluate operation
+     * is in progress, so in this case, defer schedule itself.
+     */
+    private void scheduleThrottledReevaluate() {
+        if (isEvaluatePendingAndNotInProgress()) {
+            logi("scheduleThrottledReevaluate: throttling reevaluate, eval already pending: "
+                    + mScheduledEvaluateFuture);
+        } else {
+            mScheduledEvaluateFuture = mExecutorService.schedule(this::reevaluateDelegates,
+                    mTimerAdapter.getReevaluateThrottleTimerMilliseconds(), TimeUnit.MILLISECONDS);
+            logi("scheduleThrottledReevaluate: new reevaluate scheduled: "
+                    + mScheduledEvaluateFuture);
+        }
+    }
+
+    /**
+     * @return true if there is a evaluate pending, false if there is not. If evaluate has already
+     * begun, but we are waiting for it to complete, this will also return false.
+     */
+    private boolean isEvaluatePendingAndNotInProgress() {
+        boolean isEvalScheduled = mScheduledEvaluateFuture != null
+                && !mScheduledEvaluateFuture.isDone();
+        boolean isEvalInProgress = mEvaluateCompleteFuture != null
+                && !mEvaluateCompleteFuture.isDone();
+        return isEvalScheduled && !isEvalInProgress;
+    }
+
+    /**
+     * Cancel any pending re-evaluates and perform it as soon as possible. This is done in the case
+     * where we need to do something like tear down this controller or change subId.
+     */
+    private void scheduleReevaluateNow(CompletableFuture<Void> onDoneFuture) {
+        if (isEvaluatePendingAndNotInProgress()) {
+            mScheduledEvaluateFuture.cancel(false /*interrupt*/);
+            logi("scheduleReevaluateNow: cancelling pending reevaluate: "
+                    + mScheduledEvaluateFuture);
+        }
+        // we have tasks that depend on this potentially, so once the last reevaluate is done,
+        // schedule a new one right away.
+        if (mEvaluateCompleteFuture != null && !mEvaluateCompleteFuture.isDone()) {
+            mEvaluateCompleteFuture.thenRunAsync(
+                    () -> scheduleReevaluateNow(onDoneFuture), mExecutorService);
+            return;
+        }
+
+        reevaluateDelegates();
+        mEvaluateCompleteFuture.thenAccept(onDoneFuture::complete);
+    }
+
+    /**
+     * Apply all operations that have been pending by collecting pending create/destroy operations
+     * and batch applying them to the mDelegatePriorityQueue.
+     *
+     * First perform the operation of destroying all SipDelegateConnections that have been pending
+     * destroy. Next, add all pending new SipDelegateControllers to the end of
+     * mDelegatePriorityQueue and loop through all in the queue, applying feature tags to the
+     * appropriate SipDelegateController if they pass role checks and have not already been claimed
+     * by another delegate higher in the priority queue.
+     */
+    private void reevaluateDelegates() {
+        if (mEvaluateCompleteFuture != null && !mEvaluateCompleteFuture.isDone()) {
+            logw("reevaluateDelegates: last evaluate not done, deferring new request");
+            // Defer re-evaluate until after the pending re-evaluate is complete.
+            mEvaluateCompleteFuture.thenRunAsync(this::scheduleThrottledReevaluate,
+                    mExecutorService);
+            return;
+        }
+
+        // Destroy all pending destroy delegates first. Order doesn't matter.
+        List<CompletableFuture<Void>> pendingDestroyList = mDelegatePendingDestroy.stream()
+                .map(d -> triggerDestroy(d.controller, d.reason)).collect(
+                Collectors.toList());
+        CompletableFuture<Void> pendingDestroy = CompletableFuture.allOf(
+                pendingDestroyList.toArray(new CompletableFuture[mDelegatePendingDestroy.size()]));
+        mDelegatePriorityQueue.removeAll(mDelegatePendingDestroy.stream().map(d -> d.controller)
+                .collect(Collectors.toList()));
+        mDelegatePendingDestroy.clear();
+
+        // Add newly created SipDelegates to end of queue before evaluating associated features.
+        mDelegatePriorityQueue.addAll(mDelegatePendingCreate);
+        for (SipDelegateController c : mDelegatePendingCreate) {
+            logi("reevaluateDelegates: pending create: " + c);
+        }
+        mDelegatePendingCreate.clear();
+
+        // Wait for destroy stages to complete, then loop from oldest to most recent and associate
+        // feature tags that the app has requested to the SipDelegate.
+        // Each feature tag can only be associated with one SipDelegate, so as feature tags are
+        // taken, do not allow other SipDelegates to be associated with those tags as well. Each
+        // stage of the CompletableFuture chain passes the previously claimed feature tags into the
+        // next stage so that those feature tags can be denied if already claimed.
+        // Executor doesn't matter here, just composing here to transform to the next stage.
+        CompletableFuture<Set<String>> pendingChange = pendingDestroy.thenCompose((ignore) -> {
+            logi("reevaluateDelegates: destroy phase complete");
+            return CompletableFuture.completedFuture(new ArraySet<>());
+        });
+        final String cachedSmsRolePackage = mCachedSmsRolePackageName;
+        for (SipDelegateController c : mDelegatePriorityQueue) {
+            logi("reevaluateDelegates: pending reeval: " + c);
+            pendingChange = pendingChange.thenComposeAsync((takenTags) -> {
+                logi("reevaluateDelegates: last stage completed with result:" + takenTags);
+                if (takenTags == null) {
+                    // return early, the ImsService is no longer available. This will eventually be
+                    // destroyed.
+                    return CompletableFuture.completedFuture(null /*failed*/);
+                }
+                return changeSupportedFeatureTags(c, cachedSmsRolePackage, takenTags);
+            }, mExecutorService);
+        }
+
+        // Executor doesn't matter here, just adding an extra stage to print result.
+        mEvaluateCompleteFuture = pendingChange
+                .thenAccept((associatedFeatures) -> logi("reevaluateDelegates: reevaluate complete,"
+                        + " feature tags associated: " + associatedFeatures));
+        logi("reevaluateDelegates: future created.");
+    }
+
+    private CompletableFuture<Void> triggerDestroy(SipDelegateController c, int reason) {
+        return c.destroy(isForcedFromReason(reason), reason)
+                // Executor doesn't matter here, just for logging.
+                .thenAccept((delegateReason) -> logi("destroy triggered with " + reason
+                        + " and finished with reason= " + delegateReason));
+    }
+
+    private boolean isForcedFromReason(int reason) {
+        switch (reason) {
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_UNKNOWN:
+                logw("isForcedFromReason, unknown reason");
+                /*intentional fallthrough*/
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP:
+                /*intentional fallthrough*/
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_USER_DISABLED_RCS:
+                return false;
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD:
+                /*intentional fallthrough*/
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN:
+                return true;
+        }
+        logw("isForcedFromReason, unexpected reason: " + reason);
+        return false;
+    }
+
+    /**
+     * Called by RoleManager when a role has changed so that we can query the new role holder.
+     * @param roleName the name of the role whose holders are changed
+     * @param user the user for this role holder change
+     */
+    // Called on mExecutorThread
+    @Override
+    public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
+        logi("onRoleHoldersChanged, roleName= " + roleName + ", user= " + user);
+        // Only monitor changes on the system
+        if (!UserHandle.SYSTEM.equals(user)) {
+            return;
+        }
+
+        if (!RoleManager.ROLE_SMS.equals(roleName)) {
+            logi("onRoleHoldersChanged, ignoring non SMS role change");
+            // TODO: only target default sms app for now and add new roles later using
+            // CarrierConfigManager
+            return;
+        }
+        updateRoleCache();
+        // new denied tags will be picked up when reevaluate completes.
+        scheduleThrottledReevaluate();
+    }
+
+
+    private void updateRoleCache() {
+        // Only one app can fulfill the SMS role.
+        String newSmsRolePackageName = mRoleManagerAdapter.getRoleHolders(RoleManager.ROLE_SMS)
+                .stream().findFirst().orElse("");
+
+        if (TextUtils.equals(mCachedSmsRolePackageName, newSmsRolePackageName)) {
+            logi("onRoleHoldersChanged, skipping, role did not change");
+            return;
+        }
+        mCachedSmsRolePackageName = newSmsRolePackageName;
+    }
+
+    /**
+     * Check the requested roles for the specified package name and return the tags that were
+     * applied to that SipDelegateController.
+     * @param controller Controller to attribute feature tags to.
+     * @param alreadyRequestedTags The feature tags that were already granted to other SipDelegates.
+     * @return Once complete, contains the set of feature tags that the SipDelegate now has
+     * associated with it along with the feature tags that previous SipDelegates had.
+     *
+     * // TODO: we currently only track SMS role, extend to support other roles as well.
+     */
+    private CompletableFuture<Set<String>> changeSupportedFeatureTags(
+            SipDelegateController controller, String smsRolePackageName,
+            Set<String> alreadyRequestedTags) {
+        Set<String> requestedFeatureTags = controller.getInitialRequest().getFeatureTags();
+        String packageName = controller.getPackageName();
+        if (!smsRolePackageName.equals(packageName)) {
+            // Deny all tags.
+            Set<FeatureTagState> deniedTags = new ArraySet<>();
+            for (String s : requestedFeatureTags) {
+                deniedTags.add(new FeatureTagState(s,
+                        SipDelegateManager.DENIED_REASON_NOT_ALLOWED));
+            }
+            CompletableFuture<Boolean> pendingDeny = controller.changeSupportedFeatureTags(
+                    Collections.emptySet(), deniedTags);
+            logi("changeSupportedFeatureTags pendingDeny=" + pendingDeny);
+            // do not worry about executor used here, this stage used to interpret result + add log.
+            return pendingDeny.thenApply((completedSuccessfully) ->  {
+                logi("changeSupportedFeatureTags: deny completed: " + completedSuccessfully);
+                if (!completedSuccessfully) return null;
+                // Return back the previous list of requested tags, as we did not add any more.
+                return alreadyRequestedTags;
+            });
+        }
+
+        ArraySet<String> previouslyGrantedTags = new ArraySet<>(alreadyRequestedTags);
+        // deny tags already used by other delegates
+        Set<FeatureTagState> deniedTags = new ArraySet<>();
+        for (String s : requestedFeatureTags) {
+            if (previouslyGrantedTags.contains(s)) {
+                deniedTags.add(new FeatureTagState(s,
+                        SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE));
+            }
+        }
+        Set<String> nonDeniedTags = requestedFeatureTags.stream()
+                .filter(r -> !previouslyGrantedTags.contains(r))
+                .collect(Collectors.toSet());
+        // Add newly granted tags to the already requested tags list.
+        previouslyGrantedTags.addAll(nonDeniedTags);
+        CompletableFuture<Boolean> pendingChange = controller.changeSupportedFeatureTags(
+                nonDeniedTags, deniedTags);
+        logi("changeSupportedFeatureTags pendingChange=" + pendingChange);
+        // do not worry about executor used here, this stage used to interpret result + add log.
+        return pendingChange.thenApply((completedSuccessfully) ->  {
+            logi("changeSupportedFeatureTags: change completed: " + completedSuccessfully);
+            if (!completedSuccessfully) return null;
+            return previouslyGrantedTags;
+        });
+    }
+
     /**
      * Run a Callable on the ExecutorService Thread and wait for the result.
      * If an ImsException is thrown, catch it and rethrow it to caller.
@@ -207,7 +786,26 @@
 
     private void onRcsManagerChanged(RcsFeatureManager m) {
         logi("manager changed, " + mRcsManager + "->" + m);
+        if (mRcsManager == m) return;
         mRcsManager = m;
+        if (mRcsManager == null) {
+            logi("onRcsManagerChanged: lost connection to ImsService, tearing down...");
+            unregisterListeners();
+            scheduleDestroyDelegates(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD);
+        } else {
+            registerListeners();
+            updateRoleCache();
+        }
+    }
+
+    private void registerListeners() {
+        mRoleManagerAdapter.addOnRoleHoldersChangedListenerAsUser(mExecutorService, this,
+                UserHandle.SYSTEM);
+    }
+
+    private void unregisterListeners() {
+        mRoleManagerAdapter.removeOnRoleHoldersChangedListenerAsUser(this, UserHandle.SYSTEM);
+        mCachedSmsRolePackageName = "";
     }
 
     /**
@@ -216,18 +814,65 @@
      */
     private void onSubIdChanged(int newSubId) {
         logi("subId changed, " + mSubId + "->" + newSubId);
-        mSubId = newSubId;
+        if (mSubId != newSubId) {
+            // Swap subId, any pending create/destroy on old subId will be denied.
+            mSubId = newSubId;
+            scheduleDestroyDelegates(
+                    SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN);
+            return;
+        }
+        // TODO: if subId hasn't changed this means that we should load in any new carrier configs
+        // that we care about and apply.
     }
 
-    private void logi(String message) {
-        Log.i(LOG_TAG, getPrefix() + ": " + message);
+    /**
+     * Destroy all tracked SipDelegateConnections due to the subscription being torn down.
+     * @return A CompletableFuture that will complete when all SipDelegates have been torn down.
+     */
+    private CompletableFuture<Void> scheduleDestroyDelegates(int reason) {
+        boolean addedDestroy = false;
+        for (SipDelegateController c : mDelegatePriorityQueue) {
+            logi("scheduleDestroyDelegates: Controller pending destroy: " + c);
+            addedDestroy |= addPendingDestroy(c, reason);
+        }
+        if (addedDestroy) {
+            CompletableFuture<Void> pendingDestroy = new CompletableFuture<>();
+            scheduleReevaluateNow(pendingDestroy);
+            return pendingDestroy;
+        } else {
+            return CompletableFuture.completedFuture(null);
+        }
     }
 
-    private void logw(String message) {
-        Log.w(LOG_TAG, getPrefix() + ": " + message);
+    @Override
+    public void dump(PrintWriter printWriter) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("SipTransportController" + "[" + mSlotId  + "->" + mSubId + "]:");
+        pw.increaseIndent();
+        pw.println("LocalLog:");
+        pw.increaseIndent();
+        mLocalLog.dump(pw);
+        pw.decreaseIndent();
+        pw.println("SipDelegateControllers (in priority order):");
+        pw.increaseIndent();
+        if (mDelegatePriorityQueue.isEmpty()) {
+            pw.println("[NONE]");
+        } else {
+            for (SipDelegateController c : mDelegatePriorityQueue) {
+                c.dump(pw);
+            }
+        }
+        pw.decreaseIndent();
+        pw.decreaseIndent();
     }
 
-    private String getPrefix() {
-        return "[" + mSlotId + "," + mSubId + "]";
+    private void logi(String log) {
+        Log.w(LOG_TAG, "[" + mSlotId  + "->" + mSubId + "] " + log);
+        mLocalLog.log("[I] " + log);
+    }
+
+    private void logw(String log) {
+        Log.w(LOG_TAG, "[" + mSlotId  + "->" + mSubId + "] " + log);
+        mLocalLog.log("[W] " + log);
     }
 }
diff --git a/src/com/android/services/telephony/rcs/UceControllerManager.java b/src/com/android/services/telephony/rcs/UceControllerManager.java
index db8c933..d1f91d1 100644
--- a/src/com/android/services/telephony/rcs/UceControllerManager.java
+++ b/src/com/android/services/telephony/rcs/UceControllerManager.java
@@ -28,7 +28,9 @@
 import com.android.ims.RcsFeatureManager;
 import com.android.ims.rcs.uce.UceController;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
 
+import java.io.PrintWriter;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -231,4 +233,15 @@
         }
         return true;
     }
+
+
+    @Override
+    public void dump(PrintWriter printWriter) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("UceControllerManager" + "[" + mSlotId + "]:");
+        pw.increaseIndent();
+        pw.println("UceController available = " + mUceController != null);
+        //TODO: Add dump for UceController
+        pw.decreaseIndent();
+    }
 }
