%%% -*- mode: latex; TeX-PDF-mode: t -*-

\documentclass{article}
\usepackage[palatino, helvetica, courier, maths=cmr]{mdwfonts}

\usepackage{syntax}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}

\errorcontextlines=999

\begin{document}

\begin{tikzpicture}
  [>=stealth, thick,
   order/.append style={color=green!70!black},
   code/.append style={font=\sffamily},
   action/.append style={font=\itshape},
   method/.append style={rectangle, draw=black, thin, fill=blue!30,
                         text height=\ht\strutbox, text depth=\dp\strutbox,
                         minimum width=40mm}]

  \def\delgstack#1#2#3{
    \node (#10) [method, #2] {#3};
    \node (#11) [method, above=6mm of #10] {#3};
    \draw [->] ($(#10.north)!.5!(#10.north west) + (0mm, 1mm)$) --
               ++(0mm, 4mm)
      node [code, left=4pt, midway] {next_method};
    \draw [<-] ($(#10.north)!.5!(#10.north east) + (0mm, 1mm)$) --
               ++(0mm, 4mm)
      node [action, right=4pt, midway] {return};
    \draw [->] ($(#11.north)!.5!(#11.north west) + (0mm, 1mm)$) --
               ++(0mm, 4mm)
      node [code, left=4pt, midway] {next_method}
      node (ld) [above] {$\smash\vdots\mathstrut$};
    \draw [<-] ($(#11.north)!.5!(#11.north east) + (0mm, 1mm)$) --
               ++(0mm, 4mm)
      node [action, right=4pt, midway] {return}
      node (rd) [above] {$\smash\vdots\mathstrut$};
    \draw [->] ($(ld.north) + (0mm, 1mm)$) -- ++(0mm, 4mm)
      node [code, left=4pt, midway] {next_method};
    \draw [<-] ($(rd.north) + (0mm, 1mm)$) -- ++(0mm, 4mm)
      node [action, right=4pt, midway] {return};
    \node (p) at ($(ld.north)!.5!(rd.north)$) {};
    \node (#1n) [method, above=5mm of p] {#3};
    \draw [->, order] ($(#10.south east) + (4mm, 1mm)$) --
                        ($(#1n.north east) + (4mm, -1mm)$)
      node [midway, right, align=left] {Most to \\ least \\ specific};}

  \delgstack{a}{}{Around method}
  \draw [<-] ($(a0.south)!.5!(a0.south west) - (0mm, 1mm)$) --
             ++(0mm, -4mm);
  \draw [->] ($(a0.south)!.5!(a0.south east) - (0mm, 1mm)$) --
             ++(0mm, -4mm)
    node [action, right=4pt, midway] {return};

  \draw [->] ($(an.north)!.6!(an.north west) + (0mm, 1mm)$) --
             ++(-8mm, 8mm)
    node [code, midway, left=3mm] {next_method}
    node (b0) [method, above left = 1mm + 4mm and -6mm - 4mm] {};
  \node (b1) [method] at ($(b0) - (2mm, 2mm)$) {};
  \node (bn) [method] at ($(b1) - (2mm, 2mm)$) {Before method};
  \draw [->, order] ($(bn.west) - (6mm, 0mm)$) -- ++(12mm, 12mm)
    node [midway, above left, align=center] {Most to \\ least \\ specific};
  \draw [->] ($(b0.north east) + (-10mm, 1mm)$) -- ++(8mm, 8mm)
    node (p) {};

  \delgstack{m}{above right=1mm and 0mm of an.west |- p}{Primary method}
  \draw [->] ($(mn.north)!.5!(mn.north west) + (0mm, 1mm)$) -- ++(0mm, 4mm)
    node [code, left=4pt, midway] {next_method}
    node [above right = 0mm and -8mm]
    {$\vcenter{\hbox{\Huge\textcolor{red}{!}}}
      \vcenter{\hbox{\begin{tabular}[c]{l}
                       \textsf{next_method} \\
                       pointer is null
                     \end{tabular}}}$};

  \draw [->, color=blue, dotted]
      ($(m0.south)!.2!(m0.south east) - (0mm, 1mm)$) --
      ($(an.north)!.2!(an.north east) + (0mm, 1mm)$)
    node [midway, sloped, below] {Return value};

  \draw [<-] ($(an.north)!.6!(an.north east) + (0mm, 1mm)$) --
             ++(8mm, 8mm)
    node [action, midway, right=3mm] {return}
    node (f0) [method, above right = 1mm and -6mm] {};
  \node (f1) [method] at ($(f0) + (-2mm, 2mm)$) {};
  \node (fn) [method] at ($(f1) + (-2mm, 2mm)$) {After method};
  \draw [<-, order] ($(f0.east) + (6mm, 0mm)$) -- ++(-12mm, 12mm)
    node [midway, above right, align=center] {Least to \\ most \\ specific};
  \draw [<-] ($(fn.north west) + (6mm, 1mm)$) -- ++(-8mm, 8mm);

\end{tikzpicture}

\end{document}
