Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » ATL » Fwd: XText in combination wit ATL
Fwd: XText in combination wit ATL [message #1297194] Tue, 15 April 2014 09:44 Go to next message
Ed Willink is currently offline Ed Willink
Messages: 4035
Registered: July 2009
Senior Member
Forwarding to ATL newsgroup

-------- Original Message --------
Subject: XText in combination wit ATL
Date: Tue, 15 Apr 2014 09:30:50 -0400
From: Timm Drevensek <forums-noreply@xxxxxxxx>
Reply-To: Timm Drevensek <forums-noreply@xxxxxxxx>
Organisation: Eclipse Community Forums
Newsgroups: eclipse.modeling.tmf



Hello,

I already asked this here: http ://stackoverflow.com/questions/22841706/atl-transformation-empty-output but got no answer on how to solve this. Maybe you could help me?

I'm trying to use ATL model to model transformation on a Model, coming from a xText parsed DSL. My problem is, that the ATL does always produces empty output.

I believe that the cause of the problem is located here:
__matchFoobar:4 call MMOF!Classifier;.allInstancesFrom(S):QJ
locals: self=HDL2PAL : ASMModule Calling hdl!Model.allInstancesFrom('IN')
stack: OrderedSet {}
locals: self=HDL2PAL : ASMModule

So it seems that my Model is not connected to the Metamodel or it cannot extract the elements from it.
Re: Fwd: XText in combination wit ATL [message #1298619 is a reply to message #1297194] Wed, 16 April 2014 07:37 Go to previous messageGo to next message
Timm Drevensek is currently offline Timm Drevensek
Messages: 4
Registered: April 2014
Junior Member
So here is the full code.
Is there any magic that I have missed?

// create stuff
Injector injector = new org.xtext.hal.HdlStandaloneSetup().createInjectorAndDoEMFRegistration();
XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);

EMFModelFactory emfFactory = new EMFModelFactory();
XMIResourceFactoryImpl xmiFactory = new XMIResourceFactoryImpl();

EMFExtractor extractor = new EMFExtractor();
EMFInjector emfInjector = new EMFInjector();
ResourceSet resourceSet = new ResourceSetImpl();



// source metamodel
EMFReferenceModel hdlMetaModel = (EMFReferenceModel) emfFactory.newReferenceModel();
emfInjector.inject(hdlMetaModel, resourceSet.getResource(URI.createFileURI("org.xtext.hal/model/generated/Hdl.ecore"), true));
EMFModel hdlData = (EMFModel) emfFactory.newModel(hdlMetaModel);

// target metamodel
EMFReferenceModel palMetaModel = (EMFReferenceModel) emfFactory.newReferenceModel();
emfInjector.inject(palMetaModel, resourceSet.getResource(URI.createFileURI("org.xtext.hal/model/Pal.ecore"), true));
EMFModel palData = (EMFModel) emfFactory.newModel(palMetaModel);
palData.setIsTarget(true);

// source model
LazyLinkingResource hdlModel = (LazyLinkingResource) resourceSet.getResource(URI.createURI("input.hdl"), true);
emfInjector.inject(hdlData, hdlModel);



// ATL transformation
InputStream asm = new FileInputStream("org.xtext.hal/model/Pal.asm");
EMFVMLauncher launcher = new EMFVMLauncher();

HashMap<String,Object> options = new HashMap<String,Object>();
options.put("showSummary", "true");
options.put("step", "true");

launcher.initialize(Collections.<String, Object> emptyMap());
launcher.addInModel(hdlData, "IN", "hdl");
launcher.addOutModel(palData, "OUT", "pal");
launcher.launch(ILauncher.DEBUG_MODE, new NullProgressMonitor(), options, asm);



// get output
Resource t_palData = palData.getResource();
t_palData.setURI(URI.createURI("palData.xmi"));



hdl.ecore
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http ://www.omg.org/XMI" xmlns:xsi="http ://www.w3.org/2001/XMLSchema-instance"
    xmlns:ecore="http ://www.eclipse.org/emf/2002/Ecore" name="hdl" nsURI="http ://www.xtext.org/hal/Hdl" nsPrefix="hdl">
  <eClassifiers xsi:type="ecore:EClass" name="Model">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http ://www.eclipse.org/emf/2002/Ecore#//EString"/>
  </eClassifiers>
</ecore:EPackage>


pal.ecore
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http ://www.omg.org/XMI" xmlns:xsi="http ://www.w3.org/2001/XMLSchema-instance"
    xmlns:ecore="http ://www.eclipse.org/emf/2002/Ecore" name="pal" nsURI="http ://www.xtext.org/hal/Pal" nsPrefix="pal">
  <eClassifiers xsi:type="ecore:EClass" name="AddressSpace">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http ://www.eclipse.org/emf/2002/Ecore#//EString"/>
  </eClassifiers>
</ecore:EPackage>



pal.asm
-- @path hdl=/org.xtext.hal/model/generated/Hdl.ecore
-- @path pal=/org.xtext.hal/model/Pal.ecore

module HDL2PAL;
create OUT : pal from IN : hdl;

rule Foobar
{
  from
    s : hdl!Model
  to
    t : pal!AddressSpace (
      name <- s.name
    )
}



ATL output:
main:0  getasm
  stack: HDL2PAL : ASMModule
  locals: self=HDL2PAL : ASMModule
main:1  push OclParametrizedType
  stack: HDL2PAL : ASMModule, 'OclParametrizedType'
  locals: self=HDL2PAL : ASMModule
main:2  push #native
  stack: HDL2PAL : ASMModule, 'OclParametrizedType', '#native'
  locals: self=HDL2PAL : ASMModule
main:3  new
  stack: HDL2PAL : ASMModule, <unnamed>(null)
  locals: self=HDL2PAL : ASMModule
main:4  dup
  stack: HDL2PAL : ASMModule, <unnamed>(null), <unnamed>(null)
  locals: self=HDL2PAL : ASMModule
main:5  push Collection
  stack: HDL2PAL : ASMModule, <unnamed>(null), <unnamed>(null), 'Collection'
  locals: self=HDL2PAL : ASMModule
main:6  pcall J.setName(S):V
  locals: self=HDL2PAL : ASMModule  Calling <unnamed>(null).setName('Collection')
  stack: HDL2PAL : ASMModule, Collection(null)
  locals: self=HDL2PAL : ASMModule
main:7  dup
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null)
  locals: self=HDL2PAL : ASMModule
