You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: admin_interface.rs
    path of file: ./repos/holochain/crates/holochain/src/conductor/api/api_external
    
    the code of the file until where you have to start completion: use std::collections::HashSet;

use super::InterfaceApi;
use crate::conductor::api::error::ConductorApiError;
use crate::conductor::api::error::ConductorApiResult;
use crate::conductor::api::error::SerializationError;
use crate::conductor::error::ConductorError;
use crate::conductor::interface::error::InterfaceError;
use crate::conductor::interface::error::InterfaceResult;
use crate::conductor::ConductorHandle;
use holochain_serialized_bytes::prelude::*;
use holochain_types::dna::DnaBundle;
use holochain_types::prelude::*;
use mr_bundle::Bundle;

use tracing::*;

pub use holochain_conductor_api::*;

/// A trait for the interface that a Conductor exposes to the outside world to use for administering the conductor.
/// This trait has one mock implementation and one "real" implementation
#[async_trait::async_trait]
pub trait AdminInterfaceApi: 'static + Send + Sync + Clone {
    /// Call an admin function to modify this Conductor's behavior
    async fn handle_admin_request_inner(
        &self,
        request: AdminRequest,
    ) -> ConductorApiResult<AdminResponse>;

    // -- provided -- //

    /// Deal with error cases produced by `handle_admin_request_inner`
    async fn handle_admin_request(&self, request: AdminRequest) -> AdminResponse {
        debug!("admin request: {:?}", request);

        let res = match self.handle_admin_request_inner(request).await {
            Ok(response) => response,
            Err(e) => AdminResponse::Error(e.into()),
        };
        debug!("admin response: {:?}", res);
        res
    }
}

/// The admin interface that external connections
/// can use to make requests to the conductor
/// The concrete (non-mock) implementation of the AdminInterfaceApi
#[derive(Clone)]
pub struct RealAdminInterfaceApi {
    /// Mutable access to the Conductor
    conductor_handle: ConductorHandle,
}

impl RealAdminInterfaceApi {
    /// Create an admin interface api.
    pub fn new(conductor_handle: ConductorHandle) -> Self {
        RealAdminInterfaceApi { conductor_handle }
    }
}

