anchor.diff:     pipe_send(Pid, A, Msg, Opts).
   
   %%
  -%% send message through pipe
  +%% send message through pipe either to side (a) or (b)
   %%   Options:
   %%      yield     - suspend current processes
   %%      noconnect - do not connect to remote node
  --spec(a/2 :: (pipe(), any()) -> ok).
  --spec(a/3 :: (pipe(), any(), list()) -> ok).
  --spec(b/2 :: (pipe(), any()) -> ok).
  --spec(b/3 :: (pipe(), any(), list()) -> ok).
  +-spec(a/2 :: (pipe(), _) -> ok).
  +-spec(a/3 :: (pipe(), _, [atom()]) -> ok).
  +-spec(b/2 :: (pipe(), _) -> ok).
  +-spec(b/3 :: (pipe(), _, [atom()]) -> ok).
   
   a({pipe, Pid, _}, Msg)
    when is_pid(Pid) orelse is_atom(Pid) ->
      pipe:send(Pid, Msg);
   a({pipe, {Pid, Tx}, _}, Msg)
    when is_pid(Pid), is_reference(Tx) ->
  +   % backward compatible with gen_server:reply
      try erlang:send(Pid, {Tx, Msg}), Msg catch _:_ -> Msg end;
   a({pipe, {Tx, Pid}, _}, Msg)
    when is_pid(Pid), is_reference(Tx) ->
  
positive.code:    Msg.
  
  %%
  %% receive pipe message
  %%  Options
  %%    noexit - opts returns {error, timeout} instead of exit signal
  -spec(recv/0 :: () -> any()).
  -spec(recv/1 :: (timeout()) -> any()).
  -spec(recv/2 :: (timeout(), list()) -> any()).
  -spec(recv/3 :: (pid(), timeout(), list()) -> any()).
  
  recv() ->
     recv(5000).
  
negative.code:    Pid.
  
  spawn_link(Fun) ->
     pipe:spawn_link(Fun, []).
  
  spawn_link(Fun, Opts0) ->
     {ok, Pid} = case lists:keytake(init, 1, Opts0) of
        false ->
           start_link(pipe_funct, [Fun], Opts0);
        {value, {init, Init}, Opts1} ->
           % @todo: check usability of init option
           start_link(pipe_funct, [Init, Fun], Opts1)
     end,
     Pid.
  
  %%
  %% terminate pipe or pipeline
  -spec(free/1 :: (pid() | [pid()]) -> ok).
  
  free(Pid)
  