If there is only 1 server - all your solutions will work.
But imaging we have 2 servers. Each have its own room full of clients.

Now User enters server1 and would like to see how much users in each room.
But it is impossible since server1 only have connections/roomClients only
for 1 server, and have no information regarding second one.

On Wed, Oct 24, 2012 at 4:32 PM, [email protected] <
[email protected]> wrote:

> *I see no other way to get the number of users (per server)*
> => There are at least three alternative ways to get this number:
> a) You count the number of connection of a certain scope and then take the
> sum of it
> This will give you the total number of connections, no matter if
> audio/video, conferencing or a screensharing connection.
> b) You count the total number of RoomClients from the current session
> This will give you the total number of connections, no matter if
> audio/video, conferencing or a screensharing connection.
> c) You count the total number of RoomClients from the current session, but
> you filter the result based on if the RoomClient is a Audio/Video client or
> a Screensharing client
> With this method you would be able to calc the exact number of Audio/Video
> connection
>
> Which of those would fit yours?
> Or did I misunderstood something?
>
> Sebastian
>
>
> 2012/10/24 Maxim Solodovnik <[email protected]>
>
>> Hello Sebastian,
>>
>> I'm afraid we need something like "lightweight RoomClient" in the DB to
>> resolve 3)
>> This can be done without performance degradation.
>> I see no other way to get the number of users.
>>
>> On Wed, Oct 24, 2012 at 3:31 PM, [email protected] <
>> [email protected]> wrote:
>>
>>> So will we find a consens here? :)
>>>
>>> 1) No DB query in Sync methods to keep performance up
>>> 2) Session objects should not stay in a database but in memory
>>> 3) To have the number of users per server instance there is no need to
>>> have the RoomClient in the database.
>>>
>>> Can we find a consens based on those resolutions?
>>>
>>> Sebastian
>>>
>>> 2012/10/22 [email protected] <[email protected]>
>>>
>>> Practically in this case you would have to iterate thorugh the
>>>> connection.
>>>> You could also call IConnection => getConnection => getSize.
>>>> This would give a rough idea. But as you don't know how many of those
>>>> connection are screensharing or Audio/Video you can't tell how many users
>>>> exactly there are.
>>>>
>>>> If you want to share this information with others I would suggest you
>>>> simply add a SOAP/REST call and in that sense query the number of users via
>>>> a HTTP call.
>>>>
>>>>
>>>> Sebastian
>>>>
>>>> 2012/10/22 Maxim Solodovnik <[email protected]>
>>>>
>>>>> If I remember correctly I have added RoomClient to the DB since I need
>>>>> mechanism to retrieve how much users are currently in the room.
>>>>>
>>>>>
>>>>> On Mon, Oct 22, 2012 at 3:23 PM, [email protected] <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> We could even store it currently in the IConnection. The Red5
>>>>>> framework has the similar mechanism like the static Map that I've build.
>>>>>>
>>>>>> We will also stay with our Red5 implementation for the next 6 months
>>>>>> as we have no alternative to stream audio/video in HTML5.
>>>>>>
>>>>>> It is no option to stay with it, how can we offer OpenMeetings to be
>>>>>> scalable to 1000 concurrent users? We would have to limit it to 250. Also
>>>>>> it would become mandatory to have the database server on the same machine
>>>>>> as the red5 server. Otherwise you have performance bottlenecks. Can you
>>>>>> imagine what kind of negative public feedback we will have if every
>>>>>> question about performance of red5 is answered with: Did you install db
>>>>>> server on another instance of your network?
>>>>>>
>>>>>> Sorry but it is not possible. Also not for a temporary solution. We
>>>>>> can't sell this product like that and claim to have 1000 user sessions 
>>>>>> per
>>>>>> server unit.
>>>>>>
>>>>>> What requirements do exist to store the RoomClient in the database
>>>>>> and what is needed to be done to remove it from the db again?
>>>>>>
>>>>>>
>>>>>> Sebastian
>>>>>>
>>>>>> 2012/10/22 Maxim Solodovnik <[email protected]>
>>>>>>
>>>>>>> OK, I'm not insist. I believe RoomClient will be removed in the
>>>>>>> future.
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Oct 22, 2012 at 3:00 PM, [email protected] <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Sorry but:
>>>>>>>>
>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>       return rc;
>>>>>>>>    }
>>>>>>>> }
>>>>>>>>
>>>>>>>> That is simply not true.
>>>>>>>> There are _some_ implementations where it was needed that you need
>>>>>>>> to get the RoomClient by its public SID. However this usage was quite
>>>>>>>> limited.
>>>>>>>>
>>>>>>>> In general it was the way I described it:
>>>>>>>> The maps key was the streamid. And the streamid was obtained from
>>>>>>>> the IConnection of each stream.
>>>>>>>>
>>>>>>>>
>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/remote/red5/ClientListManager.java?revision=1339514&view=markup
>>>>>>>> Line 118, that was the function that was mainly in use all over the
>>>>>>>> application.
>>>>>>>> There is no sorting, there is no iteration => nothing.
>>>>>>>>
>>>>>>>> Search in the ScopeApplicationAdapter for "getClientByStreamId" =>
>>>>>>>> 52 of matches.
>>>>>>>> Every of this call is now replaced by a single DB query.
>>>>>>>> And if you iterate like described through all connection (like it
>>>>>>>> is in EVERY snyc method)
>>>>>>>> You will do a single query for EVERY connection.
>>>>>>>> Like 100 users in a room => 100 queries.
>>>>>>>> Think about the green dot that blinks every time you speak in the
>>>>>>>> video pod:
>>>>>>>> If it gets visible => one sync message
>>>>>>>> If its get transparent => one sync message.
>>>>>>>> If you have a quite good and sensitive micro it will flush 10 mabye
>>>>>>>> 10 times per second.
>>>>>>>> per 100 users in a room => 10 * 100 = 1000 queries in a SINGLE
>>>>>>>> SECOND
>>>>>>>> => that is just impossible !!
>>>>>>>> And that is just a SINGLE videopod with 100 users watching. Now
>>>>>>>> scale that up to 1000 concurrent rooms with  4x4 meetings where every 
>>>>>>>> user
>>>>>>>> has micro turned on ?! Should we calc the number of database queries
>>>>>>>> really?!
>>>>>>>>
>>>>>>>> Sorry we will not follow that route :)
>>>>>>>>
>>>>>>>> Sebastian
>>>>>>>>
>>>>>>>> 2012/10/22 Maxim Solodovnik <[email protected]>
>>>>>>>>
>>>>>>>>> Previous solution was:
>>>>>>>>>
>>>>>>>>> for (RoomClient rc: allClient) {
>>>>>>>>>    if (rc.getPublicSID().equals(_publicSID) {
>>>>>>>>>       return rc;
>>>>>>>>>    }
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> + screen sharing clients were filtered same way.
>>>>>>>>> Right now we can filter all sessions with 1 query this is why the
>>>>>>>>> code can work faster (after minor changes in iterating logic)
>>>>>>>>>
>>>>>>>>> I'm not insist RoomClient should be DB object. But having it as DB
>>>>>>>>> object was the only option to have user count in the room (in case 
>>>>>>>>> Rooms
>>>>>>>>> are on the different servers).
>>>>>>>>>
>>>>>>>>> I believe right now org.apache.openmeetings.web.app.WebSession
>>>>>>>>> will be session object.
>>>>>>>>> I hope everything except audio and video will move to Wicket :)
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Mon, Oct 22, 2012 at 2:33 PM, [email protected] <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> Hi Maxim,
>>>>>>>>>>
>>>>>>>>>> you can't persist on the argumentation that a HashMap stored in
>>>>>>>>>> the memory is slower then doing a single query for every entry of 
>>>>>>>>>> the map ?
>>>>>>>>>> Basicaly the previous implementation was a single HashMap.
>>>>>>>>>> Getting a RoomClient from this map was:
>>>>>>>>>> map.get($streamId)
>>>>>>>>>> and now this single line is replaced by a Database query. The
>>>>>>>>>> performance of this single line  is ... I guess smaller then 1 
>>>>>>>>>> millisecond.
>>>>>>>>>> How can you say that a "Right now I think the current code should 
>>>>>>>>>> work
>>>>>>>>>> faster or the same as previous one." :)
>>>>>>>>>>
>>>>>>>>>> I guess you had some other requirements that made you implement
>>>>>>>>>> this.
>>>>>>>>>> For example for the clustering solution.
>>>>>>>>>> However I also persist on my view:
>>>>>>>>>> A database is _not_ the right place for storing session
>>>>>>>>>> variables. This is simply a bad design decision that will cost a lot 
>>>>>>>>>> of
>>>>>>>>>> performance in the future.
>>>>>>>>>>
>>>>>>>>>> Could you explain why there is a need for having the RoomClient
>>>>>>>>>> in the database? Maybe we can resolve those requirements differently 
>>>>>>>>>> so
>>>>>>>>>> that we can have the RoomClient back in memory.
>>>>>>>>>>
>>>>>>>>>> Sebastian
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> 2012/10/19 Maxim Solodovnik <[email protected]>
>>>>>>>>>>
>>>>>>>>>>> Sorry for double post.
>>>>>>>>>>>
>>>>>>>>>>> Correct me if I'm wrong, but i think "Transient for XML
>>>>>>>>>>> export/import" is not necessary since it doesn't have @Element 
>>>>>>>>>>> annotation
>>>>>>>>>>> On Oct 19, 2012 9:59 PM, "Maxim Solodovnik" <
>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> RoomClient was mooved to the DB while I implemented cluster.
>>>>>>>>>>>> Current changes only make the calls faster (since DB is quered
>>>>>>>>>>>> only once)
>>>>>>>>>>>>
>>>>>>>>>>>> I'll try to create couple of tests. Right now I think the
>>>>>>>>>>>> current code should work faster or the same as previous one.
>>>>>>>>>>>>
>>>>>>>>>>>> Old code did lots of full filterings of RommsClient hash map to
>>>>>>>>>>>> get subset required.
>>>>>>>>>>>>
>>>>>>>>>>>> I tests will show I'm wrong on this I'll try to tune up openjpa
>>>>>>>>>>>> cache and if it doesn't help will split RoomClient to the couple 
>>>>>>>>>>>> of objects
>>>>>>>>>>>> and/or will create hashtable in parallel to speed up things.
>>>>>>>>>>>>
>>>>>>>>>>>> But I hope everything is not so slow since these changes are
>>>>>>>>>>>> present in 2.0 and nobody reports performance degradation.
>>>>>>>>>>>>
>>>>>>>>>>>> Sorry for typos, I'm from mobile phone
>>>>>>>>>>>> On Oct 19, 2012 9:11 PM, "[email protected]" <
>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> I guess this happened lately in trunk.
>>>>>>>>>>>>> How are we the in the future planning to determine the current
>>>>>>>>>>>>> users in the room.
>>>>>>>>>>>>> Session or database based?
>>>>>>>>>>>>>
>>>>>>>>>>>>> I ask that critical as some queries require to sync messages
>>>>>>>>>>>>> to all clients of a room.
>>>>>>>>>>>>> This can happen 1000 times in a single second if you think
>>>>>>>>>>>>> about having up to 1000 concurrent user sessions.
>>>>>>>>>>>>>
>>>>>>>>>>>>> For example:
>>>>>>>>>>>>> ScopeApplicationAdapter::syncMessageToCurrentScope(String
>>>>>>>>>>>>> remoteMethodName, Object newMessage, boolean sendSelf, boolean 
>>>>>>>>>>>>> sendScreen)
>>>>>>>>>>>>> => Collection<Set<IConnection>> conCollection =
>>>>>>>>>>>>> current.getScope()
>>>>>>>>>>>>>                     .getConnections();
>>>>>>>>>>>>> ==> iterates through all connection of the scope.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Now the new thing is that for every connection you will create
>>>>>>>>>>>>> a query for the RoomClient Object.
>>>>>>>>>>>>> This is simply impossible.
>>>>>>>>>>>>>
>>>>>>>>>>>>> We want to scale up to 1000 concurrent user sessions and more.
>>>>>>>>>>>>> The RoomClient is a typical Session object and it should stay
>>>>>>>>>>>>> in the session.
>>>>>>>>>>>>> It is the same issue like with the WhiteboardObject.
>>>>>>>>>>>>> We are making a real time application, there is no chance to
>>>>>>>>>>>>> run queries in sync methods.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Can we find some consens here? I know you must have refactored
>>>>>>>>>>>>> already a lot but I strictly did implement zero db related stuff 
>>>>>>>>>>>>> in sync
>>>>>>>>>>>>> methods.
>>>>>>>>>>>>>
>>>>>>>>>>>>> There might be a chance for some events to trigger db
>>>>>>>>>>>>> actions.However I don't think having two times the RoomClient 
>>>>>>>>>>>>> stored (one
>>>>>>>>>>>>> time session, second time database) makes sense.
>>>>>>>>>>>>>
>>>>>>>>>>>>> What are you thoughts on this?
>>>>>>>>>>>>>
>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2012/10/19 [email protected] <[email protected]>
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hi Maxim,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I don't understand this new code in the Rooms Entity:
>>>>>>>>>>>>>>     @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>     @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>     private List<RoomClient> currentusers;
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> We calc the current users online by iterating through the
>>>>>>>>>>>>>> Red5 Connections.
>>>>>>>>>>>>>> In which OpenMeetings version was it changed?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I guess you can set it Transient for XML export/import. So
>>>>>>>>>>>>>> maybe annotate it with:
>>>>>>>>>>>>>> @org.simpleframework.xml.Transient
>>>>>>>>>>>>>> same like roomOrganisations.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sebastian
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> 2012/10/19 <[email protected]>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>  Author: solomax
>>>>>>>>>>>>>>> Date: Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>> New Revision: 1400075
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> URL: http://svn.apache.org/viewvc?rev=1400075&view=rev
>>>>>>>>>>>>>>> Log:
>>>>>>>>>>>>>>> Wicket: calendar form is improved
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/data/conference/RoomDAO.java
>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>> @@ -76,6 +76,24 @@ public class RoomDAO implements OmDAO<Ro
>>>>>>>>>>>>>>>                 return q.getSingleResult();
>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> +       public List<Rooms> getPublicRooms() {
>>>>>>>>>>>>>>> +               //TypedQuery<Rooms> q =
>>>>>>>>>>>>>>> em.createNamedQuery("getNondeletedRooms", Rooms.class);
>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>> +                               "SELECT r from Rooms r LEFT
>>>>>>>>>>>>>>> JOIN FETCH r.currentusers WHERE r.ispublic= true and r.deleted= 
>>>>>>>>>>>>>>> false ORDER
>>>>>>>>>>>>>>> BY r.name ASC", Rooms.class);
>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +       public List<Rooms> getOrganisationRooms(long orgId) {
>>>>>>>>>>>>>>> +               TypedQuery<Rooms> q = em.createQuery(
>>>>>>>>>>>>>>> +                               "SELECT DISTINCT c.room FROM
>>>>>>>>>>>>>>> Rooms_Organisation c LEFT JOIN FETCH c.room LEFT JOIN FETCH
>>>>>>>>>>>>>>> c.room.currentusers "
>>>>>>>>>>>>>>> +               + "WHERE c.organisation.organisation_id =
>>>>>>>>>>>>>>> :orgId "
>>>>>>>>>>>>>>> +               + "AND c.deleted = false AND c.room.deleted
>>>>>>>>>>>>>>> = false "
>>>>>>>>>>>>>>> +               + "AND c.organisation.deleted = false "
>>>>>>>>>>>>>>> +               + "ORDER BY c.room.name ASC", Rooms.class);
>>>>>>>>>>>>>>> +               q.setParameter("orgId", orgId);
>>>>>>>>>>>>>>> +               return q.getResultList();
>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>         public Rooms update(Rooms entity, long userId) {
>>>>>>>>>>>>>>>                 if (entity.getRooms_id() == null) {
>>>>>>>>>>>>>>>                 /* Red5SIP integration
>>>>>>>>>>>>>>> *******************************************************************************/
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/persistence/beans/rooms/Rooms.java
>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>> @@ -38,7 +38,6 @@ import javax.persistence.NamedQuery;
>>>>>>>>>>>>>>>  import javax.persistence.OneToMany;
>>>>>>>>>>>>>>>  import javax.persistence.OneToOne;
>>>>>>>>>>>>>>>  import javax.persistence.Table;
>>>>>>>>>>>>>>> -import javax.persistence.Transient;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>  import org.apache.openjpa.persistence.ElementDependent;
>>>>>>>>>>>>>>>  import org.apache.openmeetings.persistence.beans.OmEntity;
>>>>>>>>>>>>>>> @@ -69,7 +68,6 @@ public class Rooms implements Serializab
>>>>>>>>>>>>>>>         private String name;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>         @Lob
>>>>>>>>>>>>>>> -       // @Basic(fetch=FetchType.LAZY)
>>>>>>>>>>>>>>>         @Column(name = "comment_field")
>>>>>>>>>>>>>>>         @Element(data = true, required = false)
>>>>>>>>>>>>>>>         private String comment;
>>>>>>>>>>>>>>> @@ -217,10 +215,8 @@ public class Rooms implements Serializab
>>>>>>>>>>>>>>>         @org.simpleframework.xml.Transient
>>>>>>>>>>>>>>>         private List<Rooms_Organisation> roomOrganisations =
>>>>>>>>>>>>>>> new ArrayList<Rooms_Organisation>();
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> -       /*
>>>>>>>>>>>>>>> -        * Non persistent attributes
>>>>>>>>>>>>>>> -        */
>>>>>>>>>>>>>>> -       @Transient
>>>>>>>>>>>>>>> +       @OneToMany(fetch = FetchType.LAZY)
>>>>>>>>>>>>>>> +       @JoinColumn(name = "room_id")
>>>>>>>>>>>>>>>         private List<RoomClient> currentusers;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>         public String getComment() {
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarForm.java
>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>> @@ -18,14 +18,36 @@
>>>>>>>>>>>>>>>   */
>>>>>>>>>>>>>>>  package
>>>>>>>>>>>>>>> org.apache.openmeetings.web.components.user.calendar;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.openmeetings.data.calendar.daos.AppointmentReminderTypDaoImpl;
>>>>>>>>>>>>>>> +import org.apache.openmeetings.data.conference.RoomDAO;
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.openmeetings.data.conference.Roommanagement;
>>>>>>>>>>>>>>> +import org.apache.openmeetings.data.user.dao.UsersDaoImpl;
>>>>>>>>>>>>>>>  import
>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.Appointment;
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.calendar.AppointmentReminderTyps;
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.domain.Organisation_Users;
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.RoomTypes;
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.openmeetings.persistence.beans.rooms.Rooms;
>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.Application;
>>>>>>>>>>>>>>> +import org.apache.openmeetings.web.app.WebSession;
>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.AjaxRequestTarget;
>>>>>>>>>>>>>>> +import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
>>>>>>>>>>>>>>> +import
>>>>>>>>>>>>>>> org.apache.wicket.extensions.yui.calendar.DateTimeField;
>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.ChoiceRenderer;
>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.DropDownChoice;
>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.Form;
>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.PasswordTextField;
>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.RequiredTextField;
>>>>>>>>>>>>>>>  import org.apache.wicket.markup.html.form.TextArea;
>>>>>>>>>>>>>>> +import org.apache.wicket.markup.html.form.TextField;
>>>>>>>>>>>>>>>  import org.apache.wicket.model.IModel;
>>>>>>>>>>>>>>> +import org.apache.wicket.model.PropertyModel;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>  public class CalendarForm extends Form<Appointment> {
>>>>>>>>>>>>>>>         private static final long serialVersionUID =
>>>>>>>>>>>>>>> -1764738237821487526L;
>>>>>>>>>>>>>>> +       private boolean createRoom = true;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>         public CalendarForm(String id, IModel<Appointment>
>>>>>>>>>>>>>>> model) {
>>>>>>>>>>>>>>>                 super(id, model);
>>>>>>>>>>>>>>> @@ -33,5 +55,71 @@ public class CalendarForm extends Form<A
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>> RequiredTextField<String>("appointmentName"));
>>>>>>>>>>>>>>>                 add(new
>>>>>>>>>>>>>>> TextArea<String>("appointmentDescription"));
>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>> TextField<String>("appointmentLocation"));
>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>> DateTimeField("appointmentStarttime"));
>>>>>>>>>>>>>>> +               add(new DateTimeField("appointmentEndtime"));
>>>>>>>>>>>>>>> +               final PasswordTextField pwd = new
>>>>>>>>>>>>>>> PasswordTextField("password");
>>>>>>>>>>>>>>> +               pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>> +               pwd.setOutputMarkupId(true);
>>>>>>>>>>>>>>> +               add(pwd);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +               add(new
>>>>>>>>>>>>>>> DropDownChoice<AppointmentReminderTyps>(
>>>>>>>>>>>>>>> +                               "remind"
>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>> Application.getBean(AppointmentReminderTypDaoImpl.class).getAppointmentReminderTypList()
>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>> ChoiceRenderer<AppointmentReminderTyps>("name", "typId")));
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +               final DropDownChoice<RoomTypes> roomType =
>>>>>>>>>>>>>>> new DropDownChoice<RoomTypes>(
>>>>>>>>>>>>>>> +                               "room.roomtype"
>>>>>>>>>>>>>>> +                               ,
>>>>>>>>>>>>>>> Application.getBean(Roommanagement.class).getAllRoomTypes()
>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>> ChoiceRenderer<RoomTypes>("name", "roomtypes_id"));
>>>>>>>>>>>>>>> +               roomType.setEnabled(createRoom);
>>>>>>>>>>>>>>> +               roomType.setOutputMarkupId(true);
>>>>>>>>>>>>>>> +               add(roomType);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +               final DropDownChoice<Rooms> room = new
>>>>>>>>>>>>>>> DropDownChoice<Rooms>(
>>>>>>>>>>>>>>> +                               "room"
>>>>>>>>>>>>>>> +                               , getRoomList()
>>>>>>>>>>>>>>> +                               , new
>>>>>>>>>>>>>>> ChoiceRenderer<Rooms>("name", "rooms_id"));
>>>>>>>>>>>>>>> +               room.setEnabled(!createRoom);
>>>>>>>>>>>>>>> +               room.setOutputMarkupId(true);
>>>>>>>>>>>>>>> +               add(room);
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("createRoom", new
>>>>>>>>>>>>>>> PropertyModel<Boolean>(this, "createRoom")) {
>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>> serialVersionUID = -3743113990890386035L;
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>> +                               createRoom =
>>>>>>>>>>>>>>> getConvertedInput();
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> target.add(roomType.setEnabled(createRoom), 
>>>>>>>>>>>>>>> room.setEnabled(!createRoom));
>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>> +               add(new AjaxCheckBox("isPasswordProtected") {
>>>>>>>>>>>>>>> +                       private static final long
>>>>>>>>>>>>>>> serialVersionUID = 6041200584296439976L;
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +                       @Override
>>>>>>>>>>>>>>> +                       protected void
>>>>>>>>>>>>>>> onUpdate(AjaxRequestTarget target) {
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> CalendarForm.this.getModelObject().setIsPasswordProtected(getConvertedInput());
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> pwd.setEnabled(isPwdProtected());
>>>>>>>>>>>>>>> +                               target.add(pwd);
>>>>>>>>>>>>>>> +                       }
>>>>>>>>>>>>>>> +               });
>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +       private boolean isPwdProtected() {
>>>>>>>>>>>>>>> +               return
>>>>>>>>>>>>>>> Boolean.TRUE.equals(getModelObject().getIsPasswordProtected());
>>>>>>>>>>>>>>> +       }
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +       private List<Rooms> getRoomList() {
>>>>>>>>>>>>>>> +               //FIXME need to be reviewed
>>>>>>>>>>>>>>> +               List<Rooms> result = new ArrayList<Rooms>();
>>>>>>>>>>>>>>> +               RoomDAO dao =
>>>>>>>>>>>>>>> Application.getBean(RoomDAO.class);
>>>>>>>>>>>>>>> +               result.addAll(dao.getPublicRooms());
>>>>>>>>>>>>>>> +               for (Organisation_Users ou :
>>>>>>>>>>>>>>> Application.getBean(UsersDaoImpl.class).get(WebSession.getUserId()).getOrganisation_users())
>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> result.addAll(dao.getOrganisationRooms(ou.getOrganisation().getOrganisation_id()));
>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>> +               if (getModelObject().getRoom() != null &&
>>>>>>>>>>>>>>> getModelObject().getRoom().getAppointment()) { //FIXME review
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> result.add(getModelObject().getRoom());
>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>> +               return result;
>>>>>>>>>>>>>>>         }
>>>>>>>>>>>>>>>  }
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.html
>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>> @@ -71,7 +71,7 @@
>>>>>>>>>>>>>>>                                 $('#appointment').dialog({
>>>>>>>>>>>>>>>                                         closeOnEscape: true
>>>>>>>>>>>>>>>                                         , resizable: true
>>>>>>>>>>>>>>> -                                       , width: 400
>>>>>>>>>>>>>>> +                                       , width: 450
>>>>>>>>>>>>>>>                                         , autoOpen: false
>>>>>>>>>>>>>>>                                         , modal: true
>>>>>>>>>>>>>>>                                 });
>>>>>>>>>>>>>>> @@ -89,53 +89,55 @@
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="572" /></td>
>>>>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>>>>> type="text" wicket:id="appointmentName" /></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>> -                                       <!-- tr>
>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>> <td>&nbsp;</td>
>>>>>>>>>>>>>>> -                                               <td>
>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>> <wicket:ommessage key="570" /><input type="text"
>>>>>>>>>>>>>>> wicket:id="appointmentStarttime" />
>>>>>>>>>>>>>>> -
>>>>>>>>>>>>>>> <wicket:ommessage key="571" /><input type="text"
>>>>>>>>>>>>>>> wicket:id="appointmentEndtime" />
>>>>>>>>>>>>>>> -                                               </td>
>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> <td><wicket:ommessage key="570" /></td>
>>>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>>>> wicket:id="appointmentStarttime"></span></td>
>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>> +                                       <tr>
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> <td><wicket:ommessage key="571" /></td>
>>>>>>>>>>>>>>> +                                               <td><span
>>>>>>>>>>>>>>> wicket:id="appointmentEndtime"></span></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="565" /></td>
>>>>>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>>>>>> wicket:id="notification" ></select></td>
>>>>>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>>>>>> wicket:id="remind" ></select></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" wicket:id="createRoom"
>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="619" /></td>
>>>>>>>>>>>>>>> -                                               <td><select
>>>>>>>>>>>>>>> wicket:id="roomType" ></select></td>
>>>>>>>>>>>>>>> +                                               <td><select
>>>>>>>>>>>>>>> wicket:id="room.roomtype" ></select></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="406" /></td>
>>>>>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>>>>>> wicket:id="room" ></select></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>> -                                               <td
>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" 
>>>>>>>>>>>>>>> wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>> /><wicket:ommessage key="1509" /></td>
>>>>>>>>>>>>>>> +                                               <td
>>>>>>>>>>>>>>> colspan="2"><input type="checkbox" 
>>>>>>>>>>>>>>> wicket:id="isPasswordProtected"
>>>>>>>>>>>>>>> /><wicket:ommessage key="524" /></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="525" /></td>
>>>>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>>>>> type="text" wicket:id="password" /></td>
>>>>>>>>>>>>>>> +                                               <td><input
>>>>>>>>>>>>>>> type="password" wicket:id="password" /></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>> colspan="2"><wicket:ommessage key="1445" /></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>> +                                       <!--
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="803" /></td>
>>>>>>>>>>>>>>>                                                 <td><select
>>>>>>>>>>>>>>> wicket:id="meetingMember" ></select></td>
>>>>>>>>>>>>>>> -                                       </tr>
>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="569" /></td>
>>>>>>>>>>>>>>>                                                 <td><input
>>>>>>>>>>>>>>> type="text" wicket:id="appointmentLocation" /></td>
>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>> +                                       </tr>
>>>>>>>>>>>>>>>                                         <tr>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> <td><wicket:ommessage key="573" /></td>
>>>>>>>>>>>>>>> -                                               <td><input
>>>>>>>>>>>>>>> type="text" wicket:id="appointmentDescription" /></td>
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> <td><textarea 
>>>>>>>>>>>>>>> wicket:id="appointmentDescription"></textarea></td>
>>>>>>>>>>>>>>>                                         </tr>
>>>>>>>>>>>>>>>                                         <!-- tr>
>>>>>>>>>>>>>>>                                                 <td
>>>>>>>>>>>>>>> colspan="2" style="text-align: right"><input type="button" 
>>>>>>>>>>>>>>> wicket:id="save"
>>>>>>>>>>>>>>> /><input type="button" wicket:id="cancel" /></td>
>>>>>>>>>>>>>>> -                                       </tr-->
>>>>>>>>>>>>>>> +                                       </tr -->
>>>>>>>>>>>>>>>                                 </table>
>>>>>>>>>>>>>>>                         </form>
>>>>>>>>>>>>>>>                 </div>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Modified:
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>> URL:
>>>>>>>>>>>>>>> http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java?rev=1400075&r1=1400074&r2=1400075&view=diff
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ==============================================================================
>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>> (original)
>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>> incubator/openmeetings/trunk/singlewebapp/src/org/apache/openmeetings/web/components/user/calendar/CalendarPanel.java
>>>>>>>>>>>>>>> Fri Oct 19 12:39:38 2012
>>>>>>>>>>>>>>> @@ -150,6 +150,9 @@ public class CalendarPanel extends UserP
>>>>>>>>>>>>>>>                                 Calendar end =
>>>>>>>>>>>>>>> WebSession.getCalendar();
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> end.setTimeInMillis(getRequestCycle().getRequest().getRequestParameters().getParameterValue("_end").toLong());
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> +                               if (start.equals(end)) {
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> end.add(Calendar.HOUR_OF_DAY, 1);
>>>>>>>>>>>>>>> +                               }
>>>>>>>>>>>>>>>                                 Appointment a = new
>>>>>>>>>>>>>>> Appointment();
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> a.setAppointmentStarttime(start.getTime());
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> a.setAppointmentEndtime(end.getTime());
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> --
>>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> --
>>>>>>>>>>>>> Sebastian Wagner
>>>>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>>>>> [email protected]
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Sebastian Wagner
>>>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>>>> http://www.webbase-design.de
>>>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>>>> [email protected]
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> WBR
>>>>>>>>> Maxim aka solomax
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Sebastian Wagner
>>>>>>>> https://twitter.com/#!/dead_lock
>>>>>>>> http://www.webbase-design.de
>>>>>>>> http://www.wagner-sebastian.com
>>>>>>>> [email protected]
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> WBR
>>>>>>> Maxim aka solomax
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Sebastian Wagner
>>>>>> https://twitter.com/#!/dead_lock
>>>>>> http://www.webbase-design.de
>>>>>> http://www.wagner-sebastian.com
>>>>>> [email protected]
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> WBR
>>>>> Maxim aka solomax
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sebastian Wagner
>>>> https://twitter.com/#!/dead_lock
>>>> http://www.webbase-design.de
>>>> http://www.wagner-sebastian.com
>>>> [email protected]
>>>>
>>>
>>>
>>>
>>> --
>>> Sebastian Wagner
>>> https://twitter.com/#!/dead_lock
>>> http://www.webbase-design.de
>>> http://www.wagner-sebastian.com
>>> [email protected]
>>>
>>
>>
>>
>> --
>> WBR
>> Maxim aka solomax
>>
>
>
>
> --
> Sebastian Wagner
> https://twitter.com/#!/dead_lock
> http://www.webbase-design.de
> http://www.wagner-sebastian.com
> [email protected]
>



-- 
WBR
Maxim aka solomax

Reply via email to