+
+deleteDevice :: MTaskDevice -> Task ()
+deleteDevice d = sendMessages [MTShutdown] d
+ >>| wait "Waiting for the channels to empty" (\(r,s,ss)->isEmpty s) (channels d)
+ >>| upd (\(r,s,ss)->(r,s,True)) (channels d)
+ >>| maybe (treturn ()) (flip removeTask topLevelTasks) d.deviceTask
+ >>| upd (filter ((<>)d)) deviceStoreNP
+// >>| cleanSharesDevice d.deviceName
+ @! ()
+
+sendMessages :: [MTaskMSGSend] MTaskDevice -> Task Channels
+sendMessages msgs dev = upd (realMessageSend msgs) $ channels dev
+
+sendMessagesIW :: [MTaskMSGSend] MTaskDevice *IWorld -> *(MaybeError TaskException (), *IWorld)
+sendMessagesIW msgs dev iworld
+ = modify (tuple () o realMessageSend msgs) (channels dev) iworld
+
+realMessageSend :: [MTaskMSGSend] Channels -> Channels
+realMessageSend msgs (r,s,ss) = (r,msgs++s,ss)
+
+withDevices :: MTaskDevice (MTaskDevice -> MTaskDevice) -> Task [MTaskDevice]
+withDevices a trans = upd (map \b->if (b == a) (trans b) b) deviceStoreNP
+
+deviceTaskAcked :: MTaskDevice Int Int -> Task [MTaskDevice]
+deviceTaskAcked dev i mem
+ = withDevices dev (\d->{d
+ &deviceTasks=ackFirst d.deviceTasks
+ ,deviceSpec=Just {fromJust d.deviceSpec & bytesMemory=mem}})
+ where
+ ackFirst :: [MTaskTask] -> [MTaskTask]
+ ackFirst [] = []
+ ackFirst [t:ts] = if (t.ident == -1)
+ [{t & ident=i}:ts] [t:ackFirst ts]
+
+deviceTaskDelete :: MTaskDevice MTaskTask -> Task ()
+deviceTaskDelete dev task = sendMessages [MTTaskDel task.ident] dev @! ()
+
+deviceTaskDeleteAcked :: MTaskDevice Int -> Task [MTaskDevice]
+deviceTaskDeleteAcked d i = cleanSharesTask i d
+ >>| withDevices d deleteTask
+ where deleteTask d = {d & deviceTasks=[s\\s<-d.deviceTasks | i <> s.ident]}
+
+deviceAddSpec :: MTaskDevice MTaskDeviceSpec -> Task [MTaskDevice]
+deviceAddSpec d s = withDevices d $ \r->{MTaskDevice | r & deviceSpec=Just s}