g_tls_connection_base_set_property (GObject      *object,
                                    guint         prop_id,
                                    const GValue *value,
                                    GParamSpec   *pspec)
{
  GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (object);
  GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
  GInputStream *istream;
  GOutputStream *ostream;
  gboolean system_certdb;
  GTlsBackend *backend;

  switch (prop_id)
    {
    case PROP_BASE_IO_STREAM:
      g_assert (!g_value_get_object (value) || !priv->base_socket);

      if (priv->base_io_stream)
        {
          g_object_unref (priv->base_io_stream);
          priv->base_istream = NULL;
          priv->base_ostream = NULL;
        }
      priv->base_io_stream = g_value_dup_object (value);
      if (!priv->base_io_stream)
        return;

      istream = g_io_stream_get_input_stream (priv->base_io_stream);
      ostream = g_io_stream_get_output_stream (priv->base_io_stream);

      if (G_IS_POLLABLE_INPUT_STREAM (istream) &&
          g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (istream)))
        {
          priv->base_istream = G_POLLABLE_INPUT_STREAM (istream);
          priv->tls_istream = g_tls_input_stream_new (tls);
        }
      if (G_IS_POLLABLE_OUTPUT_STREAM (ostream) &&
          g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (ostream)))
        {
          priv->base_ostream = G_POLLABLE_OUTPUT_STREAM (ostream);
          priv->tls_ostream = g_tls_output_stream_new (tls);
        }
      break;

    case PROP_BASE_SOCKET:
      g_assert (!g_value_get_object (value) || !priv->base_io_stream);

      g_clear_object (&priv->base_socket);
      priv->base_socket = g_value_dup_object (value);
      break;

    case PROP_REQUIRE_CLOSE_NOTIFY:
      priv->require_close_notify = g_value_get_boolean (value);
      break;

    case PROP_REHANDSHAKE_MODE:
      priv->rehandshake_mode = g_value_get_enum (value);
      break;

    case PROP_USE_SYSTEM_CERTDB:
      system_certdb = g_value_get_boolean (value);
      if (system_certdb != priv->is_system_certdb)
        {
          g_clear_object (&priv->database);
          if (system_certdb)
            {
              backend = g_tls_backend_get_default ();
              priv->database = g_tls_backend_get_default_database (backend);
            }
          priv->is_system_certdb = system_certdb;
          priv->database_is_unset = FALSE;
        }
      break;

    case PROP_DATABASE:
      g_clear_object (&priv->database);
      priv->database = g_value_dup_object (value);
      priv->is_system_certdb = FALSE;
      priv->database_is_unset = FALSE;
      break;

    case PROP_CERTIFICATE:
      if (priv->certificate)
        g_object_unref (priv->certificate);
      priv->certificate = g_value_dup_object (value);
      break;

    case PROP_INTERACTION:
      g_clear_object (&priv->interaction);
      priv->interaction = g_value_dup_object (value);
      break;

    case PROP_ADVERTISED_PROTOCOLS:
      g_clear_pointer (&priv->advertised_protocols, g_strfreev);
      priv->advertised_protocols = g_value_dup_boxed (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}