Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Archived » Visual Editor (VE) » Break points for code generating
Break points for code generating [message #83944] Thu, 17 March 2005 15:29 Go to next message
Elena Demeter is currently offline Elena DemeterFriend
Messages: 152
Registered: July 2009
Senior Member
Hello,

in what classes can I set break points to see how the code (

private JButton getJButton() {
if (jButton == null) {
jButton = new JButton();
}
return jButton;
})

will be generated. I set the break points in DefaultMethodTextGenerator,
ExpressionRefFactory. But they were not achieved.

Thank you in advance
Elena
Re: Break points for code generating [message #84018 is a reply to message #83944] Thu, 17 March 2005 16:12 Go to previous messageGo to next message
Srimanth  is currently offline Srimanth Friend
Messages: 225
Registered: July 2009
Senior Member
Hi Elena,
Keep a breakpoint in the IMethodTemplate.generateMethod(MethodInfo) -
whatever class that implements the IMethodTemplate returned by
DefaultMethodTextGenerator.getMethodTemplate(). In VE's case for JFC it
would be DefaultMethodTemplate.generateMethod(MethodInfo).
ExpressionRefFactory is for generating new expressions into that method.
Regards,
Sri.



Elena wrote:
> Hello,
>
> in what classes can I set break points to see how the code (
>
> private JButton getJButton() {
> if (jButton == null) {
> jButton = new JButton();
> }
> return jButton;
> })
>
> will be generated. I set the break points in DefaultMethodTextGenerator,
> ExpressionRefFactory. But they were not achieved.
>
> Thank you in advance
> Elena
>
Re: Break points for code generating [message #84077 is a reply to message #84018] Fri, 18 March 2005 13:53 Go to previous messageGo to next message
Elena Demeter is currently offline Elena DemeterFriend
Messages: 152
Registered: July 2009
Senior Member
Hello Sri,

first thank you for an answer :o)

I have been trying to find out where the constructors (e.g for JButton)
are generated. As I see the string ( "new " + qn + "()"; ) is composed in
“CodeGenUtil.getInitStrin...)”. My task is to generate a constructor with
arguments.

I have read in ULC Description that it is possible to influence the
generated code with override-files:

<addedEObjects xsi:type="codeGenHelpers:CodeGenHelperClass"
source="codegen.CodeGenHelperClass"
expDecoder="com.canoo.ulc.visualeditor/
com.canoo.ulc.visualeditor.codegen.ULCWindowDecoder"
modelled="true"
/>

In my case I would write “ methodGenerator = “class that implements
IMethodTextGenerator“ “.

Is it a correct way to influence the generated code for my task?
Do I have to write another class instead of CodeGenUtil to generate a
constructor with arguments ???

Thanks in advance
Elena





Sri Gunturi wrote:

> Hi Elena,
> Keep a breakpoint in the IMethodTemplate.generateMethod(MethodInfo) -
> whatever class that implements the IMethodTemplate returned by
> DefaultMethodTextGenerator.getMethodTemplate(). In VE's case for JFC it
> would be DefaultMethodTemplate.generateMethod(MethodInfo).
> ExpressionRefFactory is for generating new expressions into that method.
> Regards,
> Sri.



> Elena wrote:
>> Hello,
>>
>> in what classes can I set break points to see how the code (
>>
>> private JButton getJButton() {
>> if (jButton == null) {
>> jButton = new JButton();
>> }
>> return jButton;
>> })
>>
>> will be generated. I set the break points in DefaultMethodTextGenerator,
>> ExpressionRefFactory. But they were not achieved.
>>
>> Thank you in advance
>> Elena
>>
Re: Break points for code generating [message #84138 is a reply to message #84077] Fri, 18 March 2005 20:16 Go to previous messageGo to next message
Gili Mendel is currently offline Gili MendelFriend
Messages: 338
Registered: July 2009
Senior Member
Yes, you can use an override file to tell VE which decoder to use. This
decoder will reverse parse and generate code that is associated with a
particular class - you may not need to do this in this case.

Every class has an EMF feature called 'allocation'. This is the feature
that describes how the class is constructed... this feature corrolate to
the constructor expression in the source. The content of the allocation
feature is mostly a PTExpression (this construct is similar to an AST
tree). PTExpression enables the target VM to evaluate complex
expressions when instantiating a live object.

VE has two constructor helpers: ConstructorDecoderHelper and the
SWTConstructorHelper

On the way up (source to VE model), the AST is converted to PTExpression
with the ConstructorDecoderHelper.getParsedTree() method.

On the way down, the decoder does not invent the PTExpression that
relates to the bean. It just "toString()" the PTExpression that is in
the VE model already. It only provides name resolutions services (e.g.,
A constructor to a SWT class contains a reference to a parent; which
will be converted to the instance variable name).

.... I think that your question is responsible for generating the
PTExpression when the class is dropped from the palette? It is the same
guy that constructs the class, and (potentially) put other settings on
it as it insert it to the VE model. see
CompositeContainerPolicy.createInitStringCommand() as an example.
Re: Break points for code generating [message #84271 is a reply to message #84138] Mon, 21 March 2005 17:48 Go to previous messageGo to next message
Elena Demeter is currently offline Elena DemeterFriend
Messages: 152
Registered: July 2009
Senior Member
Yes, my question is responsible for generating the PTExpression when the
class is dropped from the palette. I had a look at all classes that you
have mentioned but have not found a solution yet :-(.

How can I change the "allocation" for my class? Or could you give me one
more tips please :o)

Many thanks in advance
Elena
Re: Break points for code generating [message #84356 is a reply to message #84271] Mon, 21 March 2005 23:41 Go to previous messageGo to next message
Srimanth  is currently offline Srimanth Friend
Messages: 225
Registered: July 2009
Senior Member
Hi Elena,
Codegen simply generates whatever PTExpression is set in the allocation
feature of the bean. If you keep a breakpoint at
CompositeContainerPolicy.createInitStringCommand(), you can observe the
creation of the PTExpression for the default pattern of 'new
<someSWTClass>(<someParent>, org.eclipse.swt.SWT.NONE)' - Button, Label
etc. use this pattern.

However if you would like to have customization (something which might
interest you) to the constructor (like CheckBox), where the constructor
is different that the above mentioned - like 'new
org.eclipse.swt.widgets.Button(<someParent>,
org.eclipse.swt.SWT.CHECK)', you can specify in the override file itself
(look at org.eclipse.ve.swt\CheckBox.xmi for the element '<allocation
xsi:type="org.eclipse.jem.internal.instantiation:ParseTreeAllocation ">')
what the allocation should look like - and the editpolicy (via command
CompositeContainerPolicy.EnsureCorrectParentCommand) will fill in the
allocation. Keep a breakpoint at EnsureCorrectParentCommand.execute() to
see how this is done. Hope this helps in your implementation.
Regards,
Sri.




Elena wrote:
> Yes, my question is responsible for generating the PTExpression when the
> class is dropped from the palette. I had a look at all classes that you
> have mentioned but have not found a solution yet :-(.
> How can I change the "allocation" for my class? Or could you give me one
> more tips please :o)
>
> Many thanks in advance
> Elena
>
>
>
Re: Break points for code generating [message #84370 is a reply to message #84356] Mon, 21 March 2005 23:51 Go to previous messageGo to next message
Srimanth  is currently offline Srimanth Friend
Messages: 225
Registered: July 2009
Senior Member
Small correction - org.eclipse.ve.swt\CheckBox.xmi is the file which
represents the CheckBox Palette Entry in the palette. It is not the
override file. It is a palette entry of type EMFPrototypeToolEntry,
where you can customize which ParseTreeAllocation to use.

So, if you wanted to have a palette entry for a bean called FooBar and
when dropped, create a constructor 'new FooBar(Foo.foo, new Bar())' -
you would create a EMFPrototypeToolEntry entry for FooBar, and then in
the FooBar.xmi, specify the ParseTreeAllocation for the custom
constructor you have above.
Regards,
Sri.


Sri Gunturi wrote:
> Hi Elena,
> Codegen simply generates whatever PTExpression is set in the
> allocation feature of the bean. If you keep a breakpoint at
> CompositeContainerPolicy.createInitStringCommand(), you can observe the
> creation of the PTExpression for the default pattern of 'new
> <someSWTClass>(<someParent>, org.eclipse.swt.SWT.NONE)' - Button, Label
> etc. use this pattern.
>
> However if you would like to have customization (something which might
> interest you) to the constructor (like CheckBox), where the constructor
> is different that the above mentioned - like 'new
> org.eclipse.swt.widgets.Button(<someParent>,
> org.eclipse.swt.SWT.CHECK)', you can specify in the override file itself
> (look at org.eclipse.ve.swt\CheckBox.xmi for the element '<allocation
> xsi:type="org.eclipse.jem.internal.instantiation:ParseTreeAllocation ">')
> what the allocation should look like - and the editpolicy (via command
> CompositeContainerPolicy.EnsureCorrectParentCommand) will fill in the
> allocation. Keep a breakpoint at EnsureCorrectParentCommand.execute() to
> see how this is done. Hope this helps in your implementation.
> Regards,
> Sri.
>
>
>
>
> Elena wrote:
>
>> Yes, my question is responsible for generating the PTExpression when
>> the class is dropped from the palette. I had a look at all classes
>> that you have mentioned but have not found a solution yet :-(.
>> How can I change the "allocation" for my class? Or could you give me
>> one more tips please :o)
>>
>> Many thanks in advance
>> Elena
>>
>>
>>
Re: Break points for code generating [message #84605 is a reply to message #84138] Tue, 22 March 2005 22:19 Go to previous messageGo to next message
Gili Mendel is currently offline Gili MendelFriend
Messages: 338
Registered: July 2009
Senior Member
The Edit Policy that creates the object in the VE model (using commands) is responsible to create the allocation setting
(constructor) for that object. As I mentioned earlier the CompositeContainerPolicy.createInitStringCommand will create a
default SWT allocation setting.

The following is an (XMI) example of what it will build if you drop a Button on top of a Shell (I removed the pkg.
prefixes to save some space):

It will generate a *new* class creation (2) with two arguments:
One a reference to the shell (swt parent) 3
One is a Field access 4,5


<members xsi:type="org.eclipse.swt.widgets:Button" bounds="<xpath_to_Rectangle_object>">

<allocation xsi:type="ParseTreeAllocation"> 1
<expression xsi:type="PTClassInstanceCreation" type="Button"> 2
<arguments xsi:type="PTInstanceReference" object="<xpath_to_shell_parent>"/> 3
<arguments xsi:type="PTFieldAccess" field="NONE"> 4
<receiver xsi:type="PTName" name="org.eclipse.swt.SWT"/> 5
</arguments>
</expression>
</allocation>

</members>

The decoder will generate the following out of the above allocation tree:

new Button(<parent_shell_instance_name>, org.eclipse.swt.SWT.NONE);

The following is the code in the creates this parse tree:

PTClassInstanceCreation ic = InstantiationFactory.eINSTANCE.createPTClassInstanceCreation () ; 2
ic.setType(child.getJavaType().getJavaName()) ; 2

// set the arguments
PTInstanceReference ir = InstantiationFactory.eINSTANCE.createPTInstanceReference() ; 3
ir.setObject((IJavaObjectInstance)getContainer()) ; 3
PTFieldAccess fa = InstantiationFactory.eINSTANCE.createPTFieldAccess(); 4
PTName name = InstantiationFactory.eINSTANCE.createPTName("org.eclipse.swt.SWT ") ; 5
fa.setField("NONE"); 4
fa.setReceiver(name) ; 4


ic.getArguments().add(ir);
ic.getArguments().add(fa) ;
Re: Break points for code generating [message #84638 is a reply to message #84370] Wed, 23 March 2005 17:34 Go to previous message
Elena Demeter is currently offline Elena DemeterFriend
Messages: 152
Registered: July 2009
Senior Member
Hello!

Thank you very much for a detailed explanation. I have seen that in
EnsureCorrectParentCommand.execute the reference to Shell that comes from

------------------------------------------------------------ -------------
<arguments xsi:type="org.eclipse.jem.internal.instantiation:PTName"
-name="{parentComposite}"/> -
------------------------------------------------------------ -------------

will be set in

------------------------------------------------------------ -------------
parentRef.setObject(correctParent); -
------------------------------------------------------------ -------------

Where the name of a shell (sShell) will be inserted?
My next task is to insert a variable name as an argument. And it is not a
string or a constant. E.g.

------------------------------------------------------------ -------------
int var; -
MyButton mb = new MyButton(var); -
------------------------------------------------------------ -------------

MyButton and int have a relationship to each other.
Of course the variable can also have another name.

Is there a way to implement this without a new decoder/decoderhelper?

Thanks in advance
Elena
Re: Break points for code generating [message #605933 is a reply to message #83944] Thu, 17 March 2005 16:12 Go to previous message
Srimanth  is currently offline Srimanth Friend
Messages: 225
Registered: July 2009
Senior Member
Hi Elena,
Keep a breakpoint in the IMethodTemplate.generateMethod(MethodInfo) -
whatever class that implements the IMethodTemplate returned by
DefaultMethodTextGenerator.getMethodTemplate(). In VE's case for JFC it
would be DefaultMethodTemplate.generateMethod(MethodInfo).
ExpressionRefFactory is for generating new expressions into that method.
Regards,
Sri.



Elena wrote:
> Hello,
>
> in what classes can I set break points to see how the code (
>
> private JButton getJButton() {
> if (jButton == null) {
> jButton = new JButton();
> }
> return jButton;
> })
>
> will be generated. I set the break points in DefaultMethodTextGenerator,
> ExpressionRefFactory. But they were not achieved.
>
> Thank you in advance
> Elena
>
Re: Break points for code generating [message #605942 is a reply to message #84018] Fri, 18 March 2005 13:53 Go to previous message
Elena Demeter is currently offline Elena DemeterFriend
Messages: 152
Registered: July 2009
Senior Member
Hello Sri,

first thank you for an answer :o)

I have been trying to find out where the constructors (e.g for JButton)
are generated. As I see the string ( "new " + qn + "()"; ) is composed in
“CodeGenUtil.getInitStrin...)”. My task is to generate a constructor with
arguments.

I have read in ULC Description that it is possible to influence the
generated code with override-files:

<addedEObjects xsi:type="codeGenHelpers:CodeGenHelperClass"
source="codegen.CodeGenHelperClass"
expDecoder="com.canoo.ulc.visualeditor/
com.canoo.ulc.visualeditor.codegen.ULCWindowDecoder"
modelled="true"
/>

In my case I would write “ methodGenerator = “class that implements
IMethodTextGenerator“ “.

Is it a correct way to influence the generated code for my task?
Do I have to write another class instead of CodeGenUtil to generate a
constructor with arguments ???

Thanks in advance
Elena





Sri Gunturi wrote:

> Hi Elena,
> Keep a breakpoint in the IMethodTemplate.generateMethod(MethodInfo) -
> whatever class that implements the IMethodTemplate returned by
> DefaultMethodTextGenerator.getMethodTemplate(). In VE's case for JFC it
> would be DefaultMethodTemplate.generateMethod(MethodInfo).
> ExpressionRefFactory is for generating new expressions into that method.
> Regards,
> Sri.



> Elena wrote:
>> Hello,
>>
>> in what classes can I set break points to see how the code (
>>
>> private JButton getJButton() {
>> if (jButton == null) {
>> jButton = new JButton();
>> }
>> return jButton;
>> })
>>
>> will be generated. I set the break points in DefaultMethodTextGenerator,
>> ExpressionRefFactory. But they were not achieved.
>>
>> Thank you in advance
>> Elena
>>
Re: Break points for code generating [message #605950 is a reply to message #84077] Fri, 18 March 2005 20:16 Go to previous message
Gili Mendel is currently offline Gili MendelFriend
Messages: 338
Registered: July 2009
Senior Member
Yes, you can use an override file to tell VE which decoder to use. This
decoder will reverse parse and generate code that is associated with a
particular class - you may not need to do this in this case.

Every class has an EMF feature called 'allocation'. This is the feature
that describes how the class is constructed... this feature corrolate to
the constructor expression in the source. The content of the allocation
feature is mostly a PTExpression (this construct is similar to an AST
tree). PTExpression enables the target VM to evaluate complex
expressions when instantiating a live object.

VE has two constructor helpers: ConstructorDecoderHelper and the
SWTConstructorHelper

On the way up (source to VE model), the AST is converted to PTExpression
with the ConstructorDecoderHelper.getParsedTree() method.

On the way down, the decoder does not invent the PTExpression that
relates to the bean. It just "toString()" the PTExpression that is in
the VE model already. It only provides name resolutions services (e.g.,
A constructor to a SWT class contains a reference to a parent; which
will be converted to the instance variable name).

.... I think that your question is responsible for generating the
PTExpression when the class is dropped from the palette? It is the same
guy that constructs the class, and (potentially) put other settings on
it as it insert it to the VE model. see
CompositeContainerPolicy.createInitStringCommand() as an example.
Re: Break points for code generating [message #605966 is a reply to message #84138] Mon, 21 March 2005 17:48 Go to previous message
Elena Demeter is currently offline Elena DemeterFriend
Messages: 152
Registered: July 2009
Senior Member
Yes, my question is responsible for generating the PTExpression when the
class is dropped from the palette. I had a look at all classes that you
have mentioned but have not found a solution yet :-(.

How can I change the "allocation" for my class? Or could you give me one
more tips please :o)

Many thanks in advance
Elena
Re: Break points for code generating [message #605983 is a reply to message #84271] Mon, 21 March 2005 23:41 Go to previous message
Srimanth  is currently offline Srimanth Friend
Messages: 225
Registered: July 2009
Senior Member
Hi Elena,
Codegen simply generates whatever PTExpression is set in the allocation
feature of the bean. If you keep a breakpoint at
CompositeContainerPolicy.createInitStringCommand(), you can observe the
creation of the PTExpression for the default pattern of 'new
<someSWTClass>(<someParent>, org.eclipse.swt.SWT.NONE)' - Button, Label
etc. use this pattern.

However if you would like to have customization (something which might
interest you) to the constructor (like CheckBox), where the constructor
is different that the above mentioned - like 'new
org.eclipse.swt.widgets.Button(<someParent>,
org.eclipse.swt.SWT.CHECK)', you can specify in the override file itself
(look at org.eclipse.ve.swt\CheckBox.xmi for the element '<allocation
xsi:type="org.eclipse.jem.internal.instantiation:ParseTreeAllocation ">')
what the allocation should look like - and the editpolicy (via command
CompositeContainerPolicy.EnsureCorrectParentCommand) will fill in the
allocation. Keep a breakpoint at EnsureCorrectParentCommand.execute() to
see how this is done. Hope this helps in your implementation.
Regards,
Sri.




Elena wrote:
> Yes, my question is responsible for generating the PTExpression when the
> class is dropped from the palette. I had a look at all classes that you
> have mentioned but have not found a solution yet :-(.
> How can I change the "allocation" for my class? Or could you give me one
> more tips please :o)
>
> Many thanks in advance
> Elena
>
>
>
Re: Break points for code generating [message #605986 is a reply to message #84356] Mon, 21 March 2005 23:51 Go to previous message
Srimanth  is currently offline Srimanth Friend
Messages: 225
Registered: July 2009
Senior Member
Small correction - org.eclipse.ve.swt\CheckBox.xmi is the file which
represents the CheckBox Palette Entry in the palette. It is not the
override file. It is a palette entry of type EMFPrototypeToolEntry,
where you can customize which ParseTreeAllocation to use.

So, if you wanted to have a palette entry for a bean called FooBar and
when dropped, create a constructor 'new FooBar(Foo.foo, new Bar())' -
you would create a EMFPrototypeToolEntry entry for FooBar, and then in
the FooBar.xmi, specify the ParseTreeAllocation for the custom
constructor you have above.
Regards,
Sri.


Sri Gunturi wrote:
> Hi Elena,
> Codegen simply generates whatever PTExpression is set in the
> allocation feature of the bean. If you keep a breakpoint at
> CompositeContainerPolicy.createInitStringCommand(), you can observe the
> creation of the PTExpression for the default pattern of 'new
> <someSWTClass>(<someParent>, org.eclipse.swt.SWT.NONE)' - Button, Label
> etc. use this pattern.
>
> However if you would like to have customization (something which might
> interest you) to the constructor (like CheckBox), where the constructor
> is different that the above mentioned - like 'new
> org.eclipse.swt.widgets.Button(<someParent>,
> org.eclipse.swt.SWT.CHECK)', you can specify in the override file itself
> (look at org.eclipse.ve.swt\CheckBox.xmi for the element '<allocation
> xsi:type="org.eclipse.jem.internal.instantiation:ParseTreeAllocation ">')
> what the allocation should look like - and the editpolicy (via command
> CompositeContainerPolicy.EnsureCorrectParentCommand) will fill in the
> allocation. Keep a breakpoint at EnsureCorrectParentCommand.execute() to
> see how this is done. Hope this helps in your implementation.
> Regards,
> Sri.
>
>
>
>
> Elena wrote:
>
>> Yes, my question is responsible for generating the PTExpression when
>> the class is dropped from the palette. I had a look at all classes
>> that you have mentioned but have not found a solution yet :-(.
>> How can I change the "allocation" for my class? Or could you give me
>> one more tips please :o)
>>
>> Many thanks in advance
>> Elena
>>
>>
>>
Re: Break points for code generating [message #606017 is a reply to message #84138] Tue, 22 March 2005 22:19 Go to previous message
Gili Mendel is currently offline Gili MendelFriend
Messages: 338
Registered: July 2009
Senior Member
The Edit Policy that creates the object in the VE model (using commands) is responsible to create the allocation setting
(constructor) for that object. As I mentioned earlier the CompositeContainerPolicy.createInitStringCommand will create a
default SWT allocation setting.

The following is an (XMI) example of what it will build if you drop a Button on top of a Shell (I removed the pkg.
prefixes to save some space):

It will generate a *new* class creation (2) with two arguments:
One a reference to the shell (swt parent) 3
One is a Field access 4,5


<members xsi:type="org.eclipse.swt.widgets:Button" bounds="<xpath_to_Rectangle_object>">

<allocation xsi:type="ParseTreeAllocation"> 1
<expression xsi:type="PTClassInstanceCreation" type="Button"> 2
<arguments xsi:type="PTInstanceReference" object="<xpath_to_shell_parent>"/> 3
<arguments xsi:type="PTFieldAccess" field="NONE"> 4
<receiver xsi:type="PTName" name="org.eclipse.swt.SWT"/> 5
</arguments>
</expression>
</allocation>

</members>

The decoder will generate the following out of the above allocation tree:

new Button(<parent_shell_instance_name>, org.eclipse.swt.SWT.NONE);

The following is the code in the creates this parse tree:

PTClassInstanceCreation ic = InstantiationFactory.eINSTANCE.createPTClassInstanceCreation () ; 2
ic.setType(child.getJavaType().getJavaName()) ; 2

// set the arguments
PTInstanceReference ir = InstantiationFactory.eINSTANCE.createPTInstanceReference() ; 3
ir.setObject((IJavaObjectInstance)getContainer()) ; 3
PTFieldAccess fa = InstantiationFactory.eINSTANCE.createPTFieldAccess(); 4
PTName name = InstantiationFactory.eINSTANCE.createPTName("org.eclipse.swt.SWT ") ; 5
fa.setField("NONE"); 4
fa.setReceiver(name) ; 4


ic.getArguments().add(ir);
ic.getArguments().add(fa) ;
Re: Break points for code generating [message #606048 is a reply to message #84370] Wed, 23 March 2005 17:34 Go to previous message
Elena Demeter is currently offline Elena DemeterFriend
Messages: 152
Registered: July 2009
Senior Member
Hello!

Thank you very much for a detailed explanation. I have seen that in
EnsureCorrectParentCommand.execute the reference to Shell that comes from

------------------------------------------------------------ -------------
<arguments xsi:type="org.eclipse.jem.internal.instantiation:PTName"
-name="{parentComposite}"/> -
------------------------------------------------------------ -------------

will be set in

------------------------------------------------------------ -------------
parentRef.setObject(correctParent); -
------------------------------------------------------------ -------------

Where the name of a shell (sShell) will be inserted?
My next task is to insert a variable name as an argument. And it is not a
string or a constant. E.g.

------------------------------------------------------------ -------------
int var; -
MyButton mb = new MyButton(var); -
------------------------------------------------------------ -------------

MyButton and int have a relationship to each other.
Of course the variable can also have another name.

Is there a way to implement this without a new decoder/decoderhelper?

Thanks in advance
Elena
Previous Topic:New_Tutorial && Next_Steps
Next Topic:Screen scrape
Goto Forum:
  


Current Time: Tue Apr 23 17:41:25 GMT 2024

Powered by FUDForum. Page generated in 0.05674 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top