#[async_trait::async_trait]
impl AdminInterfaceApi for RealAdminInterfaceApi {
    async fn handle_admin_request_inner(
        &self,
        request: AdminRequest,
    ) -> ConductorApiResult<AdminResponse> {
        use AdminRequest::*;
        match request {
            AddAdminInterfaces(configs) => {
                self.conductor_handle
                    .clone()
                    .add_admin_interfaces(configs)
                    .await?;
                Ok(AdminResponse::AdminInterfacesAdded)
            }
            RegisterDna(payload) => {
                trace!(register_dna_payload = ?payload);
                let RegisterDnaPayload { modifiers, source } = *payload;
                let modifiers = modifiers.serialized().map_err(SerializationError::Bytes)?;
                // network seed and properties from the register call will override any in the bundle
                let dna = match source {
                    DnaSource::Hash(ref hash) => {
                        if !modifiers.has_some_option_set() {
                            return Err(ConductorApiError::DnaReadError(
                                "DnaSource::Hash requires `properties` or `network_seed` or `origin_time` to create a derived Dna"
                                    .to_string(),
                            ));
               
    
    // async fn install_list_dna_app() {
    // holochain_trace::test_run().ok();
    // let db_dir = test_db_dir();
    // let handle = Conductor::builder().test(db_dir.path(), &[]).await.unwrap();
    // let shutdown = handle.take_shutdown_handle().unwrap();
    // let admin_api = RealAdminInterfaceApi::new(handle.clone());
    // let network_seed = Uuid::new_v4();
    // let dna = fake_dna_zomes(
    //     &network_seed.to_string(),
    //     vec![(TestWasm::Foo.into(), TestWasm::Foo.into())],
    // );
    // let (dna_path, _tempdir) = write_fake_dna_file(dna.clone()).await.unwrap();
    // let agent_key1 = fake_agent_pubkey_1();

    // attempt install with a hash before the DNA has been registered
    // let dna_hash = dna.dna_hash().clone();
    // let hash_payload = InstallAppDnaPayload::hash_only(dna_hash.clone(), "".to_string());
    // let hash_install_payload = InstallAppPayload {
    //     dnas: vec![hash_payload],
    //     installed_app_id: "test-by-hash".to_string(),
    //     agent_key: agent_key1,
    // };
    // let install_response = admin_api
    //     .handle_admin_request(AdminRequest::InstallApp(Box::new(
    //         hash_install_payload.clone(),
    //     )))
    //     .await;
    // assert_matches!(
    //     install_response,
    //     AdminResponse::Error(ExternalApiWireError::DnaReadError(e)) if e == format!("Given dna has not been registered: {}", dna_hash)
    // );

    // now register a DNA
    // let path_payload = RegisterDnaPayload {
    //     modifiers: DnaModifiersOpt::none(),
    //     source: DnaSource::Path(dna_path),
    // };
    // let path_install_response = admin_api
    //     .handle_admin_request(AdminRequest::RegisterDna(Box::new(path_payload)))
    //     .await;
    // assert_matches!(
    //     path_install_response,
    //     AdminResponse::DnaRegistered(h) if h == dna_hash
    // );

    // let agent_key2 = fake_agent_pubkey_2();
    // let path_payload = InstallAppDnaPayload::hash_only(dna_hash.clone(), "".to_string());
    // let cell_id2 = CellId::new(dna_hash.clone(), agent_key2.clone());
    // let expected_installed_app = InstalledApp::new_fresh(
    //     InstalledAppCommon::new_legacy(
    //         "test-by-path".to_string(),
    //         vec![InstalledCell::new(cell_id2.clone(), "".to_string())],
    //     )
    //     .unwrap(),
    // );
    // let expected_installed_app_info: InstalledAppInfo = (&expected_installed_app).into();
    // let path_install_payload = InstallAppPayload {
    //     dnas: vec![path_payload],
    //     installed_app_id: "test-by-path".to_string(),
    //     agent_key: agent_key2,
    // };

    // let install_response = admin_api
    //     .handle_admin_request(AdminRequest::InstallApp(Box::new(path_install_payload)))
    //     .await;
    // assert_matches!(
    //     install_response,
    //     AdminResponse::AppInstalled(info) if info == expected_installed_app_info
    // );
    // let dna_list = admin_api.handle_admin_request(AdminRequest::ListDnas).await;
    // let expects = vec![dna_hash.clone()];
    // assert_matches!(dna_list, AdminResponse::DnasListed(a) if a == expects);

    // let expected_enabled_app = InstalledApp::new_running(
    //     InstalledAppCommon::new_legacy(
    //         "test-by-path".to_string(),
    //         vec![InstalledCell::new(cell_id2.clone(), "".to_string())],
    //     )
    //     .unwrap(),
    // );
    // let expected_enabled_app_info: InstalledAppInfo = (&expected_enabled_app).into();
    // let res = admin_api
    //     .handle_admin_request(AdminRequest::EnableApp {
    //         installed_app_id: "test-by-path".to_string(),
    //     })
    //     .await;
    // assert_matches!(res,
    //     AdminResponse::AppEnabled {app, ..} if app == expected_enabled_app_info
    // );

    // let res = admin_api
    //     .handle_admin_request(AdminRequest::ListCellIds)
    //     .await;

    // assert_matches!(res, AdminResponse::CellIdsListed(v) if v == vec![cell_id2]);

    // now try to install the happ using the hash
    // let _install_response = admin_api
    //     .handle_admin_request(AdminRequest::InstallApp(Box::new(hash_install_payload)))
    //     .await;
    // let _res = admin_api
    //     .handle_admin_request(AdminRequest::EnableApp {
    //         installed_app_id: "test-by-hash".to_string(),
    //     })
    //     .await;

    // let res = admin_api
    //     .handle_admin_request(AdminRequest::ListApps {
    //         status_filter: Some(AppStatusFilter::Enabled),
    //     })
    //     .await;

    // assert_matches!(res, AdminResponse::AppsListed(v) if v.iter().find(|app_info| app_info.installed_app_id.as_str() == "test-by-path").is_some() && v.iter().find(|app_info| app_info.installed_app_id.as_str() == "test-by-hash").is_some());

    // handle.shutdown();
    // tokio::time::timeout(std::time::Duration::from_secs(1), shutdown)
    //     .await
    //     .ok();
    // }