main:8  push OclSimpleType
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null), 'OclSimpleType'
  locals: self=HDL2PAL : ASMModule
main:9  push #native
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null), 'OclSimpleType', '#native'
  locals: self=HDL2PAL : ASMModule
main:10 new
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null), <unnamed>
  locals: self=HDL2PAL : ASMModule
main:11 dup
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null), <unnamed>, <unnamed>
  locals: self=HDL2PAL : ASMModule
main:12 push OclAny
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null), <unnamed>, <unnamed>, 'OclAny'
  locals: self=HDL2PAL : ASMModule
main:13 pcall J.setName(S):V
  locals: self=HDL2PAL : ASMModule  Calling <unnamed>.setName('OclAny')
  stack: HDL2PAL : ASMModule, Collection(null), Collection(null), OclAny
  locals: self=HDL2PAL : ASMModule
main:14 pcall J.setElementType(J):V
  locals: self=HDL2PAL : ASMModule  Calling Collection(null).setElementType(OclAny)
  stack: HDL2PAL : ASMModule, Collection(OclAny)
  locals: self=HDL2PAL : ASMModule
main:15 set col
  stack: 
  locals: self=HDL2PAL : ASMModule
main:16 getasm
  stack: HDL2PAL : ASMModule
  locals: self=HDL2PAL : ASMModule
main:17 push TransientLinkSet
  stack: HDL2PAL : ASMModule, 'TransientLinkSet'
  locals: self=HDL2PAL : ASMModule
main:18 push #native
  stack: HDL2PAL : ASMModule, 'TransientLinkSet', '#native'
  locals: self=HDL2PAL : ASMModule
main:19 new
  stack: HDL2PAL : ASMModule, TransientLinkSet {}
  locals: self=HDL2PAL : ASMModule
