\RequirePackage{environ}

% Pipelines
\usepackage{calc}
\tikzset{%
	pipelineStep/.style			= {rectangle, draw, minimum width=5em, align=center, minimum height=2em},
	pipelineInput/.style		= {coordinate, draw, circle, inner sep=0pt,minimum size=0.7cm},
	pipelineOutput/.style		= {coordinate, draw, circle, inner sep=0pt,minimum size=0.7cm},
	pipelineConnection/.style	= {draw, -latex'}
}

\newcounter{previouspipelineelementindexcounter}
\newcounter{nextpipelineelementindexcounter}
\NewEnviron{pipeline}[1][]{
	\setcounter{previouspipelineelementindexcounter}{0}
	\setcounter{nextpipelineelementindexcounter}{1}
	
	\newcommand{\pipelineInput}[2][]{
		\node[pipelineInput,##1] (step0) {##2};
	}
	\newcommand{\pipelineElement}[2][]{
		\node[pipelineStep, right of=step\thepreviouspipelineelementindexcounter,##1](step\thenextpipelineelementindexcounter){##2};
		\path[pipelineConnection] (step\thepreviouspipelineelementindexcounter) -- (step\thenextpipelineelementindexcounter);
		\addtocounter{previouspipelineelementindexcounter}{1}
		\addtocounter{nextpipelineelementindexcounter}{1}
	}
	\newcommand{\pipelineOutput}[2][]{
		\node[pipelineOutput, right of=step\thepreviouspipelineelementindexcounter,##1](step\thenextpipelineelementindexcounter){##2};
		\path[pipelineConnection] (step\thepreviouspipelineelementindexcounter) -- (step\thenextpipelineelementindexcounter);
		\addtocounter{previouspipelineelementindexcounter}{1}
		\addtocounter{nextpipelineelementindexcounter}{1}
	}
	% Group a range of pipeline elements within a rectangle
	% param 1: from (number of the first element)
	% param 2: to (number of the last element)
	% param 3: Title of the group
	\newcommand{\pipelineGroupSegment}[4][]{
		\node[draw,inner sep=2mm,label=above:##4,fit=(step##2) (step##3),##1] {};
	}

	\begin{tikzpicture}[#1]
		\BODY
	\end{tikzpicture}
}