diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 7a4a3ea..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed 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.
\ No newline at end of file
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index 8ec56a5..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,5 +0,0 @@
-Apache Cordova
-Copyright 2012 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
diff --git a/README.md b/README.md
index b14b35b..e83d0cc 100644
--- a/README.md
+++ b/README.md
@@ -20,3 +20,5 @@
 # org.apache.cordova.globalization
 
 Plugin documentation: [doc/index.md](doc/index.md)
+
+This is `dev` - the deprecated development branch of this plugin; development of this plugin has moved to the `master` branch
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
deleted file mode 100644
index 07a092c..0000000
--- a/RELEASENOTES.md
+++ /dev/null
@@ -1,49 +0,0 @@
-<!--
-#
-# 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.
-#
--->
-# Release Notes
-
-### 0.2.2 (Sept 25, 2013)
-* CB-4889 bumping&resetting version
-* CB-4889 renaming org.apache.cordova.core.globalization to org.apache.cordova.globalization
-* Rename CHANGELOG.md -> RELEASENOTES.md
-* [CB-4752] Incremented plugin version on dev branch.
-
- ### 0.2.3 (Oct 28, 2013)
-* CB-5128: added repo + issue tag to plugin.xml for globalization plugin
-* [CB-4915] Incremented plugin version on dev branch.
-
-### 0.2.4 (Dec 4, 2013)
-* [ubuntu] add missing file
-* add ubuntu platform
-* Added amazon-fireos platform. Change to use amazon-fireos as a platform if the user agent string contains 'cordova-amazon-fireos'
-
-### 0.2.5 (Jan 02, 2014)
-* CB-5658 Add doc/index.md for Globalization plugin
-
-### 0.2.6 (Feb 05, 2014)
-* Add Tizen plugin support
-
-### 0.2.7 (Apr 17, 2014)
-* CB-4908: [android] Long.valueOf(0) instead of new Long(0)
-* CB-6212: [iOS] fix warnings compiled under arm64 64-bit
-* CB-6460: Update license headers
-* CB-6465: Add license headers to Tizen code
-* Add NOTICE file
diff --git a/doc/index.md b/doc/index.md
deleted file mode 100644
index 74bf9ee..0000000
--- a/doc/index.md
+++ /dev/null
@@ -1,698 +0,0 @@
-<!---
-    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.
--->
-
-# org.apache.cordova.globalization
-
-This plugin obtains information and performs operations specific to the user's
-locale and timezone.
-
-## Installation
-
-    cordova plugin add org.apache.cordova.globalization
-
-## Objects
-
-- GlobalizationError
-
-## Methods
-
-- navigator.globalization.getPreferredLanguage
-- navigator.globalization.getLocaleName
-- navigator.globalization.dateToString
-- navigator.globalization.stringToDate
-- navigator.globalization.getDatePattern
-- navigator.globalization.getDateNames
-- navigator.globalization.isDayLightSavingsTime
-- navigator.globalization.getFirstDayOfWeek
-- navigator.globalization.numberToString
-- navigator.globalization.stringToNumber
-- navigator.globalization.getNumberPattern
-- navigator.globalization.getCurrencyPattern
-
-
-## navigator.globalization.dateToString
-
-Returns a date formatted as a string according to the client's locale and timezone.
-
-    navigator.globalization.dateToString(date, successCallback, errorCallback, options);
-
-### Description
-
-Returns the formatted date `String` via a `value` property accessible
-from the object passed as a parameter to the `successCallback`.
-
-The inbound `date` parameter should be of type `Date`.
-
-If there is an error formatting the date, then the `errorCallback`
-executes with a `GlobalizationError` object as a parameter. The
-error's expected code is `GlobalizationError.FORMATTING\_ERROR`.
-
-The `options` parameter is optional, and its default values are:
-
-    {formatLength:'short', selector:'date and time'}
-
-The `options.formatLength` can be `short`, `medium`, `long`, or `full`.
-
-The `options.selector` can be `date`, `time` or `date and time`.
-
-### Supported Platforms
-
-- Amazon Fire OS
-- Android
-- iOS
-- Windows Phone 8
-
-### Example
-
-If the browser is set to the `en\_US` locale, this displays a popup
-dialog with text similar to `date: 9/25/2012 4:21PM` using the default
-options:
-
-    navigator.globalization.dateToString(
-        new Date(),
-        function (date) { alert('date: ' + date.value + '\n'); },
-        function () { alert('Error getting dateString\n'); },
-        { formatLength: 'short', selector: 'date and time' }
-    );
-
-### Windows Phone 8 Quirks
-
-- The `formatLength` option supports only `short` and `full` values.
-
-## navigator.globalization.getCurrencyPattern
-
-Returns a pattern string to format and parse currency values according
-to the client's user preferences and ISO 4217 currency code.
-
-     navigator.globalization.getCurrencyPattern(currencyCode, successCallback, errorCallback);
-
-### Description
-
-Returns the pattern to the `successCallback` with a `properties` object
-as a parameter. That object should contain the following properties:
-
-- __pattern__: The currency pattern to format and parse currency values.  The patterns follow [Unicode Technical Standard #35](http://unicode.org/reports/tr35/tr35-4.html). _(String)_
-
-- __code__: The ISO 4217 currency code for the pattern. _(String)_
-
-- __fraction__: The number of fractional digits to use when parsing and formatting currency. _(Number)_
-
-- __rounding__: The rounding increment to use when parsing and formatting. _(Number)_
-
-- __decimal__: The decimal symbol to use for parsing and formatting. _(String)_
-
-- __grouping__: The grouping symbol to use for parsing and formatting. _(String)_
-
-The inbound `currencyCode` parameter should be a `String` of one of
-the ISO 4217 currency codes, for example 'USD'.
-
-If there is an error obtaining the pattern, then the `errorCallback`
-executes with a `GlobalizationError` object as a parameter. The
-error's expected code is `GlobalizationError.FORMATTING\_ERROR`.
-
-### Supported Platforms
-
-- Amazon Fire OS
-- Android
-- iOS
-
-### Example
-
-When the browser is set to the `en\_US` locale and the selected
-currency is United States Dollars, this example displays a popup
-dialog with text similar to the results that follow:
-
-    navigator.globalization.getCurrencyPattern(
-        'USD',
-        function (pattern) {
-            alert('pattern: '  + pattern.pattern  + '\n' +
-                  'code: '     + pattern.code     + '\n' +
-                  'fraction: ' + pattern.fraction + '\n' +
-                  'rounding: ' + pattern.rounding + '\n' +
-                  'decimal: '  + pattern.decimal  + '\n' +
-                  'grouping: ' + pattern.grouping);
-        },
-        function () { alert('Error getting pattern\n'); }
-    );
-
-Expected result:
-
-    pattern: $#,##0.##;($#,##0.##)
-    code: USD
-    fraction: 2
-    rounding: 0
-    decimal: .
-    grouping: ,
-
-
-## navigator.globalization.getDateNames
-
-Returns an array of the names of the months or days of the week,
-depending on the client's user preferences and calendar.
-
-    navigator.globalization.getDateNames(successCallback, errorCallback, options);
-
-### Description
-
-Returns the array of names to the `successCallback` with a
-`properties` object as a parameter. That object contains a `value`
-property with an `Array` of `String` values. The array features names
-starting from either the first month in the year or the first day of
-the week, depending on the option selected.
-
-If there is an error obtaining the names, then the `errorCallback`
-executes with a `GlobalizationError` object as a parameter. The
-error's expected code is `GlobalizationError.UNKNOWN\_ERROR`.
-
-The `options` parameter is optional, and its default values are:
-
-    {type:'wide', item:'months'}
-
-The value of `options.type` can be `narrow` or `wide`.
-
-The value of `options.item` can be `months` or `days`.
-
-### Supported Platforms
-
-- Amazon Fire OS
-- Android
-- iOS
-- Windows Phone 8
-
-### Example
-
-When the browser is set to the `en\_US` locale, this example displays
-a series of twelve popup dialogs, one per month, with text similar to
-`month: January`:
-
-    navigator.globalization.getDateNames(
-        function (names) {
-            for (var i = 0; i < names.value.length; i++) {
-                alert('month: ' + names.value[i] + '\n');
-            }
-        },
-        function () { alert('Error getting names\n'); },
-        { type: 'wide', item: 'months' }
-    );
-
-
-## navigator.globalization.getDatePattern
-
-Returns a pattern string to format and parse dates according to the
-client's user preferences.
-
-    navigator.globalization.getDatePattern(successCallback, errorCallback, options);
-
-### Description
-
-Returns the pattern to the `successCallback`. The object passed in as
-a parameter contains the following properties:
-
-- __pattern__: The date and time pattern to format and parse dates. The patterns follow [Unicode Technical Standard #35](http://unicode.org/reports/tr35/tr35-4.html). _(String)_
-
-- __timezone__: The abbreviated name of the time zone on the client. _(String)_
-
-- __utc\_offset__: The current difference in seconds between the client's time zone and coordinated universal time. _(Number)_
-
-- __dst\_offset__: The current daylight saving time offset in seconds between the client's non-daylight saving's time zone and the client's daylight saving's time zone. _(Number)_
-
-If there is an error obtaining the pattern, the `errorCallback`
-executes with a `GlobalizationError` object as a parameter. The
-error's expected code is `GlobalizationError.PATTERN\_ERROR`.
-
-The `options` parameter is optional, and defaults to the following values:
-
-    {formatLength:'short', selector:'date and time'}
-
-The `options.formatLength` can be `short`, `medium`, `long`, or
-`full`.  The `options.selector` can be `date`, `time` or `date and
-time`.
-
-### Supported Platforms
-
-- Amazon Fire OS
-- Android
-- iOS
-- Windows Phone 8
-
-### Example
-
-When the browser is set to the `en\_US` locale, this example displays
-a popup dialog with text such as `pattern: M/d/yyyy h:mm a`:
-
-    function checkDatePattern() {
-        navigator.globalization.getDatePattern(
-            function (date) { alert('pattern: ' + date.pattern + '\n'); },
-            function () { alert('Error getting pattern\n'); },
-            { formatLength: 'short', selector: 'date and time' }
-        );
-    }
-
-### Windows Phone 8 Quirks
-
-- The `formatLength` supports only `short` and `full` values.
-
-- The `pattern` for `date and time` pattern returns only full datetime format.
-
-- The `timezone` returns the full time zone name.
-
-- The `dst_offset` property is not supported, and always returns zero.
-
-
-## navigator.globalization.getFirstDayOfWeek
-
-Returns the first day of the week according to the client's user
-preferences and calendar.
-
-    navigator.globalization.getFirstDayOfWeek(successCallback, errorCallback);
-
-### Description
-
-The days of the week are numbered starting from 1, where 1 is assumed
-to be Sunday.  Returns the day to the `successCallback` with a
-`properties` object as a parameter. That object should have a `value`
-property with a `Number` value.
-
-If there is an error obtaining the pattern, then the `errorCallback`
-executes with a `GlobalizationError` object as a parameter. The
-error's expected code is `GlobalizationError.UNKNOWN\_ERROR`.
-
-### Supported Platforms
-
-- Amazon Fire OS
-- Android
-- iOS
-- Windows Phone 8
-
-### Example
-
-When the browser is set to the `en\_US` locale, this displays a
-popup dialog with text similar to `day: 1`.
-
-    navigator.globalization.getFirstDayOfWeek(
-        function (day) {alert('day: ' + day.value + '\n');},
-        function () {alert('Error getting day\n');}
-    );
-
-
-Get the string identifier for the client's current locale setting.
-
-    navigator.globalization.getLocaleName(successCallback, errorCallback);
-
-### Description
-
-Returns the locale identifier string to the `successCallback` with a
-`properties` object as a parameter. That object should have a `value`
-property with a `String` value.
-
-If there is an error getting the locale, then the `errorCallback`
-executes with a `GlobalizationError` object as a parameter. The
-error's expected code is `GlobalizationError.UNKNOWN\_ERROR`.
-
-### Supported Platforms
-
-- Amazon Fire OS
-- Android
-- iOS
-- Windows Phone 8
-
-### Example
-
-When the browser is set to the `en\_US` locale, this displays a popup
-dialog with the text `locale: en\_US`.
-
-    navigator.globalization.getLocaleName(
-        function (locale) {alert('locale: ' + locale.value + '\n');},
-        function () {alert('Error getting locale\n');}
-    );
-
-
-### Windows Phone 8 Quirks
-
-- Returns the two-letter code defined in ISO 3166 for the current country/region.
-
-## navigator.globalization.getNumberPattern
-
-Returns a pattern string to format and parse numbers according to the client's user preferences.
-
-    navigator.globalization.getNumberPattern(successCallback, errorCallback, options);
-
-### Description
-
-Returns the pattern to the `successCallback` with a `properties` object
-as a parameter. That object contains the following properties:
-
-- __pattern__: The number pattern to format and parse numbers.  The patterns follow [Unicode Technical Standard #35](http://unicode.org/reports/tr35/tr35-4.html). _(String)_
-
-- __symbol__: The symbol to use when formatting and parsing, such as a percent or currency symbol. _(String)_
-
-- __fraction__: The number of fractional digits to use when parsing and formatting numbers. _(Number)_
-
-- __rounding__: The rounding increment to use when parsing and formatting. _(Number)_
-
-- __positive__: The symbol to use for positive numbers when parsing and formatting. _(String)_
-
-- __negative__: The symbol to use for negative numbers when parsing and formatting. _(String)_
-
-- __decimal__: The decimal symbol to use for parsing and formatting. _(String)_
-
-- __grouping__: The grouping symbol to use for parsing and formatting. _(String)_
-
-If there is an error obtaining the pattern, then the `errorCallback`
-executes with a `GlobalizationError` object as a parameter. The
-error's expected code is `GlobalizationError.PATTERN\_ERROR`.
-
-The `options` parameter is optional, and default values are:
-
-    {type:'decimal'}
-
-The `options.type` can be `decimal`, `percent`, or `currency`.
-
-### Supported Platforms
-
-- Amazon Fire OS
-- Android
-- iOS
-- Windows Phone 8
-
-### Example
-
-When the browser is set to the `en\_US` locale, this should display a
-popup dialog with text similar to the results that follow:
-
-    navigator.globalization.getNumberPattern(
-        function (pattern) {alert('pattern: '  + pattern.pattern  + '\n' +
-                                  'symbol: '   + pattern.symbol   + '\n' +
-                                  'fraction: ' + pattern.fraction + '\n' +
-                                  'rounding: ' + pattern.rounding + '\n' +
-                                  'positive: ' + pattern.positive + '\n' +
-                                  'negative: ' + pattern.negative + '\n' +
-                                  'decimal: '  + pattern.decimal  + '\n' +
-                                  'grouping: ' + pattern.grouping);},
-        function () {alert('Error getting pattern\n');},
-        {type:'decimal'}
-    );
-
-Results:
-
-    pattern: #,##0.###
-    symbol: .
-    fraction: 0
-    rounding: 0
-    positive:
-    negative: -
-    decimal: .
-    grouping: ,
-
-
-### Windows Phone 8 Quirks
-
-- The `pattern` property is not supported, and retuens an empty string.
-
-- The `fraction` property is not supported, and returns zero.
-
-## navigator.globalization.getPreferredLanguage
-
-Get the string identifier for the client's current language.
-
-    navigator.globalization.getPreferredLanguage(successCallback, errorCallback);
-
-### Description
-
-Returns the language identifier string to the `successCallback` with a
-`properties` object as a parameter. That object should have a `value`
-property with a `String` value.
-
-If there is an error getting the language, then the `errorCallback`
-executes with a `GlobalizationError` object as a parameter. The
-error's expected code is `GlobalizationError.UNKNOWN\_ERROR`.
-
-### Supported Platforms
-
-- Amazon Fire OS
-- Android
-- iOS
-- Windows Phone 8
-
-### Example
-
-When the browser is set to the `en\_US` locale, this should display a
-popup dialog with the text `language: English`:
-
-    navigator.globalization.getPreferredLanguage(
-        function (language) {alert('language: ' + language.value + '\n');},
-        function () {alert('Error getting language\n');}
-    );
-
-
-### Windows Phone 8 Quirks
-
-- Returns the ISO 639-1 two-letter code for the current language.
-
-## navigator.globalization.isDayLightSavingsTime
-
-Indicates whether daylight savings time is in effect for a given date
-using the client's time zone and calendar.
-
-    navigator.globalization.isDayLightSavingsTime(date, successCallback, errorCallback);
-
-### Description
-
-Indicates whether or not daylight savings time is in effect to the
-`successCallback` with a `properties` object as a parameter. That object
-should have a `dst` property with a `Boolean` value. A `true` value
-indicates that daylight savings time is in effect for the given date,
-and `false` indicates that it is not.
-
-The inbound parameter `date` should be of type `Date`.
-
-If there is an error reading the date, then the `errorCallback`
-executes. The error's expected code is `GlobalizationError.UNKNOWN\_ERROR`.
-
-### Supported Platforms
-
-- Amazon Fire OS
-- Android
-- iOS
-- Windows Phone 8
-
-### Example
-
-During the summer, and if the browser is set to a DST-enabled
-timezone, this should display a popup dialog with text similar to
-`dst: true`:
-
-    navigator.globalization.isDayLightSavingsTime(
-        new Date(),
-        function (date) {alert('dst: ' + date.dst + '\n');},
-        function () {alert('Error getting names\n');}
-    );
-
-
-
-## navigator.globalization.numberToString
-
-Returns a number formatted as a string according to the client's user preferences.
-
-    navigator.globalization.numberToString(number, successCallback, errorCallback, options);
-
-### Description
-
-Returns the formatted number string to the `successCallback` with a
-`properties` object as a parameter. That object should have a `value`
-property with a `String` value.
-
-If there is an error formatting the number, then the `errorCallback`
-executes with a `GlobalizationError` object as a parameter. The
-error's expected code is `GlobalizationError.FORMATTING\_ERROR`.
-
-The `options` parameter is optional, and its default values are:
-
-    {type:'decimal'}
-
-The `options.type` can be 'decimal', 'percent', or 'currency'.
-
-### Supported Platforms
-
-- Amazon Fire OS
-- Android
-- iOS
-- Windows Phone 8
-
-### Example
-
-When the browser is set to the `en\_US` locale, this displays a popup
-dialog with text similar to `number: 3.142`:
-
-    navigator.globalization.numberToString(
-        3.1415926,
-        function (number) {alert('number: ' + number.value + '\n');},
-        function () {alert('Error getting number\n');},
-        {type:'decimal'}
-    );
-
-
-## navigator.globalization.stringToDate
-
-Parses a date formatted as a string, according to the client's user
-preferences and calendar using the time zone of the client, and
-returns the corresponding date object.
-
-    navigator.globalization.stringToDate(dateString, successCallback, errorCallback, options);
-
-### Description
-
-Returns the date to the success callback with a `properties` object as
-a parameter. That object should have the following properties:
-
-- __year__: The four digit year. _(Number)_
-
-- __month__: The month from (0-11). _(Number)_
-
-- __day__: The day from (1-31). _(Number)_
-
-- __hour__: The hour from (0-23). _(Number)_
-
-- __minute__: The minute from (0-59). _(Number)_
-
-- __second__: The second from (0-59). _(Number)_
-
-- __millisecond__: The milliseconds (from 0-999), not available on all platforms. _(Number)_
-
-The inbound `dateString` parameter should be of type `String`.
-
-The `options` parameter is optional, and defaults to the following
-values:
-
-    {formatLength:'short', selector:'date and time'}
-
-The `options.formatLength` can be `short`, `medium`, `long`, or
-`full`.  The `options.selector` can be `date`, `time` or `date and
-time`.
-
-If there is an error parsing the date string, then the `errorCallback`
-executes with a `GlobalizationError` object as a parameter. The
-error's expected code is `GlobalizationError.PARSING\_ERROR`.
-
-### Supported Platforms
-
-- Amazon Fire OS
-- Android
-- iOS
-- Windows Phone 8
-
-### Example
-
-When the browser is set to the `en\_US` locale, this displays a
-popup dialog with text similar to `month:8 day:25 year:2012`. Note
-that the month integer is one less than the string, as the month
-integer represents an array index.
-
-    navigator.globalization.stringToDate(
-        '9/25/2012',
-        function (date) {alert('month:' + date.month +
-                               ' day:'  + date.day   +
-                               ' year:' + date.year  + '\n');},
-        function () {alert('Error getting date\n');},
-        {selector: 'date'}
-    );
-
-
-### Windows Phone 8 Quirks
-
-- The `formatLength` option supports only `short` and `full` values.
-
-## navigator.globalization.stringToNumber
-
-Parses a number formatted as a string according to the client's user
-preferences and returns the corresponding number.
-
-    navigator.globalization.stringToNumber(string, successCallback, errorCallback, options);
-
-### Description
-
-Returns the number to the `successCallback` with a `properties` object
-as a parameter. That object should have a `value` property with a
-`Number` value.
-
-If there is an error parsing the number string, then the
-`errorCallback` executes with a `GlobalizationError` object as a
-parameter. The error's expected code is
-`GlobalizationError.PARSING\_ERROR`.
-
-The `options` parameter is optional, and defaults to the following
-values:
-
-    {type:'decimal'}
-
-The `options.type` can be `decimal`, `percent`, or `currency`.
-
-### Supported Platforms
-
-- Amazon Fire OS
-- Android
-- iOS
-- Windows Phone 8
-
-### Example
-
-When the browser is set to the `en\_US` locale, this should display a
-popup dialog with text similar to `number: 1234.56`:
-
-    navigator.globalization.stringToNumber(
-        '1234.56',
-        function (number) {alert('number: ' + number.value + '\n');},
-        function () {alert('Error getting number\n');},
-        {type:'decimal'}
-    );
-
-
-## GlobalizationError
-
-An object representing a error from the Globalization API.
-
-### Properties
-
-- __code__:  One of the following codes representing the error type _(Number)_
-  - GlobalizationError.UNKNOWN\_ERROR: 0
-  - GlobalizationError.FORMATTING\_ERROR: 1
-  - GlobalizationError.PARSING\_ERROR: 2
-  - GlobalizationError.PATTERN\_ERROR: 3
-- __message__:  A text message that includes the error's explanation and/or details _(String)_
-
-### Description
-
-This object is created and populated by Cordova, and returned to a callback in the case of an error.
-
-### Supported Platforms
-
-- Amazon Fire OS
-- Android
-- iOS
-
-### Example
-
-When the following error callback executes, it displays a
-popup dialog with the text similar to `code: 3` and `message:`
-
-    function errorCallback(error) {
-        alert('code: ' + error.code + '\n' +
-              'message: ' + error.message + '\n');
-    };
-
diff --git a/plugin.xml b/plugin.xml
deleted file mode 100644
index a1a90df..0000000
--- a/plugin.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-<?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.
--->
-
-<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
-           id="org.apache.cordova.globalization"
-      version="0.2.8-dev">
-    <name>Globalization</name>
-    <description>Cordova Globalization Plugin</description>
-    <license>Apache 2.0</license>
-    <keywords>cordova,globalization</keywords>
-    <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-globalization.git</repo>
-    <issue>https://issues.apache.org/jira/browse/CB/component/12320649</issue>
-
-    <js-module src="www/GlobalizationError.js" name="GlobalizationError">
-        <clobbers target="window.GlobalizationError" />
-    </js-module>
-    
-    <js-module src="www/globalization.js" name="globalization">
-        <clobbers target="navigator.globalization" />
-    </js-module>
-    
-    <!-- android -->
-    <platform name="android">
-        <config-file target="res/xml/config.xml" parent="/*">
-            <feature name="Globalization">
-                <param name="android-package" value="org.apache.cordova.globalization.Globalization" />
-            </feature>
-        </config-file>
-
-        <source-file src="src/android/Globalization.java" target-dir="src/org/apache/cordova/globalization" />
-        <source-file src="src/android/GlobalizationError.java" target-dir="src/org/apache/cordova/globalization" />
-    </platform>
-       
-    <!-- amazon-fireos -->
-    <platform name="amazon-fireos">
-        <config-file target="res/xml/config.xml" parent="/*">
-            <feature name="Globalization">
-                <param name="android-package" value="org.apache.cordova.globalization.Globalization" />
-            </feature>
-        </config-file>
-
-        <source-file src="src/android/Globalization.java" target-dir="src/org/apache/cordova/globalization" />
-        <source-file src="src/android/GlobalizationError.java" target-dir="src/org/apache/cordova/globalization" />
-    </platform>
-    
-   <!-- ubuntu -->
-   <platform name="ubuntu">
-       <header-file src="src/ubuntu/globalization.h" />
-       <source-file src="src/ubuntu/globalization.cpp" />
-
-       <js-module src="www/ubuntu/globalization.js" name="Globalization1">
-           <merges target="navigator.globalization" />
-       </js-module>
-   </platform>
-
-   <!-- ios -->
-   <platform name="ios">    
-        <config-file target="config.xml" parent="/*">
-            <feature name="Globalization">
-                <param name="ios-package" value="CDVGlobalization" /> 
-            </feature>
-        </config-file>
-        <header-file src="src/ios/CDVGlobalization.h" />
-        <source-file src="src/ios/CDVGlobalization.m" />
-    </platform>
-
-    <!-- wp7 -->
-    <platform name="wp7">
-        <config-file target="config.xml" parent="/*">
-            <feature name="Globalization">
-                <param name="wp-package" value="Globalization"/>
-            </feature>
-        </config-file>
-
-        <source-file src="src/wp/Globalization.cs" />
-    </platform>
-
-    <!-- wp8 -->
-    <platform name="wp8">
-        <config-file target="config.xml" parent="/*">
-            <feature name="Globalization">
-                <param name="wp-package" value="Globalization"/>
-            </feature>
-        </config-file>
-
-        <source-file src="src/wp/Globalization.cs" />
-    </platform>
-
-    <!-- tizen -->
-    <platform name="tizen">
-        <js-module src="src/tizen/GlobalizationProxy.js" name="GlobalizationProxy">
-            <runs/>
-        </js-module>
-    </platform>
-</plugin>
diff --git a/src/android/Globalization.java b/src/android/Globalization.java
deleted file mode 100644
index 588fe4a..0000000
--- a/src/android/Globalization.java
+++ /dev/null
@@ -1,578 +0,0 @@
-/*
-       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.
-*/
-
-package org.apache.cordova.globalization;
-
-import java.text.DateFormat;
-import java.text.DecimalFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Currency;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
-
-import org.apache.cordova.CallbackContext;
-import org.apache.cordova.CordovaPlugin;
-import org.apache.cordova.PluginResult;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.annotation.TargetApi;
-import android.text.format.Time;
-
-/**
- *
- */
-public class Globalization extends CordovaPlugin  {
-    //GlobalizationCommand Plugin Actions
-    public static final String GETLOCALENAME = "getLocaleName";
-    public static final String DATETOSTRING = "dateToString";
-    public static final String STRINGTODATE = "stringToDate";
-    public static final String GETDATEPATTERN = "getDatePattern";
-    public static final String GETDATENAMES = "getDateNames";
-    public static final String ISDAYLIGHTSAVINGSTIME = "isDayLightSavingsTime";
-    public static final String GETFIRSTDAYOFWEEK = "getFirstDayOfWeek";
-    public static final String NUMBERTOSTRING = "numberToString";
-    public static final String STRINGTONUMBER = "stringToNumber";
-    public static final String GETNUMBERPATTERN = "getNumberPattern";
-    public static final String GETCURRENCYPATTERN = "getCurrencyPattern";
-    public static final String GETPREFERREDLANGUAGE = "getPreferredLanguage";
-
-    //GlobalizationCommand Option Parameters
-    public static final String OPTIONS = "options";
-    public static final String FORMATLENGTH = "formatLength";
-    //public static final String SHORT = "short"; //default for dateToString format
-    public static final String MEDIUM = "medium";
-    public static final String LONG = "long";
-    public static final String FULL = "full";
-    public static final String SELECTOR = "selector";
-    //public static final String DATEANDTIME = "date and time"; //default for dateToString
-    public static final String DATE = "date";
-    public static final String TIME = "time";
-    public static final String DATESTRING = "dateString";
-    public static final String TYPE = "type";
-    public static final String ITEM = "item";
-    public static final String NARROW = "narrow";
-    public static final String WIDE = "wide";
-    public static final String MONTHS = "months";
-    public static final String DAYS = "days";
-    //public static final String DECMIAL = "wide"; //default for numberToString
-    public static final String NUMBER = "number";
-    public static final String NUMBERSTRING = "numberString";
-    public static final String PERCENT = "percent";
-    public static final String CURRENCY = "currency";
-    public static final String CURRENCYCODE = "currencyCode";
-
-    @Override
-    public boolean execute(String action, JSONArray data, CallbackContext callbackContext) {
-        JSONObject obj = new JSONObject();
-
-        try{
-            if (action.equals(GETLOCALENAME)){
-                obj = getLocaleName();
-            }else if (action.equals(GETPREFERREDLANGUAGE)){
-                obj = getPreferredLanguage();
-            } else if (action.equalsIgnoreCase(DATETOSTRING)) {
-                obj = getDateToString(data);
-            }else if(action.equalsIgnoreCase(STRINGTODATE)){
-                obj = getStringtoDate(data);
-            }else if(action.equalsIgnoreCase(GETDATEPATTERN)){
-                obj = getDatePattern(data);
-            }else if(action.equalsIgnoreCase(GETDATENAMES)){
-                if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.GINGERBREAD) {
-                    throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR);
-                } else {
-                    obj = getDateNames(data);
-                }
-            }else if(action.equalsIgnoreCase(ISDAYLIGHTSAVINGSTIME)){
-                obj = getIsDayLightSavingsTime(data);
-            }else if(action.equalsIgnoreCase(GETFIRSTDAYOFWEEK)){
-                obj = getFirstDayOfWeek(data);
-            }else if(action.equalsIgnoreCase(NUMBERTOSTRING)){
-                obj = getNumberToString(data);
-            }else if(action.equalsIgnoreCase(STRINGTONUMBER)){
-                obj = getStringToNumber(data);
-            }else if(action.equalsIgnoreCase(GETNUMBERPATTERN)){
-                obj = getNumberPattern(data);
-            }else if(action.equalsIgnoreCase(GETCURRENCYPATTERN)){
-                obj = getCurrencyPattern(data);
-            }else {
-                return false;
-            }
-
-            callbackContext.success(obj);
-        }catch (GlobalizationError ge){
-            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, ge.toJson()));
-        }catch (Exception e){
-            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-        }
-        return true;
-    }
-    /*
-     * @Description: Returns the string identifier for the client's current locale setting
-     *
-     * @Return: JSONObject
-     *          Object.value {String}: The locale identifier
-     *
-     * @throws: GlobalizationError.UNKNOWN_ERROR
-     */
-    private JSONObject getLocaleName() throws GlobalizationError{
-        JSONObject obj = new JSONObject();
-        try{
-            obj.put("value",Locale.getDefault().toString());//get the locale from the Android Device
-            return obj;
-        }catch(Exception e){
-            throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR);
-        }
-    }
-    /*
-     * @Description: Returns the string identifier for the client's current language
-     *
-     * @Return: JSONObject
-     *          Object.value {String}: The language identifier
-     *
-     * @throws: GlobalizationError.UNKNOWN_ERROR
-     */
-    private JSONObject getPreferredLanguage() throws GlobalizationError {
-        JSONObject obj = new JSONObject();
-        try {
-            obj.put("value", Locale.getDefault().getDisplayLanguage().toString());
-            return obj;
-        } catch (Exception e) {
-            throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR);
-        }
-    }
-    /*
-     * @Description: Returns a date formatted as a string according to the client's user preferences and
-     * calendar using the time zone of the client.
-     *
-     * @Return: JSONObject
-     *          Object.value {String}: The localized date string
-     *
-     * @throws: GlobalizationError.FORMATTING_ERROR
-     */
-    private JSONObject getDateToString(JSONArray options) throws GlobalizationError{
-        JSONObject obj = new JSONObject();
-        try{
-            Date date = new Date((Long)options.getJSONObject(0).get(DATE));
-
-            //get formatting pattern from android device (Will only have device specific formatting for short form of date) or options supplied
-            JSONObject datePattern = getDatePattern(options);
-            SimpleDateFormat fmt = new SimpleDateFormat(datePattern.getString("pattern"));
-
-            //return formatted date
-            return obj.put("value",fmt.format(date));
-        }catch(Exception ge){
-            throw new GlobalizationError(GlobalizationError.FORMATTING_ERROR);
-        }
-    }
-
-    /*
-     * @Description: Parses a date formatted as a string according to the client's user
-     * preferences and calendar using the time zone of the client and returns
-     * the corresponding date object
-     * @Return: JSONObject
-     *          Object.year {Number}: The four digit year
-     *          Object.month {Number}: The month from (0 - 11)
-     *          Object.day {Number}: The day from (1 - 31)
-     *          Object.hour {Number}: The hour from (0 - 23)
-     *          Object.minute {Number}: The minute from (0 - 59)
-     *          Object.second {Number}: The second from (0 - 59)
-     *          Object.millisecond {Number}: The milliseconds (from 0 - 999), not available on all platforms
-     *
-     * @throws: GlobalizationError.PARSING_ERROR
-    */
-    private JSONObject getStringtoDate(JSONArray options)throws GlobalizationError{
-        JSONObject obj = new JSONObject();
-        Date date;
-        try{
-            //get format pattern from android device (Will only have device specific formatting for short form of date) or options supplied
-            DateFormat fmt = new SimpleDateFormat(getDatePattern(options).getString("pattern"));
-
-            //attempt parsing string based on user preferences
-            date = fmt.parse(options.getJSONObject(0).get(DATESTRING).toString());
-
-            //set Android Time object
-            Time time = new Time();
-            time.set(date.getTime());
-
-            //return properties;
-            obj.put("year", time.year);
-            obj.put("month", time.month);
-            obj.put("day", time.monthDay);
-            obj.put("hour", time.hour);
-            obj.put("minute", time.minute);
-            obj.put("second", time.second);
-            obj.put("millisecond", Long.valueOf(0));
-            return obj;
-        }catch(Exception ge){
-            throw new GlobalizationError(GlobalizationError.PARSING_ERROR);
-        }
-    }
-
-    /*
-     * @Description: Returns a pattern string for formatting and parsing dates according to the client's
-     * user preferences.
-     * @Return: JSONObject
-     *
-     *          Object.pattern {String}: The date and time pattern for formatting and parsing dates.
-     *                                  The patterns follow Unicode Technical Standard #35
-     *                                  http://unicode.org/reports/tr35/tr35-4.html
-     *          Object.timezone {String}: The abbreviated name of the time zone on the client
-     *          Object.utc_offset {Number}: The current difference in seconds between the client's
-     *                                      time zone and coordinated universal time.
-     *          Object.dst_offset {Number}: The current daylight saving time offset in seconds
-     *                                      between the client's non-daylight saving's time zone
-     *                                      and the client's daylight saving's time zone.
-     *
-     * @throws: GlobalizationError.PATTERN_ERROR
-    */
-    private JSONObject getDatePattern(JSONArray options) throws GlobalizationError{
-        JSONObject obj = new JSONObject();
-
-        try{
-            SimpleDateFormat fmtDate = (SimpleDateFormat)android.text.format.DateFormat.getDateFormat(this.cordova.getActivity()); //default user preference for date
-            SimpleDateFormat fmtTime = (SimpleDateFormat)android.text.format.DateFormat.getTimeFormat(this.cordova.getActivity());  //default user preference for time
-
-            String fmt = fmtDate.toLocalizedPattern() + " " + fmtTime.toLocalizedPattern(); //default SHORT date/time format. ex. dd/MM/yyyy h:mm a
-
-            //get Date value + options (if available)
-            if (options.getJSONObject(0).has(OPTIONS)){
-                //options were included
-
-                JSONObject innerOptions = options.getJSONObject(0).getJSONObject(OPTIONS);
-                //get formatLength option
-                if (!innerOptions.isNull(FORMATLENGTH)){
-                    String fmtOpt = innerOptions.getString(FORMATLENGTH);
-                    if (fmtOpt.equalsIgnoreCase(MEDIUM)){//medium
-                        fmtDate = (SimpleDateFormat)android.text.format.DateFormat.getMediumDateFormat(this.cordova.getActivity());
-                    }else if (fmtOpt.equalsIgnoreCase(LONG) || fmtOpt.equalsIgnoreCase(FULL)){ //long/full
-                        fmtDate = (SimpleDateFormat)android.text.format.DateFormat.getLongDateFormat(this.cordova.getActivity());
-                    }
-                }
-
-                //return pattern type
-                fmt = fmtDate.toLocalizedPattern() + " " + fmtTime.toLocalizedPattern();
-                if (!innerOptions.isNull(SELECTOR)){
-                    String selOpt = innerOptions.getString(SELECTOR);
-                    if (selOpt.equalsIgnoreCase(DATE)){
-                        fmt =  fmtDate.toLocalizedPattern();
-                    }else if (selOpt.equalsIgnoreCase(TIME)){
-                        fmt = fmtTime.toLocalizedPattern();
-                    }
-                }
-            }
-
-            //TimeZone from users device
-            //TimeZone tz = Calendar.getInstance(Locale.getDefault()).getTimeZone(); //substitute method
-            TimeZone tz = TimeZone.getTimeZone(Time.getCurrentTimezone());
-
-            obj.put("pattern", fmt);
-            obj.put("timezone", tz.getDisplayName(tz.inDaylightTime(Calendar.getInstance().getTime()),TimeZone.SHORT));
-            obj.put("utc_offset", tz.getRawOffset()/1000);
-            obj.put("dst_offset", tz.getDSTSavings()/1000);
-            return obj;
-
-        }catch(Exception ge){
-            throw new GlobalizationError(GlobalizationError.PATTERN_ERROR);
-        }
-    }
-
-    /*
-     * @Description: Returns an array of either the names of the months or days of the week
-     * according to the client's user preferences and calendar
-     * @Return: JSONObject
-     *          Object.value {Array{String}}: The array of names starting from either
-     *                                      the first month in the year or the
-     *                                      first day of the week.
-     *
-     * @throws: GlobalizationError.UNKNOWN_ERROR
-    */
-    @TargetApi(9)
-    private JSONObject getDateNames(JSONArray options) throws GlobalizationError{
-        JSONObject obj = new JSONObject();
-        //String[] value;
-        JSONArray value = new JSONArray();
-        List<String> namesList = new ArrayList<String>();
-        final Map<String,Integer> namesMap; // final needed for sorting with anonymous comparator
-        try{
-            int type = 0; //default wide
-            int item = 0; //default months
-
-            //get options if available
-            if (options.getJSONObject(0).length() > 0){
-                //get type if available
-                if (!((JSONObject)options.getJSONObject(0).get(OPTIONS)).isNull(TYPE)){
-                    String t = (String)((JSONObject)options.getJSONObject(0).get(OPTIONS)).get(TYPE);
-                    if (t.equalsIgnoreCase(NARROW)){type++;} //DateUtils.LENGTH_MEDIUM
-                }
-                //get item if available
-                if (!((JSONObject)options.getJSONObject(0).get(OPTIONS)).isNull(ITEM)){
-                    String t = (String)((JSONObject)options.getJSONObject(0).get(OPTIONS)).get(ITEM);
-                    if (t.equalsIgnoreCase(DAYS)){item += 10;} //Days of week start at 1
-                }
-            }
-            //determine return value
-            int method = item + type;
-            if  (method == 1) { //months and narrow
-                namesMap = Calendar.getInstance().getDisplayNames(Calendar.MONTH, Calendar.SHORT, Locale.getDefault());
-            } else if (method == 10) { //days and wide
-                namesMap = Calendar.getInstance().getDisplayNames(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.getDefault());
-            } else if (method == 11) { //days and narrow
-                namesMap = Calendar.getInstance().getDisplayNames(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault());
-            } else { //default: months and wide
-                namesMap = Calendar.getInstance().getDisplayNames(Calendar.MONTH, Calendar.LONG, Locale.getDefault());
-            }
-
-            // save names as a list
-            for(String name : namesMap.keySet()) {
-                namesList.add(name);
-            }
-
-            // sort the list according to values in namesMap
-            Collections.sort(namesList, new Comparator<String>() {
-                public int compare(String arg0, String arg1) {
-                    return namesMap.get(arg0).compareTo(namesMap.get(arg1));
-                }
-            });
-
-            // convert nameList into JSONArray of String objects
-            for (int i = 0; i < namesList.size(); i ++){
-                value.put(namesList.get(i));
-            }
-
-            //return array of names
-            return obj.put("value", value);
-        }catch(Exception ge){
-            throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR);
-        }
-    }
-
-    /*
-     * @Description: Returns whether daylight savings time is in effect for a given date using the client's
-     * time zone and calendar.
-     * @Return: JSONObject
-     *          Object.dst {Boolean}: The value "true" indicates that daylight savings time is
-     *                              in effect for the given date and "false" indicate that it is not.    *
-     *
-     * @throws: GlobalizationError.UNKNOWN_ERROR
-    */
-    private JSONObject getIsDayLightSavingsTime(JSONArray options) throws GlobalizationError{
-        JSONObject obj = new JSONObject();
-        boolean dst = false;
-        try{
-            Date date = new Date((Long)options.getJSONObject(0).get(DATE));
-            //TimeZone tz = Calendar.getInstance(Locale.getDefault()).getTimeZone();
-            TimeZone tz = TimeZone.getTimeZone(Time.getCurrentTimezone());
-            dst = tz.inDaylightTime(date); //get daylight savings data from date object and user timezone settings
-
-            return obj.put("dst",dst);
-        }catch(Exception ge){
-            throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR);
-        }
-    }
-
-    /*
-     * @Description: Returns the first day of the week according to the client's user preferences and calendar.
-     * The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
-     * @Return: JSONObject
-     *          Object.value {Number}: The number of the first day of the week.
-     *
-     * @throws: GlobalizationError.UNKNOWN_ERROR
-    */
-    private JSONObject getFirstDayOfWeek(JSONArray options) throws GlobalizationError{
-        JSONObject obj = new JSONObject();
-        try{
-            int value = Calendar.getInstance(Locale.getDefault()).getFirstDayOfWeek(); //get first day of week based on user locale settings
-            return obj.put("value", value);
-        }catch(Exception ge){
-            throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR);
-        }
-    }
-
-    /*
-     * @Description: Returns a number formatted as a string according to the client's user preferences.
-     * @Return: JSONObject
-     *          Object.value {String}: The formatted number string.
-     *
-     * @throws: GlobalizationError.FORMATTING_ERROR
-    */
-    private JSONObject getNumberToString(JSONArray options) throws GlobalizationError{
-        JSONObject obj = new JSONObject();
-        String value = "";
-        try{
-            DecimalFormat fmt = getNumberFormatInstance(options);//returns Decimal/Currency/Percent instance
-            value = fmt.format(options.getJSONObject(0).get(NUMBER));
-            return obj.put("value", value);
-        }catch(Exception ge){
-            throw new GlobalizationError(GlobalizationError.FORMATTING_ERROR);
-        }
-    }
-
-    /*
-     * @Description: Parses a number formatted as a string according to the client's user preferences and
-     * returns the corresponding number.
-     * @Return: JSONObject
-     *          Object.value {Number}: The parsed number.
-     *
-     * @throws: GlobalizationError.PARSING_ERROR
-    */
-    private JSONObject getStringToNumber(JSONArray options) throws GlobalizationError{
-        JSONObject obj = new JSONObject();
-        Number value;
-        try{
-            DecimalFormat fmt = getNumberFormatInstance(options); //returns Decimal/Currency/Percent instance
-            value = fmt.parse((String)options.getJSONObject(0).get(NUMBERSTRING));
-            return obj.put("value", value);
-        }catch(Exception ge){
-            throw new GlobalizationError(GlobalizationError.PARSING_ERROR);
-        }
-    }
-
-    /*
-     * @Description: Returns a pattern string for formatting and parsing numbers according to the client's user
-     * preferences.
-     * @Return: JSONObject
-     *          Object.pattern {String}: The number pattern for formatting and parsing numbers.
-     *                                  The patterns follow Unicode Technical Standard #35.
-     *                                  http://unicode.org/reports/tr35/tr35-4.html
-     *          Object.symbol {String}: The symbol to be used when formatting and parsing
-     *                                  e.g., percent or currency symbol.
-     *          Object.fraction {Number}: The number of fractional digits to use when parsing and
-     *                                  formatting numbers.
-     *          Object.rounding {Number}: The rounding increment to use when parsing and formatting.
-     *          Object.positive {String}: The symbol to use for positive numbers when parsing and formatting.
-     *          Object.negative: {String}: The symbol to use for negative numbers when parsing and formatting.
-     *          Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
-     *          Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
-     *
-     * @throws: GlobalizationError.PATTERN_ERROR
-    */
-    private JSONObject getNumberPattern(JSONArray options) throws GlobalizationError{
-        JSONObject obj = new JSONObject();
-        try{
-            //uses java.text.DecimalFormat to format value
-            DecimalFormat fmt = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault()); //default format
-            String symbol = String.valueOf(fmt.getDecimalFormatSymbols().getDecimalSeparator());
-            //get Date value + options (if available)
-            if (options.getJSONObject(0).length() > 0){
-                //options were included
-                if (!((JSONObject)options.getJSONObject(0).get(OPTIONS)).isNull(TYPE)){
-                    String fmtOpt = (String)((JSONObject)options.getJSONObject(0).get(OPTIONS)).get(TYPE);
-                    if (fmtOpt.equalsIgnoreCase(CURRENCY)){
-                        fmt = (DecimalFormat) DecimalFormat.getCurrencyInstance(Locale.getDefault());
-                        symbol = fmt.getDecimalFormatSymbols().getCurrencySymbol();
-                    }else if(fmtOpt.equalsIgnoreCase(PERCENT)){
-                        fmt = (DecimalFormat) DecimalFormat.getPercentInstance(Locale.getDefault());
-                        symbol = String.valueOf(fmt.getDecimalFormatSymbols().getPercent());
-                    }
-                }
-            }
-
-            //return properties
-            obj.put("pattern", fmt.toPattern());
-            obj.put("symbol", symbol);
-            obj.put("fraction", fmt.getMinimumFractionDigits());
-            obj.put("rounding", Integer.valueOf(0));
-            obj.put("positive", fmt.getPositivePrefix());
-            obj.put("negative", fmt.getNegativePrefix());
-            obj.put("decimal", String.valueOf(fmt.getDecimalFormatSymbols().getDecimalSeparator()));
-            obj.put("grouping", String.valueOf(fmt.getDecimalFormatSymbols().getGroupingSeparator()));
-
-            return obj;
-        }catch(Exception ge){
-            throw new GlobalizationError(GlobalizationError.PATTERN_ERROR);
-        }
-    }
-
-    /*
-     * @Description: Returns a pattern string for formatting and parsing currency values according to the client's
-     * user preferences and ISO 4217 currency code.
-     * @Return: JSONObject
-     *          Object.pattern {String}: The currency pattern for formatting and parsing currency values.
-     *                                  The patterns follow Unicode Technical Standard #35
-     *                                  http://unicode.org/reports/tr35/tr35-4.html
-     *          Object.code {String}: The ISO 4217 currency code for the pattern.
-     *          Object.fraction {Number}: The number of fractional digits to use when parsing and
-     *                                  formatting currency.
-     *          Object.rounding {Number}: The rounding increment to use when parsing and formatting.
-     *          Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
-     *          Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
-     *
-     * @throws: GlobalizationError.FORMATTING_ERROR
-    */
-    private JSONObject getCurrencyPattern(JSONArray options) throws GlobalizationError{
-        JSONObject obj = new JSONObject();
-        try{
-            //get ISO 4217 currency code
-            String code = options.getJSONObject(0).getString(CURRENCYCODE);
-
-            //uses java.text.DecimalFormat to format value
-            DecimalFormat fmt = (DecimalFormat) DecimalFormat.getCurrencyInstance(Locale.getDefault());
-
-            //set currency format
-            Currency currency = Currency.getInstance(code);
-            fmt.setCurrency(currency);
-
-            //return properties
-            obj.put("pattern", fmt.toPattern());
-            obj.put("code", currency.getCurrencyCode());
-            obj.put("fraction", fmt.getMinimumFractionDigits());
-            obj.put("rounding", Integer.valueOf(0));
-            obj.put("decimal", String.valueOf(fmt.getDecimalFormatSymbols().getDecimalSeparator()));
-            obj.put("grouping", String.valueOf(fmt.getDecimalFormatSymbols().getGroupingSeparator()));
-
-            return obj;
-        }catch(Exception ge){
-            throw new GlobalizationError(GlobalizationError.FORMATTING_ERROR);
-        }
-    }
-
-    /*
-     * @Description: Parses a JSONArray from user options and returns the correct Instance of Decimal/Percent/Currency.
-     * @Return: DecimalFormat : The Instance to use.
-     *
-     * @throws: JSONException
-    */
-    private DecimalFormat getNumberFormatInstance(JSONArray options) throws JSONException{
-        DecimalFormat fmt =  (DecimalFormat)DecimalFormat.getInstance(Locale.getDefault()); //default format
-        try{
-            if (options.getJSONObject(0).length() > 1){
-                //options were included
-                if (!((JSONObject)options.getJSONObject(0).get(OPTIONS)).isNull(TYPE)){
-                    String fmtOpt = (String)((JSONObject)options.getJSONObject(0).get(OPTIONS)).get(TYPE);
-                    if (fmtOpt.equalsIgnoreCase(CURRENCY)){
-                        fmt = (DecimalFormat)DecimalFormat.getCurrencyInstance(Locale.getDefault());
-                    }else if(fmtOpt.equalsIgnoreCase(PERCENT)){
-                        fmt = (DecimalFormat)DecimalFormat.getPercentInstance(Locale.getDefault());
-                    }
-                }
-            }
-
-        }catch (JSONException je){}
-        return fmt;
-    }
-}
diff --git a/src/android/GlobalizationError.java b/src/android/GlobalizationError.java
deleted file mode 100644
index 33ce718..0000000
--- a/src/android/GlobalizationError.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
-       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.
-*/
-
-package org.apache.cordova.globalization;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/** 
- * @description Exception class representing defined Globalization error codes
- * @Globalization error codes:
- *      GlobalizationError.UNKNOWN_ERROR = 0;
- *      GlobalizationError.FORMATTING_ERROR = 1;   
- *      GlobalizationError.PARSING_ERROR = 2;   
- *      GlobalizationError.PATTERN_ERROR = 3;
- */
-public class GlobalizationError extends Exception{
-    /**
-     * 
-     */
-    private static final long serialVersionUID = 1L;
-    public static final String UNKNOWN_ERROR = "UNKNOWN_ERROR";
-    public static final String FORMATTING_ERROR = "FORMATTING_ERROR";
-    public static final String PARSING_ERROR = "PARSING_ERROR";
-    public static final String PATTERN_ERROR = "PATTERN_ERROR";
-    
-    int error = 0;  //default unknown error thrown
-    /**
-     * Default constructor        
-     */
-    public GlobalizationError() {}
-    /**
-     * Create an exception returning an error code 
-     *    
-     * @param   s           
-     */
-    public GlobalizationError(String s) {       
-        if (s.equalsIgnoreCase(FORMATTING_ERROR)){
-            error = 1;
-        }else if (s.equalsIgnoreCase(PARSING_ERROR)){
-            error = 2;
-        }else if (s.equalsIgnoreCase(PATTERN_ERROR)){
-            error = 3;
-        }       
-    }
-    /**
-     * get error string based on error code 
-     *    
-     * @param   String msg           
-     */
-    public String getErrorString(){
-        String msg = "";
-        switch (error){
-        case 0:
-            msg = UNKNOWN_ERROR;
-            break;
-        case 1:
-            msg =  FORMATTING_ERROR;
-            break;
-        case 2:
-            msg =  PARSING_ERROR;
-            break;
-        case 3:
-            msg =  PATTERN_ERROR;
-            break;
-        }
-        return msg;
-    }
-    /**
-     * get error code 
-     *    
-     * @param   String msg           
-     */
-    public int getErrorCode(){      
-        return error;
-    }
-    
-    /**
-     * get the json version of this object to return to javascript
-     * @return
-     */
-    public JSONObject toJson() {
-        JSONObject obj = new JSONObject();
-        try {
-            obj.put("code", getErrorCode());
-            obj.put("message", getErrorString());
-        } catch (JSONException e) {
-            // never happens
-        }
-        return obj;
-    }
-}
diff --git a/src/ios/CDVGlobalization.h b/src/ios/CDVGlobalization.h
deleted file mode 100644
index 379b704..0000000
--- a/src/ios/CDVGlobalization.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- 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.
- */
-
-#import <Foundation/Foundation.h>
-#import <Cordova/CDVPlugin.h>
-
-#define CDV_FORMAT_SHORT 0
-#define CDV_FORMAT_MEDIUM 1
-#define CDV_FORMAT_LONG 2
-#define CDV_FORMAT_FULL 3
-#define CDV_SELECTOR_MONTHS 0
-#define CDV_SELECTOR_DAYS 1
-
-enum CDVGlobalizationError {
-    CDV_UNKNOWN_ERROR = 0,
-    CDV_FORMATTING_ERROR = 1,
-    CDV_PARSING_ERROR = 2,
-    CDV_PATTERN_ERROR = 3,
-};
-typedef NSUInteger CDVGlobalizationError;
-
-@interface CDVGlobalization : CDVPlugin {
-    CFLocaleRef currentLocale;
-}
-
-- (void)getPreferredLanguage:(CDVInvokedUrlCommand*)command;
-
-/**
- * Returns the string identifier for the clients current locale setting.
- * It returns the locale identifier string to the successCB callback with a
- * properties object as a parameter. If there is an error getting the locale,
- * then the errorCB callback is invoked.
- */
-- (void)getLocaleName:(CDVInvokedUrlCommand*)command;
-
-/**
- * Returns a date formatted as a string according to the clients user preferences and
- * calendar using the time zone of the client. It returns the formatted date string to the
- * successCB callback with a properties object as a parameter. If there is an error
- * formatting the date, then the errorCB callback is invoked.
- *
- * options: "date" contains the number of milliseconds that represents the JavaScript date
- */
-- (void)dateToString:(CDVInvokedUrlCommand*)command;
-
-/**
- * Parses a date formatted as a string according to the clients user
- * preferences and calendar using the time zone of the client and returns
- * the corresponding date object. It returns the date to the successCB
- * callback with a properties object as a parameter. If there is an error
- * parsing the date string, then the errorCB callback is invoked.
- *
- * options: "dateString" contains the JavaScript string to parse for a date
- */
-- (void)stringToDate:(CDVInvokedUrlCommand*)command;
-
-/**
- * Returns a pattern string for formatting and parsing dates according to the clients
- * user preferences. It returns the pattern to the successCB callback with a
- * properties object as a parameter. If there is an error obtaining the pattern,
- * then the errorCB callback is invoked.
- *
- */
-- (void)getDatePattern:(CDVInvokedUrlCommand*)command;
-
-/**
- * Returns an array of either the names of the months or days of the week
- * according to the clients user preferences and calendar. It returns the array of names to the
- * successCB callback with a properties object as a parameter. If there is an error obtaining the
- * names, then the errorCB callback is invoked.
- *
- */
-- (void)getDateNames:(CDVInvokedUrlCommand*)command;
-
-/**
- * Returns whether daylight savings time is in effect for a given date using the clients
- * time zone and calendar. It returns whether or not daylight savings time is in effect
- * to the successCB callback with a properties object as a parameter. If there is an error
- * reading the date, then the errorCB callback is invoked.
- *
- * options: "date" contains the number of milliseconds that represents the JavaScript date
- *
- */
-- (void)isDayLightSavingsTime:(CDVInvokedUrlCommand*)command;
-
-/**
- * Returns the first day of the week according to the clients user preferences and calendar.
- * The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
- * It returns the day to the successCB callback with a properties object as a parameter.
- * If there is an error obtaining the pattern, then the errorCB callback is invoked.
- *
- */
-- (void)getFirstDayOfWeek:(CDVInvokedUrlCommand*)command;
-
-/**
- * Returns a number formatted as a string according to the clients user preferences.
- * It returns the formatted number string to the successCB callback with a properties object as a
- * parameter. If there is an error formatting the number, then the errorCB callback is invoked.
- *
- * options: "number" contains the JavaScript number to format
- *
- */
-- (void)numberToString:(CDVInvokedUrlCommand*)command;
-
-/**
- * Parses a number formatted as a string according to the clients user preferences and
- * returns the corresponding number. It returns the number to the successCB callback with a
- * properties object as a parameter. If there is an error parsing the number string, then
- * the errorCB callback is invoked.
- *
- * options: "numberString" contains the JavaScript string to parse for a number
- *
- */
-- (void)stringToNumber:(CDVInvokedUrlCommand*)command;
-
-/**
- * Returns a pattern string for formatting and parsing numbers according to the clients user
- * preferences. It returns the pattern to the successCB callback with a properties object as a
- * parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked.
- *
- */
-- (void)getNumberPattern:(CDVInvokedUrlCommand*)command;
-
-/**
- * Returns a pattern string for formatting and parsing currency values according to the clients
- * user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a
- * properties object as a parameter. If there is an error obtaining the pattern, then the errorCB
- * callback is invoked.
- *
- * options: "currencyCode" contains the ISO currency code from JavaScript
- */
-- (void)getCurrencyPattern:(CDVInvokedUrlCommand*)command;
-
-@end
diff --git a/src/ios/CDVGlobalization.m b/src/ios/CDVGlobalization.m
deleted file mode 100644
index 8a07c8e..0000000
--- a/src/ios/CDVGlobalization.m
+++ /dev/null
@@ -1,877 +0,0 @@
-/*
- 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.
- */
-
-#import "CDVGlobalization.h"
-
-@implementation CDVGlobalization
-
-- (id)initWithWebView:(UIWebView*)theWebView
-{
-    self = (CDVGlobalization*)[super initWithWebView:theWebView];
-    if (self) {
-        currentLocale = CFLocaleCopyCurrent();
-    }
-    return self;
-}
-
-- (void)getPreferredLanguage:(CDVInvokedUrlCommand*)command
-{
-    CDVPluginResult* result = nil;
-
-    NSLog(@"log1");
-    // Source: http://stackoverflow.com/questions/3910244/getting-current-device-language-in-ios
-    // (should be OK)
-    NSString* language = [[NSLocale preferredLanguages] objectAtIndex:0];
-
-    if (language) {
-        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:language forKey:@"value"];
-
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
-                               messageAsDictionary:dictionary];
-    } else {
-        // TBD is this ever expected to happen?
-        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
-        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
-        [dictionary setValue:@"Unknown error" forKey:@"message"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
-    }
-
-    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-}
-
-- (void)getLocaleName:(CDVInvokedUrlCommand*)command
-{
-    CDVPluginResult* result = nil;
-    NSDictionary* dictionary = nil;
-
-    NSLocale* locale = [NSLocale currentLocale];
-
-    if (locale) {
-        dictionary = [NSDictionary dictionaryWithObject:[locale localeIdentifier] forKey:@"value"];
-
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
-    } else {
-        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
-        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
-        [dictionary setValue:@"Unknown error" forKey:@"message"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
-    }
-
-    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-}
-
-- (void)dateToString:(CDVInvokedUrlCommand*)command
-{
-    CFDateFormatterStyle style = kCFDateFormatterShortStyle;
-    CFDateFormatterStyle dateStyle = kCFDateFormatterShortStyle;
-    CFDateFormatterStyle timeStyle = kCFDateFormatterShortStyle;
-    NSDate* date = nil;
-    NSString* dateString = nil;
-    CDVPluginResult* result = nil;
-
-    NSDictionary* options;
-
-    if ([command.arguments count] > 0) {
-        options = [command.arguments objectAtIndex:0];
-    }
-    if (!options) {
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
-        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-        return;
-    }
-
-    id milliseconds = [options valueForKey:@"date"];
-
-    if (milliseconds && [milliseconds isKindOfClass:[NSNumber class]]) {
-        // get the number of seconds since 1970 and create the date object
-        date = [NSDate dateWithTimeIntervalSince1970:[milliseconds doubleValue] / 1000];
-    }
-
-    // see if any options have been specified
-    id items = [options valueForKey:@"options"];
-    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
-        NSEnumerator* enumerator = [items keyEnumerator];
-        id key;
-
-        // iterate through all the options
-        while ((key = [enumerator nextObject])) {
-            id item = [items valueForKey:key];
-
-            // make sure that only string values are present
-            if ([item isKindOfClass:[NSString class]]) {
-                // get the desired format length
-                if ([key isEqualToString:@"formatLength"]) {
-                    if ([item isEqualToString:@"short"]) {
-                        style = kCFDateFormatterShortStyle;
-                    } else if ([item isEqualToString:@"medium"]) {
-                        style = kCFDateFormatterMediumStyle;
-                    } else if ([item isEqualToString:@"long"]) {
-                        style = kCFDateFormatterLongStyle;
-                    } else if ([item isEqualToString:@"full"]) {
-                        style = kCFDateFormatterFullStyle;
-                    }
-                }
-                // get the type of date and time to generate
-                else if ([key isEqualToString:@"selector"]) {
-                    if ([item isEqualToString:@"date"]) {
-                        dateStyle = style;
-                        timeStyle = kCFDateFormatterNoStyle;
-                    } else if ([item isEqualToString:@"time"]) {
-                        dateStyle = kCFDateFormatterNoStyle;
-                        timeStyle = style;
-                    } else if ([item isEqualToString:@"date and time"]) {
-                        dateStyle = style;
-                        timeStyle = style;
-                    }
-                }
-            }
-        }
-    }
-
-    // create the formatter using the user's current default locale and formats for dates and times
-    CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
-            currentLocale,
-            dateStyle,
-            timeStyle);
-    // if we have a valid date object then call the formatter
-    if (date) {
-        dateString = (__bridge_transfer NSString*)CFDateFormatterCreateStringWithDate(kCFAllocatorDefault,
-                formatter,
-                (__bridge CFDateRef)date);
-    }
-
-    // if the date was converted to a string successfully then return the result
-    if (dateString) {
-        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:dateString forKey:@"value"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
-    }
-    // error
-    else {
-        // DLog(@"GlobalizationCommand dateToString unable to format %@", [date description]);
-        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
-        [dictionary setValue:[NSNumber numberWithInt:CDV_FORMATTING_ERROR] forKey:@"code"];
-        [dictionary setValue:@"Formatting error" forKey:@"message"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
-    }
-
-    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-
-    CFRelease(formatter);
-}
-
-- (void)stringToDate:(CDVInvokedUrlCommand*)command
-{
-    CFDateFormatterStyle style = kCFDateFormatterShortStyle;
-    CFDateFormatterStyle dateStyle = kCFDateFormatterShortStyle;
-    CFDateFormatterStyle timeStyle = kCFDateFormatterShortStyle;
-    CDVPluginResult* result = nil;
-    NSString* dateString = nil;
-    NSDateComponents* comps = nil;
-
-    NSDictionary* options;
-
-    if ([command.arguments count] > 0) {
-        options = [command.arguments objectAtIndex:0];
-    }
-    if (!options) {
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
-        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-        return;
-    }
-
-    // get the string that is to be parsed for a date
-    id ms = [options valueForKey:@"dateString"];
-
-    if (ms && [ms isKindOfClass:[NSString class]]) {
-        dateString = ms;
-    }
-
-    // see if any options have been specified
-    id items = [options valueForKey:@"options"];
-    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
-        NSEnumerator* enumerator = [items keyEnumerator];
-        id key;
-
-        // iterate through all the options
-        while ((key = [enumerator nextObject])) {
-            id item = [items valueForKey:key];
-
-            // make sure that only string values are present
-            if ([item isKindOfClass:[NSString class]]) {
-                // get the desired format length
-                if ([key isEqualToString:@"formatLength"]) {
-                    if ([item isEqualToString:@"short"]) {
-                        style = kCFDateFormatterShortStyle;
-                    } else if ([item isEqualToString:@"medium"]) {
-                        style = kCFDateFormatterMediumStyle;
-                    } else if ([item isEqualToString:@"long"]) {
-                        style = kCFDateFormatterLongStyle;
-                    } else if ([item isEqualToString:@"full"]) {
-                        style = kCFDateFormatterFullStyle;
-                    }
-                }
-                // get the type of date and time to generate
-                else if ([key isEqualToString:@"selector"]) {
-                    if ([item isEqualToString:@"date"]) {
-                        dateStyle = style;
-                        timeStyle = kCFDateFormatterNoStyle;
-                    } else if ([item isEqualToString:@"time"]) {
-                        dateStyle = kCFDateFormatterNoStyle;
-                        timeStyle = style;
-                    } else if ([item isEqualToString:@"date and time"]) {
-                        dateStyle = style;
-                        timeStyle = style;
-                    }
-                }
-            }
-        }
-    }
-
-    // get the user's default settings for date and time formats
-    CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
-            currentLocale,
-            dateStyle,
-            timeStyle);
-
-    // set the parsing to be more lenient
-    CFDateFormatterSetProperty(formatter, kCFDateFormatterIsLenient, kCFBooleanTrue);
-
-    // parse tha date and time string
-    CFDateRef date = CFDateFormatterCreateDateFromString(kCFAllocatorDefault,
-            formatter,
-            (__bridge CFStringRef)dateString,
-            NULL);
-
-    // if we were able to parse the date then get the date and time components
-    if (date != NULL) {
-        NSCalendar* calendar = [NSCalendar currentCalendar];
-
-        unsigned unitFlags = NSYearCalendarUnit |
-            NSMonthCalendarUnit |
-            NSDayCalendarUnit |
-            NSHourCalendarUnit |
-            NSMinuteCalendarUnit |
-            NSSecondCalendarUnit;
-
-        comps = [calendar components:unitFlags fromDate:(__bridge NSDate*)date];
-        CFRelease(date);
-    }
-
-    // put the various elements of the date and time into a dictionary
-    if (comps != nil) {
-        NSArray* keys = [NSArray arrayWithObjects:@"year", @"month", @"day", @"hour", @"minute", @"second", @"millisecond", nil];
-        NSArray* values = [NSArray arrayWithObjects:[NSNumber numberWithInteger:[comps year]],
-            [NSNumber numberWithInteger:[comps month] - 1],
-            [NSNumber numberWithInteger:[comps day]],
-            [NSNumber numberWithInteger:[comps hour]],
-            [NSNumber numberWithInteger:[comps minute]],
-            [NSNumber numberWithInteger:[comps second]],
-            [NSNumber numberWithInteger:0],                /* iOS does not provide milliseconds */
-            nil];
-
-        NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
-    }
-    // error
-    else {
-        // Dlog(@"GlobalizationCommand stringToDate unable to parse %@", dateString);
-        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
-        [dictionary setValue:[NSNumber numberWithInt:CDV_PARSING_ERROR] forKey:@"code"];
-        [dictionary setValue:@"unable to parse" forKey:@"message"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
-    }
-
-    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-
-    CFRelease(formatter);
-}
-
-- (void)getDatePattern:(CDVInvokedUrlCommand*)command
-{
-    CFDateFormatterStyle style = kCFDateFormatterShortStyle;
-    CFDateFormatterStyle dateStyle = kCFDateFormatterShortStyle;
-    CFDateFormatterStyle timeStyle = kCFDateFormatterShortStyle;
-    CDVPluginResult* result = nil;
-
-    NSDictionary* options;
-
-    if ([command.arguments count] > 0) {
-        options = [command.arguments objectAtIndex:0];
-    }
-    if (!options) {
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
-        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-        return;
-    }
-
-    // see if any options have been specified
-    id items = [options valueForKey:@"options"];
-
-    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
-        NSEnumerator* enumerator = [items keyEnumerator];
-        id key;
-
-        // iterate through all the options
-        while ((key = [enumerator nextObject])) {
-            id item = [items valueForKey:key];
-
-            // make sure that only string values are present
-            if ([item isKindOfClass:[NSString class]]) {
-                // get the desired format length
-                if ([key isEqualToString:@"formatLength"]) {
-                    if ([item isEqualToString:@"short"]) {
-                        style = kCFDateFormatterShortStyle;
-                    } else if ([item isEqualToString:@"medium"]) {
-                        style = kCFDateFormatterMediumStyle;
-                    } else if ([item isEqualToString:@"long"]) {
-                        style = kCFDateFormatterLongStyle;
-                    } else if ([item isEqualToString:@"full"]) {
-                        style = kCFDateFormatterFullStyle;
-                    }
-                }
-                // get the type of date and time to generate
-                else if ([key isEqualToString:@"selector"]) {
-                    if ([item isEqualToString:@"date"]) {
-                        dateStyle = style;
-                        timeStyle = kCFDateFormatterNoStyle;
-                    } else if ([item isEqualToString:@"time"]) {
-                        dateStyle = kCFDateFormatterNoStyle;
-                        timeStyle = style;
-                    } else if ([item isEqualToString:@"date and time"]) {
-                        dateStyle = style;
-                        timeStyle = style;
-                    }
-                }
-            }
-        }
-    }
-
-    // get the user's default settings for date and time formats
-    CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
-            currentLocale,
-            dateStyle,
-            timeStyle);
-
-    // get the date pattern to apply when formatting and parsing
-    CFStringRef datePattern = CFDateFormatterGetFormat(formatter);
-    // get the user's current time zone information
-    CFTimeZoneRef timezone = (CFTimeZoneRef)CFDateFormatterCopyProperty(formatter, kCFDateFormatterTimeZone);
-
-    // put the pattern and time zone information into the dictionary
-    if ((datePattern != nil) && (timezone != nil)) {
-        NSArray* keys = [NSArray arrayWithObjects:@"pattern", @"timezone", @"utc_offset", @"dst_offset", nil];
-        NSArray* values = [NSArray arrayWithObjects:((__bridge NSString*)datePattern),
-            [((__bridge NSTimeZone*)timezone)abbreviation],
-            [NSNumber numberWithLong:[((__bridge NSTimeZone*)timezone)secondsFromGMT]],
-            [NSNumber numberWithDouble:[((__bridge NSTimeZone*)timezone)daylightSavingTimeOffset]],
-            nil];
-
-        NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
-    }
-    // error
-    else {
-        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
-        [dictionary setValue:[NSNumber numberWithInt:CDV_PATTERN_ERROR] forKey:@"code"];
-        [dictionary setValue:@"Pattern error" forKey:@"message"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
-    }
-
-    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-
-    if (timezone) {
-        CFRelease(timezone);
-    }
-    CFRelease(formatter);
-}
-
-- (void)getDateNames:(CDVInvokedUrlCommand*)command
-{
-    int style = CDV_FORMAT_LONG;
-    int selector = CDV_SELECTOR_MONTHS;
-    CFStringRef dataStyle = kCFDateFormatterMonthSymbols;
-    CDVPluginResult* result = nil;
-
-    NSDictionary* options;
-
-    if ([command.arguments count] > 0) {
-        options = [command.arguments objectAtIndex:0];
-    }
-    if (!options) {
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
-        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-        return;
-    }
-
-    // see if any options have been specified
-    id items = [options valueForKey:@"options"];
-
-    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
-        NSEnumerator* enumerator = [items keyEnumerator];
-        id key;
-
-        // iterate through all the options
-        while ((key = [enumerator nextObject])) {
-            id item = [items valueForKey:key];
-
-            // make sure that only string values are present
-            if ([item isKindOfClass:[NSString class]]) {
-                // get the desired type of name
-                if ([key isEqualToString:@"type"]) {
-                    if ([item isEqualToString:@"narrow"]) {
-                        style = CDV_FORMAT_SHORT;
-                    } else if ([item isEqualToString:@"wide"]) {
-                        style = CDV_FORMAT_LONG;
-                    }
-                }
-                // determine if months or days are needed
-                else if ([key isEqualToString:@"item"]) {
-                    if ([item isEqualToString:@"months"]) {
-                        selector = CDV_SELECTOR_MONTHS;
-                    } else if ([item isEqualToString:@"days"]) {
-                        selector = CDV_SELECTOR_DAYS;
-                    }
-                }
-            }
-        }
-    }
-
-    CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
-            currentLocale,
-            kCFDateFormatterFullStyle,
-            kCFDateFormatterFullStyle);
-
-    if ((selector == CDV_SELECTOR_MONTHS) && (style == CDV_FORMAT_LONG)) {
-        dataStyle = kCFDateFormatterMonthSymbols;
-    } else if ((selector == CDV_SELECTOR_MONTHS) && (style == CDV_FORMAT_SHORT)) {
-        dataStyle = kCFDateFormatterShortMonthSymbols;
-    } else if ((selector == CDV_SELECTOR_DAYS) && (style == CDV_FORMAT_LONG)) {
-        dataStyle = kCFDateFormatterWeekdaySymbols;
-    } else if ((selector == CDV_SELECTOR_DAYS) && (style == CDV_FORMAT_SHORT)) {
-        dataStyle = kCFDateFormatterShortWeekdaySymbols;
-    }
-
-    CFArrayRef names = (CFArrayRef)CFDateFormatterCopyProperty(formatter, dataStyle);
-
-    if (names) {
-        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:((__bridge NSArray*)names) forKey:@"value"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
-        CFRelease(names);
-    }
-    // error
-    else {
-        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
-        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
-        [dictionary setValue:@"Unknown error" forKey:@"message"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
-    }
-
-    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-
-    CFRelease(formatter);
-}
-
-- (void)isDayLightSavingsTime:(CDVInvokedUrlCommand*)command
-{
-    NSDate* date = nil;
-    CDVPluginResult* result = nil;
-
-    NSDictionary* options;
-
-    if ([command.arguments count] > 0) {
-        options = [command.arguments objectAtIndex:0];
-    }
-    if (!options) {
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
-        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-        return;
-    }
-
-    id milliseconds = [options valueForKey:@"date"];
-
-    if (milliseconds && [milliseconds isKindOfClass:[NSNumber class]]) {
-        // get the number of seconds since 1970 and create the date object
-        date = [NSDate dateWithTimeIntervalSince1970:[milliseconds doubleValue] / 1000];
-    }
-
-    if (date) {
-        // get the current calendar for the user and check if the date is using DST
-        NSCalendar* calendar = [NSCalendar currentCalendar];
-        NSTimeZone* timezone = [calendar timeZone];
-        NSNumber* dst = [NSNumber numberWithBool:[timezone isDaylightSavingTimeForDate:date]];
-
-        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:dst forKey:@"dst"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
-    }
-    // error
-    else {
-        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
-        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
-        [dictionary setValue:@"Unknown error" forKey:@"message"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
-    }
-    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-}
-
-- (void)getFirstDayOfWeek:(CDVInvokedUrlCommand*)command
-{
-    CDVPluginResult* result = nil;
-
-    NSCalendar* calendar = [NSCalendar autoupdatingCurrentCalendar];
-
-    NSNumber* day = [NSNumber numberWithInteger:[calendar firstWeekday]];
-
-    if (day) {
-        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:day forKey:@"value"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
-    }
-    // error
-    else {
-        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
-        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
-        [dictionary setValue:@"Unknown error" forKey:@"message"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
-    }
-
-    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-}
-
-- (void)numberToString:(CDVInvokedUrlCommand*)command
-{
-    CDVPluginResult* result = nil;
-    CFNumberFormatterStyle style = kCFNumberFormatterDecimalStyle;
-    NSNumber* number = nil;
-
-    NSDictionary* options;
-
-    if ([command.arguments count] > 0) {
-        options = [command.arguments objectAtIndex:0];
-    }
-    if (!options) {
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
-        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-        return;
-    }
-
-    id value = [options valueForKey:@"number"];
-
-    if (value && [value isKindOfClass:[NSNumber class]]) {
-        number = (NSNumber*)value;
-    }
-
-    // see if any options have been specified
-    id items = [options valueForKey:@"options"];
-    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
-        NSEnumerator* enumerator = [items keyEnumerator];
-        id key;
-
-        // iterate through all the options
-        while ((key = [enumerator nextObject])) {
-            id item = [items valueForKey:key];
-
-            // make sure that only string values are present
-            if ([item isKindOfClass:[NSString class]]) {
-                // get the desired style of formatting
-                if ([key isEqualToString:@"type"]) {
-                    if ([item isEqualToString:@"percent"]) {
-                        style = kCFNumberFormatterPercentStyle;
-                    } else if ([item isEqualToString:@"currency"]) {
-                        style = kCFNumberFormatterCurrencyStyle;
-                    } else if ([item isEqualToString:@"decimal"]) {
-                        style = kCFNumberFormatterDecimalStyle;
-                    }
-                }
-            }
-        }
-    }
-
-    CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
-            currentLocale,
-            style);
-
-    // get the localized string based upon the locale and user preferences
-    NSString* numberString = (__bridge_transfer NSString*)CFNumberFormatterCreateStringWithNumber(kCFAllocatorDefault,
-            formatter,
-            (__bridge CFNumberRef)number);
-
-    if (numberString) {
-        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:numberString forKey:@"value"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
-    }
-    // error
-    else {
-        // DLog(@"GlobalizationCommand numberToString unable to format %@", [number stringValue]);
-        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
-        [dictionary setValue:[NSNumber numberWithInt:CDV_FORMATTING_ERROR] forKey:@"code"];
-        [dictionary setValue:@"Unable to format" forKey:@"message"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
-    }
-
-    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-
-    CFRelease(formatter);
-}
-
-- (void)stringToNumber:(CDVInvokedUrlCommand*)command
-{
-    CDVPluginResult* result = nil;
-    CFNumberFormatterStyle style = kCFNumberFormatterDecimalStyle;
-    NSString* numberString = nil;
-    double doubleValue;
-
-    NSDictionary* options;
-
-    if ([command.arguments count] > 0) {
-        options = [command.arguments objectAtIndex:0];
-    }
-    if (!options) {
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
-        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-        return;
-    }
-
-    id value = [options valueForKey:@"numberString"];
-
-    if (value && [value isKindOfClass:[NSString class]]) {
-        numberString = (NSString*)value;
-    }
-
-    // see if any options have been specified
-    id items = [options valueForKey:@"options"];
-    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
-        NSEnumerator* enumerator = [items keyEnumerator];
-        id key;
-
-        // iterate through all the options
-        while ((key = [enumerator nextObject])) {
-            id item = [items valueForKey:key];
-
-            // make sure that only string values are present
-            if ([item isKindOfClass:[NSString class]]) {
-                // get the desired style of formatting
-                if ([key isEqualToString:@"type"]) {
-                    if ([item isEqualToString:@"percent"]) {
-                        style = kCFNumberFormatterPercentStyle;
-                    } else if ([item isEqualToString:@"currency"]) {
-                        style = kCFNumberFormatterCurrencyStyle;
-                    } else if ([item isEqualToString:@"decimal"]) {
-                        style = kCFNumberFormatterDecimalStyle;
-                    }
-                }
-            }
-        }
-    }
-
-    CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
-            currentLocale,
-            style);
-
-    // we need to make this lenient so as to avoid problems with parsing currencies that have non-breaking space characters
-    if (style == kCFNumberFormatterCurrencyStyle) {
-        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterIsLenient, kCFBooleanTrue);
-    }
-
-    // parse againist the largest type to avoid data loss
-    Boolean rc = CFNumberFormatterGetValueFromString(formatter,
-            (__bridge CFStringRef)numberString,
-            NULL,
-            kCFNumberDoubleType,
-            &doubleValue);
-
-    if (rc) {
-        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithDouble:doubleValue] forKey:@"value"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
-    }
-    // error
-    else {
-        // DLog(@"GlobalizationCommand stringToNumber unable to parse %@", numberString);
-        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
-        [dictionary setValue:[NSNumber numberWithInt:CDV_PARSING_ERROR] forKey:@"code"];
-        [dictionary setValue:@"Unable to parse" forKey:@"message"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
-    }
-
-    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-
-    CFRelease(formatter);
-}
-
-- (void)getNumberPattern:(CDVInvokedUrlCommand*)command
-{
-    CDVPluginResult* result = nil;
-    CFNumberFormatterStyle style = kCFNumberFormatterDecimalStyle;
-    CFStringRef symbolType = NULL;
-    NSString* symbol = @"";
-
-    NSDictionary* options;
-
-    if ([command.arguments count] > 0) {
-        options = [command.arguments objectAtIndex:0];
-    }
-    if (!options) {
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
-        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-        return;
-    }
-
-    // see if any options have been specified
-    id items = [options valueForKey:@"options"];
-
-    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
-        NSEnumerator* enumerator = [items keyEnumerator];
-        id key;
-
-        // iterate through all the options
-        while ((key = [enumerator nextObject])) {
-            id item = [items valueForKey:key];
-
-            // make sure that only string values are present
-            if ([item isKindOfClass:[NSString class]]) {
-                // get the desired style of formatting
-                if ([key isEqualToString:@"type"]) {
-                    if ([item isEqualToString:@"percent"]) {
-                        style = kCFNumberFormatterPercentStyle;
-                    } else if ([item isEqualToString:@"currency"]) {
-                        style = kCFNumberFormatterCurrencyStyle;
-                    } else if ([item isEqualToString:@"decimal"]) {
-                        style = kCFNumberFormatterDecimalStyle;
-                    }
-                }
-            }
-        }
-    }
-
-    CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
-            currentLocale,
-            style);
-
-    NSString* numberPattern = (__bridge NSString*)CFNumberFormatterGetFormat(formatter);
-
-    if (style == kCFNumberFormatterCurrencyStyle) {
-        symbolType = kCFNumberFormatterCurrencySymbol;
-    } else if (style == kCFNumberFormatterPercentStyle) {
-        symbolType = kCFNumberFormatterPercentSymbol;
-    }
-
-    if (symbolType) {
-        symbol = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, symbolType);
-    }
-
-    NSString* decimal = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterDecimalSeparator);
-    NSString* grouping = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterGroupingSeparator);
-    NSString* posSign = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterPlusSign);
-    NSString* negSign = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterMinusSign);
-    NSNumber* fracDigits = (__bridge_transfer NSNumber*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterMinFractionDigits);
-    NSNumber* roundingDigits = (__bridge_transfer NSNumber*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterRoundingIncrement);
-
-    // put the pattern information into the dictionary
-    if (numberPattern != nil) {
-        NSArray* keys = [NSArray arrayWithObjects:@"pattern", @"symbol", @"fraction", @"rounding",
-            @"positive", @"negative", @"decimal", @"grouping", nil];
-        NSArray* values = [NSArray arrayWithObjects:numberPattern, symbol, fracDigits, roundingDigits,
-            posSign, negSign, decimal, grouping, nil];
-        NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
-    }
-    // error
-    else {
-        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
-        [dictionary setValue:[NSNumber numberWithInt:CDV_PATTERN_ERROR] forKey:@"code"];
-        [dictionary setValue:@"Pattern error" forKey:@"message"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
-    }
-
-    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-
-    CFRelease(formatter);
-}
-
-- (void)getCurrencyPattern:(CDVInvokedUrlCommand*)command
-{
-    CDVPluginResult* result = nil;
-    NSString* currencyCode = nil;
-    NSString* numberPattern = nil;
-    NSString* decimal = nil;
-    NSString* grouping = nil;
-    int32_t defaultFractionDigits;
-    double roundingIncrement;
-    Boolean rc;
-
-    NSDictionary* options;
-
-    if ([command.arguments count] > 0) {
-        options = [command.arguments objectAtIndex:0];
-    }
-    if (!options) {
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no options given"];
-        [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-        return;
-    }
-
-    id value = [options valueForKey:@"currencyCode"];
-
-    if (value && [value isKindOfClass:[NSString class]]) {
-        currencyCode = (NSString*)value;
-    }
-
-    // first see if there is base currency info available and fill in the currency_info structure
-    rc = CFNumberFormatterGetDecimalInfoForCurrencyCode((__bridge CFStringRef)currencyCode, &defaultFractionDigits, &roundingIncrement);
-
-    // now set the currency code in the formatter
-    if (rc) {
-        CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
-                currentLocale,
-                kCFNumberFormatterCurrencyStyle);
-
-        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterCurrencyCode, (__bridge CFStringRef)currencyCode);
-        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterInternationalCurrencySymbol, (__bridge CFStringRef)currencyCode);
-
-        numberPattern = (__bridge NSString*)CFNumberFormatterGetFormat(formatter);
-        decimal = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterCurrencyDecimalSeparator);
-        grouping = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterCurrencyGroupingSeparator);
-
-        NSArray* keys = [NSArray arrayWithObjects:@"pattern", @"code", @"fraction", @"rounding",
-            @"decimal", @"grouping", nil];
-        NSArray* values = [NSArray arrayWithObjects:numberPattern, currencyCode, [NSNumber numberWithInt:defaultFractionDigits],
-            [NSNumber numberWithDouble:roundingIncrement], decimal, grouping, nil];
-        NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
-        CFRelease(formatter);
-    }
-    // error
-    else {
-        // DLog(@"GlobalizationCommand getCurrencyPattern unable to get pattern for %@", currencyCode);
-        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
-        [dictionary setValue:[NSNumber numberWithInt:CDV_PATTERN_ERROR] forKey:@"code"];
-        [dictionary setValue:@"Unable to get pattern" forKey:@"message"];
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
-    }
-
-    [self.commandDelegate sendPluginResult:result callbackId:[command callbackId]];
-}
-
-- (void)dealloc
-{
-    if (currentLocale) {
-        CFRelease(currentLocale);
-        currentLocale = nil;
-    }
-}
-
-@end
diff --git a/src/tizen/GlobalizationProxy.js b/src/tizen/GlobalizationProxy.js
deleted file mode 100644
index 6f8c84e..0000000
--- a/src/tizen/GlobalizationProxy.js
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- *
- * 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.
- *
-*/
-
-var argscheck = require('cordova/argscheck'),
-    GlobalizationError = require('org.apache.cordova.globalization.GlobalizationError');
-
-var globalization = {
-    /**
-    * Returns the string identifier for the client's current language.
-    * It returns the language identifier string to the successCB callback with a
-    * properties object as a parameter. If there is an error getting the language,
-    * then the errorCB callback is invoked.
-    *
-    * @param {Function} successCB
-    * @param {Function} errorCB
-    *
-    * @return Object.value {String}: The language identifier
-    *
-    * @error GlobalizationError.UNKNOWN_ERROR
-    *
-    * Example
-    *    globalization.getPreferredLanguage(function (language) {alert('language:' + language.value + '\n');},
-    *                                function () {});
-    */
-    getPreferredLanguage:function(successCB, failureCB) {
-        console.log('exec(successCB, failureCB, "Globalization","getPreferredLanguage", []);');
-
-        tizen.systeminfo.getPropertyValue (
-            "LOCALE",
-            function (localeInfo) {
-                console.log("Cordova, getLocaleName, language is  " + localeInfo.language);
-                successCB( {"value": localeInfo.language});
-            },
-            function(error) {
-                console.log("Cordova, getLocaleName, An error occurred " + error.message);
-                failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "cannot retrieve language name"));
-            }
-        );
-    },
-
-    /**
-    * Returns the string identifier for the client's current locale setting.
-    * It returns the locale identifier string to the successCB callback with a
-    * properties object as a parameter. If there is an error getting the locale,
-    * then the errorCB callback is invoked.
-    *
-    * @param {Function} successCB
-    * @param {Function} errorCB
-    *
-    * @return Object.value {String}: The locale identifier
-    *
-    * @error GlobalizationError.UNKNOWN_ERROR
-    *
-    * Example
-    *    globalization.getLocaleName(function (locale) {alert('locale:' + locale.value + '\n');},
-    *                                function () {});
-    */
-    getLocaleName:function(successCB, failureCB) {
-        tizen.systeminfo.getPropertyValue (
-            "LOCALE",
-            function (localeInfo) {
-                console.log("Cordova, getLocaleName, locale name (country) is  " + localeInfo.country);
-                successCB( {"value":localeInfo.language});
-            },
-            function(error) {
-                console.log("Cordova, getLocaleName, An error occurred " + error.message);
-                failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "cannot retrieve locale name"));
-            }
-        );
-    },
-
-
-    /**
-    * Returns a date formatted as a string according to the client's user preferences and
-    * calendar using the time zone of the client. It returns the formatted date string to the
-    * successCB callback with a properties object as a parameter. If there is an error
-    * formatting the date, then the errorCB callback is invoked.
-    *
-    * The defaults are: formatLenght="short" and selector="date and time"
-    *
-    * @param {Date} date
-    * @param {Function} successCB
-    * @param {Function} errorCB
-    * @param {Object} options {optional}
-    *            formatLength {String}: 'short', 'medium', 'long', or 'full'
-    *            selector {String}: 'date', 'time', or 'date and time'
-    *
-    * @return Object.value {String}: The localized date string
-    *
-    * @error GlobalizationError.FORMATTING_ERROR
-    *
-    * Example
-    *    globalization.dateToString(new Date(),
-    *                function (date) {alert('date:' + date.value + '\n');},
-    *                function (errorCode) {alert(errorCode);},
-    *                {formatLength:'short'});
-    */
-    dateToString:function(date, successCB, failureCB, options) {
-        var dateValue = date.valueOf();
-        console.log('exec(successCB, failureCB, "Globalization", "dateToString", [{"date": dateValue, "options": options}]);');
-
-        var tzdate = null;
-        var format = null;
-
-        tzdate = new tizen.TZDate(date);
-
-        if (tzdate) {
-            if (options && (options.formatLength == 'short') ){
-                format = tzdate.toLocaleDateString();
-            }
-            else{
-                format = tzdate.toLocaleString();
-            }
-            console.log('Cordova, globalization, dateToString ' +format);
-        }
-
-        if (format)
-        {
-            successCB ({"value": format});
-        }
-        else {
-            failureCB(new GlobalizationError(GlobalizationError.FORMATTING_ERROR , "cannot format date string"));
-        }
-    },
-
-
-    /**
-    * Parses a date formatted as a string according to the client's user
-    * preferences and calendar using the time zone of the client and returns
-    * the corresponding date object. It returns the date to the successCB
-    * callback with a properties object as a parameter. If there is an error
-    * parsing the date string, then the errorCB callback is invoked.
-    *
-    * The defaults are: formatLength="short" and selector="date and time"
-    *
-    * @param {String} dateString
-    * @param {Function} successCB
-    * @param {Function} errorCB
-    * @param {Object} options {optional}
-    *            formatLength {String}: 'short', 'medium', 'long', or 'full'
-    *            selector {String}: 'date', 'time', or 'date and time'
-    *
-    * @return    Object.year {Number}: The four digit year
-    *            Object.month {Number}: The month from (0 - 11)
-    *            Object.day {Number}: The day from (1 - 31)
-    *            Object.hour {Number}: The hour from (0 - 23)
-    *            Object.minute {Number}: The minute from (0 - 59)
-    *            Object.second {Number}: The second from (0 - 59)
-    *            Object.millisecond {Number}: The milliseconds (from 0 - 999),
-    *                                        not available on all platforms
-    *
-    * @error GlobalizationError.PARSING_ERROR
-    *
-    * Example
-    *    globalization.stringToDate('4/11/2011',
-    *                function (date) { alert('Month:' + date.month + '\n' +
-    *                    'Day:' + date.day + '\n' +
-    *                    'Year:' + date.year + '\n');},
-    *                function (errorCode) {alert(errorCode);},
-    *                {selector:'date'});
-    */
-    stringToDate:function(dateString, successCB, failureCB, options) {
-        argscheck.checkArgs('sfFO', 'Globalization.stringToDate', arguments);
-        console.log('exec(successCB, failureCB, "Globalization", "stringToDate", [{"dateString": dateString, "options": options}]);');
-
-        //not supported
-        failureCB(new GlobalizationError(GlobalizationError.PARSING_ERROR , "unsupported"));
-    },
-
-
-    /**
-    * Returns a pattern string for formatting and parsing dates according to the client's
-    * user preferences. It returns the pattern to the successCB callback with a
-    * properties object as a parameter. If there is an error obtaining the pattern,
-    * then the errorCB callback is invoked.
-    *
-    * The defaults are: formatLength="short" and selector="date and time"
-    *
-    * @param {Function} successCB
-    * @param {Function} errorCB
-    * @param {Object} options {optional}
-    *            formatLength {String}: 'short', 'medium', 'long', or 'full'
-    *            selector {String}: 'date', 'time', or 'date and time'
-    *
-    * @return    Object.pattern {String}: The date and time pattern for formatting and parsing dates.
-    *                                    The patterns follow Unicode Technical Standard #35
-    *                                    http://unicode.org/reports/tr35/tr35-4.html
-    *            Object.timezone {String}: The abbreviated name of the time zone on the client
-    *            Object.utc_offset {Number}: The current difference in seconds between the client's
-    *                                        time zone and coordinated universal time.
-    *            Object.dst_offset {Number}: The current daylight saving time offset in seconds
-    *                                        between the client's non-daylight saving's time zone
-    *                                        and the client's daylight saving's time zone.
-    *
-    * @error GlobalizationError.PATTERN_ERROR
-    *
-    * Example
-    *    globalization.getDatePattern(
-    *                function (date) {alert('pattern:' + date.pattern + '\n');},
-    *                function () {},
-    *                {formatLength:'short'});
-    */
-    getDatePattern:function(successCB, failureCB, options) {
-        console.log(' exec(successCB, failureCB, "Globalization", "getDatePattern", [{"options": options}]);');
-
-        var shortFormat = (options) ? ( options.formatLength === 'short') : true;
-
-        var formatString = tizen.time.getDateFormat ( shortFormat);
-
-
-        var current_datetime = tizen.time.getCurrentDateTime();
-
-        // probably will require some control of operation...
-        if (formatString)
-        {
-            successCB(
-                {
-                    "pattern": formatString,
-                    "timezone": current_datetime.getTimezoneAbbreviation(),
-                    "utc_offset": current_datetime.difference(current_datetime.toUTC()).length,
-                    "dst_offset": current_datetime.isDST()
-                }
-            );
-        }
-        else {
-            failureCB(new GlobalizationError(GlobalizationError.PATTERN_ERROR , "cannot get pattern"));
-        }
-    },
-
-
-    /**
-    * Returns an array of either the names of the months or days of the week
-    * according to the client's user preferences and calendar. It returns the array of names to the
-    * successCB callback with a properties object as a parameter. If there is an error obtaining the
-    * names, then the errorCB callback is invoked.
-    *
-    * The defaults are: type="wide" and item="months"
-    *
-    * @param {Function} successCB
-    * @param {Function} errorCB
-    * @param {Object} options {optional}
-    *            type {String}: 'narrow' or 'wide'
-    *            item {String}: 'months', or 'days'
-    *
-    * @return Object.value {Array{String}}: The array of names starting from either
-    *                                        the first month in the year or the
-    *                                        first day of the week.
-    * @error GlobalizationError.UNKNOWN_ERROR
-    *
-    * Example
-    *    globalization.getDateNames(function (names) {
-    *        for(var i = 0; i < names.value.length; i++) {
-    *            alert('Month:' + names.value[i] + '\n');}},
-    *        function () {});
-    */
-    getDateNames:function(successCB, failureCB, options) {
-        argscheck.checkArgs('fFO', 'Globalization.getDateNames', arguments);
-        console.log('exec(successCB, failureCB, "Globalization", "getDateNames", [{"options": options}]);');
-
-        failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported"));
-    },
-
-    /**
-    * Returns whether daylight savings time is in effect for a given date using the client's
-    * time zone and calendar. It returns whether or not daylight savings time is in effect
-    * to the successCB callback with a properties object as a parameter. If there is an error
-    * reading the date, then the errorCB callback is invoked.
-    *
-    * @param {Date} date
-    * @param {Function} successCB
-    * @param {Function} errorCB
-    *
-    * @return Object.dst {Boolean}: The value "true" indicates that daylight savings time is
-    *                                in effect for the given date and "false" indicate that it is not.
-    *
-    * @error GlobalizationError.UNKNOWN_ERROR
-    *
-    * Example
-    *    globalization.isDayLightSavingsTime(new Date(),
-    *                function (date) {alert('dst:' + date.dst + '\n');}
-    *                function () {});
-    */
-    isDayLightSavingsTime:function(date, successCB, failureCB) {
-
-        var tzdate = null,
-            isDLS = false;
-
-        console.log('exec(successCB, failureCB, "Globalization", "isDayLightSavingsTime", [{"date": dateValue}]);');
-        console.log("date " + date + " value " + date.valueOf()) ;
-
-        tzdate = new tizen.TZDate(date);
-        if (tzdate) {
-            isDLS = false | (tzdate && tzdate.isDST());
-
-            console.log ("Cordova, globalization, isDayLightSavingsTime, " + isDLS);
-
-            successCB({"dst":isDLS});
-        }
-        else {
-            failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "cannot get information"));
-        }
-    },
-
-    /**
-    * Returns the first day of the week according to the client's user preferences and calendar.
-    * The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
-    * It returns the day to the successCB callback with a properties object as a parameter.
-    * If there is an error obtaining the pattern, then the errorCB callback is invoked.
-    *
-    * @param {Function} successCB
-    * @param {Function} errorCB
-    *
-    * @return Object.value {Number}: The number of the first day of the week.
-    *
-    * @error GlobalizationError.UNKNOWN_ERROR
-    *
-    * Example
-    *    globalization.getFirstDayOfWeek(function (day)
-    *                { alert('Day:' + day.value + '\n');},
-    *                function () {});
-    */
-    getFirstDayOfWeek:function(successCB, failureCB) {
-        argscheck.checkArgs('fF', 'Globalization.getFirstDayOfWeek', arguments);
-        console.log('exec(successCB, failureCB, "Globalization", "getFirstDayOfWeek", []);');
-
-        // there is no API to get the fist day of the week in Tizen Dvice API
-        successCB({value:1});
-
-        // first day of week is a settings in the date book app
-        // what about : getting the settings directly or asking the date book ?
-    },
-
-
-    /**
-    * Returns a number formatted as a string according to the client's user preferences.
-    * It returns the formatted number string to the successCB callback with a properties object as a
-    * parameter. If there is an error formatting the number, then the errorCB callback is invoked.
-    *
-    * The defaults are: type="decimal"
-    *
-    * @param {Number} number
-    * @param {Function} successCB
-    * @param {Function} errorCB
-    * @param {Object} options {optional}
-    *            type {String}: 'decimal', "percent", or 'currency'
-    *
-    * @return Object.value {String}: The formatted number string.
-    *
-    * @error GlobalizationError.FORMATTING_ERROR
-    *
-    * Example
-    *    globalization.numberToString(3.25,
-    *                function (number) {alert('number:' + number.value + '\n');},
-    *                function () {},
-    *                {type:'decimal'});
-    */
-    numberToString:function(number, successCB, failureCB, options) {
-        argscheck.checkArgs('nfFO', 'Globalization.numberToString', arguments);
-        console.log('exec(successCB, failureCB, "Globalization", "numberToString", [{"number": number, "options": options}]);');
-        //not supported
-        failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported"));
-    },
-
-    /**
-    * Parses a number formatted as a string according to the client's user preferences and
-    * returns the corresponding number. It returns the number to the successCB callback with a
-    * properties object as a parameter. If there is an error parsing the number string, then
-    * the errorCB callback is invoked.
-    *
-    * The defaults are: type="decimal"
-    *
-    * @param {String} numberString
-    * @param {Function} successCB
-    * @param {Function} errorCB
-    * @param {Object} options {optional}
-    *            type {String}: 'decimal', "percent", or 'currency'
-    *
-    * @return Object.value {Number}: The parsed number.
-    *
-    * @error GlobalizationError.PARSING_ERROR
-    *
-    * Example
-    *    globalization.stringToNumber('1234.56',
-    *                function (number) {alert('Number:' + number.value + '\n');},
-    *                function () { alert('Error parsing number');});
-    */
-    stringToNumber:function(numberString, successCB, failureCB, options) {
-        argscheck.checkArgs('sfFO', 'Globalization.stringToNumber', arguments);
-        console.log('exec(successCB, failureCB, "Globalization", "stringToNumber", [{"numberString": numberString, "options": options}]);');
-
-        //not supported
-        failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported"));
-    },
-
-    /**
-    * Returns a pattern string for formatting and parsing numbers according to the client's user
-    * preferences. It returns the pattern to the successCB callback with a properties object as a
-    * parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked.
-    *
-    * The defaults are: type="decimal"
-    *
-    * @param {Function} successCB
-    * @param {Function} errorCB
-    * @param {Object} options {optional}
-    *            type {String}: 'decimal', "percent", or 'currency'
-    *
-    * @return    Object.pattern {String}: The number pattern for formatting and parsing numbers.
-    *                                    The patterns follow Unicode Technical Standard #35.
-    *                                    http://unicode.org/reports/tr35/tr35-4.html
-    *            Object.symbol {String}: The symbol to be used when formatting and parsing
-    *                                    e.g., percent or currency symbol.
-    *            Object.fraction {Number}: The number of fractional digits to use when parsing and
-    *                                    formatting numbers.
-    *            Object.rounding {Number}: The rounding increment to use when parsing and formatting.
-    *            Object.positive {String}: The symbol to use for positive numbers when parsing and formatting.
-    *            Object.negative: {String}: The symbol to use for negative numbers when parsing and formatting.
-    *            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
-    *            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
-    *
-    * @error GlobalizationError.PATTERN_ERROR
-    *
-    * Example
-    *    globalization.getNumberPattern(
-    *                function (pattern) {alert('Pattern:' + pattern.pattern + '\n');},
-    *                function () {});
-    */
-    getNumberPattern:function(successCB, failureCB, options) {
-        argscheck.checkArgs('fFO', 'Globalization.getNumberPattern', arguments);
-        console.log('exec(successCB, failureCB, "Globalization", "getNumberPattern", [{"options": options}]);');
-
-        //not supported
-        failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported"));
-    },
-
-    /**
-    * Returns a pattern string for formatting and parsing currency values according to the client's
-    * user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a
-    * properties object as a parameter. If there is an error obtaining the pattern, then the errorCB
-    * callback is invoked.
-    *
-    * @param {String} currencyCode
-    * @param {Function} successCB
-    * @param {Function} errorCB
-    *
-    * @return    Object.pattern {String}: The currency pattern for formatting and parsing currency values.
-    *                                    The patterns follow Unicode Technical Standard #35
-    *                                    http://unicode.org/reports/tr35/tr35-4.html
-    *            Object.code {String}: The ISO 4217 currency code for the pattern.
-    *            Object.fraction {Number}: The number of fractional digits to use when parsing and
-    *                                    formatting currency.
-    *            Object.rounding {Number}: The rounding increment to use when parsing and formatting.
-    *            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
-    *            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
-    *
-    * @error GlobalizationError.FORMATTING_ERROR
-    *
-    * Example
-    *    globalization.getCurrencyPattern('EUR',
-    *                function (currency) {alert('Pattern:' + currency.pattern + '\n');}
-    *                function () {});
-    */
-    getCurrencyPattern:function(currencyCode, successCB, failureCB) {
-        argscheck.checkArgs('sfF', 'Globalization.getCurrencyPattern', arguments);
-        console.log('exec(successCB, failureCB, "Globalization", "getCurrencyPattern", [{"currencyCode": currencyCode}]);');
-
-        //not supported
-        failureCB(new GlobalizationError(GlobalizationError.UNKNOWN_ERROR , "unsupported"));
-    }
-};
-
-module.exports = globalization;
-
-require("cordova/tizen/commandProxy").add("Globalization", module.exports);
diff --git a/src/ubuntu/globalization.cpp b/src/ubuntu/globalization.cpp
deleted file mode 100644
index 2c15017..0000000
--- a/src/ubuntu/globalization.cpp
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- *
- * Copyright 2013 Canonical Ltd.
- *
- * Licensed 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.
- *
-*/
-
-#include <ctime> //TODO: switch to QTimeZone (QT 5.1)
-#include <unicode/decimfmt.h>
-#include <unicode/timezone.h>
-
-#include "globalization.h"
-
-Globalization::Globalization(Cordova *cordova):
-    CPlugin(cordova) {
-}
-
-void Globalization::getPreferredLanguage(int scId, int ecId) {
-    Q_UNUSED(ecId)
-
-    QLocale locale;
-    QString lang = QLocale::languageToString(locale.language());
-    QVariantMap obj;
-    obj.insert("value", lang);
-    this->cb(scId, obj);
-}
-
-void Globalization::getLocaleName(int scId, int ecId) {
-    Q_UNUSED(ecId)
-
-    QVariantMap obj;
-    obj.insert("value", QLocale().name());
-    this->cb(scId, obj);
-}
-
-void Globalization::getFirstDayOfWeek(int scId, int ecId) {
-    Q_UNUSED(ecId)
-
-    QLocale locale;
-
-    int res;
-    if (locale.firstDayOfWeek() == Qt::Sunday) {
-        res = 1;
-    } else {
-        res = (2 - Qt::Monday) + locale.firstDayOfWeek();
-    }
-
-    QVariantMap obj;
-    obj.insert("value", res);
-    this->cb(scId, obj);
-}
-
-void Globalization::isDayLightSavingsTime(int scId, int ecId, const QVariantMap &options) {
-    time_t time = options.find("time_t")->toLongLong() / 1000;
-    const tm *desc = std::localtime(&time);
-    if (desc->tm_isdst < 0) {
-        this->callback(ecId, QString("new GlobalizationError(%1, 'information is not available');").arg(Globalization::UNKNOWN_ERROR));
-        return;
-    }
-    this->callback(scId, QString("{dst:%1}").arg(desc->tm_isdst > 0 ? "true" : "false"));
-}
-
-QLocale::FormatType translateFormat(Globalization::Format formatLength) {
-    QLocale::FormatType format = QLocale::ShortFormat;
-    switch (formatLength) {
-    case Globalization::FORMAT_FULL:
-    case Globalization::FORMAT_LONG:
-        format = QLocale::ShortFormat; // TODO: Qt cant parse string produced with QLocale::LongFormat;
-        break;
-    case Globalization::FORMAT_MEDIUM:
-        format = QLocale::ShortFormat;
-        break;
-    case Globalization::FORMAT_SHORT:
-        format = QLocale::NarrowFormat;
-        break;
-    }
-    return format;
-}
-
-void Globalization::dateToString(int scId, int ecId, const QVariantMap &options) {
-    time_t time = options.find("time_t")->toLongLong() / 1000;
-
-    Globalization::Format formatLength = static_cast<Globalization::Format>(options.find("formatLength")->toInt());
-    Globalization::Selector selector = static_cast<Globalization::Selector>(options.find("selector")->toInt());
-
-    QLocale::FormatType format = translateFormat(formatLength);
-    if (time < 0) {
-        this->callback(ecId, QString("new GlobalizationError(%1, 'unsupported operation');").arg(Globalization::FORMATTING_ERROR));
-        return;
-    }
-
-    QLocale locale;
-    QString res;
-    QDateTime dateTime = QDateTime::fromTime_t((uint)time);
-    switch (selector) {
-    case SELECTOR_ALL:
-        res = locale.toString(dateTime,format);
-        break;
-    case SELECTOR_TIME:
-        res = locale.toString(dateTime.time(), format);
-        break;
-    case SELECTOR_DATE:
-        res = locale.toString(dateTime.date(), format);
-        break;
-    }
-    QVariantMap obj;
-    obj.insert("value", res);
-    this->cb(scId, obj);
-}
-
-void Globalization::stringToDate(int scId, int ecId, const QVariantMap &options) {
-    QString dateString = options.find("dateString")->toString();
-    Globalization::Format formatLength = static_cast<Globalization::Format>(options.find("formatLength")->toInt());
-    Globalization::Selector selector = static_cast<Globalization::Selector>(options.find("selector")->toInt());
-
-    QLocale::FormatType format = translateFormat(formatLength);
-    QLocale locale;
-    bool valid(true);
-    int year(0), month(0), day(0), hour(0), minute(0), second(0), millisecond(0);
-    switch (selector) {
-    case SELECTOR_ALL:
-        {
-            QDateTime dateTime = locale.toDateTime(dateString, format);
-            valid = dateTime.isValid();
-            QTime time = dateTime.time();
-            hour = time.hour(); minute = time.minute(); second = time.second(); millisecond = time.msec();
-            QDate date = dateTime.date();
-            year = date.year(); month = date.month(); day = date.day();
-        }
-        break;
-    case SELECTOR_TIME:
-        {
-            QTime time = locale.toTime(dateString, format);
-            valid = time.isValid();
-            hour = time.hour(); minute = time.minute(); second = time.second(); millisecond = time.msec();
-        }
-        break;
-    case SELECTOR_DATE:
-        {
-            QDate date = locale.toDate(dateString, format);
-            valid = date.isValid();
-            year = date.year(); month = date.month(); day = date.day();
-        }
-        break;
-    }
-    if ((format == QLocale::NarrowFormat || format == QLocale::ShortFormat) && year < 2000 && year > 1900) {
-        year += 100;
-    }
-    if (!valid) {
-        this->callback(ecId, QString("new GlobalizationError(%1, 'parsing error')").arg(Globalization::PARSING_ERROR));
-    } else {
-        QVariantMap obj;
-        obj.insert("year", year);
-        obj.insert("month", month - 1);
-        obj.insert("day", day);
-        obj.insert("hour", hour);
-        obj.insert("minute", minute);
-        obj.insert("second", second);
-        obj.insert("millisecond", millisecond);
-        this->cb(scId, obj);
-    }
-}
-
-void Globalization::getDateNames(int scId, int ecId, const QVariantMap &options) {
-    Q_UNUSED(ecId)
-
-    int type = options.find("type")->toInt();
-    int item = options.find("item")->toInt();
-
-    QLocale::FormatType format;
-    if (type == FORMAT_SHORT)
-        format = QLocale::ShortFormat;
-    else
-        format = QLocale::LongFormat;
-    QLocale locale;
-    QList<QString> res;
-    if (item == REQUEST_DAY_NAMES) {
-        for (int i = 1; i <= 7; i++) {
-            res.append(locale.dayName(i, format));
-        }
-    } else { //REQUEST_MONTH_NAMES
-        for (int i = 1; i <= 12; i++) {
-            res.append(locale.monthName(i, format));
-        }
-    }
-
-    QString result;
-    for (QList<QString>::iterator it = res.begin(); it != res.end(); it++) {
-        result += QString("'%1',").arg(*it);
-    }
-    this->callback(scId, QString("{ value: [ %1 ]}").arg(result));
-}
-
-template<class T>
-static QString format(T number, Globalization::NumberType type) {
-    QString res;
-    QLocale locale;
-    switch (type) {
-    case Globalization::DECIMAL:
-        res = locale.toString(number);
-        break;
-    case Globalization::PERCENT:
-        res = locale.toString(number) + locale.percent();
-        break;
-    case Globalization::CURRENCY:
-        res = locale.toCurrencyString(number);
-        break;
-    };
-    return res;
-}
-
-void Globalization::numberToString(int scId, int ecId, const QVariantMap &options) {
-    Q_UNUSED(ecId)
-
-    bool isInt = options.find("isInt")->toBool();
-    NumberType type = static_cast<NumberType>(options.find("type")->toBool());
-
-    QString res;
-    if (isInt) {
-        long long number = options.find("number")->toLongLong();
-        res = format(number, type);
-    } else {
-        double number = options.find("number")->toDouble();
-        res = format(number, type);
-    }
-    this->callback(scId, QString("{ value: '%1' }").arg(res));
-}
-
-void Globalization::stringToNumber(int scId, int ecId, int type, QString string) {
-    switch ((NumberType)type) {
-    case Globalization::DECIMAL:
-        string = string.remove(QLocale().groupSeparator());
-        break;
-    case Globalization::PERCENT:
-        string = string.remove(QLocale().percent()).remove(QLocale().groupSeparator());
-        break;
-    case Globalization::CURRENCY:
-        string = string.remove(QLocale().currencySymbol()).remove(QLocale().groupSeparator());
-        break;
-    };
-    bool ok;
-    double res = QLocale().toDouble(string, &ok);
-    if (ok)
-        this->callback(scId, QString("{ value: %1 }").arg(res));
-    else
-        this->callback(ecId, QString("new GlobalizationError(%1, 'parsing error')").arg(Globalization::PARSING_ERROR));
-}
-
-static QString ustr2qstr(UnicodeString &ustr) {
-    std::string res;
-    ustr.toUTF8String(res);
-
-    return QString(res.c_str());
-}
-
-void Globalization::getNumberPattern(int scId, int ecId, int type) {
-    Q_UNUSED(ecId);
-    UErrorCode status = U_ZERO_ERROR;
-    icu::DecimalFormat icu(status);
-
-    icu::UnicodeString pattern;
-    icu.toPattern(pattern);
-
-    QLocale locale;
-    QVariantMap obj;
-
-    obj.insert("pattern", ustr2qstr(pattern));
-
-    switch ((NumberType)type) {
-    case Globalization::DECIMAL:
-        obj.insert("symbol", "");
-        break;
-    case Globalization::PERCENT:
-        obj.insert("symbol", QString(locale.percent()));
-        break;
-    case Globalization::CURRENCY:
-        obj.insert("symbol", QString(locale.currencySymbol()));
-        break;
-    };
-
-    obj.insert("fraction", icu.getMaximumFractionDigits());
-    obj.insert("rounding", icu.getRoundingIncrement());
-    obj.insert("positive", QString(locale.positiveSign()));
-    obj.insert("negative", QString(locale.negativeSign()));
-    obj.insert("decimal", QString(locale.decimalPoint()));
-    obj.insert("grouping", QString(locale.groupSeparator()));
-
-    this->cb(scId, obj);
-}
-
-static bool inDayLightSavingsTime() {
-    time_t now;
-
-    time(&now);
-
-    const tm *desc = std::localtime(&now);
-
-    return desc->tm_isdst > 0;
-}
-
-void Globalization::getDatePattern(int scId, int ecId, int formatLength, int selector) {
-    Q_UNUSED(ecId);
-
-    QLocale locale;
-    QVariantMap res;
-    QLocale::FormatType format = translateFormat((Format)formatLength);
-
-    switch ((Selector)selector) {
-    case Selector::SELECTOR_TIME:
-        res.insert("pattern", locale.timeFormat(format));
-        break;
-    case Selector::SELECTOR_DATE:
-        res.insert("pattern", locale.dateFormat(format));
-        break;
-    case Selector::SELECTOR_ALL:
-        res.insert("pattern", locale.dateTimeFormat(format));
-        break;
-    };
-
-    UnicodeString result;
-    QSharedPointer<TimeZone> timezone = QSharedPointer<TimeZone>(TimeZone::createDefault());
-    timezone->getDisplayName(inDayLightSavingsTime(), TimeZone::SHORT, result);
-
-    res.insert("timezone", ustr2qstr(result));
-    res.insert("utc_offset", timezone->getRawOffset() / 1000 + timezone->getDSTSavings() / 1000);
-    res.insert("dst_offset", timezone->getDSTSavings() / 1000);
-
-    this->cb(scId, res);
-}
-
diff --git a/src/ubuntu/globalization.h b/src/ubuntu/globalization.h
deleted file mode 100644
index 3f59c63..0000000
--- a/src/ubuntu/globalization.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- *
- * Copyright 2013 Canonical Ltd.
- *
- * Licensed 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.
- *
-*/
-#ifndef GLOBALIZATION_H_SVO2013
-#define GLOBALIZATION_H_SVO2013
-
-#include <QtCore>
-#include <QLocale>
-
-#include <cplugin.h>
-
-class Globalization: public CPlugin {
-    Q_OBJECT
-    enum GlobalizationError {
-        UNKNOWN_ERROR = 0,
-        FORMATTING_ERROR = 1,
-        PARSING_ERROR = 2,
-        PATTERN_ERROR = 3
-    };
-
-    enum Selector {
-        SELECTOR_DATE = 0,
-        SELECTOR_TIME = 1,
-        SELECTOR_ALL = 2
-    };
-
-    enum Format {
-        FORMAT_SHORT = 0,
-        FORMAT_MEDIUM = 1,
-        FORMAT_LONG = 2,
-        FORMAT_FULL = 3
-    };
-
-    enum {
-        REQUEST_DAY_NAMES = 0,
-        REQUEST_MONTH_NAMES = 1
-    };
-
-    enum NumberType {
-        DECIMAL,
-        PERCENT,
-        CURRENCY
-    };
-
-public:
-    explicit Globalization(Cordova *cordova);
-
-    virtual const QString fullName() override {
-        return Globalization::fullID();
-    }
-
-    virtual const QString shortName() override {
-        return "Globalization";
-    }
-
-    static const QString fullID() {
-        return "Globalization";
-    }
-
-public slots:
-    void getPreferredLanguage(int scId, int ecId);
-    void getLocaleName(int scId, int ecId);
-    void getFirstDayOfWeek(int scId, int ecId);
-    void isDayLightSavingsTime(int scId, int ecId, const QVariantMap &options);
-    void dateToString(int scId, int ecId, const QVariantMap &options);
-    void stringToDate(int scId, int ecId, const QVariantMap &options);
-
-    void getDateNames(int scId, int ecId, const QVariantMap &options);
-    void numberToString(int scId, int ecId, const QVariantMap &options);
-    void stringToNumber(int scId, int ecId, int type, QString string);
-    void getNumberPattern(int scId, int ecId, int type);
-    void getDatePattern(int scId, int ecId, int formatLength, int selector);
-private:
-    friend QLocale::FormatType translateFormat(Globalization::Format formatLength);
-    template<class T> friend QString format(T number, Globalization::NumberType type);
-};
-
-#endif
diff --git a/src/wp/Globalization.cs b/src/wp/Globalization.cs
deleted file mode 100644
index ffe27ec..0000000
--- a/src/wp/Globalization.cs
+++ /dev/null
@@ -1,1177 +0,0 @@
-﻿/*  
-	Licensed 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.
-*/
-
-using System;
-using System.Globalization;
-using System.Runtime.Serialization;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    /// <summary>
-    /// Provides information about system locale, culture settings, number formats, ect.
-    /// </summary>
-    public class Globalization : BaseCommand
-    {
-
-        #region Globalization errors
-
-        /// <summary>
-        /// Globalization error codes.
-        /// </summary>
-        public enum ErrorCode : int
-        {
-            UnknownError = 0,
-            FormattingError = 1,
-            ParsingError = 2,
-            PatternError = 3
-        }
-
-        /// <summary>
-        /// Represents globalization error object.
-        /// </summary>
-        [DataContract]
-        public class GlobalizationError
-        {
-            #region Error messages
-            /// <summary>
-            /// Error messages
-            /// </summary>        
-            public const string UnknownError = "UNKNOWN_ERROR";
-            public const string FormattingError = "FORMATTIN_ERROR";
-            public const string ParsingError = "PARSING_ERROR";
-            public const string PatternError = "PATTERN_ERROR";
-
-            #endregion
-
-            /// <summary>
-            /// Error code
-            /// </summary>
-            [DataMember(Name = "code", IsRequired = false)]
-            public ErrorCode Code { get; set; }
-
-            /// <summary>
-            /// Error message
-            /// </summary>
-            [DataMember(Name = "message", IsRequired = false)]
-            public string Message { get; set; }
-
-            /// <summary>
-            /// Default constructor
-            /// </summary>
-            public GlobalizationError()
-            {
-                this.Code = ErrorCode.UnknownError;
-                this.Message = UnknownError;
-            }
-
-            /// <summary>
-            /// Constructor setting error code
-            /// </summary>
-            public GlobalizationError(ErrorCode error)
-            {
-                this.Code = error;
-
-                switch (error)
-                {
-                    case ErrorCode.ParsingError:
-                        {
-                            this.Message = ParsingError;
-                            break;
-                        }
-                    case ErrorCode.FormattingError:
-                        {
-                            this.Message = FormattingError;
-                            break;
-                        }
-                    case ErrorCode.PatternError:
-                        {
-                            this.Message = PatternError;
-                            break;
-                        }
-                    default:
-                        {
-                            this.Message = UnknownError;
-                            break;
-                        }
-                }
-            }
-        }
-
-        #endregion
-
-        #region Globalization options
-
-        /// <summary>
-        /// Represents globalization options.
-        /// </summary>
-        [DataContract]
-        public class GlobalizationOptions
-        {
-            #region available option values
-            /// <summary>
-            /// Number pattern types.
-            /// </summary>        
-            public const string Percent = "percent";
-            public const string Currency = "currency";
-            public const string Decimal = "decimal";
-
-            /// <summary>
-            /// Format length types
-            /// </summary>        
-            public const string Short = "short";
-            public const string Medium = "medium";
-            public const string Long = "long";
-            public const string Full = "full";
-
-            /// <summary>
-            /// Selector types
-            /// </summary>        
-            public const string TimeSelector = "time";
-            public const string DateSelector = "date";
-            public const string DateAndTimeSelector = "date and time";
-
-            /// <summary>
-            /// Date name types
-            /// </summary>        
-            public const string Narrow = "narrow";
-            public const string Wide = "wide";
-
-            /// <summary>
-            /// Date name items
-            /// </summary>        
-            public const string Months = "months";
-            public const string Days = "days";
-
-            #endregion
-
-            /// <summary>
-            /// Additional options
-            /// </summary>
-            [DataMember(Name = "options", IsRequired = false)]
-            public Options AdditionalOptions { get; set; }
-
-            /// <summary>
-            /// Date to convert
-            /// </summary>
-            [DataMember(Name = "date", IsRequired = false)]
-            public long Date { get; set; }
-
-            /// <summary>
-            /// Date as stirng
-            /// </summary>
-            [DataMember(Name = "dateString", IsRequired = false)]
-            public string DateString { get; set; }
-
-            /// <summary>
-            /// Currency code
-            /// </summary>
-            [DataMember(Name = "currencyCode", IsRequired = false)]
-            public string CurrencyCode { get; set; }
-
-            /// <summary>
-            /// Number as string
-            /// </summary>
-            [DataMember(Name = "numberString", IsRequired = false)]
-            public string NumberString { get; set; }
-
-            /// <summary>
-            /// Number to convert
-            /// </summary>
-            [DataMember(Name = "number", IsRequired = false)]
-            public double Number { get; set; }
-        }
-
-        /// <summary>
-        /// Represents additional options
-        /// </summary>
-        [DataContract]
-        public class Options
-        {
-            /// <summary>
-            /// Pattern type
-            /// </summary>
-            [DataMember(Name = "type", IsRequired = false)]
-            public string Type { get; set; }
-
-            /// <summary>
-            /// Format length
-            /// </summary>
-            [DataMember(Name = "formatLength", IsRequired = false)]
-            public string FormatLength { get; set; }
-
-            /// <summary>
-            /// Selector
-            /// </summary>
-            [DataMember(Name = "selector", IsRequired = false)]
-            public string Selector { get; set; }
-
-            /// <summary>
-            /// Date name item
-            /// </summary>
-            [DataMember(Name = "item", IsRequired = false)]
-            public string Item { get; set; }
-        }
-
-        #endregion
-
-        #region returned objects
-
-        #region Number pattern object
-
-        /// <summary>
-        /// Represents number pattern
-        /// </summary>
-        [DataContract]
-        public class NumberPattern
-        {
-            /// <summary>
-            /// Pattern
-            /// </summary>
-            [DataMember(Name = "pattern", IsRequired = false)]
-            public string Pattern { get; set; }
-
-            /// <summary>
-            /// Symbol
-            /// </summary>
-            [DataMember(Name = "symbol", IsRequired = false)]
-            public string Symbol { get; set; }
-
-            /// <summary>
-            /// Fraction
-            /// </summary>
-            [DataMember(Name = "fraction", IsRequired = false)]
-            public int Fraction { get; set; }
-
-            /// <summary>
-            /// Positive
-            /// </summary>
-            [DataMember(Name = "positive", IsRequired = false)]
-            public string Positive { get; set; }
-
-            /// <summary>
-            /// Negative
-            /// </summary>
-            [DataMember(Name = "negative", IsRequired = false)]
-            public string Negative { get; set; }
-
-            /// <summary>
-            /// Rounding
-            /// </summary>
-            [DataMember(Name = "rounding", IsRequired = false)]
-            public int Rounding { get; set; }
-
-            /// <summary>
-            /// Decimal
-            /// </summary>
-            [DataMember(Name = "decimal", IsRequired = false)]
-            public string Decimal { get; set; }
-
-            /// <summary>
-            /// Grouping
-            /// </summary>
-            [DataMember(Name = "grouping", IsRequired = false)]
-            public string Grouping { get; set; }
-
-            /// <summary>
-            /// Constructor of the class
-            /// </summary>
-            /// <param name="pattern"></param>
-            /// <param name="symbol"></param>
-            /// <param name="fraction"></param>
-            /// <param name="positive"></param>
-            /// <param name="negative"></param>
-            /// <param name="rounding"></param>
-            /// <param name="dec"></param>
-            /// <param name="grouping"></param>
-            public NumberPattern(string pattern, string symbol, int fraction, string positive, string negative, int rounding, string dec, string grouping)
-            {
-                this.Pattern = pattern;
-                this.Symbol = symbol;
-                this.Fraction = fraction;
-                this.Positive = positive;
-                this.Negative = negative;
-                this.Rounding = rounding;
-                this.Decimal = dec;
-                this.Grouping = grouping;
-            }
-        }
-        #endregion
-
-        #region Date format object
-
-        /// <summary>
-        /// Represents date format
-        /// </summary>
-        [DataContract]
-        public class DateFormat
-        {
-            /// <summary>
-            /// Year
-            /// </summary>
-            [DataMember(Name = "year", IsRequired = false)]
-            public int Year { get; set; }
-
-            /// <summary>
-            /// Month
-            /// </summary>
-            [DataMember(Name = "month", IsRequired = false)]
-            public int Month { get; set; }
-
-            /// <summary>
-            /// Day
-            /// </summary>
-            [DataMember(Name = "day", IsRequired = false)]
-            public int Day { get; set; }
-
-            /// <summary>
-            /// Hour
-            /// </summary>
-            [DataMember(Name = "hour", IsRequired = false)]
-            public int Hour { get; set; }
-
-            /// <summary>
-            /// Minute
-            /// </summary>
-            [DataMember(Name = "minute", IsRequired = false)]
-            public int Minute { get; set; }
-
-            /// <summary>
-            /// Second
-            /// </summary>
-            [DataMember(Name = "second", IsRequired = false)]
-            public int Second { get; set; }
-
-            /// <summary>
-            /// Millisecond
-            /// </summary>
-            [DataMember(Name = "millisecond", IsRequired = false)]
-            public int Millisecond { get; set; }
-
-            public DateFormat(int year, int month, int day, int hour, int minute, int second, int millisecond)
-            {
-                this.Year = year;
-                this.Month = month;
-                this.Day = day;
-                this.Hour = hour;
-                this.Minute = minute;
-                this.Millisecond = millisecond;
-            }
-
-        }
-        #endregion
-
-        #region Date pattern object
-
-        /// <summary>
-        /// Represents date pattern object
-        /// </summary>
-        [DataContract]
-        public class DatePattern
-        {
-
-            /// <summary>
-            /// Date pattern
-            /// </summary>
-            [DataMember(Name = "pattern", IsRequired = false)]
-            public string Pattern { get; set; }
-
-            /// <summary>
-            /// TimeZone
-            /// </summary>
-            [DataMember(Name = "timezone", IsRequired = false)]
-            public string TimeZone { get; set; }
-
-            /// <summary>
-            /// UTC offset
-            /// </summary>
-            [DataMember(Name = "utc_offset", IsRequired = false)]
-            public double UtcOffset { get; set; }
-
-            /// <summary>
-            /// Dst offset
-            /// </summary>
-            [DataMember(Name = "dst_offset", IsRequired = false)]
-            public double DstOffset { get; set; }
-
-            /// <summary>
-            /// Constructor of the class
-            /// </summary>
-            /// <param name="pattern"></param>
-            /// <param name="timezone"></param>
-            /// <param name="utcOffset"></param>
-            /// <param name="dstOffset"></param>
-            public DatePattern(string pattern, string timezone, double utcOffset, double dstOffset)
-            {
-                this.Pattern = pattern;
-                this.TimeZone = timezone;
-                this.UtcOffset = utcOffset;
-                this.DstOffset = dstOffset;
-            }
-
-        }
-
-        #endregion
-
-        #endregion
-
-        #region Locale info
-
-        /// <summary>
-        /// Gets the string identifier for the client's current locale setting.
-        /// </summary>
-        /// <param name="options"></param>               
-        public void getLocaleName(string options)
-        {
-            try
-            {
-                var locale = RegionInfo.CurrentRegion.TwoLetterISORegionName;
-                PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(locale));
-                this.DispatchCommandResult(result);
-            }
-            catch (Exception)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
-            }
-        }
-
-        /// <summary>
-        /// Gets the string identifier for the client's current language.
-        /// </summary>
-        /// <param name="options"></param>               
-        public void getPreferredLanguage(string options)
-        {
-            try
-            {
-                var language = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
-                PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(language));
-                this.DispatchCommandResult(result);
-            }
-            catch (Exception)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
-            }
-        }
-
-        #endregion
-
-        #region Date and time info
-
-        /// <summary>
-        /// Gets whether daylight savings time is in effect for a given date using the client's 
-        /// time zone and calendar.        
-        /// </summary>
-        /// <param name="opitons">Date to daylight savings check.</param>
-        public void isDayLightSavingsTime(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-                DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
-                TimeZoneInfo localZone = TimeZoneInfo.Local;
-                bool isDaylightSavingTime = localZone.IsDaylightSavingTime(date);
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(isDaylightSavingTime, "dst")));
-            }
-            catch (Exception)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
-            }
-        }
-
-        /// <summary>
-        /// Gets the first day of the week according to the client's user preferences and calendar.
-        /// The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
-        /// </summary>
-        /// <param name="options"></param>
-        public void getFirstDayOfWeek(string options)
-        {
-            try
-            {
-                // DateTimeFormat returns days of the week numbered from zero, so we have to increase returned value by one.
-                var firstDayOfWeek = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 1;
-                PluginResult result = new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(firstDayOfWeek));
-                this.DispatchCommandResult(result);
-            }
-            catch (Exception)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
-            }
-        }
-
-        #endregion
-
-        #region Formatting
-
-        /// <summary>
-        /// Gets a date formatted as a string according to the client's user preferences and calendar using the time zone of the client. 
-        /// </summary>
-        /// <param name="options"></param>
-        public void dateToString(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-                DateTime date = start.AddMilliseconds(globalOptions.Date).ToLocalTime();
-
-                string format = "{0:M/dd/yy H:m:s}"; //short datetime by default
-                int formatLength = 0; //default format
-                int selector = 0; //default selector 
-
-                if (globalOptions.AdditionalOptions != null)
-                {
-                    if (globalOptions.AdditionalOptions.FormatLength != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.FormatLength;
-
-                        if (t.Equals(GlobalizationOptions.Full))
-                        {
-                            formatLength++;
-                        }
-                    }
-
-                    if (globalOptions.AdditionalOptions.Selector != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.Selector;
-
-                        if (t.Equals(GlobalizationOptions.DateSelector))
-                        {
-                            selector += 10;
-                        }
-                        else if (t.Equals(GlobalizationOptions.TimeSelector))
-                        {
-                            selector += 20;
-                        }
-                    }
-
-                    //determine return value
-                    int method = formatLength + selector;
-
-                    switch (method)
-                    {
-                        case 1: // full datetime
-                            {
-                                format = "{0:MMMM/dddd/yyyy HH:mm:ss tt}";
-                                break;
-                            }
-                        case 10: // short date
-                            {
-                                format = "{0:d}";
-                                break;
-                            }
-                        case 11: // full date
-                            {
-                                format = "{0:D}";
-                                break;
-                            }
-                        case 20: // short time
-                            {
-                                format = "{0:t}";
-                                break;
-                            }
-                        case 21: // full time
-                            {
-                                format = "{0:T}";
-                                break;
-                            }
-                        default: // short datetime
-                            {
-                                format = "{0:M/dd/yy H:m:s}";
-                                break;
-                            }
-                    }
-                }
-
-                string formattedValue = string.Format(CultureInfo.CurrentCulture, format, date);
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
-            }
-            catch (Exception)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
-            }
-        }
-
-        /// <summary>
-        /// Parses a date formatted as a string according to the client's user preferences and calendar using the time zone of the client and returns the corresponding date object
-        /// </summary>
-        /// <param name="options"></param>
-        public void stringToDate(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                if (string.IsNullOrEmpty(globalOptions.DateString))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                string format = "M/dd/yy H:m:s"; // short datetime by default
-                int formatLength = 0; //default format
-                int selector = 0; //default selector 
-
-                if (globalOptions.AdditionalOptions != null)
-                {
-                    if (globalOptions.AdditionalOptions.FormatLength != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.FormatLength;
-
-                        if (t.Equals(GlobalizationOptions.Full))
-                        {
-                            formatLength++;
-                        }
-                    }
-
-                    if (globalOptions.AdditionalOptions.Selector != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.Selector;
-
-                        if (t.Equals(GlobalizationOptions.DateSelector))
-                        {
-                            selector += 10;
-                        }
-                        else if (t.Equals(GlobalizationOptions.TimeSelector))
-                        {
-                            selector += 20;
-                        }
-                    }
-
-                    //determine return value
-                    int method = formatLength + selector;
-
-                    switch (method)
-                    {
-                        case 1: // full datetime
-                            {
-                                format = "MMMM/dddd/yyyy HH:mm:ss tt";
-                                break;
-                            }
-                        case 10: // short date
-                            {
-                                format = "d";
-                                break;
-                            }
-                        case 11: // full date
-                            {
-                                format = "D";
-                                break;
-                            }
-                        case 20: // short time
-                            {
-                                format = "t";
-                                break;
-                            }
-                        case 21: // full time
-                            {
-                                format = "T";
-                                break;
-                            }
-                        default: // short datetime
-                            {
-                                format = "M/dd/yy H:m:s";
-                                break;
-                            }
-                    }
-                }
-
-                DateTime date = DateTime.ParseExact(globalOptions.DateString, format, CultureInfo.CurrentCulture);
-                DateFormat dateFormat = new DateFormat(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Millisecond);
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, dateFormat));
-
-            }
-            catch (Exception)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
-            }
-        }
-
-        /// <summary>
-        /// Gets a pattern string for formatting and parsing dates according to the client's user preferences.
-        /// </summary>
-        /// <param name="options"></param>
-        public void getDatePattern(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                DateTimeFormatInfo dateFormatInfo = DateTimeFormatInfo.CurrentInfo;
-                string pattern = dateFormatInfo.FullDateTimePattern; // full datetime by default
-                int formatLength = 0; //default format
-                int selector = 0; //default selector 
-
-                if (globalOptions.AdditionalOptions != null)
-                {
-                    if (globalOptions.AdditionalOptions.FormatLength != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.FormatLength;
-
-                        if (t.Equals(GlobalizationOptions.Full))
-                        {
-                            formatLength++;
-                        }
-                    }
-
-                    if (globalOptions.AdditionalOptions.Selector != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.Selector;
-
-                        if (t.Equals(GlobalizationOptions.DateSelector))
-                        {
-                            selector += 10;
-                        }
-                        else if (t.Equals(GlobalizationOptions.TimeSelector))
-                        {
-                            selector += 20;
-                        }
-                    }
-
-                    //determine return value
-                    int method = formatLength + selector;
-
-                    switch (method)
-                    {
-                        case 1: // full datetime
-                            {
-                                pattern = dateFormatInfo.FullDateTimePattern;
-                                break;
-                            }
-                        case 10: // short date
-                            {
-                                pattern = dateFormatInfo.ShortDatePattern;
-                                break;
-                            }
-                        case 11: // full date
-                            {
-                                pattern = dateFormatInfo.LongDatePattern;
-                                break;
-                            }
-                        case 20: // short time
-                            {
-                                pattern = dateFormatInfo.ShortTimePattern;
-                                break;
-                            }
-                        case 21: // full time
-                            {
-                                pattern = dateFormatInfo.LongTimePattern;
-                                break;
-                            }
-                        default: // short datetime
-                            {
-                                // Seems like C# doesn't support short datetime pattern so we use full format
-                                // http://msdn.microsoft.com/en-us/library/1at0z4ew%28v=vs.71%29.aspx
-                                pattern = dateFormatInfo.FullDateTimePattern;
-                                break;
-                            }
-                    }
-                }
-
-                TimeZoneInfo localZone = TimeZoneInfo.Local;
-                DatePattern datePattern = new DatePattern(pattern, localZone.DisplayName, localZone.BaseUtcOffset.TotalSeconds, 0);
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, datePattern));
-            }
-            catch (Exception)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
-            }
-        }
-
-        /// <summary>
-        /// Gets an array of either the names of the months or days of the week according to the client's user preferences and calendar.
-        /// </summary>
-        /// <param name="options"></param>
-        public void getDateNames(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                int type = 0; //default wide
-                int item = 0; //default months 
-
-                if (globalOptions.AdditionalOptions != null)
-                {
-                    if (globalOptions.AdditionalOptions.Type != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.Type;
-
-                        if (t.Equals(GlobalizationOptions.Narrow))
-                        {
-                            type++;
-                        }
-                    }
-
-                    if (globalOptions.AdditionalOptions.Item != null)
-                    {
-                        string t = globalOptions.AdditionalOptions.Item;
-
-                        if (t.Equals(GlobalizationOptions.Days))
-                        {
-                            item += 10;
-                        }
-                    }
-                }
-
-                //determine return value
-                int method = item + type;
-                string[] namesArray;
-                CultureInfo currentCulture = CultureInfo.CurrentCulture;
-
-                if (method == 1) //months and narrow
-                {
-                    namesArray = currentCulture.DateTimeFormat.AbbreviatedMonthNames;
-                }
-                else if (method == 10) //days and wide
-                {
-                    namesArray = currentCulture.DateTimeFormat.DayNames;
-                }
-                else if (method == 11) //days and narrow
-                {
-                    namesArray = currentCulture.DateTimeFormat.AbbreviatedDayNames;
-                }
-                else //default: months and wide
-                {
-                    namesArray = currentCulture.DateTimeFormat.MonthNames;
-                }
-
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(namesArray)));
-            }
-            catch (Exception)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError()));
-            }
-        }
-
-        /// <summary>
-        /// Gets a number formatted as a string according to the client's user preferences. 
-        /// </summary>
-        /// <param name="options"></param>
-        public void numberToString(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                string format = string.Empty;
-                string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
-                    GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-
-                switch (numberFormatType)
-                {
-                    case GlobalizationOptions.Percent:
-                        {
-                            format = "{0:p}";
-                            break;
-                        }
-
-                    case GlobalizationOptions.Currency:
-                        {
-                            format = "{0:c}";
-                            break;
-                        }
-
-                    default:
-                        {
-                            format = "{0:f}";
-                            break;
-                        }
-                }
-
-                string formattedValue = string.Format(CultureInfo.CurrentCulture, format, globalOptions.Number);
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(formattedValue)));
-
-            }
-            catch (Exception)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
-            }
-        }
-
-        /// <summary>
-        /// Gets a number formatted as a string according to the client's user preferences and returns the corresponding number.
-        /// </summary>
-        /// <param name="options"></param>
-        public void stringToNumber(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                if (string.IsNullOrEmpty(globalOptions.NumberString))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                string numberString = globalOptions.NumberString;
-                string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
-                    GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-
-                NumberStyles numberStyle;
-
-                switch (numberFormatType)
-                {
-                    case GlobalizationOptions.Percent:
-                        {
-                            numberStyle = NumberStyles.Any;
-                            numberString = numberString.Replace(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PercentSymbol, "");
-                            break;
-                        }
-
-                    case GlobalizationOptions.Currency:
-                        {
-                            numberStyle = NumberStyles.Currency;
-                            break;
-                        }
-
-                    default:
-                        {
-                            numberStyle = NumberStyles.Number;
-                            break;
-                        }
-                }
-
-                double value = double.Parse(numberString, numberStyle, CultureInfo.CurrentCulture);
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, this.WrapIntoJSON(value)));
-
-            }
-            catch (Exception)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.ParsingError)));
-            }
-        }
-
-
-        /// <summary>
-        /// Gets a pattern string for formatting and parsing numbers according to the client's user preferences.
-        /// </summary>
-        /// <param name="options"></param>
-        public void getNumberPattern(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                CultureInfo cultureInfo = CultureInfo.CurrentCulture;
-                NumberFormatInfo formatInfo = cultureInfo.NumberFormat;
-                string numberFormatType = (globalOptions.AdditionalOptions == null || string.IsNullOrEmpty(globalOptions.AdditionalOptions.Type)) ?
-                    GlobalizationOptions.Decimal : globalOptions.AdditionalOptions.Type;
-                NumberPattern pattern = null;
-                string symbol;
-
-                // TODO find out how to get format pattern and the number of fraction digits
-                switch (numberFormatType)
-                {
-                    case GlobalizationOptions.Percent:
-                        {
-                            symbol = formatInfo.PercentSymbol;
-                            pattern = new NumberPattern("", symbol, 0, formatInfo.PercentPositivePattern.ToString(), formatInfo.PercentNegativePattern.ToString(), 0, formatInfo.PercentDecimalSeparator, formatInfo.PercentGroupSeparator);
-                            break;
-                        }
-                    case GlobalizationOptions.Currency:
-                        {
-                            symbol = formatInfo.CurrencySymbol;
-                            pattern = new NumberPattern("", symbol, 0, formatInfo.CurrencyPositivePattern.ToString(), formatInfo.CurrencyNegativePattern.ToString(), 0, formatInfo.CurrencyDecimalSeparator, formatInfo.CurrencyGroupSeparator);
-                            break;
-                        }
-                    default:
-                        {
-                            symbol = formatInfo.NumberDecimalSeparator;
-                            pattern = new NumberPattern("", symbol, 0, "", formatInfo.NumberNegativePattern.ToString(), 0, formatInfo.NumberDecimalSeparator, formatInfo.NumberGroupSeparator);
-                            break;
-                        }
-                }
-
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, pattern));
-            }
-            catch (Exception)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.PatternError)));
-            }
-        }
-
-        /// <summary>
-        /// Gets a pattern string for formatting and parsing currency values according to the client's user preferences and ISO 4217 currency code.
-        /// </summary>
-        /// <param name="options"></param>
-        public void getCurrencyPattern(string options)
-        {
-            GlobalizationOptions globalOptions;
-
-            try
-            {
-                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
-                globalOptions = JSON.JsonHelper.Deserialize<GlobalizationOptions>(args[0]);
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-
-            try
-            {
-                if (string.IsNullOrEmpty(globalOptions.CurrencyCode))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                string currencyCode = globalOptions.CurrencyCode;
-
-                // temporary not supported via lack of api required
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.INVALID_ACTION, "Not supported"));
-                return;
-
-                // TODO find the way to get currency info from currency code
-                // http://stackoverflow.com/questions/12373800/3-digit-currency-code-to-currency-symbol
-                // http://stackoverflow.com/questions/6924067/how-to-get-specific-culture-currency-pattern
-                // CultureInfo cultureInfo = new CultureInfo(currencyCode);
-                // NumberFormatInfo numberFormat = cultureInfo.NumberFormat;
-            }
-            catch (Exception)
-            {
-                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new GlobalizationError(ErrorCode.FormattingError)));
-            }
-        }
-
-        #endregion
-
-        #region private methods
-
-        /// <summary>
-        /// Wraps data into JSON format
-        /// </summary>
-        /// <param name="data">data</param>
-        /// <returns>data formatted as JSON object</returns>
-        private string WrapIntoJSON<T>(T data, string keyName = "value")
-        {
-            string param = "{0}";
-            string stringifiedData = data.ToString();
-
-            if (data.GetType() == typeof(string))
-            {
-                param = "\"" + param + "\"";
-            }
-
-            if (data.GetType() == typeof(bool))
-            {
-                stringifiedData = stringifiedData.ToLower();
-            }
-
-            if (data.GetType() == typeof(string[]))
-            {
-                stringifiedData = JSON.JsonHelper.Serialize(data);
-            }
-
-            var formattedData = string.Format("\"" + keyName + "\":" + param, stringifiedData);
-            formattedData = "{" + formattedData + "}";
-
-            return formattedData;
-        }
-
-        #endregion
-    }
-}
diff --git a/www/GlobalizationError.js b/www/GlobalizationError.js
deleted file mode 100644
index d2dcced..0000000
--- a/www/GlobalizationError.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *
- * 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.
- *
-*/
-
-
-/**
- * Globalization error object
- *
- * @constructor
- * @param code
- * @param message
- */
-var GlobalizationError = function(code, message) {
-    this.code = code || null;
-    this.message = message || '';
-};
-
-// Globalization error codes
-GlobalizationError.UNKNOWN_ERROR = 0;
-GlobalizationError.FORMATTING_ERROR = 1;
-GlobalizationError.PARSING_ERROR = 2;
-GlobalizationError.PATTERN_ERROR = 3;
-
-module.exports = GlobalizationError;
diff --git a/www/globalization.js b/www/globalization.js
deleted file mode 100644
index 88b3640..0000000
--- a/www/globalization.js
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- *
- * 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.
- *
-*/
-
-var argscheck = require('cordova/argscheck'),
-    exec = require('cordova/exec'),
-    GlobalizationError = require('./GlobalizationError');
-
-var globalization = {
-
-/**
-* Returns the string identifier for the client's current language.
-* It returns the language identifier string to the successCB callback with a
-* properties object as a parameter. If there is an error getting the language,
-* then the errorCB callback is invoked.
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return Object.value {String}: The language identifier
-*
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.getPreferredLanguage(function (language) {alert('language:' + language.value + '\n');},
-*                                function () {});
-*/
-getPreferredLanguage:function(successCB, failureCB) {
-    argscheck.checkArgs('fF', 'Globalization.getPreferredLanguage', arguments);
-    exec(successCB, failureCB, "Globalization","getPreferredLanguage", []);
-},
-
-/**
-* Returns the string identifier for the client's current locale setting.
-* It returns the locale identifier string to the successCB callback with a
-* properties object as a parameter. If there is an error getting the locale,
-* then the errorCB callback is invoked.
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return Object.value {String}: The locale identifier
-*
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.getLocaleName(function (locale) {alert('locale:' + locale.value + '\n');},
-*                                function () {});
-*/
-getLocaleName:function(successCB, failureCB) {
-    argscheck.checkArgs('fF', 'Globalization.getLocaleName', arguments);
-    exec(successCB, failureCB, "Globalization","getLocaleName", []);
-},
-
-
-/**
-* Returns a date formatted as a string according to the client's user preferences and
-* calendar using the time zone of the client. It returns the formatted date string to the
-* successCB callback with a properties object as a parameter. If there is an error
-* formatting the date, then the errorCB callback is invoked.
-*
-* The defaults are: formatLenght="short" and selector="date and time"
-*
-* @param {Date} date
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            formatLength {String}: 'short', 'medium', 'long', or 'full'
-*            selector {String}: 'date', 'time', or 'date and time'
-*
-* @return Object.value {String}: The localized date string
-*
-* @error GlobalizationError.FORMATTING_ERROR
-*
-* Example
-*    globalization.dateToString(new Date(),
-*                function (date) {alert('date:' + date.value + '\n');},
-*                function (errorCode) {alert(errorCode);},
-*                {formatLength:'short'});
-*/
-dateToString:function(date, successCB, failureCB, options) {
-    argscheck.checkArgs('dfFO', 'Globalization.dateToString', arguments);
-    var dateValue = date.valueOf();
-    exec(successCB, failureCB, "Globalization", "dateToString", [{"date": dateValue, "options": options}]);
-},
-
-
-/**
-* Parses a date formatted as a string according to the client's user
-* preferences and calendar using the time zone of the client and returns
-* the corresponding date object. It returns the date to the successCB
-* callback with a properties object as a parameter. If there is an error
-* parsing the date string, then the errorCB callback is invoked.
-*
-* The defaults are: formatLength="short" and selector="date and time"
-*
-* @param {String} dateString
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            formatLength {String}: 'short', 'medium', 'long', or 'full'
-*            selector {String}: 'date', 'time', or 'date and time'
-*
-* @return    Object.year {Number}: The four digit year
-*            Object.month {Number}: The month from (0 - 11)
-*            Object.day {Number}: The day from (1 - 31)
-*            Object.hour {Number}: The hour from (0 - 23)
-*            Object.minute {Number}: The minute from (0 - 59)
-*            Object.second {Number}: The second from (0 - 59)
-*            Object.millisecond {Number}: The milliseconds (from 0 - 999),
-*                                        not available on all platforms
-*
-* @error GlobalizationError.PARSING_ERROR
-*
-* Example
-*    globalization.stringToDate('4/11/2011',
-*                function (date) { alert('Month:' + date.month + '\n' +
-*                    'Day:' + date.day + '\n' +
-*                    'Year:' + date.year + '\n');},
-*                function (errorCode) {alert(errorCode);},
-*                {selector:'date'});
-*/
-stringToDate:function(dateString, successCB, failureCB, options) {
-    argscheck.checkArgs('sfFO', 'Globalization.stringToDate', arguments);
-    exec(successCB, failureCB, "Globalization", "stringToDate", [{"dateString": dateString, "options": options}]);
-},
-
-
-/**
-* Returns a pattern string for formatting and parsing dates according to the client's
-* user preferences. It returns the pattern to the successCB callback with a
-* properties object as a parameter. If there is an error obtaining the pattern,
-* then the errorCB callback is invoked.
-*
-* The defaults are: formatLength="short" and selector="date and time"
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            formatLength {String}: 'short', 'medium', 'long', or 'full'
-*            selector {String}: 'date', 'time', or 'date and time'
-*
-* @return    Object.pattern {String}: The date and time pattern for formatting and parsing dates.
-*                                    The patterns follow Unicode Technical Standard #35
-*                                    http://unicode.org/reports/tr35/tr35-4.html
-*            Object.timezone {String}: The abbreviated name of the time zone on the client
-*            Object.utc_offset {Number}: The current difference in seconds between the client's
-*                                        time zone and coordinated universal time.
-*            Object.dst_offset {Number}: The current daylight saving time offset in seconds
-*                                        between the client's non-daylight saving's time zone
-*                                        and the client's daylight saving's time zone.
-*
-* @error GlobalizationError.PATTERN_ERROR
-*
-* Example
-*    globalization.getDatePattern(
-*                function (date) {alert('pattern:' + date.pattern + '\n');},
-*                function () {},
-*                {formatLength:'short'});
-*/
-getDatePattern:function(successCB, failureCB, options) {
-    argscheck.checkArgs('fFO', 'Globalization.getDatePattern', arguments);
-    exec(successCB, failureCB, "Globalization", "getDatePattern", [{"options": options}]);
-},
-
-
-/**
-* Returns an array of either the names of the months or days of the week
-* according to the client's user preferences and calendar. It returns the array of names to the
-* successCB callback with a properties object as a parameter. If there is an error obtaining the
-* names, then the errorCB callback is invoked.
-*
-* The defaults are: type="wide" and item="months"
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            type {String}: 'narrow' or 'wide'
-*            item {String}: 'months', or 'days'
-*
-* @return Object.value {Array{String}}: The array of names starting from either
-*                                        the first month in the year or the
-*                                        first day of the week.
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.getDateNames(function (names) {
-*        for(var i = 0; i < names.value.length; i++) {
-*            alert('Month:' + names.value[i] + '\n');}},
-*        function () {});
-*/
-getDateNames:function(successCB, failureCB, options) {
-    argscheck.checkArgs('fFO', 'Globalization.getDateNames', arguments);
-    exec(successCB, failureCB, "Globalization", "getDateNames", [{"options": options}]);
-},
-
-/**
-* Returns whether daylight savings time is in effect for a given date using the client's
-* time zone and calendar. It returns whether or not daylight savings time is in effect
-* to the successCB callback with a properties object as a parameter. If there is an error
-* reading the date, then the errorCB callback is invoked.
-*
-* @param {Date} date
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return Object.dst {Boolean}: The value "true" indicates that daylight savings time is
-*                                in effect for the given date and "false" indicate that it is not.
-*
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.isDayLightSavingsTime(new Date(),
-*                function (date) {alert('dst:' + date.dst + '\n');}
-*                function () {});
-*/
-isDayLightSavingsTime:function(date, successCB, failureCB) {
-    argscheck.checkArgs('dfF', 'Globalization.isDayLightSavingsTime', arguments);
-    var dateValue = date.valueOf();
-    exec(successCB, failureCB, "Globalization", "isDayLightSavingsTime", [{"date": dateValue}]);
-},
-
-/**
-* Returns the first day of the week according to the client's user preferences and calendar.
-* The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
-* It returns the day to the successCB callback with a properties object as a parameter.
-* If there is an error obtaining the pattern, then the errorCB callback is invoked.
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return Object.value {Number}: The number of the first day of the week.
-*
-* @error GlobalizationError.UNKNOWN_ERROR
-*
-* Example
-*    globalization.getFirstDayOfWeek(function (day)
-*                { alert('Day:' + day.value + '\n');},
-*                function () {});
-*/
-getFirstDayOfWeek:function(successCB, failureCB) {
-    argscheck.checkArgs('fF', 'Globalization.getFirstDayOfWeek', arguments);
-    exec(successCB, failureCB, "Globalization", "getFirstDayOfWeek", []);
-},
-
-
-/**
-* Returns a number formatted as a string according to the client's user preferences.
-* It returns the formatted number string to the successCB callback with a properties object as a
-* parameter. If there is an error formatting the number, then the errorCB callback is invoked.
-*
-* The defaults are: type="decimal"
-*
-* @param {Number} number
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            type {String}: 'decimal', "percent", or 'currency'
-*
-* @return Object.value {String}: The formatted number string.
-*
-* @error GlobalizationError.FORMATTING_ERROR
-*
-* Example
-*    globalization.numberToString(3.25,
-*                function (number) {alert('number:' + number.value + '\n');},
-*                function () {},
-*                {type:'decimal'});
-*/
-numberToString:function(number, successCB, failureCB, options) {
-    argscheck.checkArgs('nfFO', 'Globalization.numberToString', arguments);
-    exec(successCB, failureCB, "Globalization", "numberToString", [{"number": number, "options": options}]);
-},
-
-/**
-* Parses a number formatted as a string according to the client's user preferences and
-* returns the corresponding number. It returns the number to the successCB callback with a
-* properties object as a parameter. If there is an error parsing the number string, then
-* the errorCB callback is invoked.
-*
-* The defaults are: type="decimal"
-*
-* @param {String} numberString
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            type {String}: 'decimal', "percent", or 'currency'
-*
-* @return Object.value {Number}: The parsed number.
-*
-* @error GlobalizationError.PARSING_ERROR
-*
-* Example
-*    globalization.stringToNumber('1234.56',
-*                function (number) {alert('Number:' + number.value + '\n');},
-*                function () { alert('Error parsing number');});
-*/
-stringToNumber:function(numberString, successCB, failureCB, options) {
-    argscheck.checkArgs('sfFO', 'Globalization.stringToNumber', arguments);
-    exec(successCB, failureCB, "Globalization", "stringToNumber", [{"numberString": numberString, "options": options}]);
-},
-
-/**
-* Returns a pattern string for formatting and parsing numbers according to the client's user
-* preferences. It returns the pattern to the successCB callback with a properties object as a
-* parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked.
-*
-* The defaults are: type="decimal"
-*
-* @param {Function} successCB
-* @param {Function} errorCB
-* @param {Object} options {optional}
-*            type {String}: 'decimal', "percent", or 'currency'
-*
-* @return    Object.pattern {String}: The number pattern for formatting and parsing numbers.
-*                                    The patterns follow Unicode Technical Standard #35.
-*                                    http://unicode.org/reports/tr35/tr35-4.html
-*            Object.symbol {String}: The symbol to be used when formatting and parsing
-*                                    e.g., percent or currency symbol.
-*            Object.fraction {Number}: The number of fractional digits to use when parsing and
-*                                    formatting numbers.
-*            Object.rounding {Number}: The rounding increment to use when parsing and formatting.
-*            Object.positive {String}: The symbol to use for positive numbers when parsing and formatting.
-*            Object.negative: {String}: The symbol to use for negative numbers when parsing and formatting.
-*            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
-*            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
-*
-* @error GlobalizationError.PATTERN_ERROR
-*
-* Example
-*    globalization.getNumberPattern(
-*                function (pattern) {alert('Pattern:' + pattern.pattern + '\n');},
-*                function () {});
-*/
-getNumberPattern:function(successCB, failureCB, options) {
-    argscheck.checkArgs('fFO', 'Globalization.getNumberPattern', arguments);
-    exec(successCB, failureCB, "Globalization", "getNumberPattern", [{"options": options}]);
-},
-
-/**
-* Returns a pattern string for formatting and parsing currency values according to the client's
-* user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a
-* properties object as a parameter. If there is an error obtaining the pattern, then the errorCB
-* callback is invoked.
-*
-* @param {String} currencyCode
-* @param {Function} successCB
-* @param {Function} errorCB
-*
-* @return    Object.pattern {String}: The currency pattern for formatting and parsing currency values.
-*                                    The patterns follow Unicode Technical Standard #35
-*                                    http://unicode.org/reports/tr35/tr35-4.html
-*            Object.code {String}: The ISO 4217 currency code for the pattern.
-*            Object.fraction {Number}: The number of fractional digits to use when parsing and
-*                                    formatting currency.
-*            Object.rounding {Number}: The rounding increment to use when parsing and formatting.
-*            Object.decimal: {String}: The decimal symbol to use for parsing and formatting.
-*            Object.grouping: {String}: The grouping symbol to use for parsing and formatting.
-*
-* @error GlobalizationError.FORMATTING_ERROR
-*
-* Example
-*    globalization.getCurrencyPattern('EUR',
-*                function (currency) {alert('Pattern:' + currency.pattern + '\n');}
-*                function () {});
-*/
-getCurrencyPattern:function(currencyCode, successCB, failureCB) {
-    argscheck.checkArgs('sfF', 'Globalization.getCurrencyPattern', arguments);
-    exec(successCB, failureCB, "Globalization", "getCurrencyPattern", [{"currencyCode": currencyCode}]);
-}
-
-};
-
-module.exports = globalization;
diff --git a/www/ubuntu/globalization.js b/www/ubuntu/globalization.js
deleted file mode 100644
index 51900db..0000000
--- a/www/ubuntu/globalization.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- *
- * Copyright 2013 Canonical Ltd.
- *
- * Licensed 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.
- *
-*/
-var exec = require('cordova/exec');
-var argscheck = require('cordova/argscheck');
-var GlobalizationError = require('./GlobalizationError');
-
-function convertStringToDateOptions(override) {
-    var options = { formatLength: 'short', selector: 'date and time' };
-
-    if (override) {
-        for (var key in options) {
-            if (!options.hasOwnProperty(key))
-                continue;
-            if (typeof(options[key]) !== typeof(override[key]))
-                continue;
-            options[key] = override[key];
-        }
-    }
-    var formats = ["short", "medium", "long", "full"];
-    var selectors = ["date", "time", "date and time"];
-
-    options.formatLength = formats.indexOf(options.formatLength);
-    options.selector = selectors.indexOf(options.selector);
-    //TODO: throw error
-    if (options.formatLength === -1)
-        options.formatLength = 0;
-    if (options.selector === -1)
-        options.selector = 0;
-
-    return options;
-}
-
-function convertStringToNumberOptions(override) {
-    var options = { type: 'decimal' };
-    //TODO: make function
-    if (override) {
-        for (var key in options) {
-            if (!options.hasOwnProperty(key))
-                continue;
-            if (typeof(options[key]) !== typeof(override[key]))
-                continue;
-            options[key] = override[key];
-        }
-    }
-
-    var types = [ 'decimal', 'percent', 'currency' ];
-    options.type = types.indexOf(options.type);
-    if (options.type === -1)
-        options.type = 0;
-
-    return options;
-}
-
-function isInt(n) {
-   return n % 1 === 0;
-}
-
-module.exports = {
-    isDayLightSavingsTime: function(date, successCB, failureCB) {
-        argscheck.checkArgs('dfF', 'Globalization.isDayLightSavingsTime', arguments);
-
-        exec(successCB, failureCB, "Globalization", "isDayLightSavingsTime", [ { time_t: date.getTime() } ]);
-    },
-
-    dateToString: function(date, successCB, failureCB, override) {
-        argscheck.checkArgs('dfFO', 'Globalization.dateToString', arguments);
-
-        var options = convertStringToDateOptions(override);
-        exec(successCB, failureCB, "Globalization", "dateToString",
-             [ { time_t: date.getTime(), formatLength: options.formatLength, selector: options.selector } ]);
-
-    },
-
-    stringToDate: function(dateString, successCB, failureCB, override) {
-        argscheck.checkArgs('sfFO', 'Globalization.stringToDate', arguments);
-
-        var options = convertStringToDateOptions(override);
-        exec(successCB, failureCB, "Globalization", "stringToDate",
-             [ { dateString: dateString, formatLength: options.formatLength, selector: options.selector } ]);
-    },
-
-    getDateNames: function(successCB, failureCB, override) {
-        argscheck.checkArgs('fFO', 'Globalization.getDateNames', arguments);
-
-        var options = { type: 'wide', item: 'months' };
-
-        if (override) {
-            for (var key in options) {
-                if (!options.hasOwnProperty(key))
-                    continue;
-                if (typeof(options[key]) !== typeof(override[key]))
-                    continue;
-                options[key] = override[key];
-            }
-        }
-
-        var requests = ["days", "months"];
-        var formats = ["narrow", "wide"];
-
-        options.item = requests.indexOf(options.item);
-        options.type = formats.indexOf(options.type);
-
-        //TODO: throw error
-        if (options.item === -1)
-            options.item = 0;
-        if (options.type === -1)
-            options.type = 0;
-
-        exec(successCB, failureCB, "Globalization", "getDateNames", [ options ]);
-    },
-
-    numberToString: function(number, successCB, failureCB, override) {
-        argscheck.checkArgs('nfFO', 'Globalization.numberToString', arguments);
-
-        var options = convertStringToNumberOptions(override);
-
-        exec(successCB, failureCB, "Globalization", "numberToString",
-             [ { type: options.type, isInt: isInt(number), number: number } ]);
-    },
-
-    stringToNumber: function(numberString, successCB, failureCB, override) {
-        argscheck.checkArgs('sfFO', 'Globalization.stringToNumber', arguments);
-
-        var options = convertStringToNumberOptions(override);
-        exec(successCB, failureCB, "Globalization", "stringToNumber", [ options.type, numberString ]);
-    },
-
-    getDatePattern: function(successCB, failureCB, override) {
-        argscheck.checkArgs('fFO', 'Globalization.getDatePattern', arguments);
-
-        var options = convertStringToDateOptions(override);
-        exec(successCB, failureCB, "Globalization", "getDatePattern", [ options.formatLength, options.selector ]);
-    },
-
-    getNumberPattern: function (successCB, failureCB, override) {
-        argscheck.checkArgs('fFO', 'getNumberPattern', arguments);
-
-        var options = convertStringToNumberOptions(override);
-        Cordova.exec(successCB, failureCB, "Globalization", "getNumberPattern", [ options.type ]);
-    },
-
-    getCurrencyPattern: function(currencyCode, successCB, failureCB) {
-        argscheck.checkArgs('sfF', 'Globalization.getCurrencyPattern', arguments);
-
-        failureCB(new GlobalizationError(GlobalizationError.PATTERN_ERROR, "unimplemented"))
-        //exec(successCB, failureCB, "Globalization", "getCurrencyPattern", [{"currencyCode": currencyCode}]);
-    }
-};
-
-require("cordova/exec/proxy").add("navigator.globalization", module.exports);