main:20 set links
  stack: 
  locals: self=HDL2PAL : ASMModule
main:21 getasm
  stack: HDL2PAL : ASMModule
  locals: self=HDL2PAL : ASMModule
main:22 pcall A.__matcher__():V
  locals: self=HDL2PAL : ASMModule  Calling HDL2PAL : ASMModule.__matcher__()


__matcher__:0   getasm
  stack: HDL2PAL : ASMModule
  locals: self=HDL2PAL : ASMModule
__matcher__:1   pcall A.__matchFoobar():V
  locals: self=HDL2PAL : ASMModule  Calling HDL2PAL : ASMModule.__matchFoobar()
__matchFoobar:0 push Model
  stack: 'Model'
  locals: self=HDL2PAL : ASMModule
__matchFoobar:1 push hdl
  stack: 'Model', 'hdl'
  locals: self=HDL2PAL : ASMModule
__matchFoobar:2 findme
  stack: hdl!Model
  locals: self=HDL2PAL : ASMModule
__matchFoobar:3 push IN
  stack: hdl!Model, 'IN'
  locals: self=HDL2PAL : ASMModule
__matchFoobar:4 call MMOF!Classifier;.allInstancesFrom(S):QJ
  locals: self=HDL2PAL : ASMModule  Calling hdl!Model.allInstancesFrom('IN')
  stack: OrderedSet {}
  locals: self=HDL2PAL : ASMModule
__matchFoobar:5 iterate
  stack: 
  locals: 
  stack: 
  locals: 
  stack: 
  locals: self=HDL2PAL : ASMModule


main:23 getasm
  stack: HDL2PAL : ASMModule
  locals: self=HDL2PAL : ASMModule
main:24 pcall A.__exec__():V
  locals: self=HDL2PAL : ASMModule  Calling HDL2PAL : ASMModule.__exec__()
__exec__:0  getasm
  stack: HDL2PAL : ASMModule
  locals: self=HDL2PAL : ASMModule
__exec__:1  get links
  stack: TransientLinkSet {}
  locals: self=HDL2PAL : ASMModule
__exec__:2  push Foobar
  stack: TransientLinkSet {}, 'Foobar'
  locals: self=HDL2PAL : ASMModule
__exec__:3  call NTransientLinkSet;.getLinksByRule(S):QNTransientLink;
  locals: self=HDL2PAL : ASMModule  Calling TransientLinkSet {}.getLinksByRule('Foobar')
  stack: []
  locals: self=HDL2PAL : ASMModule
__exec__:4  iterate
  stack: 
  locals: 
  stack: 
  locals: 

