Java 8 closures vs. anonymous inner classes

Discussion in 'Java' started by Sebastian, Dec 4, 2013.

  1. Sebastian

    Sebastian Guest

    Someone made a passing comment in another thread to the effect that Java
    8 lambdas ("closures") were nothing but syntactic sugar for (anonymous)
    inner classes. Here are a three differences:

    1) lambdas can only instantiate "functional" (single abstract method)
    interfaces

    2) lambdas have different scoping rules ("this" means different things)

    3) lambdas perform better due to the use of the invokedynamic JVM
    instruction. Type representation, instance creation, and invocation
    strategy are decided at runtime. This offers optimization potentials,
    because evaluating a lambda expression need not create a new instance
    each time. There could be „shared lambdas“ through use of a constant
    static method in a constant pool, needing no new class and/or new object.

    This is quite a bit more than what I'd call "syntactic sugar".

    -- Sebastian
    Sebastian, Dec 4, 2013
    #1
    1. Advertising

  2. Am 04.12.2013 21:07, schrieb Sebastian:
    > Someone made a passing comment in another thread to the effect that Java
    > 8 lambdas ("closures") were nothing but syntactic sugar for (anonymous)
    > inner classes. Here are a three differences:
    >
    > 1) lambdas can only instantiate "functional" (single abstract method)
    > interfaces


    so?

    > 2) lambdas have different scoping rules ("this" means different things)


    so?

    > 3) lambdas perform better due to the use of the invokedynamic JVM
    > instruction. Type representation, instance creation, and invocation
    > strategy are decided at runtime. This offers optimization potentials,
    > because evaluating a lambda expression need not create a new instance
    > each time. There could be „shared lambdas“ through use of a constant
    > static method in a constant pool, needing no new class and/or new object.


    When I was digging through the byte code, invokedynamic was simply used
    to invoke some fancy method that would basically encapsulate the
    creation of the lambda object (which then is nothing more than an
    instance of some class that implements the interface in question).
    So obviously, all some magic happens here - but the magic is pretty much
    limited to some a bunch of things that may likely speedup the creation
    of lambda objects.

    My point being: after creating the object representing the lambda
    object, everything is as it was before, even the performance I guess.

    I suspect, one could easily have achieved the speed up (if there is any)
    by re-using instances of some inner class instead of using invokedynamic
    plus some magic in the JVM.

    > This is quite a bit more than what I'd call "syntactic sugar".


    Certainly. And the implementation of it all is probably pretty ugly too!


    Regards,
    Sven
    Sven Köhler, Dec 4, 2013
    #2
    1. Advertising

  3. Responding to Sven Köhler:

    > When I was digging through the byte code, invokedynamic was simply used
    > to invoke some fancy method that would basically encapsulate the
    > creation of the lambda object (which then is nothing more than an
    > instance of some class that implements the interface in question).


    invokedynamic provides a layer of indirection that will allow switching
    to another implementation.

    http://wiki.jvmlangsummit.com/images/1/1e/2011_Goetz_Lambda.pdf

    Best regards,
    Patrick
    Patrick Roemer, Dec 4, 2013
    #3
  4. Sven K??hler wrote:

    > When I was digging through the byte code, invokedynamic was simply used
    > to invoke some fancy method that would basically encapsulate the
    > creation of the lambda object (which then is nothing more than an
    > instance of some class that implements the interface in question).
    > So obviously, all some magic happens here - but the magic is pretty much
    > limited to some a bunch of things that may likely speedup the creation
    > of lambda objects.
    >
    > My point being: after creating the object representing the lambda
    > object, everything is as it was before, even the performance I guess.


    When I dug through the byte code, I had the impression that there was
    more to it. I didn't understand all the details because neither eclipse
    nor jad were capable of handling them correctly. There was some method
    handle trickery, but no obvious hidden class.

    > Certainly. And the implementation of it all is probably pretty ugly too!


    For values of "pretty" approximately equal to aleph 7.

    --

    "I'm a doctor, not a mechanic." Dr Leonard McCoy <>
    "I'm a mechanic, not a doctor." Volker Borchert <>
    Volker Borchert, Dec 4, 2013
    #4
  5. Sebastian

    Roedy Green Guest

    On Wed, 04 Dec 2013 20:07:42 +0100, Sebastian
    <> wrote, quoted or indirectly quoted someone
    who said :

    >This is quite a bit more than what I'd call "syntactic sugar".


    What that means is, if you looked a the JVM byte codes generated, it
    would look identical to some code written using anonymous inner
    classes.

    see http://mindprod.com/jgloss/syntacticsugar.html
    --
    Roedy Green Canadian Mind Products http://mindprod.com
    Unlike many machines, computers require no water once they are
    manufactured.
    Roedy Green, Dec 6, 2013
    #5
  6. On 12/04/2013 03:07 PM, Sebastian wrote:
    > Someone made a passing comment in another thread to the effect that Java
    > 8 lambdas ("closures") were nothing but syntactic sugar for (anonymous)
    > inner classes. Here are a three differences:
    >
    > 1) lambdas can only instantiate "functional" (single abstract method)
    > interfaces


    I don't see this as being important. That's actually what Java lambdas
    are for, to provide a shorthand for instances of single-method classes.
    That's all they are for.

    > 2) lambdas have different scoping rules ("this" means different things)


    No argument here, the scoping is somewhat different.

    > 3) lambdas perform better due to the use of the invokedynamic JVM
    > instruction. Type representation, instance creation, and invocation
    > strategy are decided at runtime. This offers optimization potentials,
    > because evaluating a lambda expression need not create a new instance
    > each time. There could be „shared lambdas“ through use of a constant
    > static method in a constant pool, needing no new class and/or new object.


    To put it bluntly, who cares? The last time I ran into a speed
    bottleneck with any language was over a decade ago. The last time I ran
    into memory issues with any language was just this year, it happened to
    be Java, and the problem was easily solved by jacking up VM RAM - JVMs
    with most apps are somewhat of memory pigs, and I doubt that Java 8
    lambdas are going to help much with that problem.

    > This is quite a bit more than what I'd call "syntactic sugar".
    >
    > -- Sebastian


    In a way they are just syntactic sugar. Most Java programmers will be
    unimpressed with your first point - if they don't completely miss it,
    they won't even (most of them) notice your second point (until it bites
    them and they sort of muddle through), and they won't even understand
    what the hell you are talking about wrt your third point: most
    developers work M-F 9-5 and don't have the time nor the inclination to
    get particularly good at their profession.

    AHS
    --
    When a true genius appears, you can know him by this sign:
    that all the dunces are in a confederacy against him.
    -- Jonathan Swift
    Arved Sandstrom, Dec 14, 2013
    #6
  7. Sebastian

    Arne Vajhøj Guest

    On 12/6/2013 4:28 PM, Roedy Green wrote:
    > On Wed, 04 Dec 2013 20:07:42 +0100, Sebastian
    > <> wrote, quoted or indirectly quoted someone
    > who said :
    >
    >> This is quite a bit more than what I'd call "syntactic sugar".

    >
    > What that means is, if you looked a the JVM byte codes generated, it
    > would look identical to some code written using anonymous inner
    > classes.


    You did not read the post?

    Arne
    Arne Vajhøj, Dec 14, 2013
    #7
  8. On 12/14/2013 2:13 AM, Arved Sandstrom wrote:
    > On 12/04/2013 03:07 PM, Sebastian wrote:
    >> 3) lambdas perform better due to the use of the invokedynamic JVM
    >> instruction. Type representation, instance creation, and invocation
    >> strategy are decided at runtime. This offers optimization potentials,
    >> because evaluating a lambda expression need not create a new instance
    >> each time. There could be „shared lambdas“ through use of a constant
    >> static method in a constant pool, needing no new class and/or new object.

    >
    > To put it bluntly, who cares? The last time I ran into a speed
    > bottleneck with any language was over a decade ago.


    > and they won't even understand
    > what the hell you are talking about wrt your third point: most
    > developers work M-F 9-5 and don't have the time nor the inclination to
    > get particularly good at their profession.


    This sounds a bit contradictory to me.

    Arne
    Arne Vajhøj, Dec 14, 2013
    #8
  9. Sebastian

    Arne Vajhøj Guest

    On 12/14/2013 7:03 AM, Chris Uppal wrote:
    > Arved Sandstrom wrote:
    >
    >> To put it bluntly, who cares? The last time I ran into a speed
    >> bottleneck with any language was over a decade ago.

    >
    > Hmm...
    >
    > Maybe you mean something more specific than I'm understanding, but that isn't
    > my experience at all. I'd say about 1/3 of my working time is spent on
    > performance-motivated stuff: re-writing things to be faster (or not as slow),
    > experimenting to see if thngs /can/ run at reasonable speeds, finding
    > workarounds (or at least excuses) when they can't...
    >
    > And I work with desktop to server-class machines.
    >
    > But those are mostly architectural issues -- maybe you mean something more like
    > "performance problems caused by a uniformed/ill-advised use of the idioms of
    > the language" ?


    I think Arved's statement was in the context of two different language
    constructs with similar functionality resulting in different byte code.

    Performance problems are common.

    But byte code optimization "assembler programming in Java" is
    rarely the cause of those performance problems.

    Arne
    Arne Vajhøj, Dec 14, 2013
    #9
  10. On 12/14/2013 06:02 PM, Arne Vajhøj wrote:
    > On 12/14/2013 7:03 AM, Chris Uppal wrote:
    >> Arved Sandstrom wrote:
    >>
    >>> To put it bluntly, who cares? The last time I ran into a speed
    >>> bottleneck with any language was over a decade ago.

    >>
    >> Hmm...
    >>
    >> Maybe you mean something more specific than I'm understanding, but
    >> that isn't
    >> my experience at all. I'd say about 1/3 of my working time is spent on
    >> performance-motivated stuff: re-writing things to be faster (or not as
    >> slow),
    >> experimenting to see if thngs /can/ run at reasonable speeds, finding
    >> workarounds (or at least excuses) when they can't...
    >>
    >> And I work with desktop to server-class machines.
    >>
    >> But those are mostly architectural issues -- maybe you mean something
    >> more like
    >> "performance problems caused by a uniformed/ill-advised use of the
    >> idioms of
    >> the language" ?

    >
    > I think Arved's statement was in the context of two different language
    > constructs with similar functionality resulting in different byte code.
    >
    > Performance problems are common.
    >
    > But byte code optimization "assembler programming in Java" is
    > rarely the cause of those performance problems.
    >
    > Arne
    >
    >

    I mostly meant what Chris surmised I meant. In other words, avoiding the
    need for optimization by writing stuff correctly in the first place.
    Basic programmer skills...choosing the correct data structures, choosing
    algorithms well, managing resources properly, etc.

    To use a specific example, let's say you have to write a JSF web app
    that uses Tomcat and also JPA. Reading information like
    http://www.mulesoft.com/tomcat-performance (or any of the dozens like
    it) is something you should do ahead of time, not after. Understanding
    the JSF lifecycle, and hence knowing what managed bean methods get
    accessed how often - and by extension, when and how often business logic
    and data layer methods get accessed, is available upfront knowledge: no
    programmer should need a postmortem profiler run to tell them that
    time-consuming logic in a JSF managed bean getter is maybe a bad idea.
    It's a web app: understanding concurrency, and how to be threadsafe
    without major performance hits, is also something to be understood ahead
    of time, not after you deploy the app. And a JPA implementation can be a
    performance pig or no serious problem at all...assuming you read some
    docs and exercised some common sense ahead of time.

    I did mean what I said about not having encountered speed bottlenecks
    with a *language* - any programming language - in at least a decade. In
    my experience it's almost always been improper use of a language or
    libraries, or insufficient resources, or network latencies, and so forth
    - not a core deficiency of a language. The last time I used C or C++ to
    speed up a language was I think with PerlXS or SWIG back in the '90s.

    Don't get me wrong: I've often been engaged with trying to speed up a
    program, and using profilers. And invariably it turns out to be bad
    architecture or design, or bad implementation, or resource or network
    constraints...so not a language problem.

    To Arne's point, I do believe that too, and that's partially what I
    meant. I sincerely believe that your typical Java programmer - myself
    included - really doesn't have to worry about the bytecode result of
    their proper use of source.

    AHS
    --
    When a true genius appears, you can know him by this sign:
    that all the dunces are in a confederacy against him.
    -- Jonathan Swift
    Arved Sandstrom, Dec 15, 2013
    #10
  11. On 12/14/2013 06:00 PM, Arne Vajhøj wrote:
    > On 12/14/2013 2:13 AM, Arved Sandstrom wrote:
    >> On 12/04/2013 03:07 PM, Sebastian wrote:
    >>> 3) lambdas perform better due to the use of the invokedynamic JVM
    >>> instruction. Type representation, instance creation, and invocation
    >>> strategy are decided at runtime. This offers optimization potentials,
    >>> because evaluating a lambda expression need not create a new instance
    >>> each time. There could be „shared lambdas“ through use of a constant
    >>> static method in a constant pool, needing no new class and/or new
    >>> object.

    >>
    >> To put it bluntly, who cares? The last time I ran into a speed
    >> bottleneck with any language was over a decade ago.

    >
    >> and they won't even understand
    >> what the hell you are talking about wrt your third point: most
    >> developers work M-F 9-5 and don't have the time nor the inclination to
    >> get particularly good at their profession.

    >
    > This sounds a bit contradictory to me.
    >
    > Arne
    >

    No aspersion on the M-F 9-5 programmers, Arne. But by definition M-F 9-5
    programmers have made a decision - not something I will heavily
    criticize - to confine their work to work hours, and keep their free
    time for family and leisure. As such they don't spend nearly as much
    time on off-hours professional education (if any), and we all know that
    work hours don't lend themselves to professional education either.

    So my point really had to do with the fact that we often don't learn
    much new stuff on the job. Most of my career - for my M-F 9-5
    engagements - I've had to work on stuff that's well behind the power
    curve, because that's what clients use. I've yet to run across a client
    in my region that was willing to use JVM languages other than Java, and
    I expect I'll have the luxury of using Java 8 extensively maybe in the
    year 2016.

    Let's also not forget, who has the time to focus just on Java or its
    ecosystem? I don't, and I spend way too much of my free time on software
    development. Only speaking for myself, but I also have to keep track of
    what's happening with other languages, and libraries, and tools, and I
    seriously don't have the luxury of examining the intricacies of Java
    bytecode. I doubt that M-F 9-5 coders do.

    AHS
    --
    When a true genius appears, you can know him by this sign:
    that all the dunces are in a confederacy against him.
    -- Jonathan Swift
    Arved Sandstrom, Dec 15, 2013
    #11
  12. On 12/17/2013 03:09 PM, Wanja Gayk wrote:
    > In article <g4nru.546685$>, Arved Sandstrom
    > () says...
    >
    >> No aspersion on the M-F 9-5 programmers, Arne. But by definition M-F 9-5
    >> programmers have made a decision - not something I will heavily
    >> criticize - to confine their work to work hours, and keep their free
    >> time for family and leisure. As such they don't spend nearly as much
    >> time on off-hours professional education (if any), and we all know that
    >> work hours don't lend themselves to professional education either.

    >
    > To put it bluntly, this is nonsense. You can't generalize like that.


    Sure I can generalize like that. When I refer to a programmer as a M-F
    9-5 programmer, it's not a slur, it's a straightforward definition of a
    programmer who only practices his trade M-F 9-5. It then follows - from
    the definition - that they don't study programming on their own time.
    I'm not making a value judgment here, I'm objectively stating that there
    are software developers with different priorities.

    > I do work M-F 9-5, but I do take my time on the job to educate myself
    > from time to time, simply because it is part of my job to know what I'm
    > doing.


    We all do, within reason. Note the "within reason": there is knowledge
    that it's OK to acquire on employer time, and knowledge that isn't.

    But as soon as I'm at home, I've seen enough code for the day,
    > except maybe some nice video, book or presentation on programming
    > catches my attention.


    That's fine. It may even be a healthy approach. I wasn't busting on M-F
    9-5 programmers per se. If you can execute on the job no employer cares
    whether you spend your time watching football or perusing programming
    articles.

    > On the other hand I've seen self-employed consultants who don't give a
    > flying **** about the quality of their work, they come into a project,
    > get it to work just well enough to not cause major mayhem, and leave a
    > pile of stinking source code behind for the next one to deal with it,
    > while they enjoy puking into the next customer's version control system.
    > Not my kind of work ethics, I might add.
    >
    > W
    >

    Not my kind of work ethics either. In my experience however you've got
    that kind of person equally represented amongst self-employed
    consultants, company-employed consultants, and straight in-house employees.

    AHS
    --
    When a true genius appears, you can know him by this sign:
    that all the dunces are in a confederacy against him.
    -- Jonathan Swift
    Arved Sandstrom, Dec 21, 2013
    #12
  13. Sebastian

    Joerg Meier Guest

    On Sat, 21 Dec 2013 11:54:10 +0000, lipska the kat wrote:

    > Who works 9-5?


    > I never had a job where I worked 9-5


    > [...]


    > 9-5 developers?
    > No such thing.


    According to this logic, the country of Mexico is entirely fictional. No
    such thing. Since I've never been there nor met someone from there.

    The vast majority of programmers that I know IRL work their jobs 9-5.

    Liebe Gruesse,
    Joerg

    --
    Ich lese meine Emails nicht, replies to Email bleiben also leider
    ungelesen.
    Joerg Meier, Dec 21, 2013
    #13
  14. On 12/21/2013 07:54 AM, lipska the kat wrote:
    > On 21/12/13 02:28, Arved Sandstrom wrote:
    >> On 12/17/2013 03:09 PM, Wanja Gayk wrote:
    >>> In article <g4nru.546685$>, Arved Sandstrom
    >>> () says...
    >>>
    >>>> No aspersion on the M-F 9-5 programmers, Arne. But by definition M-F
    >>>> 9-5
    >>>> programmers have made a decision - not something I will heavily
    >>>> criticize - to confine their work to work hours, and keep their free
    >>>> time for family and leisure. As such they don't spend nearly as much
    >>>> time on off-hours professional education (if any), and we all know that
    >>>> work hours don't lend themselves to professional education either.
    >>>
    >>> To put it bluntly, this is nonsense. You can't generalize like that.

    >>
    >> Sure I can generalize like that. When I refer to a programmer as a M-F
    >> 9-5 programmer, it's not a slur, it's a straightforward definition of a
    >> programmer who only practices his trade M-F 9-5.

    >
    > <snip>
    >
    > Who works 9-5?
    >
    > I never had a job where I worked 9-5
    >
    > 8-6 minimum plus any unpaid overtime required to get the job done by
    > release date. Then there are the nights (or small part thereof) spent in
    > the company flat sleeping on the floor because some suit said we could
    > do so and so by such and such and now we are working until we drop while
    > he sleeps at home with his wife, or mistress.
    >
    > Then there's the time spent crammed up against some herbert who could do
    > with a bath, on an overcrowded train, waiting for the upline to become
    > available and swotting up for the latest Java certification.
    >
    > Or spending your weekends getting your head around some shitty new
    > framework that some twat decided was the latest greatest waste of time
    > that would look good on his CV, whilst your kids are growing up and you
    > are missing the best time of their lives.
    >
    > Or trying to learn some pointlessly complicated XML at 11.00pm on a
    > weeknight, or ... or ... or ...
    >
    > 9-5 developers?
    > No such thing.
    >
    >

    Then you've certainly not ever been in a union, for starters. :)

    And you've evidently never worked in a private sector company (like IBM
    or Oracle or Microsoft, for example, or well-established local software
    consultancies with lucrative long-term contracts) where usually the only
    reason you work outside hours is because you're self-motivated, not
    because anyone required you to do so.

    For what it's worth, I wasn't referring to occasional "incompetency"
    time. As in, some manager f**ks up, and you kill a weekend and some
    evenings to repair his mistake. Even union people have to do
    that...although they get overtime. I meant independent un-coerced
    decisions to sacrifice family time or personal recreational
    opportunities in order to swot up on SOA, and suchlike. Not as many
    people do that as you may think. And they may be mentally healthier for it.

    AHS
    --
    When a true genius appears, you can know him by this sign:
    that all the dunces are in a confederacy against him.
    -- Jonathan Swift
    Arved Sandstrom, Dec 21, 2013
    #14
  15. Sebastian

    Tim Slattery Guest

    lipska the kat <"lipskathekat at yahoo dot co dot uk"> wrote:


    >I don't know any 9-5 developers so don't recognize the idiom '9-5 developer'


    I'm recently retired after working 40 years as a developer. My hours
    for the whole time were 8:15 - 4:45. Not exactly 9-5, but the same
    general idea, I think. Yes, there was overtime sometimes, but not a
    lot.

    --
    Tim Slattery
    tim <at> risingdove <dot> com
    Tim Slattery, Dec 21, 2013
    #15
  16. Sebastian

    Stefan Ram Guest

    Tim Slattery <> writes:
    >lipska the kat <"lipskathekat at yahoo dot co dot uk"> wrote:
    >>I don't know any 9-5 developers so don't recognize the idiom '9-5 developer'

    >I'm recently retired after working 40 years as a developer. My hours
    >for the whole time were 8:15 - 4:45. Not exactly 9-5, but the same
    >general idea, I think. Yes, there was overtime sometimes, but not a
    >lot.


    To read an intriguing article about 9-5 programmers, you all have to
    search the web for an article called »They write the right stuff«.
    Stefan Ram, Dec 21, 2013
    #16
  17. On 12/21/2013 03:35 PM, lipska the kat wrote:
    > On 21/12/13 18:52, Arved Sandstrom wrote:
    >> On 12/21/2013 07:54 AM, lipska the kat wrote:
    >>> On 21/12/13 02:28, Arved Sandstrom wrote:
    >>>> On 12/17/2013 03:09 PM, Wanja Gayk wrote:
    >>>>> In article <g4nru.546685$>, Arved Sandstrom
    >>>>> () says...
    >>>>>
    >>>>>> No aspersion on the M-F 9-5 programmers, Arne. But by definition M-F
    >>>>>> 9-5
    >>>>>> programmers have made a decision - not something I will heavily
    >>>>>> criticize - to confine their work to work hours, and keep their free
    >>>>>> time for family and leisure. As such they don't spend nearly as much
    >>>>>> time on off-hours professional education (if any), and we all know
    >>>>>> that
    >>>>>> work hours don't lend themselves to professional education either.
    >>>>>
    >>>>> To put it bluntly, this is nonsense. You can't generalize like that.
    >>>>
    >>>> Sure I can generalize like that. When I refer to a programmer as a M-F
    >>>> 9-5 programmer, it's not a slur, it's a straightforward definition of a
    >>>> programmer who only practices his trade M-F 9-5.
    >>>
    >>> <snip>
    >>>
    >>> Who works 9-5?

    >
    > <snip>
    >
    >>> 9-5 developers?
    >>> No such thing.
    >>>
    >>>

    >> Then you've certainly not ever been in a union, for starters. :)
    >>
    >> And you've evidently never worked in a private sector company (like IBM
    >> or Oracle or Microsoft, for example, or well-established local software
    >> consultancies with lucrative long-term contracts) where usually the only
    >> reason you work outside hours is because you're self-motivated, not
    >> because anyone required you to do so.

    >
    > I did work for a large company once. Company car, company mobile,
    > company laptop ... multiple layers of management, bored stiff.
    >
    > Start-ups was my thing. Design, prototype, implement, launch, get bored,
    > move on.
    >
    > How can you be a developer without being self-motivated?
    >


    Hey, I'm with you here. Software development for me is not just a job,
    and my bookshelves, professional activities, and the occasional
    irritation of my wife prove it. Actually, the fact that I have been in
    this NG so long must mean something...seeing as how way less than one
    hundredth of one percent of Java developers engage in earnest discourse
    in Usenet Java programming groups. :)

    I'm not quite at the startup stage anymore...I've been through two that
    failed terribly, and several others that have survived but are probably
    not poised for IPOs or buyouts by IBM. You get to a certain age and you
    enjoy a bit of stability.

    AHS
    --
    When a true genius appears, you can know him by this sign:
    that all the dunces are in a confederacy against him.
    -- Jonathan Swift
    Arved Sandstrom, Dec 21, 2013
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. VisionSet
    Replies:
    4
    Views:
    487
    Bent C Dalager
    Dec 5, 2003
  2. Scott Simpson
    Replies:
    8
    Views:
    1,026
    Stefan Ram
    Jan 13, 2006
  3. Carlo v. Dango
    Replies:
    14
    Views:
    1,027
    Alex Martelli
    Oct 19, 2003
  4. Jon Harrop

    Anonymous inner classes

    Jon Harrop, Jan 24, 2007, in forum: Java
    Replies:
    6
    Views:
    662
    Mike Schilling
    Jan 26, 2007
  5. Pyenos
    Replies:
    2
    Views:
    386
    Pyenos
    Dec 27, 2006
Loading...

Share This Page