You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by ad...@apache.org on 2015/04/22 18:50:40 UTC

[10/19] wicket git commit: Integration of Wicket-User-Guide into build process

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/grails-app/i18n/messages_pt_BR.properties
----------------------------------------------------------------------
diff --git a/wicket-user-guide/grails-app/i18n/messages_pt_BR.properties b/wicket-user-guide/grails-app/i18n/messages_pt_BR.properties
new file mode 100644
index 0000000..0c368f2
--- /dev/null
+++ b/wicket-user-guide/grails-app/i18n/messages_pt_BR.properties
@@ -0,0 +1,59 @@
+#
+# Translated by Lucas Teixeira - lucastex@gmail.com
+#
+
+default.doesnt.match.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atende ao padrão definido [{3}]
+default.invalid.url.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é uma URL válida
+default.invalid.creditCard.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um número válido de cartão de crédito
+default.invalid.email.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um endereço de email válido.
+default.invalid.range.message=O campo [{0}] da classe [{1}] com o valor [{2}] não está entre a faixa de valores válida de [{3}] até [{4}]
+default.invalid.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] não está na faixa de tamanho válida de [{3}] até [{4}]
+default.invalid.max.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapass o valor máximo [{3}]
+default.invalid.min.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o valor mínimo [{3}]
+default.invalid.max.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o tamanho máximo de [{3}]
+default.invalid.min.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o tamanho mínimo de [{3}]
+default.invalid.validator.message=O campo [{0}] da classe [{1}] com o valor [{2}] não passou na validação
+default.not.inlist.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um valor dentre os permitidos na lista [{3}]
+default.blank.message=O campo [{0}] da classe [{1}] não pode ficar em branco
+default.not.equal.message=O campo [{0}] da classe [{1}] com o valor [{2}] não pode ser igual a [{3}]
+default.null.message=O campo [{0}] da classe [{1}] não pode ser vazia
+default.not.unique.message=O campo [{0}] da classe [{1}] com o valor [{2}] deve ser único
+
+default.paginate.prev=Anterior
+default.paginate.next=Próximo
+default.boolean.true=Sim
+default.boolean.false=Não
+default.date.format=dd/MM/yyyy HH:mm:ss z
+default.number.format=0
+
+default.created.message={0} {1} criado
+default.updated.message={0} {1} atualizado
+default.deleted.message={0} {1} removido
+default.not.deleted.message={0} {1} não pode ser removido
+default.not.found.message={0} não foi encontrado com id {1}
+default.optimistic.locking.failure=Outro usuário atualizou este [{0}] enquanto você tentou salvá-lo
+
+default.home.label=Principal
+default.list.label={0} Listagem
+default.add.label=Adicionar {0}
+default.new.label=Novo {0}
+default.create.label=Criar {0}
+default.show.label=Ver {0}
+default.edit.label=Editar {0}
+
+default.button.create.label=Criar
+default.button.edit.label=Editar
+default.button.update.label=Alterar
+default.button.delete.label=Remover
+default.button.delete.confirm.message=Tem certeza?
+
+# Mensagens de erro em atribuição de valores. Use "typeMismatch.$className.$propertyName" para customizar (eg typeMismatch.Book.author)
+typeMismatch.java.net.URL=O campo {0} deve ser uma URL válida.
+typeMismatch.java.net.URI=O campo {0} deve ser uma URI válida.
+typeMismatch.java.util.Date=O campo {0} deve ser uma data válida
+typeMismatch.java.lang.Double=O campo {0} deve ser um número válido.
+typeMismatch.java.lang.Integer=O campo {0} deve ser um número válido.
+typeMismatch.java.lang.Long=O campo {0} deve ser um número válido.
+typeMismatch.java.lang.Short=O campo {0} deve ser um número válido.
+typeMismatch.java.math.BigDecimal=O campo {0} deve ser um número válido.
+typeMismatch.java.math.BigInteger=O campo {0} deve ser um número válido.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/grails-app/i18n/messages_pt_PT.properties
----------------------------------------------------------------------
diff --git a/wicket-user-guide/grails-app/i18n/messages_pt_PT.properties b/wicket-user-guide/grails-app/i18n/messages_pt_PT.properties
new file mode 100644
index 0000000..43a6416
--- /dev/null
+++ b/wicket-user-guide/grails-app/i18n/messages_pt_PT.properties
@@ -0,0 +1,34 @@
+#
+# translation by miguel.ping@gmail.com, based on pt_BR translation by Lucas Teixeira - lucastex@gmail.com
+#
+
+default.doesnt.match.message=O campo [{0}] da classe [{1}] com o valor [{2}] não corresponde ao padrão definido [{3}]
+default.invalid.url.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um URL válido
+default.invalid.creditCard.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um número válido de cartão de crédito
+default.invalid.email.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um endereço de email válido.
+default.invalid.range.message=O campo [{0}] da classe [{1}] com o valor [{2}] não está dentro dos limites de valores válidos de [{3}] a [{4}]
+default.invalid.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] está fora dos limites de tamanho válido de [{3}] a [{4}]
+default.invalid.max.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o valor máximo [{3}]
+default.invalid.min.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o valor mínimo [{3}]
+default.invalid.max.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o tamanho máximo de [{3}]
+default.invalid.min.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o tamanho mínimo de [{3}]
+default.invalid.validator.message=O campo [{0}] da classe [{1}] com o valor [{2}] não passou na validação
+default.not.inlist.message=O campo [{0}] da classe [{1}] com o valor [{2}] não se encontra nos valores permitidos da lista [{3}]
+default.blank.message=O campo [{0}] da classe [{1}] não pode ser vazio
+default.not.equal.message=O campo [{0}] da classe [{1}] com o valor [{2}] não pode ser igual a [{3}]
+default.null.message=O campo [{0}] da classe [{1}] não pode ser vazio
+default.not.unique.message=O campo [{0}] da classe [{1}] com o valor [{2}] deve ser único
+
+default.paginate.prev=Anterior
+default.paginate.next=Próximo
+
+# Mensagens de erro em atribuição de valores. Use "typeMismatch.$className.$propertyName" para personalizar(eg typeMismatch.Book.author)
+typeMismatch.java.net.URL=O campo {0} deve ser um URL válido.
+typeMismatch.java.net.URI=O campo {0} deve ser um URI válido.
+typeMismatch.java.util.Date=O campo {0} deve ser uma data válida
+typeMismatch.java.lang.Double=O campo {0} deve ser um número válido.
+typeMismatch.java.lang.Integer=O campo {0} deve ser um número válido.
+typeMismatch.java.lang.Long=O campo {0} deve ser um número valido.
+typeMismatch.java.lang.Short=O campo {0} deve ser um número válido.
+typeMismatch.java.math.BigDecimal=O campo {0} deve ser um número válido.
+typeMismatch.java.math.BigInteger=O campo {0} deve ser um número válido.

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/grails-app/i18n/messages_ru.properties
----------------------------------------------------------------------
diff --git a/wicket-user-guide/grails-app/i18n/messages_ru.properties b/wicket-user-guide/grails-app/i18n/messages_ru.properties
new file mode 100644
index 0000000..02239db
--- /dev/null
+++ b/wicket-user-guide/grails-app/i18n/messages_ru.properties
@@ -0,0 +1,31 @@
+default.doesnt.match.message=Значение [{2}] поля [{0}] класса [{1}] не соответствует образцу [{3}]
+default.invalid.url.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым URL-адресом
+default.invalid.creditCard.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым номером кредитной карты
+default.invalid.email.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым e-mail адресом
+default.invalid.range.message=Значение [{2}] поля [{0}] класса [{1}] не попадает в допустимый интервал от [{3}] до [{4}]
+default.invalid.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) не попадает в допустимый интервал от [{3}] до [{4}]
+default.invalid.max.message=Значение [{2}] поля [{0}] класса [{1}] больше чем максимально допустимое значение [{3}]
+default.invalid.min.message=Значение [{2}] поля [{0}] класса [{1}] меньше чем минимально допустимое значение [{3}]
+default.invalid.max.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) больше чем максимально допустимый размер [{3}]
+default.invalid.min.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) меньше чем минимально допустимый размер [{3}]
+default.invalid.validator.message=Значение [{2}] поля [{0}] класса [{1}] не допустимо
+default.not.inlist.message=Значение [{2}] поля [{0}] класса [{1}] не попадает в список допустимых значений [{3}]
+default.blank.message=Поле [{0}] класса [{1}] не может быть пустым
+default.not.equal.message=Значение [{2}] поля [{0}] класса [{1}] не может быть равно [{3}]
+default.null.message=Поле [{0}] класса [{1}] не может иметь значение null
+default.not.unique.message=Значение [{2}] поля [{0}] класса [{1}] должно быть уникальным
+
+default.paginate.prev=Предыдушая страница
+default.paginate.next=Следующая страница
+
+# Ошибки при присвоении данных. Для точной настройки для полей классов используйте
+# формат "typeMismatch.$className.$propertyName" (например, typeMismatch.Book.author)
+typeMismatch.java.net.URL=Значение поля {0} не является допустимым URL
+typeMismatch.java.net.URI=Значение поля {0} не является допустимым URI
+typeMismatch.java.util.Date=Значение поля {0} не является допустимой датой
+typeMismatch.java.lang.Double=Значение поля {0} не является допустимым числом
+typeMismatch.java.lang.Integer=Значение поля {0} не является допустимым числом
+typeMismatch.java.lang.Long=Значение поля {0} не является допустимым числом
+typeMismatch.java.lang.Short=Значение поля {0} не является допустимым числом
+typeMismatch.java.math.BigDecimal=Значение поля {0} не является допустимым числом
+typeMismatch.java.math.BigInteger=Значение поля {0} не является допустимым числом

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/grails-app/i18n/messages_sv.properties
----------------------------------------------------------------------
diff --git a/wicket-user-guide/grails-app/i18n/messages_sv.properties b/wicket-user-guide/grails-app/i18n/messages_sv.properties
new file mode 100644
index 0000000..61899d7
--- /dev/null
+++ b/wicket-user-guide/grails-app/i18n/messages_sv.properties
@@ -0,0 +1,55 @@
+default.doesnt.match.message=Attributet [{0}] för klassen [{1}] med värde [{2}] matchar inte mot uttrycket [{3}]
+default.invalid.url.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte en giltig URL
+default.invalid.creditCard.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte ett giltigt kreditkortsnummer
+default.invalid.email.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte en giltig e-postadress
+default.invalid.range.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte inom intervallet [{3}] till [{4}]
+default.invalid.size.message=Attributet [{0}] för klassen [{1}] med värde [{2}] har en storlek som inte är inom [{3}] till [{4}]
+default.invalid.max.message=Attributet [{0}] för klassen [{1}] med värde [{2}] överskrider maxvärdet [{3}]
+default.invalid.min.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är mindre än minimivärdet [{3}]
+default.invalid.max.size.message=Attributet [{0}] för klassen [{1}] med värde [{2}] överskrider maxstorleken [{3}]
+default.invalid.min.size.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är mindre än minimistorleken [{3}]
+default.invalid.validator.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte giltigt enligt anpassad regel
+default.not.inlist.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte giltigt, måste vara ett av [{3}]
+default.blank.message=Attributet [{0}] för klassen [{1}] får inte vara tomt
+default.not.equal.message=Attributet [{0}] för klassen [{1}] med värde [{2}] får inte vara lika med [{3}]
+default.null.message=Attributet [{0}] för klassen [{1}] får inte vara tomt
+default.not.unique.message=Attributet [{0}] för klassen [{1}] med värde [{2}] måste vara unikt
+
+default.paginate.prev=Föregående
+default.paginate.next=Nästa
+default.boolean.true=Sant
+default.boolean.false=Falskt
+default.date.format=yyyy-MM-dd HH:mm:ss z
+default.number.format=0
+
+default.created.message={0} {1} skapades
+default.updated.message={0} {1} uppdaterades
+default.deleted.message={0} {1} borttagen
+default.not.deleted.message={0} {1} kunde inte tas bort
+default.not.found.message={0} med id {1} kunde inte hittas
+default.optimistic.locking.failure=En annan användare har uppdaterat det här {0} objektet medan du redigerade det
+
+default.home.label=Hem
+default.list.label= {0} - Lista
+default.add.label=Lägg till {0}
+default.new.label=Skapa {0}
+default.create.label=Skapa {0}
+default.show.label=Visa {0}
+default.edit.label=Ändra {0}
+
+default.button.create.label=Skapa
+default.button.edit.label=Ändra
+default.button.update.label=Uppdatera
+default.button.delete.label=Ta bort
+default.button.delete.confirm.message=Är du säker?
+
+# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author)
+typeMismatch.java.net.URL=Värdet för {0} måste vara en giltig URL
+typeMismatch.java.net.URI=Värdet för {0} måste vara en giltig URI
+typeMismatch.java.util.Date=Värdet {0} måste vara ett giltigt datum
+typeMismatch.java.lang.Double=Värdet {0} måste vara ett giltigt nummer
+typeMismatch.java.lang.Integer=Värdet {0} måste vara ett giltigt heltal
+typeMismatch.java.lang.Long=Värdet {0} måste vara ett giltigt heltal
+typeMismatch.java.lang.Short=Värdet {0} måste vara ett giltigt heltal
+typeMismatch.java.math.BigDecimal=Värdet {0} måste vara ett giltigt nummer
+typeMismatch.java.math.BigInteger=Värdet {0} måste vara ett giltigt heltal
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/grails-app/i18n/messages_th.properties
----------------------------------------------------------------------
diff --git a/wicket-user-guide/grails-app/i18n/messages_th.properties b/wicket-user-guide/grails-app/i18n/messages_th.properties
new file mode 100644
index 0000000..4f4076d
--- /dev/null
+++ b/wicket-user-guide/grails-app/i18n/messages_th.properties
@@ -0,0 +1,55 @@
+default.doesnt.match.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบที่กำหนดไว้ใน [{3}]
+default.invalid.url.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบ URL
+default.invalid.creditCard.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบหมายเลขบัตรเครดิต
+default.invalid.email.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบอีเมล์
+default.invalid.range.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้มีค่าที่ถูกต้องในช่วงจาก [{3}] ถึง [{4}]
+default.invalid.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้มีขนาดที่ถูกต้องในช่วงจาก [{3}] ถึง [{4}]
+default.invalid.max.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีค่าเกิดกว่าค่ามากสุด [{3}]
+default.invalid.min.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีค่าน้อยกว่าค่าต่ำสุด  [{3}]
+default.invalid.max.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีขนาดเกินกว่าขนาดมากสุดของ [{3}]
+default.invalid.min.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีขนาดต่ำกว่าขนาดต่ำสุดของ  [{3}]
+default.invalid.validator.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ผ่านการทวนสอบค่าที่ตั้งขึ้น
+default.not.inlist.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้อยู่ในรายการต่อไปนี้  [{3}]
+default.blank.message=คุณสมบัติ [{0}] ของคลาส [{1}] ไม่สามารถเป็นค่าว่างได้
+default.not.equal.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่สามารถเท่ากับ [{3}] ได้
+default.null.message=คุณสมบัติ [{0}] ของคลาส [{1}] ไม่สามารถเป็น null ได้
+default.not.unique.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] จะต้องไม่ซ้ำ (unique)
+
+default.paginate.prev=ก่อนหน้า
+default.paginate.next=ถัดไป
+default.boolean.true=จริง
+default.boolean.false=เท็จ
+default.date.format=dd-MM-yyyy HH:mm:ss z
+default.number.format=0
+
+default.created.message=สร้าง {0} {1} เรียบร้อยแล้ว
+default.updated.message=ปรับปรุง {0} {1} เรียบร้อยแล้ว
+default.deleted.message=ลบ {0} {1} เรียบร้อยแล้ว
+default.not.deleted.message=ไม่สามารถลบ {0} {1} 
+default.not.found.message=ไม่พบ {0} ด้วย id {1} นี้
+default.optimistic.locking.failure=มีผู้ใช้ท่านอื่นปรับปรุง {0} ขณะที่คุณกำลังแก้ไขข้อมูลอยู่
+
+default.home.label=หน้าแรก
+default.list.label=รายการ {0}
+default.add.label=เพิ่ม {0}
+default.new.label=สร้าง {0} ใหม่
+default.create.label=สร้าง {0}
+default.show.label=แสดง {0}
+default.edit.label=แก้ไข {0}
+
+default.button.create.label=สร้าง
+default.button.edit.label=แก้ไข
+default.button.update.label=ปรับปรุง
+default.button.delete.label=ลบ
+default.button.delete.confirm.message=คุณแน่ใจหรือไม่ ?
+
+# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author)
+typeMismatch.java.net.URL=คุณสมบัติ '{0}' จะต้องเป็นค่า URL ที่ถูกต้อง
+typeMismatch.java.net.URI=คุณสมบัติ '{0}' จะต้องเป็นค่า URI ที่ถูกต้อง
+typeMismatch.java.util.Date=คุณสมบัติ '{0}' จะต้องมีค่าเป็นวันที่
+typeMismatch.java.lang.Double=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Double
+typeMismatch.java.lang.Integer=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Integer
+typeMismatch.java.lang.Long=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Long
+typeMismatch.java.lang.Short=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Short
+typeMismatch.java.math.BigDecimal=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท BigDecimal
+typeMismatch.java.math.BigInteger=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท BigInteger

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/grails-app/i18n/messages_zh_CN.properties
----------------------------------------------------------------------
diff --git a/wicket-user-guide/grails-app/i18n/messages_zh_CN.properties b/wicket-user-guide/grails-app/i18n/messages_zh_CN.properties
new file mode 100644
index 0000000..782580b
--- /dev/null
+++ b/wicket-user-guide/grails-app/i18n/messages_zh_CN.properties
@@ -0,0 +1,18 @@
+default.blank.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u4E0D\u80FD\u4E3A\u7A7A
+default.doesnt.match.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0E\u5B9A\u4E49\u7684\u6A21\u5F0F [{3}]\u4E0D\u5339\u914D
+default.invalid.creditCard.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u4FE1\u7528\u5361\u53F7
+default.invalid.email.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u5408\u6CD5\u7684\u7535\u5B50\u90AE\u4EF6\u5730\u5740
+default.invalid.max.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u6BD4\u6700\u5927\u503C [{3}]\u8FD8\u5927
+default.invalid.max.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u6BD4\u6700\u5927\u503C [{3}]\u8FD8\u5927
+default.invalid.min.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u6BD4\u6700\u5C0F\u503C [{3}]\u8FD8\u5C0F
+default.invalid.min.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u6BD4\u6700\u5C0F\u503C [{3}]\u8FD8\u5C0F
+default.invalid.range.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u5728\u5408\u6CD5\u7684\u8303\u56F4\u5185( [{3}] \uFF5E [{4}] )
+default.invalid.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u4E0D\u5728\u5408\u6CD5\u7684\u8303\u56F4\u5185( [{3}] \uFF5E [{4}] )
+default.invalid.url.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u5408\u6CD5\u7684URL
+default.invalid.validator.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u672A\u80FD\u901A\u8FC7\u81EA\u5B9A\u4E49\u7684\u9A8C\u8BC1
+default.not.equal.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0E[{3}]\u4E0D\u76F8\u7B49
+default.not.inlist.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u5728\u5217\u8868\u7684\u53D6\u503C\u8303\u56F4\u5185
+default.not.unique.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u5FC5\u987B\u662F\u552F\u4E00\u7684
+default.null.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u4E0D\u80FD\u4E3Anull
+default.paginate.next=\u4E0B\u9875
+default.paginate.prev=\u4E0A\u9875

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/grails-app/views/error.gsp
----------------------------------------------------------------------
diff --git a/wicket-user-guide/grails-app/views/error.gsp b/wicket-user-guide/grails-app/views/error.gsp
new file mode 100644
index 0000000..d85f57b
--- /dev/null
+++ b/wicket-user-guide/grails-app/views/error.gsp
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title><g:if env="development">Grails Runtime Exception</g:if><g:else>Error</g:else></title>
+		<meta name="layout" content="main">
+		<g:if env="development"><link rel="stylesheet" href="${resource(dir: 'css', file: 'errors.css')}" type="text/css"></g:if>
+	</head>
+	<body>
+		<g:if env="development">
+			<g:renderException exception="${exception}" />
+		</g:if>
+		<g:else>
+			<ul class="errors">
+				<li>An error has occurred</li>
+			</ul>
+		</g:else>
+	</body>
+</html>

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/grails-app/views/index.gsp
----------------------------------------------------------------------
diff --git a/wicket-user-guide/grails-app/views/index.gsp b/wicket-user-guide/grails-app/views/index.gsp
new file mode 100644
index 0000000..cf4c0b4
--- /dev/null
+++ b/wicket-user-guide/grails-app/views/index.gsp
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta name="layout" content="main"/>
+		<title>Welcome to Grails</title>
+		<style type="text/css" media="screen">
+			#status {
+				background-color: #eee;
+				border: .2em solid #fff;
+				margin: 2em 2em 1em;
+				padding: 1em;
+				width: 12em;
+				float: left;
+				-moz-box-shadow: 0px 0px 1.25em #ccc;
+				-webkit-box-shadow: 0px 0px 1.25em #ccc;
+				box-shadow: 0px 0px 1.25em #ccc;
+				-moz-border-radius: 0.6em;
+				-webkit-border-radius: 0.6em;
+				border-radius: 0.6em;
+			}
+
+			.ie6 #status {
+				display: inline; /* float double margin fix http://www.positioniseverything.net/explorer/doubled-margin.html */
+			}
+
+			#status ul {
+				font-size: 0.9em;
+				list-style-type: none;
+				margin-bottom: 0.6em;
+				padding: 0;
+			}
+
+			#status li {
+				line-height: 1.3;
+			}
+
+			#status h1 {
+				text-transform: uppercase;
+				font-size: 1.1em;
+				margin: 0 0 0.3em;
+			}
+
+			#page-body {
+				margin: 2em 1em 1.25em 18em;
+			}
+
+			h2 {
+				margin-top: 1em;
+				margin-bottom: 0.3em;
+				font-size: 1em;
+			}
+
+			p {
+				line-height: 1.5;
+				margin: 0.25em 0;
+			}
+
+			#controller-list ul {
+				list-style-position: inside;
+			}
+
+			#controller-list li {
+				line-height: 1.3;
+				list-style-position: inside;
+				margin: 0.25em 0;
+			}
+
+			@media screen and (max-width: 480px) {
+				#status {
+					display: none;
+				}
+
+				#page-body {
+					margin: 0 1em 1em;
+				}
+
+				#page-body h1 {
+					margin-top: 0;
+				}
+			}
+		</style>
+	</head>
+	<body>
+		<a href="#page-body" class="skip"><g:message code="default.link.skip.label" default="Skip to content&hellip;"/></a>
+		<div id="status" role="complementary">
+			<h1>Application Status</h1>
+			<ul>
+				<li>App version: <g:meta name="app.version"/></li>
+				<li>Grails version: <g:meta name="app.grails.version"/></li>
+				<li>Groovy version: ${GroovySystem.getVersion()}</li>
+				<li>JVM version: ${System.getProperty('java.version')}</li>
+				<li>Reloading active: ${grails.util.Environment.reloadingAgentEnabled}</li>
+				<li>Controllers: ${grailsApplication.controllerClasses.size()}</li>
+				<li>Domains: ${grailsApplication.domainClasses.size()}</li>
+				<li>Services: ${grailsApplication.serviceClasses.size()}</li>
+				<li>Tag Libraries: ${grailsApplication.tagLibClasses.size()}</li>
+			</ul>
+			<h1>Installed Plugins</h1>
+			<ul>
+				<g:each var="plugin" in="${applicationContext.getBean('pluginManager').allPlugins}">
+					<li>${plugin.name} - ${plugin.version}</li>
+				</g:each>
+			</ul>
+		</div>
+		<div id="page-body" role="main">
+			<h1>Welcome to Grails</h1>
+			<p>Congratulations, you have successfully started your first Grails application! At the moment
+			   this is the default page, feel free to modify it to either redirect to a controller or display whatever
+			   content you may choose. Below is a list of controllers that are currently deployed in this application,
+			   click on each to execute its default action:</p>
+
+			<div id="controller-list" role="navigation">
+				<h2>Available Controllers:</h2>
+				<ul>
+					<g:each var="c" in="${grailsApplication.controllerClasses.sort { it.fullName } }">
+						<li class="controller"><g:link controller="${c.logicalPropertyName}">${c.fullName}</g:link></li>
+					</g:each>
+				</ul>
+			</div>
+		</div>
+	</body>
+</html>

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/grails-app/views/layouts/main.gsp
----------------------------------------------------------------------
diff --git a/wicket-user-guide/grails-app/views/layouts/main.gsp b/wicket-user-guide/grails-app/views/layouts/main.gsp
new file mode 100644
index 0000000..c69c988
--- /dev/null
+++ b/wicket-user-guide/grails-app/views/layouts/main.gsp
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
+<!--[if IE 7 ]>    <html lang="en" class="no-js ie7"> <![endif]-->
+<!--[if IE 8 ]>    <html lang="en" class="no-js ie8"> <![endif]-->
+<!--[if IE 9 ]>    <html lang="en" class="no-js ie9"> <![endif]-->
+<!--[if (gt IE 9)|!(IE)]><!--> <html lang="en" class="no-js"><!--<![endif]-->
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+		<title><g:layoutTitle default="Grails"/></title>
+		<meta name="viewport" content="width=device-width, initial-scale=1.0">
+		<link rel="shortcut icon" href="${resource(dir: 'images', file: 'favicon.ico')}" type="image/x-icon">
+		<link rel="apple-touch-icon" href="${resource(dir: 'images', file: 'apple-touch-icon.png')}">
+		<link rel="apple-touch-icon" sizes="114x114" href="${resource(dir: 'images', file: 'apple-touch-icon-retina.png')}">
+		<link rel="stylesheet" href="${resource(dir: 'css', file: 'main.css')}" type="text/css">
+		<link rel="stylesheet" href="${resource(dir: 'css', file: 'mobile.css')}" type="text/css">
+		<g:layoutHead/>
+		<r:layoutResources />
+	</head>
+	<body>
+		<div id="grailsLogo" role="banner"><a href="http://grails.org"><img src="${resource(dir: 'images', file: 'grails_logo.png')}" alt="Grails"/></a></div>
+		<g:layoutBody/>
+		<div class="footer" role="contentinfo"></div>
+		<div id="spinner" class="spinner" style="display:none;"><g:message code="spinner.alt" default="Loading&hellip;"/></div>
+		<g:javascript library="application"/>
+		<r:layoutResources />
+	</body>
+</html>

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/pom.xml
----------------------------------------------------------------------
diff --git a/wicket-user-guide/pom.xml b/wicket-user-guide/pom.xml
new file mode 100644
index 0000000..28d55c9
--- /dev/null
+++ b/wicket-user-guide/pom.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.apache.wicket</groupId>
+		<artifactId>wicket-parent</artifactId>
+		<version>7.0.0-SNAPSHOT</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+	<artifactId>wicket-user-guide</artifactId>
+	<packaging>jar</packaging>
+	<name>Wicket User Guide</name>
+	<description>
+		Provides the user guide of wicket
+	</description>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.grails</groupId>
+			<artifactId>grails-dependencies</artifactId>
+			<version>${grails.version}</version>
+			<type>pom</type>
+			<exclusions>
+				<exclusion>
+					<artifactId>log4j</artifactId>
+					<groupId>log4j</groupId>
+				</exclusion>
+				<exclusion>
+					<artifactId>grails-plugin-log4j</artifactId>
+					<groupId>org.grails</groupId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.grails</groupId>
+			<artifactId>grails-docs</artifactId>
+			<version>${grails.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-log4j12</artifactId>
+		</dependency>
+	</dependencies>
+
+	<repositories>
+		<repository>
+			<id>grails</id>
+			<name>grails</name>
+			<url>http://repo.grails.org/grails/core</url>
+		</repository>
+		<repository>
+			<id>grails-plugins</id>
+			<name>grails-plugins</name>
+			<url>http://repo.grails.org/grails/plugins</url>
+		</repository>
+	</repositories>
+
+	<profiles>
+		<profile>
+			<id>guide</id>
+			<activation>
+				<activeByDefault>false</activeByDefault>
+			</activation>
+			<build>
+				<plugins>
+					<plugin>
+						<artifactId>maven-clean-plugin</artifactId>
+						<configuration>
+							<filesets>
+								<fileset>
+									<directory>plugins</directory>
+									<includes>
+										<include>**/*</include>
+									</includes>
+									<followSymlinks>false</followSymlinks>
+								</fileset>
+							</filesets>
+						</configuration>
+					</plugin>
+					<plugin>
+						<groupId>org.grails</groupId>
+						<artifactId>grails-maven-plugin</artifactId>
+						<version>${grails.version}</version>
+						<extensions>true</extensions>
+						<configuration>
+							<grailsVersion>${grails.version}</grailsVersion>
+						</configuration>
+						<executions>
+							<!-- HTML guide -->
+							<execution>
+								<id>doc</id>
+								<phase>package</phase>
+								<goals>
+									<goal>exec</goal>
+								</goals>
+								<configuration>
+									<command>doc</command>
+								</configuration>
+							</execution>
+							<!-- PDF guide -->
+							<execution>
+								<id>pdf</id>
+								<phase>package</phase>
+								<goals>
+									<goal>exec</goal>
+								</goals>
+								<configuration>
+									<command>doc</command>
+									<args>--pdf</args>
+								</configuration>
+							</execution>
+						</executions>
+					</plugin>
+				</plugins>
+			</build>
+		</profile>
+	</profiles>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/scripts/_Events.groovy
----------------------------------------------------------------------
diff --git a/wicket-user-guide/scripts/_Events.groovy b/wicket-user-guide/scripts/_Events.groovy
new file mode 100644
index 0000000..fddcd7b
--- /dev/null
+++ b/wicket-user-guide/scripts/_Events.groovy
@@ -0,0 +1,10 @@
+eventDocStart = { kind ->
+   println "Started $kind"
+}
+
+eventDocEnd = { kind ->
+   println "Completed $kind"
+   /*new File("../img").eachFile() { file -> 
+      println file.getName()
+   }*/
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/src/docs/css/custom-pdf.css
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/css/custom-pdf.css b/wicket-user-guide/src/docs/css/custom-pdf.css
new file mode 100644
index 0000000..51868bd
--- /dev/null
+++ b/wicket-user-guide/src/docs/css/custom-pdf.css
@@ -0,0 +1,35 @@
+/*
+   Dummy stylesheet allowing for some customisation of pdf output without having to copy and modify the other stylesheets.
+*/
+
+ body{
+   font-family:helvetica,arial,sans-serif!important;
+   font-size: 10pt!important;
+ } 
+
+.paragraph{
+   font-family:helvetica,arial,sans-serif!important;	
+}
+
+.code pre {
+    page-break-inside: auto!important;
+}
+
+.bq {
+    page-break-inside: auto!important;
+}
+
+table {
+    page-break-inside: auto!important;
+}
+
+.paragraph{
+ text-indent: 1em!important;
+}
+
+h1{
+  font-size:3em!important;
+  text-align:right;
+  padding-bottom: 30px;	
+}
+

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/src/docs/css/custom.css
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/css/custom.css b/wicket-user-guide/src/docs/css/custom.css
new file mode 100644
index 0000000..735b223
--- /dev/null
+++ b/wicket-user-guide/src/docs/css/custom.css
@@ -0,0 +1,59 @@
+/*
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Color.
+//
+////////////////////////////////////////////////////////////////////////////////
+*/
+
+h1, h2, #main a, #main .project strong, .local .local-title .toggle a, #table-of-content a strong {
+    color: #E8590A!important;
+}
+
+
+/*
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Background Color.
+//
+////////////////////////////////////////////////////////////////////////////////
+*/
+
+
+#navigation .selected a {
+    background: #E8590A!important;
+}
+
+#navigation a:hover {
+    background: #777777!important;
+}
+
+#navigation .selected a:hover, #navigation .active .button {
+    background: #E8590A!important;
+}
+
+#table-of-content a {
+	border-right-color: #E8590A!important;
+}
+
+/*
+////////////////////////////////////////////////////////////////////////////////
+//
+//  Background Image.
+//
+////////////////////////////////////////////////////////////////////////////////
+*/
+
+.wiki-table th, #navigation {
+    background: #F17A2F!important;
+}
+
+#navigation .separator {
+    background: none!important;
+}
+
+@media print
+  {
+   #col2 {display:none!important;}
+  }
+

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/src/docs/guide/advanced.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/advanced.gdoc b/wicket-user-guide/src/docs/guide/advanced.gdoc
new file mode 100644
index 0000000..9ed5818
--- /dev/null
+++ b/wicket-user-guide/src/docs/guide/advanced.gdoc
@@ -0,0 +1 @@
+In this chapter we will learn some advanced topics which have not been covered yet in the previous chapters but which are nonetheless essential to make the most of Wicket and to build sophisticated web applications.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/src/docs/guide/advanced/advanced_1.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/advanced/advanced_1.gdoc b/wicket-user-guide/src/docs/guide/advanced/advanced_1.gdoc
new file mode 100644
index 0000000..bde225a
--- /dev/null
+++ b/wicket-user-guide/src/docs/guide/advanced/advanced_1.gdoc
@@ -0,0 +1,45 @@
+
+
+With class @org.apache.wicket.behavior.Behavior@ Wicket provides a very flexible mechanism to share common features across different components and to enrich existing components with further functionalities. As the class name suggests, @Behavior@ adds a generic behavior to a component modifying its markup and/or contributing to the header section of the page (@Behavior@ implements the interface @IHeaderContributor@).
+
+One or more behaviors can be added to a component with @Component@'s method @add(Behavior...)@, while to remove a behavior we must use method @remove(Behavior)@.
+
+Here is a partial list of methods defined inside class @Behavior@ along with a brief description of what they do:
+
+* *beforeRender(Component component)*: called when a component is about to be rendered. 
+* *afterRender(Component component)*: called after a component has been rendered. 
+* *onComponentTag(Component component, ComponentTag tag)*: called when component tag is being rendered.
+* *getStatelessHint(Component component)*: returns if a behavior is stateless or not.
+* *bind(Component component)*: called after a behavior has been added to a component.
+* *unbind(Component component)*: called when a behavior has been removed from a component.
+* *detach(Component component)*: overriding this method a behavior can detach its state before being serialized.
+* *isEnabled(Component component)*: tells if the current behavior is enabled for a given component. When a behavior is disabled it will be simply ignored and not executed.
+* *isTemporary(Component component)*: tells component if the current behavior is temporary. A temporary behavior is discarded at the end of the current request (i.e it's executed only once). 
+* *onConfigure(Component component)*: called right after the owner component has been configured.
+* *onRemove(Component component)*: called when the owner component has been removed from its container.
+* *renderHead(Component component, IHeaderResponse response)*: overriding this method behaviors can render resources to the header section of the page. 
+
+For example the following behavior prepends a red asterisk to the tag of a form component if this one  is required:
+
+{code}
+public class RedAsteriskBehavior extends Behavior {
+
+  @Override
+  public void beforeRender(Component component) {
+      Response response = component.getResponse();
+      StringBuffer asterisktHtml = new StringBuffer(200);
+      
+      if(componet instanceof FormComponent 
+            && ((FormComponent)component).isRequired()){
+        asteriskHtml.append(" <b style=\"color:red;font-size:medium\">*</b>");
+      }  
+      response.write(asteriskHtml);
+  }
+}
+{code}
+
+Since method @beforeRender@ is called before the coupled component is rendered, we can use it to prepend custom markup to component tag. This can be done writing our markup directly to the current  Response object, as we did in the example above.
+
+Please note that we could achieve the same result overriding component method @onBeforeRender@. However using a behavior we can easily reuse our custom code with any other kind of component without modifying its source code. As general best practice we should always consider to implement a new functionality using a behavior if it can be shared among different kinds of component.
+
+Behaviors play also a strategic role in the built-in AJAX support provided by Wicket, as we will see in the next chapter. 

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/src/docs/guide/advanced/advanced_2.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/advanced/advanced_2.gdoc b/wicket-user-guide/src/docs/guide/advanced/advanced_2.gdoc
new file mode 100644
index 0000000..1d1dda0
--- /dev/null
+++ b/wicket-user-guide/src/docs/guide/advanced/advanced_2.gdoc
@@ -0,0 +1,168 @@
+
+
+With Wicket it's quite easy to build a callback URL that executes a specific method on server side. This method must be defined in a functional interface (i.e. an an interface that defines just one method) that inherits from built-in @org.apache.wicket.IRequestListener@ and it must be a void method with no parameters in input:
+
+{code}
+public interface IMyListener extends IRequestListener
+{
+	/**
+	 * Called when the relative callback URL is requested.
+	 */
+	void myCallbackMethod();
+}
+{code}
+
+To control how the method will be invoked we must use class @org.apache.wicket.RequestListenerInterface@. In Wicket is a common practice to instantiate this class as a public static field inside the relative callback interface:
+
+{code}
+public interface IMyListener extends IRequestListener
+{
+	/**RequestListenerInterface instance*/
+	public static final RequestListenerInterface INTERFACE = new 
+                               RequestListenerInterface(IMyListener.class);
+	/**
+	 * Called when the relative callback URL is requested.
+	 */
+	void myCallbackMethod();
+}
+{code}
+
+By default @RequestListenerInterface@ will respond rendering the current page after the callback method has been executed (if we have a non-AJAX request). To change this behavior we can use setter method @setRenderPageAfterInvocation(boolean)@.
+
+Now that our callback interface is complete we can generate a callback URL with @Component@'s method @urlFor(RequestListenerInterface, PageParameters)@ or with method @urlFor (Behavior, RequestListenerInterface, PageParameters)@ if we are using a callback interface with a behavior (see the following example).
+
+Project CallbackURLExample contains a behavior (class @OnChangeSingleChoiceBehavior@) that implements a callback interface to update the model of an @AbstractSingleSelectChoice@ component when user changes the selected option (it provides the same functionality of method @wantOnSelectionChangedNotifications@). 
+
+Instead of a custom callback interface, @OnChangeSingleChoiceBehavior@ implements built-in interface @org.apache.wicket.behavior.IBehaviorListener@ which is designed to generate a callback URL for behaviors. The callback method defined in this interface is @onRequest()@ and the following is the implementation provided by @OnSelectionChangedNotifications@:
+
+{code}
+@Override
+public void onRequest() {	
+	Request request = RequestCycle.get().getRequest();
+	IRequestParameters requestParameters = request.getRequestParameters();
+	StringValue choiceId = requestParameters.getParameterValue("choiceId");
+	//boundComponent is the component that the behavior it is bound to.
+	boundComponent.setDefaultModelObject( convertChoiceIdToChoice(choiceId.toString()));
+}
+{code}
+
+When invoked via URL, the behavior expects to find a request parameter (choiceId) containing the id of the selected choice. This value is used to obtain the corresponding choice object that must be used to set the model of the component that the behavior is bound to (boundComponent). Method @convertChoiceIdToChoice@ is in charge of retrieving the choice object given its id and it has been copied from class @AbstractSingleSelectChoice@.
+
+Another interesting part of @OnChangeSingleChoiceBehavior@ is its method @onComponentTag@ where some JavaScript “magic” is used to move user's browser to the callback URL when event “change” occurs on bound component:
+
+{code}
+@Override
+public void onComponentTag(Component component, ComponentTag tag) {
+	super.onComponentTag(component, tag);
+		
+	CharSequence callBackURL = getCallbackUrl();
+	String separatorChar = (callBackURL.toString().indexOf('?') > -1 ? "&" : "?");
+		
+	String finalScript = "var isSelect = $(this).is('select');\n" +
+				 "var component;\n" +	
+				 "if(isSelect)\n" +
+				 "	component = $(this);\n" +
+				 "else \n" +
+				 "	component = $(this).find('input:radio:checked');\n" +
+				 "window.location.href='" + callBackURL +  separatorChar + 
+				 "choiceId=' + " + "component.val()";
+		
+	tag.put("onchange", finalScript);
+}
+{code}
+
+The goal of @onComponentTag@ is to build an onchange handler that forces user's browser to move to the callback URL (modifing standard property window.location.href). Please note that we have appended the expected parameter (choiceId) to the URL retrieving its value with a JQuery selector suited for the current type of component (a drop-down menu or a radio group). Since we are using JQuery in our JavaScript code, the behavior comes also with method @renderHead@ that adds the bundled JQuery library to the current page.
+
+Method @getCallbackUrl()@ is used to generate the callback URL for our custom behavior and it has been copied from built-in class @AbstractAjaxBehavior@: 
+
+{code}
+public CharSequence getCallbackUrl(){
+	if (boundComponent == null){
+		throw new IllegalArgumentException(
+			"Behavior must be bound to a component to create the URL");
+	}
+
+	final RequestListenerInterface rli;
+
+	rli = IBehaviorListener.INTERFACE;
+
+	return boundComponent.urlFor(this, rli, new PageParameters());
+}
+{code}
+
+Static field @IBehaviorListener.INTERFACE@ is the implementation of @RequestListenerInterface@ defined inside callback interface @IBehaviorListener@.
+
+The home page of project @CallbackURLExample@ contains a @DropDownChoice@ and a @RadioChoice@ which use our custom behavior. There are also two labels to display the content of the models of the two components:
+
+!CallbackURLExample-screenshot.png!
+
+{note}
+Implementing interface @IBehaviorListener@ makes a behavior stateful because its callback URL is specific for a given instance of component.
+{note}
+
+As final note it's interesting to see how Wicket internally uses callback URLs for its standard link component. Class @org.apache.wicket.markup.html.link.Link@ implements interface @org.apache.wicket.markup.html.link.ILinkListener@ which in turn extends @IRequestListener@:
+
+{code}
+public interface ILinkListener extends IRequestListener
+{
+	/** Listener interface */
+	public static final RequestListenerInterface INTERFACE = new RequestListenerInterface(
+		ILinkListener.class);
+
+	/**
+	 * Called when a link is clicked.
+	 */
+	void onLinkClicked();
+}
+{code}
+
+The implementation of method @onLinkClicked@ simply delegates event handling to our custom version of @onClick@:
+
+{code}
+@Override
+public final void onLinkClicked()
+{
+	// Invoke subclass handler
+	onClick();
+}
+{code}
+
+h3. Wicket events infrastructure
+
+Starting from version 1.5 Wicket offers an event-based infrastructure for inter-component communication. The infrastructure is based on two simple interfaces (both in package @org.apache.wicket.event@) : @IEventSource@ and @IEventSink@. 
+
+The first interface must be implemented by those entities that want to broadcast en event while the second interface must be implemented by those entities that want to receive a broadcast event.
+
+The following entities already implement both these two interfaces (i.e. they can be either sender or receiver): @Component@, @Session@, @RequestCycle@ and @Application@.
+@IEventSource@ exposes a single method named send which takes in input three parameters:
+
+* *sink*: an implementation of @IEventSink@ that will be the receiver of the event. 
+* *broadcast*: a @Broadcast@ enum which defines the broadcast method used to dispatch the event to the sink and to other entities such as sink children, sink containers, session object, application object and the current request cycle. It has four possible values:
+{table}
+*Value* | *Description*
+BREADTH | The event is sent first to the specified sink and then to all its children components following a breadth-first order.
+DEPTH | The event is sent to the specified sink only after it has been dispatched to all its children components following a depth-first order.
+BUBBLE | The event is sent first to the specified sink and then to its parent containers.
+EXACT | The event is sent only to the specified sink.
+{table}
+* *payload*: a generic object representing the data sent with the event.
+
+Each broadcast mode has its own traversal order for @Session@, @RequestCycle@ and @Application@. See JavaDoc of class @Broadcast@ for further details about this order.
+
+Interface @IEventSink@ exposes callback method @onEvent(IEvent<?> event)@ which is triggered when a sink receives an event. The interface @IEvent@ represents the received event and provides getter methods to retrieve the event broadcast type, the source of the event and its payload. Typically the received event is used checking the type of its payload object:
+
+{code}
+@Override
+public void onEvent(IEvent event) {
+  //if the type of payload is MyPayloadClass perform some actions 
+  if(event.getPayload() instanceof MyPayloadClass) {
+     //execute some business code.
+  }else{
+     //other business code
+  }   		
+}
+{code}
+
+Project @InterComponetsEventsExample@ provides a concrete example of sending an event to a component (named 'container in the middle') using all the available broadcast methods:
+
+!InterComponentsEventsExample-screenshot.png!

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/src/docs/guide/advanced/advanced_3.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/advanced/advanced_3.gdoc b/wicket-user-guide/src/docs/guide/advanced/advanced_3.gdoc
new file mode 100644
index 0000000..aaa38b4
--- /dev/null
+++ b/wicket-user-guide/src/docs/guide/advanced/advanced_3.gdoc
@@ -0,0 +1,38 @@
+
+
+Some components or resources may need to be configured before being used in our applications. While so far we used Application's init method to initialize these kinds of entities, Wicket offers a more flexible and modular way to configure our classes. 
+
+During application's bootstrap Wicket searches for any properties file named wicket.properties  placed in one of the classpath roots visible to the application. When one of these files is found, the initializer defined inside it will be executed. An initializer is an implementation of interface @org.apache.wicket.IInitializer@ and is defined inside wicket.properties with a line like this:
+
+{code}
+initializer=org.wicketTutorial.MyInitializer
+{code}
+
+The fully qualified class name corresponds to the initializer that must be executed. Interface @IInitializer@ defines method init(Application) which should contain our initialization code, and method @destroy(Application)@ which is invoked when application is terminated:
+
+{code}
+public class MyInitializer implements IInitializer{
+
+	public void init(Application application) {
+		//initialization code 
+	}
+
+	public void destroy(Application application) {
+		//code to execute when application is terminated
+	}	
+}
+{code}
+
+Only one initializer can be defined in a single wicket.properties file. To overcome this limit we can create a main initializer that in turn executes every initializer we need:
+
+{code}
+public class MainInitializer implements IInitializer{
+
+	public void init(Application application) {
+		new AnotherInitializer().init(application);
+		new YetAnotherInitializer().init(application);
+		//... 
+	}
+	//destroy... 
+}
+{code}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/src/docs/guide/advanced/advanced_4.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/advanced/advanced_4.gdoc b/wicket-user-guide/src/docs/guide/advanced/advanced_4.gdoc
new file mode 100644
index 0000000..34549c1
--- /dev/null
+++ b/wicket-user-guide/src/docs/guide/advanced/advanced_4.gdoc
@@ -0,0 +1,27 @@
+
+
+JMX (Java Management Extensions) is the standard technology adopted in Java for managing and monitoring running applications or Java Virtual Machines. Wicket offers support for JMX through module wicket-jmx. In this paragraph we will see how we can connect to a Wicket application using JMX. In our example we will use JConsole as JMX client. This program is bundled with Java SE since version 5 and we can run it typing jconsole in our OS shell. 
+
+Once JConsole has started it will ask us to establish a new connection to a Java process, choosing between a local process or a remote one. In the following picture we have selected the process corresponding to the local instance of Jetty server we used to run one of our example projects:
+
+!JMX-new-connection.png!
+
+After we have established a JMX connection, JConsole will show us the following set of tabs:
+
+!JMX-console.png!
+
+JMX exposes application-specific informations using special objects called MBeans (Manageable Beans), hence if we want to control our application we must open the corresponding tab. The MBeans containing the application's informations is named @org.apache.wicket.app.<filter/servlet name>@.
+
+In our example we have used wicket.test as filter name for our application:
+
+!JMX-console2.png!
+
+As we can see in the picture above, every MBean exposes a node containing its attributes and another node showing the possible operations that can be performed on the object. In the case of a Wicket application the available operations are clearMarkupCache and clearLocalizerCache:
+
+!JMX-console3.png!
+
+With these two operations we can force Wicket to clear the internal caches used to load components markup and resource bundles. This can be particularly useful if we have our application running in DEPLOYMENT mode and we want to publish minor fixes for markup or bundle files (like spelling or typo corrections) without restarting the entire application. Without cleaning these two caches Wicket would continue to use cached values ignoring any change made to markup or bundle files.
+
+Some of the exposed properties are editable, hence we can tune their values while the application is running. For example if we look at the properties of @ApplicationSettings@ we can set the maximum size allowed for an upload modifying the attribute DefaultMaximumUploadSize:
+
+!JMX-console4.png!
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/src/docs/guide/advanced/advanced_5.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/advanced/advanced_5.gdoc b/wicket-user-guide/src/docs/guide/advanced/advanced_5.gdoc
new file mode 100644
index 0000000..1325958
--- /dev/null
+++ b/wicket-user-guide/src/docs/guide/advanced/advanced_5.gdoc
@@ -0,0 +1,62 @@
+
+
+So far, as markup source for our pages/panels we have used a static markup file, no matter if it was inherited or directly associated to the component. Now we want to investigate a more complex use case where we want to dynamical generate the markup directly inside component code.
+
+To become a markup producer, a component must simply implement interface @org.apache.wicket.markup.IMarkupResourceStreamProvider@. The only method defined in this interface is @getMarkupResourceStream(MarkupContainer, Class<?>)@ which returns an utility interface called @IResourceStream@ representing the actual markup.
+
+In the following example we have a custom panel without a related markup file that generates a simple <div> tag as markup: 
+
+{code}
+public class AutoMarkupGenPanel extends Panel implements IMarkupResourceStreamProvider {
+	public AutoMarkupGenPanel(String id, IModel<?> model) {
+		super(id, model);		
+	}
+
+	@Override
+	public IResourceStream getMarkupResourceStream(MarkupContainer container,
+			Class<?> containerClass) {
+		String markup = "<div>Panel markup</div>";
+		StringResourceStream resourceStream = new StringResourceStream(markup);
+		
+		return resourceStream;
+	}
+}
+{code}
+
+Class StringResourceStream is a resource stream that uses a String instance as backing object.
+
+h3. Avoiding markup caching
+
+As we have seen in the previous paragraph, Wicket uses an internal cache for components markup. This can be a problem if our component dynamical generates its markup when it is rendered because once the markup has been cached, Wicket will always use the cached version for the specific component. To overwrite this default caching policy, a component can implement interface @IMarkupCacheKeyProvider@. 
+
+This interface defines method @getCacheKey(MarkupContainer, Class<?>)@ which returns a string value representing the key used by Wicket to retrieve the markup of the component from the cache. If this value is null the markup will not be cached, allowing the component to display the last generated markup each time it is rendered:
+
+{code}
+public class NoCacheMarkupPanel extends Panel implements IMarkupCacheKeyProvider {
+	public NoCacheMarkupPanel(String id, IModel<?> model) {
+		super(id, model);		
+	}
+	
+	/**
+	* Generate a dynamic HTML markup that changes every time
+	* the component is rendered
+	*/
+	@Override
+	public IResourceStream getMarkupResourceStream(MarkupContainer container,
+			Class<?> containerClass) {
+		String markup = "<div>Panel with current nanotime: " + System.nanoTime() +
+				 "</div>"; 
+		StringResourceStream resourceStream = new StringResourceStream(markup);
+		
+		return resourceStream;
+	}
+
+	/**
+	* Avoid markup caching for this component
+	*/
+	@Override
+	public String getCacheKey(MarkupContainer arg0, Class<?> arg1) {
+		return null;
+	}
+}
+{code}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/src/docs/guide/advanced/advanced_6.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/advanced/advanced_6.gdoc b/wicket-user-guide/src/docs/guide/advanced/advanced_6.gdoc
new file mode 100644
index 0000000..564322c
--- /dev/null
+++ b/wicket-user-guide/src/docs/guide/advanced/advanced_6.gdoc
@@ -0,0 +1,17 @@
+
+
+In this chapter we have introduced some advanced topics we didn't have the chance to cover yet. We have started talking about behaviors and we have seen how they can be used to enrich existing components (promoting a component-oriented approach). Behaviors are also fundamental to work with AJAX in Wicket, as we will see in the next chapter.
+
+After behaviors we have learnt how to generate callback URLs to execute a custom method on server side defined inside a specific callback interface.
+
+The third topic of the chapter has been the event infrastructure provided in Wicket for inter-component communication which brings to our components a desktop-like event-driven architecture.
+
+Then, we have introduced a new entity called initializer which can be used to configure resources and component in a modular and self-contained way.
+
+We have also looked at Wicket support for JMX and we have seen how to use this technology for monitoring and managing our running applications.
+
+Finally we have introduced a new technique to generate the markup of a component from its Java code.
+
+
+
+

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/src/docs/guide/ajax.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/ajax.gdoc b/wicket-user-guide/src/docs/guide/ajax.gdoc
new file mode 100644
index 0000000..5da1ab1
--- /dev/null
+++ b/wicket-user-guide/src/docs/guide/ajax.gdoc
@@ -0,0 +1,3 @@
+AJAX has become a must-have for nearly all kinds of web application. This technology does not only help to achieve a better user experience but it also allows to improve the bandwidth performance of web applications. Using AJAX usually means writing tons of JavaScript code to handle asynchronous requests and to update user interface, but with Wicket we can leave all this boilerplate code to the framework and we don't even need to write a single line of JavaScript to start using AJAX.
+
+In this chapter we will learn how to leverage the AJAX support provided by Wicket to make our applications fully "Web 2.0":http://en.wikipedia.org/wiki/Web_2.0 compliant.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/src/docs/guide/ajax/ajax_1.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/ajax/ajax_1.gdoc b/wicket-user-guide/src/docs/guide/ajax/ajax_1.gdoc
new file mode 100644
index 0000000..fcd54fe
--- /dev/null
+++ b/wicket-user-guide/src/docs/guide/ajax/ajax_1.gdoc
@@ -0,0 +1,64 @@
+
+
+Wicket support for AJAX is implemented in file wicket-ajax-jquery.js which makes complete transparent to Java code any detail about AJAX communication. 
+
+AJAX components and behaviors shipped with Wicket expose one or more callback methods which are executed when they receive an AJAX request. One of the arguments of these methods is an instance of interface @org.apache.wicket.ajax.AjaxRequestTarget@. 
+
+For example component AjaxLink (in package @org.apache.wicket.ajax.markup.html@) defines abstract method @onClick(AjaxRequestTarget target)@ which is executed when user clicks on the component:
+
+{code}
+new AjaxLink("ajaxLink"){
+	@Override
+	public void onClick(AjaxRequestTarget target) {
+	    //some server side code...
+	}  	
+};
+{code}
+
+Using AjaxRequestTarget we can specify the content that must be sent back to the client as response to the current AJAX request. The most commonly used method of this interface is probably @add(Component... components)@. With this method we tell Wicket to render again the specified components and refresh their markup via AJAX:
+
+{code}
+new AjaxLink("ajaxLink"){
+	@Override
+	public void onClick(AjaxRequestTarget target) {
+	    //modify the model of a label and refresh it on browser
+	    label.setDefaultModelObject("Another value 4 label.");
+	    target.add(label);
+	}  	
+};
+{code}
+
+Components can be refreshed via Ajax only if they have rendered a markup id for their related tag. As a consequence, we must remember to set a valid id value on every component we want to add to @AjaxRequestTarget@. This can be done using one of the two methods seen in paragraph 4.3:
+
+{code}
+final Label label = new Label("labelComponent", "Initial value.");
+//autogenerate a markup id
+label.setOutputMarkupId(true);
+add(label);
+//...
+new AjaxLink("ajaxLink"){
+	@Override
+	public void onClick(AjaxRequestTarget target) {
+	    //modify the model of a label and refresh it on client side
+	    label.setDefaultModelObject("Another value 4 label.");
+	    target.add(label);
+	}  	
+};
+{code}
+
+Another common use of AjaxRequestTarget is to prepend or append some JavaScript code to the generated response. For example the following AJAX link displays an alert box as response to user's click:
+
+{code}
+new AjaxLink("ajaxLink"){
+	@Override
+	public void onClick(AjaxRequestTarget target) {
+	    target.appendJavaScript(";alert('Hello!!');");
+	}  	
+};
+{code}
+
+{warning}
+Repeaters component that have @org.apache.wicket.markup.repeater.AbstractRepeater@ as base class (like @ListView@, @RepeatingView@, etc...) can not be directly updated via AJAX.
+
+If we want to refresh their markup via AJAX we must add one of their parent containers to the @AjaxRequestTarget@.
+{warning}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/c1da4aef/wicket-user-guide/src/docs/guide/ajax/ajax_2.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/ajax/ajax_2.gdoc b/wicket-user-guide/src/docs/guide/ajax/ajax_2.gdoc
new file mode 100644
index 0000000..7dc9cdc
--- /dev/null
+++ b/wicket-user-guide/src/docs/guide/ajax/ajax_2.gdoc
@@ -0,0 +1,342 @@
+
+
+Wicket distribution comes with a number of built-in AJAX components ready to be used. Some of them are the ajaxified version of common components like links and buttons, while others are AJAX-specific components. 
+
+AJAX components are not different from any other component seen so far and they don't require any additional configuration to be used. As we will shortly see, switching from a classic link or button to the ajaxified version is just a matter of appending “Ajax” to the component class name.
+
+This paragraph provides an overview of what we can find in Wicket to start writing AJAX-enhanced web applications.
+
+h3. Links and buttons
+
+In the previous paragraph we have already introduced component AjaxLink. Wicket provides also the ajaxified versions of submitting components SubmitLink and Button which are simply called AjaxSubmitLink and AjaxButton. These components come with a version of methods onSubmit, onError and onAfterSubmit that takes in input also an instance of @AjaxRequestTarget@. 
+
+Both components are in package @org.apache.wicket.ajax.markup.html.form@.
+
+h3. Fallback components
+
+Building an entire site using AJAX can be risky as some clients may not support this technology. In order to provide an usable version of our site also to these clients, we can use components @AjaxFallbackLink@ and @AjaxFallbackButton@ which are able to automatically degrade to a standard link or to a standard button if client doesn't support AJAX.
+
+h3. AJAX Checkbox
+
+Class @org.apache.wicket.ajax.markup.html.form.AjaxCheckBox@ is a checkbox component that updates its model via AJAX when user changes its value. Its AJAX callback method is @onUpdate(AjaxRequestTarget target)@. The component extends standard checkbox component @CheckBox@ adding an @AjaxFormComponentUpdatingBehavior@ to itself (we will see this behavior later in paragraph 16.3.3).
+
+h3. AJAX editable labels
+
+An editable label is a special label that can be edited by the user when she/he clicks on it. Wicket ships three different implementations for this component (all inside package @org.apache.wicket.extensions.ajax.markup.html@):
+
+* *AjaxEditableLabel*: it's a basic version of editable label. User can edit the content of the label with a text field. This is also the base class for the other two editable labels.
+* *AjaxEditableMultiLineLabel*: this label supports multi-line values and uses a text area as editor component. 
+* *AjaxEditableChoiceLabel*: this label uses a drop-down menu to edit its value.
+
+Base component AjaxEditableLabel exposes the following set of AJAX-aware methods that can be overriden:
+
+* *onEdit(AjaxRequestTarget target)*: called when user clicks on component. The default implementation shows the component used to edit the value of the label.  
+* *onSubmit(AjaxRequestTarget target)*: called when the value has been successfully updated with the new input.
+* *onError(AjaxRequestTarget target)*: called when the new inserted input has failed validation.
+* *onCancel(AjaxRequestTarget target)*: called when user has exited from editing mode pressing escape key. The default implementation brings back the label to its initial state hiding the editor component.  
+
+Wicket module wicket-examples contains page class @EditableLabelPage.java@ which shows all these three components together. You can see this page in action at "http://www.wicket-library.com/wicket-examples-6.0.x/ajax/editable-label":http://www.wicket-library.com/wicket-examples-6.0.x/ajax/editable-label :
+
+!edit-label-example-screenshot.png!
+
+h3. Autocomplete text field
+
+On Internet we can find many examples of text fields that display a list of suggestions (or options) while the user types a text inside them. This feature is known as autocomplete functionality. 
+
+Wicket offers an out-of-the-box implementation of an autocomplete text field with component @org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField@. 
+
+When using AutoCompleteTextField we are required to implement its abstract method getChoices(String input) where the input parameter is the current input of the component. This method returns an iterator over the suggestions that will be displayed as a drop-down menu:
+
+!autocomplete-example-screenshot.png!
+
+Suggestions are rendered using a render which implements interface @IAutoCompleteRenderer@. The default implementation simply calls toString() on each suggestion object. If we need to work with a custom render we can specify it via component constructor.
+
+AutoCompleteTextField supports a wide range of settings that are passed to its constructor with class @AutoCompleteSettings@.
+
+One of the most interesting parameter we can specify for @AutoCompleteTextField@ is the throttle delay which is the amount of time (in milliseconds) that must elapse between a change of input value and the transmission of a new Ajax request to display suggestions. This parameter can be set with method @setThrottleDelay(int)@:
+
+{code}
+AutoCompleteSettings settings = new AutoCompleteSettings();
+//set throttle to 400 ms: component will wait 400ms before displaying the options		
+settings.setThrottleDelay(400);
+//...		
+AutoCompleteTextField field = new AutoCompleteTextField<T>("field", model) {
+
+	@Override
+	protected Iterator getChoices(String arg0) {
+		//return an iterator over the options 
+	}
+};
+{code}
+
+Wicket module wicket-examples contains page class @AutoCompletePagePage.java@ which shows an example of autocomplete text field. The running example is available at "http://www.wicket-library.com/wicket-examples-6.0.x/ajax/autocomplete":http://www.wicket-library.com/wicket-examples-6.0.x/ajax/autocomplete .
+
+h3. Modal window
+
+Class @org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow@ is an implementation of a "modal window":http://en.wikipedia.org/wiki/Modal_window based on AJAX:
+
+!modal-window-example-screenshot.png!
+
+The content of a modal window can be either another component or a page. In the first case the id of the  component used as content must be retrieved with method getContentId(). 
+
+If instead we want to use a page as window content, we must implement the inner interface @ModalWindow.PageCreator@ and pass it to method @setPageCreator@. The page used as content will be embedded in a <iframe> tag.
+
+To display a modal window we must call its method @show(AjaxRequestTarget target)@. This is  usually done inside the AJAX callback method of another component (like an @AjaxLink@). The following markup and code are taken from project @BasicModalWindowExample@ and illustrate a basic usage of a modal window:
+
+*HTML:*
+{code:html}
+<body>
+	<h2>Modal Windod example</h2>
+	<a wicket:id="openWindow">Open the window!</a>
+	<div wicket:id="modalWindow"></div>
+</body>
+{code}
+
+*Java Code:*
+{code}
+public HomePage(final PageParameters parameters) {
+   	super(parameters);
+   	final ModalWindow modalWindow = new ModalWindow("modalWindow");
+   	Label label = new Label(modalWindow.getContentId(), "I'm a modal window!");
+    	
+   	modalWindow.setContent(label);
+   	modalWindow.setTitle("Modal window");
+    	
+   	add(modalWindow);
+   	add(new AjaxLink("openWindow") {
+	  @Override
+	  public void onClick(AjaxRequestTarget target) {
+		modalWindow.show(target);				
+	  }    		
+	});
+}
+{code}
+
+Just like any other component also @ModalWindow@ must be added to a markup tag, like we did in our example using a <div> tag. Wicket will automatically hide this tag in the final markup appending the style value display:none. 
+The component provides different setter methods to customize the appearance of the window:
+
+* *setTitle(String)*: specifies the title of the window
+* *setResizable(boolean)*: by default the window is resizeable. If we need to make its size fixed we can use this method to turn off this feature.
+* *setInitialWidth(int) and setInitialHeight(int)*: set the initial dimensions of the window.
+* *setMinimalWidth(int) and setMinimalHeight(int)*: specify the minimal dimensions of the window.
+* *setCookieName(String)*: this method can be used to specify the name of the cookie used on  client side to store size and position of the window when it is closed. The component will use this cookie to restore these two parameters the next time the window will be opened. If no cookie name is provided, the component will not remember its last position and size.
+* *setCssClassName(String)*: specifies the CSS class used for the window. 
+* *setAutoSize(boolean)*: when this flag is set to true the window will automatically adjust its size to fit content width and height. By default it is false.
+
+The modal window can be closed from code using its method @close(AjaxRequestTarget target)@. The currently opened window can be closed also with the following JavaScript instruction:
+
+{code}
+Wicket.Window.get().close();
+{code}
+
+@ModalWindow@ gives the opportunity to perform custom actions when window is closing. Inner interface @ModalWindow.WindowClosedCallback@ can be implemented and passed to window's method @setWindowClosedCallback@ to specify the callback that must be executed after window has been closed:
+
+{code}
+modalWindow.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
+
+	@Override
+	public void onClose(AjaxRequestTarget target) {
+	  //custom code...
+	}			
+});
+{code}
+
+h3. Tree repeaters
+
+Class @org.apache.wicket.extensions.markup.html.repeater.tree.AbstractTree@ is the base class of another family of repeaters called tree repeaters and designed to display a data hierarchy as a tree, resembling the behavior and the look & feel of desktop tree components. A classic example of tree component on desktop is the tree used by nearly all file managers to navigate file system:
+
+!file-system-trees.png!
+
+Because of their highly interactive nature, tree repeaters are implemented as AJAX components,  meaning that they are updated via AJAX when we expand or collapse their nodes. 
+
+The basic implementation of a tree repeater shipped with Wicket is component @NestedTree@. In order to use a tree repeater we must provide an implementation of interface @ITreeProvider@ which is in charge of returning the nodes that compose the tree.  
+
+Wicket comes with a built-in implementation of ITreeProvider called TreeModelProvider that works with the same tree model and nodes used by Swing component @javax.swing.JTree@. These Swing entities should be familiar to you if you have previously worked with the old tree repeaters (components @Tree@ and @TreeTable@) that have been deprecated with Wicket 6 and that are strongly dependent on Swing-based model and nodes. @TreeModelProvider@ can be used to migrate your code to the new tree repeaters. 
+
+In the next example (project @CheckBoxAjaxTree@) we will build a tree that displays some of the main cities of three European countries: Italy, Germany and France. The cities are sub-nodes of a main node representing the relative county. The nodes of the final tree will be also selectable with a checkbox control. The whole tree will have the classic look & feel of Windows XP. This is how our tree will look like:
+
+!AJAX-tree-repeater.png!
+
+We will start to explore the code of this example from the home page. The first portion of code we will see is where we build the nodes and the @TreeModelProvider@ for the three. As tree node we will use Swing class @javax.swing.tree.DefaultMutableTreeNode@:
+
+{code}
+public class HomePage extends WebPage {
+    public HomePage(final PageParameters parameters) {
+     super(parameters);
+     DefaultMutableTreeNode root = new DefaultMutableTreeNode("Cities of Europe");
+      
+     addNodes(addNodes(root, "Italy"), "Rome", "Venice", "Milan", "Florence");
+     addNodes(addNodes(root, "Germany"),"Stuttgart","Munich", "Berlin","Dusseldorf", "Dresden");
+     addNodes(addNodes(root, "France"), "Paris","Toulouse", "Strasbourg","Bordeaux", "Lyon");
+      
+     DefaultTreeModel treeModel = new DefaultTreeModel(root);
+     TreeModelProvider<DefaultMutableTreeNode> modelProvider = new 
+                            TreeModelProvider<DefaultMutableTreeNode>( treeModel ){
+       @Override
+       public IModel<DefaultMutableTreeNode> model(DefaultMutableTreeNode object){
+          return Model.of(object);
+       }
+     };
+     //To be continued...
+{code}
+
+Nodes have been built using simple strings as data objects and invoking custom utility method addNodes which converts string parameters into children nodes for a given parent node. Once we have our tree of @DefaultMutableTreeNodes@ we can build the Swing tree model (@DefaultTreeModel@) that will be the backing object for a @TreeModelProvider@. This provider wraps each node in a model invoking its abstract method model. In our example we have used a simple @Model@ as wrapper model.
+
+Scrolling down the code we can see how the tree component is instantiated and configured before being added to the home page:
+
+{code}
+//Continued from previous snippet...
+ NestedTree<DefaultMutableTreeNode> tree = new NestedTree<DefaultMutableTreeNode>("tree", 
+                                                      modelProvider)
+  {
+
+   @Override
+   protected Component newContentComponent(String id, IModel<DefaultMutableTreeNode>model)
+   {
+     return new CheckedFolder<DefaultMutableTreeNode>(id, this, model);
+   }
+  };
+  //select Windows theme
+  tree.add(new WindowsTheme());
+  
+  add(tree);
+  }
+  //implementation of addNodes
+  //...
+}
+{code}
+
+To use tree repeaters we must implement their abstract method @newContentComponent@ which is called internally by base class @AbstractTree@ when a new node must be built. As content component we have used built-in class @CheckedFolder@ which combines a @Folder@ component with a @CheckBox@ form control. 
+
+The final step before adding the tree to its page is to apply a theme to it. Wicket comes with two behaviors, WindowsTheme and HumanTheme, which correspond to the classic Windows XP theme and to the Human theme from Ubuntu.
+
+Our checkable tree is finished but our work is not over yet because the component doesn't offer many functionalities as it is. Unfortunately neither NestedTree nor CheckedFolder provide a means for collecting checked nodes and returning them to client code. It's up to us to implement a way to keep track of checked nodes.
+
+Another nice feature we would like to implement for our tree is the following user-friendly behavior that should occur when a user checks/unchecks a node:
+
+* When a node is checked also all its children nodes (if any) must be checked. We must also ensure that all the ancestors of the checked node (root included) are checked, otherwise we would get an inconsistent selection.
+* When a node is unchecked also all its children nodes (if any) must be unchecked and we must also ensure that ancestors get unchecked if they have no more checked children.
+
+The first goal (keeping track of checked node) can be accomplished building a custom version of @CheckedFolder@ that uses a shared Java Set to store checked node and to verify if its node has been  checked. This kind of solution requires a custom model for checkbox component in order to reflect its checked status when its container node is rendered. This model must implement typed interface @IModel<Boolean>@ and must be returned by @CheckedFolder@'s method @newCheckBoxModel@.
+
+For the second goal (auto select/unselect children and ancestor nodes) we can use @CheckedFolder@'s callback method onUpdate(AjaxRequestTarget) that is invoked after a checkbox is clicked and its value has been updated. Overriding this method we can handle user click adding/removing nodes to/from the Java Set.
+
+Following this implementation plan we can start coding our custom @CheckedFolder@ (named @AutocheckedFolder@): 
+
+{code}
+public class AutocheckedFolder<T> extends CheckedFolder<T> {
+
+   private ITreeProvider<T> treeProvider;
+   private IModel<Set<T>> checkedNodes;
+   private IModel<Boolean> checkboxModel;
+   
+   public AutocheckedFolder(String id, AbstractTree<T> tree, 
+                        IModel<T> model, IModel<Set<T>> checkedNodes) {
+      super(id, tree, model);   
+      this.treeProvider = tree.getProvider();
+      this.checkedNodes = checkedNodes;            
+   }
+   
+   @Override
+   protected IModel<Boolean> newCheckBoxModel(IModel<T> model) {
+      checkboxModel =  new CheckModel();
+      return checkboxModel;
+   }
+   
+   @Override
+   protected void onUpdate(AjaxRequestTarget target) {
+      super.onUpdate(target);
+      T node = getModelObject();
+      boolean nodeChecked = checkboxModel.getObject();
+      
+      addRemoveSubNodes(node, nodeChecked);            
+      addRemoveAncestorNodes(node, nodeChecked);            
+   }
+
+  class CheckModel extends AbstractCheckBoxModel{
+      @Override
+      public boolean isSelected() {
+         return checkedNodes.getObject().contains(getModelObject());
+      }
+
+      @Override
+      public void select() {
+         checkedNodes.getObject().add(getModelObject());
+      }
+
+      @Override
+      public void unselect() {
+         checkedNodes.getObject().remove(getModelObject());
+      }				
+  }
+}
+{code}
+
+The constructor of this new component takes in input a further parameter which is the set containing checked nodes. 
+
+Class CheckModel is the custom model we have implemented for checkbox control. As base class for this model we have used @AbstractCheckBoxModel@ which is provided to implement custom models for checkbox controls. 
+
+Methods @addRemoveSubNodes@ and @addRemoveAncestorNodes@ are called to automatically add/remove children and ancestor nodes to/from the current Set. Their implementation is mainly focused on the navigation of tree nodes and it heavily depends on the internal implementation of the tree, so we won't dwell on their code.
+
+Now we are just one step away from completing our tree as we still have to find a way to update the checked status of both children and ancestors nodes on client side. Although we could easily accomplish this task by simply refreshing the whole tree via AJAX, we would like to find a better and more performant solution for this task. 
+
+When we modify the checked status of a node we don't expand/collapse any node of the three so we can simply update the desired checkboxes rather than updating the entire tree component. This alternative approach could lead to a more responsive interface and to a strong reduction of bandwidth consumption. 
+
+With the help of JQuery we can code a couple of JavaScript functions that can be used to check/ uncheck all the children and ancestors of a given node. Then, we can append these functions to the current @AjaxRequest@ at the end of method onUpdate:
+
+{code}
+   @Override
+   protected void onUpdate(AjaxRequestTarget target) {
+      super.onUpdate(target);
+      T node = getModelObject();
+      boolean nodeChecked = checkboxModel.getObject();
+      
+      addRemoveSubNodes(node, nodeChecked);            
+      addRemoveAncestorNodes(node, nodeChecked);    
+      updateNodeOnClientSide(target, nodeChecked);		
+   }
+
+   protected void updateNodeOnClientSide(AjaxRequestTarget target,
+			boolean nodeChecked) {
+      target.appendJavaScript(";CheckAncestorsAndChildren.checkChildren('" + getMarkupId() + 
+                              "'," + nodeChecked + ");");
+		
+      target.appendJavaScript(";CheckAncestorsAndChildren.checkAncestors('" + getMarkupId() + 
+                              "'," + nodeChecked + ");");
+   }
+{code}
+
+The JavaScript code can be found inside file autocheckedFolder.js which is added to the header section as package resource:
+
+{code}
+@Override
+public void renderHead(IHeaderResponse response) {
+	PackageResourceReference scriptFile = new PackageResourceReference(this.getClass(), 
+                                                      "autocheckedFolder.js");
+	response.render(JavaScriptHeaderItem.forReference(scriptFile));
+}
+{code}
+
+h3. Working with hidden components
+
+When a component is not visible its markup and the related id attribute are not rendered in the final page, hence it can not be updated via AJAX. To overcome this problem we must use Component's method @setOutputMarkupPlaceholderTag(true)@ which has the effect of rendering a hidden <span> tag containing the markup id of the hidden component: 
+
+{code}
+final Label label = new Label("labelComponent", "Initial value.");
+//make label invisible
+label.setVisible(false);
+//ensure that label will leave a placeholder for its markup id
+label.setOutputMarkupPlaceholderTag(true);
+add(label);
+//...
+new AjaxLink("ajaxLink"){
+	@Override
+	public void onClick(AjaxRequestTarget target) {
+	    //turn label to visible
+	    label.setVisible(true);
+	    target.add(label);
+	}  	
+};
+{code}
+
+Please note that in the code above we didn't invoked method @setOutputMarkupId(true)@ as @setOutputMarkupPlaceholderTag@ already does it internally.