[Struts Wiki] Update of "StrutsUpgradeNotes12to13" by NiallPemberton
Dear Wiki user, You have subscribed to a wiki page or wiki category on "Struts Wiki" for change notification. The following page has been changed by NiallPemberton: http://wiki.apache.org/struts/StrutsUpgradeNotes12to13 The comment on the change is: Change notes to reference Validator 1.3.0 -- [http://jakarta.apache.org/commons/fileupload/ Commons FileUpload] version 1.1 (previously was version 1.0). As well as needing to upgrade the !FileUpload jar you will now also need the [http://jakarta.apache.org/commons/io/ Commons IO] Version 1.1 jar. - === 3.3 Commons Validator 1.2.0 === + === 3.3 Commons Validator 1.3.0 === Struts 1.3 now depends on - [http://jakarta.apache.org/commons/validator/ Commons Validator] version 1.2.0 (previous was version 1.1.4) - remember to upgrade the Validator jar. + [http://jakarta.apache.org/commons/validator/ Commons Validator] version 1.3.0 (previous was version 1.1.4) - remember to upgrade the Validator jar. - * Validator 1.2 will recognize config files from prior versions. Optionally, you may + * Validator 1.3.0 will recognize config files from prior versions. Optionally, you may - * Change the doctype declaration at the top of validation.xml to refer to the dtd for version 1.2 + * Change the doctype declaration at the top of validation.xml to refer to the dtd for version 1.3.0 {{{ http://jakarta.apache.org/commons/dtds/validator_1_2_0.dtd";> + "http://jakarta.apache.org/commons/dtds/validator_1_3_0.dtd";> }}} * If you change the doctype you will have to change the deprecated ''arg0-arg3'' elements to ''arg'' elements. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[Struts Wiki] Update of "StrutsUpgradeNotes12to13" by NiallPemberton
Dear Wiki user, You have subscribed to a wiki page or wiki category on "Struts Wiki" for change notification. The following page has been changed by NiallPemberton: http://wiki.apache.org/struts/StrutsUpgradeNotes12to13 The comment on the change is: Add notes about dependencies -- * struts-el-1.3.x.jar (in addition to struts-taglib) if you want to use the JSTL expression language * struts-tiles-1.3.x.jar (if you want to use Tiles) + == 3. Dependencies == + A number of dependencies have changed from Struts 1.2.x + + === 3.1 Chain 1.0 === + Struts 1.3 introduces a new dependency on + [http://jakarta.apache.org/commons/chain/ Commons Chain] version 1.0. - remember to deploy the Chain jar + + === 3.2 File Upload 1.1 === + Struts 1.3 now depends on + [http://jakarta.apache.org/commons/fileupload/ Commons FileUpload] version 1.1 (previously was version 1.0). As well as needing to upgrade the !FileUpload jar you will now also need the + [http://jakarta.apache.org/commons/io/ Commons IO] Version 1.1 jar. + + === 3.3 Commons Validator 1.2.0 === + Struts 1.3 now depends on + [http://jakarta.apache.org/commons/validator/ Commons Validator] version 1.2.0 (previous was version 1.1.4) - remember to upgrade the Validator jar. + + * Validator 1.2 will recognize config files from prior versions. Optionally, you may + + * Change the doctype declaration at the top of validation.xml to refer to the dtd for version 1.2 + + {{{ + http://jakarta.apache.org/commons/dtds/validator_1_2_0.dtd";> + }}} + +* You must upgrade to the new version of validator-rules.xml. This file is included in struts-action.jar, so the easiest way to upgrade is to delete any copies you may have in your application and use the following Validator Plugin configuration: + + {{{ + + + + }}} + + === 3.4 CGLib 2.1_3 === + Struts 1.3 introduces a new dependency on + [http://cglib.sourceforge.net/ CGLib] version 2.1_3 - you should only need to deploy the CGLib jar if you use the new 'enhanced' feature for dyna forms. + + {{{ + + + + }}} + - == 3. Configuration == + == 4. Configuration == The ''default'' Request Processor for Struts 1.3 is the new Chain (CoR) based ''ComposableRequestProcessor''. - === 3.1 CoR Request Processor === + === 4.1 CoR Request Processor === By default, the ComposableRequestProcessor will use a configuration file included in the struts-core JAR, and you won't need to do anything. However, if you want to use Tiles, you must instruct Struts to use a configuration file included in the struts-tiles JAR instead. To do this: @@ -34, +81 @@ You can do much more to configure the ComposableRequestProcessor, but those details are outside the scope of this document. - === 3.2 Original Request Processors === + === 4.2 Original Request Processors === If you want to continue using either of the existing Request Processors (i.e. RequestProcessor or TilesRequestProcessor) then you need to specify this in the controller element of the ''struts-config.xml'' @@ -42, +89 @@ }}} - === 3.3 Commons Validator === + == 5 Deprecations which have been removed == - * Validator 1.2 will recognize config files from prior versions. Optionally, you may - - * Change the doctype declaration at the top of validation.xml to refer to the dtd for version 1.2 - - {{{ - http://jakarta.apache.org/commons/dtds/validator_1_2_0.dtd";> - }}} - -* Upgrade to the new version of validator-rules.xml. This file is included in struts-action.jar, so the easiest way to upgrade is to delete any copies you may have in your application and use the following Validator Plugin configuration: - - {{{ - - - - }}} - - == 4 Deprecations which have been removed == - - === 4.1 struts-config_1_3.dtd === + === 5.1 struts-config_1_3.dtd === Removed the contextRelative attribute of the forward element. - === 4.2 Classes === + === 5.2 Classes === ActionError has been removed. Use ActionMessage instead. - === 4.3 Methods and properties === + === 5.3 Methods and properties === ||Class||Member||Comments|| ||Action||defaultLocale||Use Locale.getDefault directly.|| ||Action||saveErrors(HttpServletRequest request, ActionErrors errors)||Use saveErrors(HttpServletRequest, ActionMessages) instead.|| @@ -109, +133 @@ ||TagUtils (Taglib)||getActionErrors()||use getActionMessages() instead.|| ||TagUtils (Tiles)||getProperty()||Use PropertyUtils.getProperty() directly.|| - === 4.4 TLD URLs === + === 5.4 TLD URLs === The struts-taglib and struts-tiles distributions no longer include TLDs which are configured with the old URIs under the ''jakarta.apache.org'' domain name. You must make the following changes: @@ -120, +144 @@ ||http://jakarta.apache.org/struts/tags-nested||http://struts.apache.org/tags-nested|| ||http://jakarta
Re: Preferred way to use Tiles with Struts 1.3 (Re: [Struts Wiki] Update of "StrutsUpgradeNotes12to13" by NiallPemberton)
Perhaps I'm missing something, but I don't think moving initialisation into the *request processor* is tidy at all. Initialisation should happen before any requests come in. Well, it would, in the sense that RequestProcessor has a "init" method. We're not talking about totally lazy initialization here, just whether the ActionServlet should have any concern for initializing commons-chain behavior if the only component which uses commons-chain is the ComposableRequestProcessor I do believe that we should be splitting out the whole config / init mechanism so that we can provide alternative ways of doing that. That's something that's been on my personal to-do list for some time, but hasn't bubbled to the top yet. +1 - all that config doesn't belong in ActionServlet as it is now. but it's not my top priority either. > More immediately, though, whether we change it or move it into the default RequestProcessor, I have no problem with having it check first for the presence of the tiles version of the chain config and then for the default; since it's just a String value (for the classpath URI), it's not a true dependency, and I think the value for users would be considerable. Does anyone object to testing for the tiles config first? And does anyone have any strong feelings about where the chain initialization code lives? I do, I guess. The goal should be *no* knowledge of Tiles outside of Tiles itself. If we can't do that, then we're not properly extensible. I know we're not there yet, but testing for Tiles first is a step in the opposite direction, IMO. Fair enough. It's not like we can't express in extremely simple terms how to set up Struts to use the tiles version of chain-config.xml -- I think packaging it in the struts-tiles.jar is good-enough for user friendliness. Joe -- Joe Germuska [EMAIL PROTECTED] http://blog.germuska.com "Narrow minds are weapons made for mass destruction" -The Ex - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Preferred way to use Tiles with Struts 1.3 (Re: [Struts Wiki] Update of "StrutsUpgradeNotes12to13" by NiallPemberton)
On 4/27/05, Joe Germuska <[EMAIL PROTECTED]> wrote: > At 5:46 PM +0100 4/27/05, Niall Pemberton wrote: > >Sounds good to me. > > > >I've realized the wiki is incorrect - since if you don't specify a > >"chainConfig" parameter then it uses the default one shipped. Maybe we can > >make it all automatic if no chainConfig is specified. - if theres a tiles > >chain config present (i.e. they ship the tiles jar) then use that one, > >otherwise the default? > > Two independent things: first, the bigger one: I'm not that excited > about the current bootstrapping mechanism for the chain. It doesn't > play well with the possibility that you don't want to use Digester to > create your CatalogFactory; maybe we should shift the responsibility > for initializing the chains into the RequestProcessor instead -- that > provides a very tidy place to drop in instead a > "SpringComposableRequestProcessor" which could retrieve its > CatalogFactory from a Spring ApplicationContext instead of digester > -- which provides a good way to provide collaborators to individual > chain commands. Perhaps I'm missing something, but I don't think moving initialisation into the *request processor* is tidy at all. Initialisation should happen before any requests come in. I do believe that we should be splitting out the whole config / init mechanism so that we can provide alternative ways of doing that. That's something that's been on my personal to-do list for some time, but hasn't bubbled to the top yet. > More immediately, though, whether we change it or move it into the > default RequestProcessor, I have no problem with having it check > first for the presence of the tiles version of the chain config and > then for the default; since it's just a String value (for the > classpath URI), it's not a true dependency, and I think the value for > users would be considerable. > > Does anyone object to testing for the tiles config first? And does > anyone have any strong feelings about where the chain initialization > code lives? I do, I guess. The goal should be *no* knowledge of Tiles outside of Tiles itself. If we can't do that, then we're not properly extensible. I know we're not there yet, but testing for Tiles first is a step in the opposite direction, IMO. -- Martin Cooper > Joe > > > >Niall > > > >- Original Message - > >From: "Joe Germuska" <[EMAIL PROTECTED]> > >Sent: Wednesday, April 27, 2005 5:22 PM > > > > > >> Niall, and everyone else:: > >> > >> This update made me realize that I still haven't gotten an answer > >> about what happened to the "Tiles" chain-config, and made me also > >> realize that for typical users, we can and should make this easier > >> than as Niall described it. > >> > >> I believe we should keep a chain-config.xml in the tiles JAR which is > >> all people need, so that they can simply specify an alternate chain > >> config with no editing. I will create and add this. Note that we'll > >> have a little extra burden to make sure it maintains synch with the > >> version in struts-core, but I think that's reasonable; I don't think > >> people should have to muck around to extract and edit an XML file > >> just to use Tiles. (Of course, I can't imagine writing an app where > >> I'm not mucking around with a customized chain-config.xml any more > >> anyway, but still, we should keep from making that a requirement for > >> people.) > > > > > > > >- > >To unsubscribe, e-mail: [EMAIL PROTECTED] > >For additional commands, e-mail: [EMAIL PROTECTED] > > -- > Joe Germuska > [EMAIL PROTECTED] > http://blog.germuska.com > "Narrow minds are weapons made for mass destruction" -The Ex > > - > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Preferred way to use Tiles with Struts 1.3 (Re: [Struts Wiki] Update of "StrutsUpgradeNotes12to13" by NiallPemberton)
At 8:52 PM +0100 4/27/05, Niall Pemberton wrote: - Original Message - From: "Joe Germuska" <[EMAIL PROTECTED]> Sent: Wednesday, April 27, 2005 8:20 PM Two independent things: first, the bigger one: I'm not that excited about the current bootstrapping mechanism for the chain. It doesn't play well with the possibility that you don't want to use Digester to create your CatalogFactory; maybe we should shift the responsibility for initializing the chains into the RequestProcessor instead -- that provides a very tidy place to drop in instead a "SpringComposableRequestProcessor" which could retrieve its CatalogFactory from a Spring ApplicationContext instead of digester -- which provides a good way to provide collaborators to individual chain commands. Having it in the RequestProcessor is probably more consistent - since thats where the RequestProcessor class is controlled/configured - makes sense to have the ComposableRequestProcessor's chain also configured there if the chain config is also specified there. So, I looked at this tonight, and unfortunately it's kind of tangled. I still think it's a good path, but I won't have time to do it right for a while -- I thought I'd mention some of what I saw in case anyone wants to run with it. It's not simple to move initChain to RequestProcessor because it depends on a method in ActionServlet which converts a list of paths into URLs which can be used to read config files. This would be a nice method to move out into a util class (I was thinking maybe ModuleUtils). That's trickier, then, to handle the exceptions correctly -- the util version probably shouldn't throw ServletException, so the question of how it should handle problems -- if it just throws MalformedURLException and IOException then we lose the information about which specific path has an error... And then also, the splitAndResolvePaths method throws an exception when it doesn't find a path, which makes it harder to do the specific task mentioned here -- test for the presence of the tiles version of chain-config.xml and then fall back to the default one. I am going to make a small tweak to expose the CatalogFactory which the RequestProcessor uses, to make it more plausible to set it using dependency injection instead of being bound to the static method on CatalogFactory, because that's an easy one ;-) Joe -- Joe Germuska [EMAIL PROTECTED] http://blog.germuska.com "Narrow minds are weapons made for mass destruction" -The Ex - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Preferred way to use Tiles with Struts 1.3 (Re: [Struts Wiki] Update of "StrutsUpgradeNotes12to13" by NiallPemberton)
- Original Message - From: "Joe Germuska" <[EMAIL PROTECTED]> Sent: Wednesday, April 27, 2005 8:20 PM > Two independent things: first, the bigger one: I'm not that excited > about the current bootstrapping mechanism for the chain. It doesn't > play well with the possibility that you don't want to use Digester to > create your CatalogFactory; maybe we should shift the responsibility > for initializing the chains into the RequestProcessor instead -- that > provides a very tidy place to drop in instead a > "SpringComposableRequestProcessor" which could retrieve its > CatalogFactory from a Spring ApplicationContext instead of digester > -- which provides a good way to provide collaborators to individual > chain commands. Having it in the RequestProcessor is probably more consistent - since thats where the RequestProcessor class is controlled/configured - makes sense to have the ComposableRequestProcessor's chain also configured there if the chain config is also specified there. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Preferred way to use Tiles with Struts 1.3 (Re: [Struts Wiki] Update of "StrutsUpgradeNotes12to13" by NiallPemberton)
At 5:46 PM +0100 4/27/05, Niall Pemberton wrote: Sounds good to me. I've realized the wiki is incorrect - since if you don't specify a "chainConfig" parameter then it uses the default one shipped. Maybe we can make it all automatic if no chainConfig is specified. - if theres a tiles chain config present (i.e. they ship the tiles jar) then use that one, otherwise the default? Two independent things: first, the bigger one: I'm not that excited about the current bootstrapping mechanism for the chain. It doesn't play well with the possibility that you don't want to use Digester to create your CatalogFactory; maybe we should shift the responsibility for initializing the chains into the RequestProcessor instead -- that provides a very tidy place to drop in instead a "SpringComposableRequestProcessor" which could retrieve its CatalogFactory from a Spring ApplicationContext instead of digester -- which provides a good way to provide collaborators to individual chain commands. More immediately, though, whether we change it or move it into the default RequestProcessor, I have no problem with having it check first for the presence of the tiles version of the chain config and then for the default; since it's just a String value (for the classpath URI), it's not a true dependency, and I think the value for users would be considerable. Does anyone object to testing for the tiles config first? And does anyone have any strong feelings about where the chain initialization code lives? Joe Niall - Original Message - From: "Joe Germuska" <[EMAIL PROTECTED]> Sent: Wednesday, April 27, 2005 5:22 PM Niall, and everyone else:: This update made me realize that I still haven't gotten an answer about what happened to the "Tiles" chain-config, and made me also realize that for typical users, we can and should make this easier than as Niall described it. I believe we should keep a chain-config.xml in the tiles JAR which is all people need, so that they can simply specify an alternate chain config with no editing. I will create and add this. Note that we'll have a little extra burden to make sure it maintains synch with the version in struts-core, but I think that's reasonable; I don't think people should have to muck around to extract and edit an XML file just to use Tiles. (Of course, I can't imagine writing an app where I'm not mucking around with a customized chain-config.xml any more anyway, but still, we should keep from making that a requirement for people.) - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] -- Joe Germuska [EMAIL PROTECTED] http://blog.germuska.com "Narrow minds are weapons made for mass destruction" -The Ex - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Preferred way to use Tiles with Struts 1.3 (Re: [Struts Wiki] Update of "StrutsUpgradeNotes12to13" by NiallPemberton)
Sounds good to me. I've realized the wiki is incorrect - since if you don't specify a "chainConfig" parameter then it uses the default one shipped. Maybe we can make it all automatic if no chainConfig is specified. - if theres a tiles chain config present (i.e. they ship the tiles jar) then use that one, otherwise the default? Niall - Original Message - From: "Joe Germuska" <[EMAIL PROTECTED]> Sent: Wednesday, April 27, 2005 5:22 PM > Niall, and everyone else:: > > This update made me realize that I still haven't gotten an answer > about what happened to the "Tiles" chain-config, and made me also > realize that for typical users, we can and should make this easier > than as Niall described it. > > I believe we should keep a chain-config.xml in the tiles JAR which is > all people need, so that they can simply specify an alternate chain > config with no editing. I will create and add this. Note that we'll > have a little extra burden to make sure it maintains synch with the > version in struts-core, but I think that's reasonable; I don't think > people should have to muck around to extract and edit an XML file > just to use Tiles. (Of course, I can't imagine writing an app where > I'm not mucking around with a customized chain-config.xml any more > anyway, but still, we should keep from making that a requirement for > people.) - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Preferred way to use Tiles with Struts 1.3 (Re: [Struts Wiki] Update of "StrutsUpgradeNotes12to13" by NiallPemberton)
Niall, and everyone else:: This update made me realize that I still haven't gotten an answer about what happened to the "Tiles" chain-config, and made me also realize that for typical users, we can and should make this easier than as Niall described it. I believe we should keep a chain-config.xml in the tiles JAR which is all people need, so that they can simply specify an alternate chain config with no editing. I will create and add this. Note that we'll have a little extra burden to make sure it maintains synch with the version in struts-core, but I think that's reasonable; I don't think people should have to muck around to extract and edit an XML file just to use Tiles. (Of course, I can't imagine writing an app where I'm not mucking around with a customized chain-config.xml any more anyway, but still, we should keep from making that a requirement for people.) I'll make these changes soon, but I thought the entire intention might not be clear just from a Wiki update message. Joe At 3:58 PM + 4/27/05, Apache Wiki wrote: Dear Wiki user, You have subscribed to a wiki page or wiki category on "Struts Wiki" for change notification. The following page has been changed by NiallPemberton: http://wiki.apache.org/struts/StrutsUpgradeNotes12to13 -- In order to configure the ComposbaleRequestProcessor you need to do the following: * Add a '''chainConfig''' ''init-param'' in the web.xml pointing to the location of the ''chain-config.xml'' + + {{{ + + chainConfig + /WEB-INF/chain-config.xml + + }}} + - * If you want to use '''Tiles''' then you need to 'un-comment' out the ''tiles command'' (i.e. TilesPreProcessor) in the chain-config.xml (and make sure you deploy the tiles jar). + * If you want to use '''Tiles''' then you need to 'un-comment' out the ''tiles command'' in the chain-config.xml (and make sure you deploy the tiles jar). + {{{ + + }}} + * Deploy the ''Chain'' configuration file: ''chain-config.xml'' === 3.2 Original Request Processors === - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] -- Joe Germuska [EMAIL PROTECTED] http://blog.germuska.com "Narrow minds are weapons made for mass destruction" -The Ex - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[Struts Wiki] Update of "StrutsUpgradeNotes12to13" by NiallPemberton
Dear Wiki user, You have subscribed to a wiki page or wiki category on "Struts Wiki" for change notification. The following page has been changed by NiallPemberton: http://wiki.apache.org/struts/StrutsUpgradeNotes12to13 -- In order to configure the ComposbaleRequestProcessor you need to do the following: * Add a '''chainConfig''' ''init-param'' in the web.xml pointing to the location of the ''chain-config.xml'' + + {{{ + + chainConfig + /WEB-INF/chain-config.xml + + }}} + - * If you want to use '''Tiles''' then you need to 'un-comment' out the ''tiles command'' (i.e. TilesPreProcessor) in the chain-config.xml (and make sure you deploy the tiles jar). + * If you want to use '''Tiles''' then you need to 'un-comment' out the ''tiles command'' in the chain-config.xml (and make sure you deploy the tiles jar). + {{{ + + }}} + * Deploy the ''Chain'' configuration file: ''chain-config.xml'' === 3.2 Original Request Processors === - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
[Struts Wiki] Update of "StrutsUpgradeNotes12to13" by NiallPemberton
Dear Wiki user, You have subscribed to a wiki page or wiki category on "Struts Wiki" for change notification. The following page has been changed by NiallPemberton: http://wiki.apache.org/struts/StrutsUpgradeNotes12to13 -- Struts 1.3 is intended to be backwards compatible with Struts 1.2.x; however, it will not be a 100% drop-in replacement. Here are things to note when you are upgrading to Struts 1.3 - == Move to Servlet 2.3/JSP 1.2 baseline == + == 1. Move to Servlet 2.3/JSP 1.2 baseline == Beginning with Struts 1.3, Struts no longer guarantees support for Servlet 2.2 or JSP 1.1. - == Packaging == + == 2 .Packaging == While previously Struts was distributed as a "monolithic" jar, beginning with the 1.3.0 release, many things which were formerly in the "core" have been split out into their own distributions. You will always need "struts-core-1.3.x.jar", and you may need one or more of the following: - * struts-taglib-1.3.x.jar (if you want to use the JSP tag libraries, except for the Tiles tag library) + * struts-taglib-1.3.x.jar (if you want to use the JSP tag libraries, except for the Tiles tag library) - * struts-el-1.3.x.jar (in addition to struts-taglib) if you want to use the JSTL expression language + * struts-el-1.3.x.jar (in addition to struts-taglib) if you want to use the JSTL expression language - * struts-tiles-1.3.x.jar (if you want to use Tiles) + * struts-tiles-1.3.x.jar (if you want to use Tiles) + == 3. Configuration == + + The ''default'' Request Processor for Struts 1.3 is the new Chain (CoR) based ''ComposableRequestProcessor''. + + === 3.1 CoR Request Processor === + In order to configure the ComposbaleRequestProcessor you need to do the following: + + * Add a '''chainConfig''' ''init-param'' in the web.xml pointing to the location of the ''chain-config.xml'' + * If you want to use '''Tiles''' then you need to 'un-comment' out the ''tiles command'' (i.e. TilesPreProcessor) in the chain-config.xml (and make sure you deploy the tiles jar). + * Deploy the ''Chain'' configuration file: ''chain-config.xml'' + + === 3.2 Original Request Processors === + + If you want to continue using either of the existing Request Processors (i.e. RequestProcessor or TilesRequestProcessor) then you need to specify this in the controller element of the ''struts-config.xml'' + + {{{ + + }}} + + (please add notes here as you gain experience with this migration) - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]