CYNumber *number_;
         CYParameter *parameter_;
         CYProperty *property_;
-        CYSelector *selector_;
+        CYSelectorPart *selector_;
         CYSource *source_;
         CYStatement *statement_;
         CYString *string_;
     ;
 
 SelectorExpression_
-    : WordOpt ":" SelectorExpressionOpt { $$ = new(driver.pool_) CYSelector($1, true, $3); }
+    : WordOpt ":" SelectorExpressionOpt { $$ = new(driver.pool_) CYSelectorPart($1, true, $3); }
     ;
 
 SelectorExpression
     : SelectorExpression_ { $$ = $1; }
-    | Word { $$ = new(driver.pool_) CYSelector($1, false, NULL); }
+    | Word { $$ = new(driver.pool_) CYSelectorPart($1, false, NULL); }
     ;
 
 PrimaryExpression_
     : MessageExpression { $$ = $1; }
-    | "@selector" "(" SelectorExpression ")" { $$ = $3; }
+    | "@selector" "(" SelectorExpression ")" { $$ = new CYSelector($3); }
     ;
 /* }}} */
 
 
 
 void CYSelector::Output(std::ostream &out) const {
     out << '"';
-    out << "<unimplemented>";
+    if (name_ != NULL)
+        name_->Output(out);
     out << '"';
 }
 
+void CYSelectorPart::Output(std::ostream &out) const {
+    if (name_ != NULL)
+        out << *name_;
+    if (value_)
+        out << ':';
+    if (next_ != NULL)
+        next_->Output(out);
+}
+
 void CYSource::Show(std::ostream &out) const {
     for (const CYSource *next(this); next != NULL; next = next->next_)
         next->Output(out, false);
 
     {
     }
 
+    CYNext(Type_ *next) :
+        next_(next)
+    {
+    }
+
     void SetNext(Type_ *next) {
         next_ = next;
     }
     }
 };
 
-struct CYLabel {
+struct CYLabel :
+    CYNext<CYLabel>
+{
     CYIdentifier *identifier_;
-    CYLabel *next_;
 
     CYLabel(CYIdentifier *identifier, CYLabel *next) :
-        identifier_(identifier),
-        next_(next)
+        CYNext<CYLabel>(next),
+        identifier_(identifier)
     {
     }
 };
 {
 };
 
-struct CYSelector :
-    CYLiteral
+struct CYSelectorPart :
+    CYNext<CYSelectorPart>
 {
     CYWord *name_;
     bool value_;
-    CYSelector *after_;
 
-    CYSelector(CYWord *name, bool value, CYSelector *after) :
+    CYSelectorPart(CYWord *name, bool value, CYSelectorPart *next) :
+        CYNext<CYSelectorPart>(next),
         name_(name),
-        value_(value),
-        after_(after)
+        value_(value)
+    {
+    }
+
+    virtual void Output(std::ostream &out) const;
+};
+
+struct CYSelector :
+    CYLiteral
+{
+    CYSelectorPart *name_;
+
+    CYSelector(CYSelectorPart *name) :
+        name_(name)
     {
     }
 
     virtual const char *Operator() const = 0;
 };
 
-struct CYArgument {
+struct CYArgument :
+    CYNext<CYArgument>
+{
     CYWord *name_;
     CYExpression *value_;
-    CYArgument *next_;
 
     CYArgument(CYWord *name, CYExpression *value, CYArgument *next = NULL) :
+        CYNext<CYArgument>(next),
         name_(name),
-        value_(value),
-        next_(next)
+        value_(value)
     {
     }
 
     virtual void Output(std::ostream &out) const;
 };
 
-struct CYElement {
+struct CYElement :
+    CYNext<CYElement>
+{
     CYExpression *value_;
-    CYElement *next_;
 
     CYElement(CYExpression *value, CYElement *next) :
-        value_(value),
-        next_(next)
+        CYNext<CYElement>(next),
+        value_(value)
     {
     }
 
 };
 
 struct CYParameter :
+    CYNext<CYParameter>,
     CYThing
 {
     CYIdentifier *name_;
-    CYParameter *next_;
 
     CYParameter(CYIdentifier *name, CYParameter *next) :
-        name_(name),
-        next_(next)
+        CYNext<CYParameter>(next),
+        name_(name)
     {
     }
 
     virtual void Output(std::ostream &out) const;
 };
 
-struct CYProperty {
+struct CYProperty :
+    CYNext<CYProperty>
+{
     CYName *name_;
     CYExpression *value_;
-    CYProperty *next_;
 
     CYProperty(CYName *name, CYExpression *value, CYProperty *next) :
+        CYNext<CYProperty>(next),
         name_(name),
-        value_(value),
-        next_(next)
+        value_(value)
     {
     }