Building a system at the architectural level can be thought of as decomposition into components followed by a series of exercises in matching. Components must be composed with each other via matching mechanisms; matching signatures within those mechanisms ensure that data and control will flow through the system; and matching semantics among the components ensures that the system will meet its behavioral requirements. The standard concepts of software architecture (components, connectors, styles) have been widely used with little more than intuitive understanding of their meaning. Mechanism matching is currently an ad hoc exercise that relies on the peculiarities of programming language facilities. This paper presents a set of well known but informally described software architectural elements used in system composition, and taxonomizes them under a basic set of characteristic features. This classification allows us to describe legal combinations of architectural elements by performing a simple matching exercise on the relevant features of the member elements. This classification also allows us to identify architectural elements that can be substituted for each other and satisfy the same mechanism matching requirements. This leads to delayed binding of architectural mechanisms, which in turns provides increased flexibility and greater opportunities for reuse of units of computation.