anchor.diff:                  gui_jq:show(<<"s3_storage">>),
                   gui_jq:hide(<<"dio_storage">>),
                   gui_jq:hide(<<"ceph_storage">>),
  +                gui_jq:hide(<<"swift_storage">>),
                   clear_textboxes(),
                   gui_jq:focus(<<"s3_storage_name">>),
  -                gui_jq:bind_enter_to_submit_button(<<"s3_bucket_name">>, <<"s3_submit">>),
  +                gui_jq:bind_enter_to_submit_button(<<"s3_timeout">>, <<"s3_submit">>),
                   State#{storage_type => SType};
   
               {set_storage_type, <<"Ceph">> = SType} ->
                   gui_jq:show(<<"ceph_storage">>),
                   gui_jq:hide(<<"dio_storage">>),
                   gui_jq:hide(<<"s3_storage">>),
  +                gui_jq:hide(<<"swift_storage">>),
                   clear_textboxes(),
                   gui_jq:focus(<<"ceph_storage_name">>),
  -                gui_jq:bind_enter_to_submit_button(<<"ceph_pool_name">>, <<"ceph_submit">>),
  +                gui_jq:bind_enter_to_submit_button(<<"ceph_timeout">>, <<"ceph_submit">>),
                   State#{storage_type => SType};
   
               {set_storage_type, <<"Posix">> = SType} ->
                   gui_jq:show(<<"dio_storage">>),
                   gui_jq:hide(<<"ceph_storage">>),
                   gui_jq:hide(<<"s3_storage">>),
  +                gui_jq:hide(<<"swift_storage">>),
                   clear_textboxes(),
                   gui_jq:focus(<<"dio_storage_name">>),
  -                gui_jq:bind_enter_to_submit_button(<<"dio_mount_point">>, <<"dio_submit">>),
  +                gui_jq:bind_enter_to_submit_button(<<"dio_timeout">>, <<"dio_submit">>),
                   State#{storage_type => SType};
   
  -            {ceph_submit, <<>>, _, _, _, _, _} ->
  +            {set_storage_type, <<"Swift">> = SType} ->
  +                gui_jq:show(<<"swift_storage">>),
  +                gui_jq:hide(<<"dio_storage">>),
  +                gui_jq:hide(<<"ceph_storage">>),
  +                gui_jq:hide(<<"s3_storage">>),
  +                clear_textboxes(),
  +                gui_jq:focus(<<"swift_storage_name">>),
  +                gui_jq:bind_enter_to_submit_button(<<"swift_timeout">>, <<"swift_submit">>),
  +                State#{storage_type => SType};
  +
  +            {ceph_submit, <<>>, _, _, _, _, _, _} ->
                   onepanel_gui_utils:message(error, <<"Please provide Ceph admin username.">>),
                   State;
   
  -            {ceph_submit, _, <<>>, _, _, _, _} ->
  +            {ceph_submit, _, <<>>, _, _, _, _, _} ->
                   onepanel_gui_utils:message(error, <<"Please provide Ceph admin key.">>),
                   State;
   
  -            {ceph_submit, _, _, <<>>, _, _, _} ->
  +            {ceph_submit, _, _, <<>>, _, _, _, _} ->
                   onepanel_gui_utils:message(error, <<"Please provide storage name.">>),
                   State;
   
  -            {ceph_submit, _, _, _, <<>>, _, _} ->
  +            {ceph_submit, _, _, _, <<>>, _, _, _} ->
                   onepanel_gui_utils:message(error, <<"Please provide monitor host.">>),
                   State;
   
  -            {ceph_submit, _, _, _, _, <<>>, _} ->
  +            {ceph_submit, _, _, _, _, <<>>, _, _} ->
                   onepanel_gui_utils:message(error, <<"Please provide cluster name.">>),
                   State;
   
  -            {ceph_submit, _, _, _, _, _, <<>>} ->
  +            {ceph_submit, _, _, _, _, _, <<>>, _} ->
                   onepanel_gui_utils:message(error, <<"Please provide pool name.">>),
                   State;
   
  -            {ceph_submit, Username, Key, StorageName, MonHost, ClusterName, PoolName} ->
  +            {ceph_submit, Username, Key, StorageName, MonHost, ClusterName, PoolName, Timeout} ->
  +                OptArgs = prepare_opt_args([{timeout, Timeout}], []),
                   case onepanel_gui_logic:add_storage([{StorageName, [{type, <<"ceph">>},
                       {monitorHostname, MonHost}, {clusterName, ClusterName},
  -                    {poolName, PoolName}, {username, Username}, {key, Key}]}]) of
  +                    {poolName, PoolName}, {username, Username}, {key, Key} | OptArgs]}]) of
                       ok ->
                           onepanel_gui_utils:message(success, <<"Storage successfully added.">>),
                           clear_textboxes(),
  
positive.code:     MonHost = gui_ctx:postback_param(<<"ceph_mon_host">>),
      ClusterName = gui_ctx:postback_param(<<"ceph_cluster_name">>),
      PoolName = gui_ctx:postback_param(<<"ceph_pool_name">>),
      get(comet) ! {ceph_submit, strip(Username), strip(Key), strip(StorageName),
          strip(MonHost), strip(ClusterName), strip(PoolName)};
  
  event(dio_submit) ->
      gui_jq:show(<<"main_spinner">>),
      StorageName = gui_ctx:postback_param(<<"dio_storage_name">>),
      MountPoint = gui_ctx:postback_param(<<"dio_mount_point">>),
      get(comet) ! {dio_submit, strip(StorageName), strip(MountPoint)};
  
  event(s3_submit) ->
      gui_jq:show(<<"main_spinner">>),
  
negative.code:         actions = gui_jq:form_submit_action(<<"ceph_submit">>,
              ceph_submit, [<<"ceph_storage_name">>, <<"ceph_username">>,
                  <<"ceph_key">>, <<"ceph_mon_host">>,
                  <<"ceph_cluster_name">>, <<"ceph_pool_name">>,
                  <<"ceph_timeout">>]),
          body = [
              #textbox{
                  id = <<"ceph_storage_name">>,
  