Re: Fwd: XText in combination wit ATL [message #1298659 is a reply to message #1298619] Wed, 16 April 2014 08:09 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 4035
Registered: July 2009
Senior Member
Hi

Postiong only parts of code, e.g. no imports etc is very unhelpfukl.

Posting concatenated text files is unhelpful; any one trying to help has
to split them all up gaian.

Much better to provide a zipped project.

Injector injector = new
org.xtext.hal.HdlStandaloneSetup().createInjectorAndDoEMFRegistration();

looks really smelly. What's wrong with the recommended
HdlStandaloneSetup.doSetup(); ?

XtextResourceSet resourceSet =
injector.getInstance(XtextResourceSet.class);
....
ResourceSet resourceSet = new ResourceSetImpl();

is dubious and a guaranteed compilation error, so clearly you are
misleading anyone trying to help.

Regards

Ed Willink


On 16/04/2014 12:37, Timm Drevensek wrote:
> So here is the full code.
> Is there any magic that I have missed?
>
>
> // create stuff
> Injector injector = new
> org.xtext.hal.HdlStandaloneSetup().createInjectorAndDoEMFRegistration();
> XtextResourceSet resourceSet =
> injector.getInstance(XtextResourceSet.class);
>
> EMFModelFactory emfFactory = new EMFModelFactory();
> XMIResourceFactoryImpl xmiFactory = new XMIResourceFactoryImpl();
>
> EMFExtractor extractor = new EMFExtractor();
> EMFInjector emfInjector = new EMFInjector();
> ResourceSet resourceSet = new ResourceSetImpl();
>
>
>
> // source metamodel
> EMFReferenceModel hdlMetaModel = (EMFReferenceModel)
> emfFactory.newReferenceModel();
> emfInjector.inject(hdlMetaModel,
> resourceSet.getResource(URI.createFileURI("org.xtext.hal/model/generated/Hdl.ecore"),
> true));
> EMFModel hdlData = (EMFModel) emfFactory.newModel(hdlMetaModel);
>
> // target metamodel
> EMFReferenceModel palMetaModel = (EMFReferenceModel)
> emfFactory.newReferenceModel();
> emfInjector.inject(palMetaModel,
> resourceSet.getResource(URI.createFileURI("org.xtext.hal/model/Pal.ecore"),
> true));
> EMFModel palData = (EMFModel) emfFactory.newModel(palMetaModel);
> palData.setIsTarget(true);
>
> // source model
> LazyLinkingResource hdlModel = (LazyLinkingResource)
> resourceSet.getResource(URI.createURI("input.hdl"), true);
> emfInjector.inject(hdlData, hdlModel);
>
>
>
> // ATL transformation
> InputStream asm = new FileInputStream("org.xtext.hal/model/Pal.asm");
> EMFVMLauncher launcher = new EMFVMLauncher();
>
> HashMap<String,Object> options = new HashMap<String,Object>();
> options.put("showSummary", "true");
> options.put("step", "true");
>
> launcher.initialize(Collections.<String, Object> emptyMap());
> launcher.addInModel(hdlData, "IN", "hdl");
> launcher.addOutModel(palData, "OUT", "pal");
> launcher.launch(ILauncher.DEBUG_MODE, new NullProgressMonitor(),
> options, asm);
>
>
>
> // get output
> Resource t_palData = palData.getResource();
> t_palData.setURI(URI.createURI("palData.xmi"));
>
>
>
> hdl.ecore
>
> <?xml version="1.0" encoding="UTF-8"?>
> <ecore:EPackage xmi:version="2.0" xmlns:xmi="http ://www.omg.org/XMI"
> xmlns:xsi="http ://www.w3.org/2001/XMLSchema-instance"
> xmlns:ecore="http ://www.eclipse.org/emf/2002/Ecore" name="hdl"
> nsURI="http ://www.xtext.org/hal/Hdl" nsPrefix="hdl">
> <eClassifiers xsi:type="ecore:EClass" name="Model">
> <eStructuralFeatures xsi:type="ecore:EAttribute" name="name"
> eType="ecore:EDataType http
> ://www.eclipse.org/emf/2002/Ecore#//EString"/>
> </eClassifiers>
> </ecore:EPackage>
>
>
> pal.ecore
>
> <?xml version="1.0" encoding="UTF-8"?>
> <ecore:EPackage xmi:version="2.0" xmlns:xmi="http ://www.omg.org/XMI"
> xmlns:xsi="http ://www.w3.org/2001/XMLSchema-instance"
> xmlns:ecore="http ://www.eclipse.org/emf/2002/Ecore" name="pal"
> nsURI="http ://www.xtext.org/hal/Pal" nsPrefix="pal">
> <eClassifiers xsi:type="ecore:EClass" name="AddressSpace">
> <eStructuralFeatures xsi:type="ecore:EAttribute" name="name"
> eType="ecore:EDataType http
> ://www.eclipse.org/emf/2002/Ecore#//EString"/>
> </eClassifiers>
> </ecore:EPackage>
>
>
>
> pal.asm
>
> -- @path hdl=/org.xtext.hal/model/generated/Hdl.ecore
> -- @path pal=/org.xtext.hal/model/Pal.ecore
>
> module HDL2PAL;
> create OUT : pal from IN : hdl;
>
> rule Foobar
> {
> from
> s : hdl!Model
> to
> t : pal!AddressSpace (
> name <- s.name
> )
> }
>
>
>
> ATL output:
>
> main:0 getasm
> stack: HDL2PAL : ASMModule
> locals: self=HDL2PAL : ASMModule
> main:1 push OclParametrizedType
> stack: HDL2PAL : ASMModule, 'OclParametrizedType'
> locals: self=HDL2PAL : ASMModule
> main:2 push #native
> stack: HDL2PAL : ASMModule, 'OclParametrizedType', '#native'
> locals: self=HDL2PAL : ASMModule
> main:3 new
> stack: HDL2PAL : ASMModule, <unnamed>(null)
> locals: self=HDL2PAL : ASMModule
> main:4 dup
> stack: HDL2PAL : ASMModule, <unnamed>(null), <unnamed>(null)
> locals: self=HDL2PAL : ASMModule
> main:5 push Collection
> stack: HDL2PAL : ASMModule, <unnamed>(null), <unnamed>(null),
> 'Collection'
> locals: self=HDL2PAL : ASMModule
> main:6 pcall J.setName(S):V
> locals: self=HDL2PAL : ASMModule Calling
> <unnamed>(null).setName('Collection')
> stack: HDL2PAL : ASMModule, Collection(null)
> locals: self=HDL2PAL : ASMModule
> main:7 dup
> stack: HDL2PAL : ASMModule, Collection(null), Collection(null)
> locals: self=HDL2PAL : ASMModule
> main:8 push OclSimpleType
> stack: HDL2PAL : ASMModule, Collection(null), Collection(null),
> 'OclSimpleType'
> locals: self=HDL2PAL : ASMModule
> main:9 push #native
> stack: HDL2PAL : ASMModule, Collection(null), Collection(null),
> 'OclSimpleType', '#native'
> locals: self=HDL2PAL : ASMModule
> main:10 new
> stack: HDL2PAL : ASMModule, Collection(null), Collection(null),
> <unnamed>
> locals: self=HDL2PAL : ASMModule
> main:11 dup
> stack: HDL2PAL : ASMModule, Collection(null), Collection(null),
> <unnamed>, <unnamed>
> locals: self=HDL2PAL : ASMModule
> main:12 push OclAny
> stack: HDL2PAL : ASMModule, Collection(null), Collection(null),
> <unnamed>, <unnamed>, 'OclAny'
> locals: self=HDL2PAL : ASMModule
> main:13 pcall J.setName(S):V
> locals: self=HDL2PAL : ASMModule Calling <unnamed>.setName('OclAny')
> stack: HDL2PAL : ASMModule, Collection(null), Collection(null), OclAny
> locals: self=HDL2PAL : ASMModule
> main:14 pcall J.setElementType(J):V
> locals: self=HDL2PAL : ASMModule Calling
> Collection(null).setElementType(OclAny)
> stack: HDL2PAL : ASMModule, Collection(OclAny)
> locals: self=HDL2PAL : ASMModule
> main:15 set col
> stack: locals: self=HDL2PAL : ASMModule
> main:16 getasm
> stack: HDL2PAL : ASMModule
> locals: self=HDL2PAL : ASMModule
> main:17 push TransientLinkSet
> stack: HDL2PAL : ASMModule, 'TransientLinkSet'
> locals: self=HDL2PAL : ASMModule
> main:18 push #native
> stack: HDL2PAL : ASMModule, 'TransientLinkSet', '#native'
> locals: self=HDL2PAL : ASMModule
> main:19 new
> stack: HDL2PAL : ASMModule, TransientLinkSet {}
> locals: self=HDL2PAL : ASMModule
> main:20 set links
> stack: locals: self=HDL2PAL : ASMModule
> main:21 getasm
> stack: HDL2PAL : ASMModule
> locals: self=HDL2PAL : ASMModule
> main:22 pcall A.__matcher__():V
> locals: self=HDL2PAL : ASMModule Calling HDL2PAL :
> ASMModule.__matcher__()
>
>
> __matcher__:0 getasm
> stack: HDL2PAL : ASMModule
> locals: self=HDL2PAL : ASMModule
> __matcher__:1 pcall A.__matchFoobar():V
> locals: self=HDL2PAL : ASMModule Calling HDL2PAL :
> ASMModule.__matchFoobar()
> __matchFoobar:0 push Model
> stack: 'Model'
> locals: self=HDL2PAL : ASMModule
> __matchFoobar:1 push hdl
> stack: 'Model', 'hdl'
> locals: self=HDL2PAL : ASMModule
> __matchFoobar:2 findme
> stack: hdl!Model
> locals: self=HDL2PAL : ASMModule
> __matchFoobar:3 push IN
> stack: hdl!Model, 'IN'
> locals: self=HDL2PAL : ASMModule
> __matchFoobar:4 call MMOF!Classifier;.allInstancesFrom(S):QJ
> locals: self=HDL2PAL : ASMModule Calling
> hdl!Model.allInstancesFrom('IN')
> stack: OrderedSet {}
> locals: self=HDL2PAL : ASMModule
> __matchFoobar:5 iterate
> stack: locals: stack: locals: stack: locals: self=HDL2PAL :
> ASMModule
>
>
> main:23 getasm
> stack: HDL2PAL : ASMModule
> locals: self=HDL2PAL : ASMModule
> main:24 pcall A.__exec__():V
> locals: self=HDL2PAL : ASMModule Calling HDL2PAL : ASMModule.__exec__()
> __exec__:0 getasm
> stack: HDL2PAL : ASMModule
> locals: self=HDL2PAL : ASMModule
> __exec__:1 get links
> stack: TransientLinkSet {}
> locals: self=HDL2PAL : ASMModule
> __exec__:2 push Foobar
> stack: TransientLinkSet {}, 'Foobar'
> locals: self=HDL2PAL : ASMModule
> __exec__:3 call NTransientLinkSet;.getLinksByRule(S):QNTransientLink;
> locals: self=HDL2PAL : ASMModule Calling TransientLinkSet
> {}.getLinksByRule('Foobar')
> stack: []
> locals: self=HDL2PAL : ASMModule
> __exec__:4 iterate
> stack: locals: stack: locals:
>
Re: Fwd: XText in combination wit ATL [message #1310543 is a reply to message #1298659] Wed, 23 April 2014 04:43 Go to previous messageGo to next message
Timm Drevensek is currently offline Timm Drevensek
Messages: 4
Registered: April 2014
Junior Member
Yes, good point.
Here is my Eclipse Workspace: https ://s3-eu-west-1.amazonaws.com/timm-public/TEST.zip

Main file calling the the ATL Model to Model transformation is located within "\org.xtext.hal\src\org\xtext\hal\generator\Main.java"
Thanks for the support!
Re: Fwd: XText in combination wit ATL [message #1312549 is a reply to message #1310543] Thu, 24 April 2014 07:02 Go to previous messageGo to next message
Dennis Wagelaar is currently offline Dennis Wagelaar
Messages: 155
Registered: September 2012
Senior Member

I haven't time now to go through your entire setup, but this post is just to let you know it is possible to get this working. EMFMigrate is another xText language, that uses ATL/EMFTVM for its compiler. You can find the invocation of ATL/EMFTVM in this code:

https://code.google.com/a/eclipselabs.org/p/emfmigrate/source/browse/trunk/it.univaq.coevolution.emfmigrate.compiler/src/it/univaq/coevolution/emfmigrate/compiler/builder/EmigBuilder.java

N.B. This is not the current ATL emfvm, but the new EMFTVM. It has a different API, as described on the Eclipse Wiki (google it).

N.B.2. As the metamodel has generated Java code to go with it, we've used the ''...Package.eINSTANCE.eResource()'' invocation to make sure we get the right instance of the metamodel (i.e. no metamodel aliasing problem, as is common with EMF).


Cheers,
Dennis
Re: Fwd: XText in combination wit ATL [message #1386365 is a reply to message #1312549] Tue, 17 June 2014 03:15 Go to previous message
Salome Maro is currently offline Salome Maro
Messages: 15
Registered: January 2014
Junior Member
Timm,
did you manage to solve this? I have the same problem and not sure how to go about it.

/Saloem
Previous Topic:[ATL API] Launch ATL transf with cross-references
Next Topic:[EMFTVM] How do I call lazy rules?
Goto Forum:
  


Current Time: Thu Aug 28 23:36:38 EDT 2014

Powered by FUDForum. Page generated in 0.01964 seconds