public static boolean accept(Program program, TokenReader reader)
    {
        boolean result = false;
        
        if (reader.lookahead(0).code() == Token.DATA_TYPE_NAME
                && reader.lookahead(1).code() == Token.IDENTIFIER
                && reader.lookahead(2).code() == Token.OPEN_PAREN)
        {
            final Token type = reader.lookahead(0);
            final Token name = reader.lookahead(1);
            
            reader.accept(Token.DATA_TYPE_NAME);
            reader.accept(Token.IDENTIFIER);
            reader.accept(Token.OPEN_PAREN);
            
            final List<Type> types = Lists.newLinkedList();
            boolean searchArgs = true;
            while (searchArgs)
            {
                if (reader.accept(Token.DATA_TYPE_NAME))
                {
                    reader.expect(Token.IDENTIFIER, "argname");
                    
                    final Token argType = reader.lookahead(-2);
                    final Token argName = reader.lookahead(-1);
                    
                    final Type arg = new Type(argType.getMatched(),
                            argName.getMatched());
                    
                    types.add(arg);
                }
                
                if (!reader.accept(Token.COMMA))
                {
                    searchArgs = false;
                }
            }
            reader.expect(Token.CLOSE_PAREN, "function args close");
            
            final Type[] args = types.toArray(new Type[0]);
            
            final Function function = new Function(new Type(type.getMatched(),
                    name.getMatched()), args);
            
            Block.accept(function, reader);
            
            program.addChild(function);
            
            result = true;
        }
        
        return result;
    }