You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devicemap.apache.org by bd...@apache.org on 2012/10/02 15:34:35 UTC

svn commit: r1392912 [4/8] - in /incubator/devicemap/trunk/openddr/csharp: ./ DDR-Simple-API/ DDR-Simple-API/Exceptions/ DDR-Simple-API/Models/ DDR-Simple-API/Properties/ DDR-Simple-API/Simple/ OpenDDR-CSharp/ OpenDDR-CSharp/Builders/ OpenDDR-CSharp/Bu...

Added: incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/AndroidDeviceBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/AndroidDeviceBuilder.cs?rev=1392912&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/AndroidDeviceBuilder.cs (added)
+++ incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/AndroidDeviceBuilder.cs Tue Oct  2 13:34:31 2012
@@ -0,0 +1,273 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using Oddr.Models.Devices;
+using System.Text.RegularExpressions;
+using Oddr.Models;
+using System.Collections;
+
+namespace Oddr.Builders.Devices
+{
+    public class AndroidDeviceBuilder : OrderedTokenDeviceBuilder
+    {
+        private const String BUILD_HASH_REGEXP = ".?>*Build/([^ \\)\\(]*).*";
+        private Regex buildHashRegex = new Regex(BUILD_HASH_REGEXP);
+        private Dictionary<String, Object> regexs = new Dictionary<String, Object>();
+        private Dictionary<String, Device> devices;
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="devices"></param>
+        /// <exception cref="System.InvalidOperationException">Thrown when unable to find device with id in devices</exception>
+        protected override void AfterOrderingCompleteInit(Dictionary<string, Device> devices)
+        {
+            this.devices = devices;
+            foreach (Object devIdObj in orderedRules.Values)
+            {
+                String devId = (String)devIdObj;
+                if (!devices.ContainsKey(devId))
+                {
+                    throw new InvalidOperationException("unable to find device with id: " + devId + " in devices");
+                }
+            }
+        }
+
+        public override void PutDevice(string deviceID, List<string> initProperties)
+        {
+            try
+            {
+                orderedRules.Add(initProperties[0], deviceID);
+                regexs.Add(initProperties[0] + "_loose", Regex.Replace(initProperties[0], "[ _/-]", ".?"));
+                regexs.Add(initProperties[0] + "_loose_icase_regex", new Regex(/*"(?i).*"*/".?>*" + Regex.Replace(initProperties[0], "[ _/-]", ".?") + ".*", RegexOptions.IgnoreCase));
+            }
+            catch (Exception ex)
+            {
+                //Console.WriteLine(this.GetType().FullName + " " + initProperties[0] + " " + deviceID + " " + ex.Message);
+            }
+        }
+
+        public override bool CanBuild(UserAgent userAgent)
+        {
+            return userAgent.containsAndroid && (userAgent.mozillaPattern || userAgent.operaPattern);
+        }
+
+        public override BuiltObject Build(UserAgent userAgent, int confidenceTreshold)
+        {
+            List<Device> foundDevices = new List<Device>();
+            ICollection tokens = orderedRules.Keys;
+            string userAgentWithoutAndroid = userAgent.completeUserAgent.Replace("Android", "");
+            foreach (string token in tokens)
+            {
+                Device d = ElaborateAndroidDeviceWithToken(userAgent, token, userAgentWithoutAndroid);
+                if (d != null)
+                {
+                    if (d.confidence > confidenceTreshold)
+                    {
+                        return d;
+                    }
+                    else
+                    {
+                        if (d.confidence > 0)
+                        {
+                            foundDevices.Add(d);
+                        }
+                    }
+                }
+            }
+
+            if (foundDevices.Count > 0)
+            {
+                foundDevices.Sort();
+                foundDevices.Reverse();
+                return foundDevices[0];
+            }
+            return null;
+        }
+
+        private Device ElaborateAndroidDeviceWithToken(UserAgent userAgent, String token, String userAgentWithoutAndroid)
+        {
+            int subtract = 0;
+            String currentToken = token;
+
+            String looseToken = (String)(regexs[token + "_loose"]); 
+            //String looseToken = Regex.Replace(token, "[ _/-]", ".?");
+
+            Regex looseRegex = (Regex)(regexs[token + "_loose_icase_regex"]);
+            //Regex looseRegex = new Regex(/*"(?i).*"*/".*" + looseToken + ".*", RegexOptions.IgnoreCase);
+
+            if (!looseRegex.IsMatch(userAgentWithoutAndroid))
+            {
+                return null;
+            }
+
+            String patternElementInsideClean = CleanPatternElementInside(userAgent.GetPatternElementsInside());
+
+            Regex currentRegex = null;
+
+            for (int i = 0; i <= 1; i++)
+            {
+                if (i == 1)
+                {
+                    currentToken = looseToken;
+                }
+
+                currentRegex = new Regex(/*"(?i).*"*/".?>*" + currentToken + ".?Build/.*", RegexOptions.IgnoreCase);
+                if (patternElementInsideClean != null && currentRegex.IsMatch(patternElementInsideClean))
+                {
+                    String deviceId = (String)orderedRules[token];
+
+                    Device retDevice = null;
+                    if (devices.TryGetValue(deviceId, out retDevice))
+                    {
+                        retDevice = (Device)retDevice.Clone();
+                        retDevice.confidence = (100 - subtract);
+                        return retDevice;
+                    }
+                }
+
+                currentRegex = new Regex(/*"(?i).*"*/".?>*" + currentToken, RegexOptions.IgnoreCase);
+                if (userAgent.GetPatternElementsPre() != null && currentRegex.IsMatch(userAgent.GetPatternElementsPre()))
+                {
+                    String deviceId = (String)orderedRules[token];
+
+                    Device retDevice = null;
+                    if (devices.TryGetValue(deviceId, out retDevice))
+                    {
+                        retDevice = (Device)retDevice.Clone();
+                        retDevice.confidence = (95 - subtract);
+                        return retDevice;
+                    }
+                }
+
+                if (patternElementInsideClean != null && currentRegex.IsMatch(patternElementInsideClean))
+                {
+                    String deviceId = (String)orderedRules[token];
+
+                    Device retDevice = null;
+                    if (devices.TryGetValue(deviceId, out retDevice))
+                    {
+                        retDevice = (Device)retDevice.Clone();
+                        retDevice.confidence = (90 - subtract);
+                        return retDevice;
+                    }
+                }
+
+                currentRegex = new Regex(/*"(?i).*"*/".?>*" + currentToken + ".?;.*", RegexOptions.IgnoreCase);
+                if (patternElementInsideClean != null && currentRegex.IsMatch(patternElementInsideClean))
+                {
+                    String deviceId = (String)orderedRules[token];
+
+                    Device retDevice = null;
+                    if (devices.TryGetValue(deviceId, out retDevice))
+                    {
+                        retDevice = (Device)retDevice.Clone();
+                        retDevice.confidence = (90 - subtract);
+                        return retDevice;
+                    }
+                }
+
+                if (i == 1)
+                {
+                    currentRegex = looseRegex;
+
+                }
+                else
+                {
+                    currentRegex = new Regex(/*"(?i).*"*/".?>*" + currentToken + ".*", RegexOptions.IgnoreCase);
+                }
+                if (patternElementInsideClean != null && currentRegex.IsMatch(patternElementInsideClean))
+                {
+                    String deviceId = (String)orderedRules[token];
+
+                    Device retDevice = null;
+                    if (devices.TryGetValue(deviceId, out retDevice))
+                    {
+                        retDevice = (Device)retDevice.Clone();
+                        retDevice.confidence = (80 - subtract);
+                        return retDevice;
+                    }
+                }
+                if (userAgent.GetPatternElementsPre() != null && currentRegex.IsMatch(userAgent.GetPatternElementsPre()))
+                {
+                    String deviceId = (String)orderedRules[token];
+
+                    Device retDevice = null;
+                    if (devices.TryGetValue(deviceId, out retDevice))
+                    {
+                        retDevice = (Device)retDevice.Clone();
+                        retDevice.confidence = (80 - subtract);
+                        return retDevice;
+                    }
+                }
+                if (userAgent.GetPatternElementsPost() != null && currentRegex.IsMatch(userAgent.GetPatternElementsPost()))
+                {
+                    String deviceId = (String)orderedRules[token];
+
+                    Device retDevice = null;
+                    if (devices.TryGetValue(deviceId, out retDevice))
+                    {
+                        retDevice = (Device)retDevice.Clone();
+                        retDevice.confidence = (60 - subtract);
+                        return retDevice;
+                    }
+                }
+                if (i == 1)
+                {
+                    if (userAgent.GetPatternElementsInside() != null && currentRegex.IsMatch(userAgent.GetPatternElementsInside()))
+                    {
+                        String deviceId = (String)orderedRules[token];
+
+                        Device retDevice = null;
+                        if (devices.TryGetValue(deviceId, out retDevice))
+                        {
+                            retDevice = (Device)retDevice.Clone();
+                            retDevice.confidence = (40 - subtract);
+                            return retDevice;
+                        }
+                    }
+                }
+                subtract += 20;
+            }
+
+            return null;
+        }
+
+        private String CleanPatternElementInside(String patternElementsInside)
+        {
+            String patternElementInsideClean = patternElementsInside;
+
+            if (buildHashRegex.IsMatch(patternElementInsideClean))
+            {
+                Match buildHashMatcher = buildHashRegex.Match(patternElementInsideClean);
+                GroupCollection groups = buildHashMatcher.Groups;
+
+                String build = groups[1].Value;
+                patternElementInsideClean = patternElementInsideClean.Replace("Build/" + build, "Build/");
+            }
+            patternElementInsideClean = patternElementInsideClean.Replace("Android", "");
+
+            return patternElementInsideClean;
+        }
+    }
+}

Added: incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/IDeviceBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/IDeviceBuilder.cs?rev=1392912&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/IDeviceBuilder.cs (added)
+++ incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/IDeviceBuilder.cs Tue Oct  2 13:34:31 2012
@@ -0,0 +1,36 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Oddr.Models.Devices;
+
+namespace Oddr.Builders.Devices
+{
+    public interface IDeviceBuilder : IBuilder
+    {
+        void PutDevice(String deviceID, List<String> initProperties);
+
+        void CompleteInit(Dictionary<String, Device> devices);
+    }
+}

Added: incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/IOSDeviceBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/IOSDeviceBuilder.cs?rev=1392912&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/IOSDeviceBuilder.cs (added)
+++ incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/IOSDeviceBuilder.cs Tue Oct  2 13:34:31 2012
@@ -0,0 +1,107 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Oddr.Models.Devices;
+using Oddr.Models;
+using System.Text.RegularExpressions;
+using System.Collections.Specialized;
+
+namespace Oddr.Builders.Devices
+{
+    public class IOSDeviceBuilder : IDeviceBuilder
+    {
+        private OrderedDictionary iOSDevices;
+        private Dictionary<String, Device> devices;
+
+        public IOSDeviceBuilder()
+            : base()
+        {
+            iOSDevices = new OrderedDictionary();
+        }
+
+        public void PutDevice(string deviceID, List<string> initProperties)
+        {
+            try
+            {
+                iOSDevices.Add(initProperties[0], deviceID);
+            }
+            catch (Exception ex)
+            {
+                //Console.WriteLine(this.GetType().FullName + " " + initProperties[0] + " " + deviceID + " " + ex.Message);
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="devices"></param>
+        /// <exception cref="System.InvalidOperationException">Thrown when unable to find device with id in devices</exception>
+        public void CompleteInit(Dictionary<string, Device> devices)
+        {
+            String global = "iPhone";
+            if (iOSDevices.Contains(global)) {
+                String iphone = (string)iOSDevices[global];
+                iOSDevices.Remove(global);
+                iOSDevices.Add(global, iphone);
+            }
+
+            this.devices = devices;
+
+            foreach (String deviceID in iOSDevices.Values) {
+                if (!devices.ContainsKey(deviceID)) {
+                    throw new InvalidOperationException("unable to find device with id: " + deviceID + " in devices");
+                }
+            }
+        }
+
+        public bool CanBuild(UserAgent userAgent)
+        {
+            return userAgent.containsIOSDevices && (!userAgent.containsAndroid) && (!userAgent.containsWindowsPhone);
+        }
+
+        public BuiltObject Build(UserAgent userAgent, int confidenceTreshold)
+        {
+            foreach (string token in iOSDevices.Keys)
+            {
+                Regex tokenRegex = new Regex(".*" + token + ".*");
+                if (tokenRegex.IsMatch(userAgent.completeUserAgent))
+                {
+                    if (iOSDevices.Contains(token))
+                    {
+                        String iosDeviceID = (string)iOSDevices[token];
+                        Device retDevice = null;
+                        if (devices.TryGetValue(iosDeviceID, out retDevice))
+                        {
+                            retDevice = (Device)retDevice.Clone();
+                            retDevice.confidence = 90;
+                            return retDevice;
+                        }
+                    }
+                }
+            }
+            return null;
+        }
+    }
+}

Added: incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/OrderedTokenDeviceBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/OrderedTokenDeviceBuilder.cs?rev=1392912&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/OrderedTokenDeviceBuilder.cs (added)
+++ incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/OrderedTokenDeviceBuilder.cs Tue Oct  2 13:34:31 2012
@@ -0,0 +1,139 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Oddr.Models.Devices;
+using System.Text.RegularExpressions;
+using Oddr.Models;
+using System.Collections.Specialized;
+using System.Diagnostics;
+
+namespace Oddr.Builders.Devices
+{
+    public abstract class OrderedTokenDeviceBuilder : IDeviceBuilder
+    {
+        protected OrderedDictionary orderedRules;
+
+        /// <exception cref="System.InvalidOperationException">Thrown when unable to find device with id in devices</exception>
+        protected abstract void AfterOrderingCompleteInit(Dictionary<String, Device> devices);
+
+        public OrderedTokenDeviceBuilder()
+        {
+            orderedRules = new OrderedDictionary();
+        }
+
+        public void CompleteInit(Dictionary<string, Device> devices)
+        {
+            
+            Dictionary<String, Object> tmp = new Dictionary<String, Object>();
+            List<String> keys = new List<String>();
+            foreach (string key in orderedRules.Keys)
+            {
+                keys.Add(key);
+            }
+
+            keys.Sort(new OrderedTokenDeviceComparer());
+
+            foreach (String str in keys)
+            {
+                tmp.Add(str, orderedRules[str]);
+            }
+            List<String> keysOrdered = new List<String>();
+
+            orderedRules = new OrderedDictionary();
+
+            while (keys.Count > 0)
+            {
+                bool found = false;
+
+                foreach (string k1 in keys)
+                {
+                    Regex k1Regex = new Regex(".*" + k1 + ".*");
+
+                    foreach (string k2 in keys)
+                    {
+                        if ((!k1.Equals(k2)) && k1Regex.IsMatch(k2))
+                        //if ((!k1.Equals(k2)) && Regex.IsMatch(k2, ".*" + k1 + ".*"))
+                        //if ((!k1.Equals(k2)) && k2.Contains(k1))
+                        {
+                            found = true;
+                            break;
+                        }
+                    }
+
+                    if (!found)
+                    {
+                        keysOrdered.Add(k1);
+                        keys.Remove(k1);
+                        break;
+                    }
+                }
+
+                if (!found)
+                {
+                    continue;
+                }
+                int max = 0;
+                int idx = -1;
+                for (int i = 0; i < keys.Count; i++)
+                {
+                    String str = keys[i];
+                    if (str.Length > max)
+                    {
+                        max = str.Length;
+                        idx = i;
+                    }
+                }
+
+                if (idx >= 0)
+                {
+                    keysOrdered.Add(keys[idx]);
+                    keys.RemoveAt(idx);
+                }
+            }
+
+            foreach (String key in keysOrdered)
+            {
+                orderedRules.Add(key, tmp[key]);
+                tmp.Remove(key);
+            }
+
+            AfterOrderingCompleteInit(devices);
+        }
+
+        public abstract void PutDevice(string deviceID, List<string> initProperties);
+
+        public abstract bool CanBuild(UserAgent userAgent);
+
+        public abstract BuiltObject Build(UserAgent userAgent, int confidenceTreshold);
+    }
+
+    public class OrderedTokenDeviceComparer : IComparer<string>
+    {
+        public int Compare(string x, string y)
+        {
+            return y.Length - x.Length;
+        }
+    }
+}

Added: incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/SimpleDeviceBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/SimpleDeviceBuilder.cs?rev=1392912&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/SimpleDeviceBuilder.cs (added)
+++ incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/SimpleDeviceBuilder.cs Tue Oct  2 13:34:31 2012
@@ -0,0 +1,101 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Collections.Specialized;
+using Oddr.Models.Devices;
+using Oddr.Models;
+using System.Text.RegularExpressions;
+
+namespace Oddr.Builders.Devices
+{
+    public class SimpleDeviceBuilder : IDeviceBuilder
+    {
+        private OrderedDictionary simpleTokenMap;
+        private Dictionary<String, Device> devices;
+
+        public SimpleDeviceBuilder()
+            : base()
+        {
+            simpleTokenMap = new OrderedDictionary();
+        }
+
+        public void PutDevice(string deviceID, List<string> initProperties)
+        {
+            foreach (String token in initProperties)
+            {
+                simpleTokenMap[token] = deviceID; // override duplicate
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="devices"></param>
+        /// <exception cref="System.InvalidOperationException">Thrown when unable to find device with id in devices</exception>
+        public void CompleteInit(Dictionary<string, Device> devices)
+        {
+            this.devices = devices;
+
+            foreach (String deviceID in simpleTokenMap.Values)
+            {
+                if (!devices.ContainsKey(deviceID))
+                {
+                    throw new InvalidOperationException("unable to find device with id: " + deviceID + "in devices");
+                }
+            }
+        }
+
+        public bool CanBuild(UserAgent userAgent)
+        {
+            foreach (String token in simpleTokenMap.Keys)
+            {
+                Regex tokenRegex = new Regex(/*"(?i).*"*/".*" + Regex.Escape(token) + ".*", RegexOptions.IgnoreCase);
+                if (tokenRegex.IsMatch(userAgent.completeUserAgent))
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public BuiltObject Build(UserAgent userAgent, int confidenceTreshold)
+        {
+            foreach (string token in simpleTokenMap.Keys)
+            {
+                Regex tokenRegex = new Regex(/*"(?i).*"*/".*" + Regex.Escape(token) + ".*", RegexOptions.IgnoreCase);
+                if (tokenRegex.IsMatch(userAgent.completeUserAgent) && simpleTokenMap.Contains(token))
+                {
+                    String desktopDeviceId = (string)simpleTokenMap[token];
+                    Device device = null;
+                    if (devices.TryGetValue(desktopDeviceId, out device))
+                    {
+                        return device;
+                    }
+                }
+            }
+            return null;
+        }
+    }
+}

Added: incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/SymbianDeviceBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/SymbianDeviceBuilder.cs?rev=1392912&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/SymbianDeviceBuilder.cs (added)
+++ incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/SymbianDeviceBuilder.cs Tue Oct  2 13:34:31 2012
@@ -0,0 +1,315 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Oddr.Models.Devices;
+using Oddr.Models;
+using System.Text.RegularExpressions;
+
+namespace Oddr.Builders.Devices
+{
+    public class SymbianDeviceBuilder : OrderedTokenDeviceBuilder
+    {
+        private Dictionary<String, Device> devices;
+        private Dictionary<String, Object> regexs = new Dictionary<String, Object>();
+
+        public SymbianDeviceBuilder()
+            : base()
+        {
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="devices"></param>
+        /// <exception cref="System.InvalidOperationException">Thrown when unable to find device with id in devices</exception>
+        protected override void AfterOrderingCompleteInit(Dictionary<string, Device> devices)
+        {
+            this.devices = devices;
+            foreach (Object devIdObj in orderedRules.Values)
+            {
+                String devId = (String)devIdObj;
+                if (!devices.ContainsKey(devId))
+                {
+                    throw new InvalidOperationException("unable to find device with id: " + devId + "in devices");
+                }
+            }
+        }
+
+        public override void PutDevice(string deviceID, List<string> initProperties)
+        {
+            try
+            {
+                orderedRules.Add(initProperties[0], deviceID);
+                regexs.Add(initProperties[0] + "_loose", Regex.Replace(initProperties[0], "[ _/-]", ".?"));
+                regexs.Add(initProperties[0] + "_loose_icase_regex", new Regex(/*"(?i).*"*/".?>*" + Regex.Replace(initProperties[0], "[ _/-]", ".?") + ".*"));
+            }
+            catch (Exception ex)
+            {
+                //Console.WriteLine(this.GetType().FullName + " " + initProperties[0] + " " + deviceID + " " + ex.Message);
+            }
+        }
+
+        public override bool CanBuild(UserAgent userAgent)
+        {
+            return userAgent.containsSymbian;
+        }
+
+        public override BuiltObject Build(UserAgent userAgent, int confidenceTreshold)
+        {
+            List<Device> foundDevices = new List<Device>();
+
+            foreach (string token in orderedRules.Keys)
+            {
+                Device d = ElaborateSymbianDeviceWithToken(userAgent, token);
+                if (d != null)
+                {
+                    if (d.confidence > confidenceTreshold)
+                    {
+                        return d;
+
+                    }
+                    else
+                    {
+                        if (d.confidence > 0)
+                        {
+                            foundDevices.Add(d);
+                        }
+                    }
+                }
+            }
+
+            if (foundDevices.Count > 0)
+            {
+                foundDevices.Sort();
+                foundDevices.Reverse();
+                return foundDevices[0];
+            }
+            return null;
+        }
+
+        private Device ElaborateSymbianDeviceWithToken(UserAgent userAgent, String token)
+        {
+            String originalToken = token;
+
+            if (userAgent.mozillaPattern || userAgent.operaPattern)
+            {
+                int subtract = 0;
+                String currentToken = token;
+
+                String looseToken = (String)(regexs[token + "_loose"]);
+                //String looseToken = Regex.Replace(token, "[ _/-]", ".?");
+
+                Regex looseRegex = (Regex)(regexs[token + "_loose_icase_regex"]);
+                //Regex looseRegex = new Regex(".*" + looseToken + ".*");
+
+                if (!looseRegex.IsMatch(userAgent.completeUserAgent))
+                {
+                    return null;
+                }
+
+                Regex currentRegex = null;
+
+                if (userAgent.operaPattern)
+                {
+                    subtract += 10;
+                }
+                for (int i = 0; i <= 1; i++)
+                {
+                    if (i == 1)
+                    {
+                        currentToken = looseToken;
+                    }
+
+                    currentRegex = new Regex(".?>*Series60.?(\\d+)\\.(\\d+).?" + currentToken + ".*");
+                    if (userAgent.GetPatternElementsInside() != null && currentRegex.IsMatch(userAgent.GetPatternElementsInside()))
+                    {
+                        if (orderedRules.Contains(originalToken))
+                        {
+                            String deviceId = (String)orderedRules[originalToken];
+                            Device retDevice = null;
+                            if (devices.TryGetValue(deviceId, out retDevice))
+                            {
+                                retDevice = (Device)retDevice.Clone();
+                                retDevice.confidence = (100 - subtract);
+                                return retDevice;
+                            }
+                        }
+                    }
+
+                    currentRegex = new Regex(".?>*" + currentToken);
+                    if (userAgent.GetPatternElementsPre() != null && currentRegex.IsMatch(userAgent.GetPatternElementsPre()))
+                    {
+                        if (orderedRules.Contains(originalToken))
+                        {
+                            String deviceId = (String)orderedRules[originalToken];
+                            Device retDevice = null;
+                            if (devices.TryGetValue(deviceId, out retDevice))
+                            {
+                                retDevice = (Device)retDevice.Clone();
+                                retDevice.confidence = (95 - subtract);
+                                return retDevice;
+                            }
+                        }
+                    }
+
+                    if (userAgent.GetPatternElementsInside() != null && currentRegex.IsMatch(userAgent.GetPatternElementsInside()))
+                    {
+                        if (orderedRules.Contains(originalToken))
+                        {
+                            String deviceId = (String)orderedRules[originalToken];
+                            Device retDevice = null;
+                            if (devices.TryGetValue(deviceId, out retDevice))
+                            {
+                                retDevice = (Device)retDevice.Clone();
+                                retDevice.confidence = (90 - subtract);
+                                return retDevice;
+                            }
+                        }
+                    }
+
+                    currentRegex = new Regex(".?>*" + currentToken + ".?;.*");
+                    if (userAgent.GetPatternElementsInside() != null && currentRegex.IsMatch(userAgent.GetPatternElementsInside()))
+                    {
+                        if (orderedRules.Contains(originalToken))
+                        {
+                            String deviceId = (String)orderedRules[originalToken];
+                            Device retDevice = null;
+                            if (devices.TryGetValue(deviceId, out retDevice))
+                            {
+                                retDevice = (Device)retDevice.Clone();
+                                retDevice.confidence = (90 - subtract);
+                                return retDevice;
+                            }
+                        }
+                    }
+
+                    if (i == 1)
+                    {
+                        currentRegex = looseRegex;
+
+                    }
+                    else
+                    {
+                        currentRegex = new Regex(".?>*" + currentToken + ".*");
+                    }
+
+                    if (userAgent.GetPatternElementsInside() != null && currentRegex.IsMatch(userAgent.GetPatternElementsInside()))
+                    {
+                        if (orderedRules.Contains(originalToken))
+                        {
+                            String deviceId = (String)orderedRules[originalToken];
+                            Device retDevice = null;
+                            if (devices.TryGetValue(deviceId, out retDevice))
+                            {
+                                retDevice = (Device)retDevice.Clone();
+                                retDevice.confidence = (80 - subtract);
+                                return retDevice;
+                            }
+                        }
+                    }
+
+                    if (userAgent.GetPatternElementsPre() != null && currentRegex.IsMatch(userAgent.GetPatternElementsPre()))
+                    {
+                        if (orderedRules.Contains(originalToken))
+                        {
+                            String deviceId = (String)orderedRules[currentToken];
+                            Device retDevice = null;
+                            if (devices.TryGetValue(deviceId, out retDevice))
+                            {
+                                retDevice = (Device)retDevice.Clone();
+                                retDevice.confidence = (80 - subtract);
+                                return retDevice;
+                            }
+                        }
+                    }
+
+                    if (userAgent.GetPatternElementsPost() != null && currentRegex.IsMatch(userAgent.GetPatternElementsPost()))
+                    {
+                        if (orderedRules.Contains(originalToken))
+                        {
+                            String deviceId = (String)orderedRules[currentToken];
+                            Device retDevice = null;
+                            if (devices.TryGetValue(deviceId, out retDevice))
+                            {
+                                retDevice = (Device)retDevice.Clone();
+                                retDevice.confidence = (60 - subtract);
+                                return retDevice;
+                            }
+                        }
+                    }
+                    subtract += 20;
+                }
+            }
+            else
+            {
+                String ua = Regex.Replace(userAgent.completeUserAgent, "SN[0-9]*", "");
+
+                int subtract = 0;
+                String currentToken = token;
+
+                String looseToken = (String)(regexs[token + "_loose"]);
+                //String looseToken = Regex.Replace(token, "[ _/-]", ".?");
+
+                Regex looseRegex = (Regex)(regexs[token + "_loose_icase_regex"]);
+                //Regex looseRegex = new Regex(".*" + looseToken + ".*");
+
+                if (!looseRegex.IsMatch(userAgent.completeUserAgent))
+                {
+                    return null;
+                }
+
+                Regex currentRegex = null;
+
+                for (int i = 0; i <= 1; i++)
+                {
+                    if (i == 1)
+                    {
+                        currentToken = looseToken;
+                    }
+
+                    currentRegex = new Regex(".?>*" + currentToken + ".*");
+                    if (currentRegex.IsMatch(ua))
+                    {
+                        if (orderedRules.Contains(originalToken))
+                        {
+                            string deviceId = orderedRules[originalToken] as string;                            
+
+                            if (devices.ContainsKey(deviceId))
+                            {
+                                Device retDevice = (Device)devices[deviceId].Clone();
+                                retDevice.confidence = 100 - subtract;
+                                return retDevice;
+                            }
+                        }
+                    }
+
+                    subtract += 20;
+                }
+            }
+
+            return null;
+        }
+    }
+}

Added: incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/TwoStepDeviceBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/TwoStepDeviceBuilder.cs?rev=1392912&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/TwoStepDeviceBuilder.cs (added)
+++ incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/TwoStepDeviceBuilder.cs Tue Oct  2 13:34:31 2012
@@ -0,0 +1,407 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Oddr.Models.Devices;
+using Oddr.Models;
+using System.Text.RegularExpressions;
+using System.Collections.Specialized;
+using System.Globalization;
+
+namespace Oddr.Builders.Devices
+{
+    public class TwoStepDeviceBuilder : OrderedTokenDeviceBuilder
+    {
+        private Dictionary<String, Device> devices;
+        private Dictionary<String, Object> regexs = new Dictionary<String, Object>();
+        private static readonly Regex litteralRegex = new Regex(".*[a-zA-Z].*", RegexOptions.Compiled);
+        private static readonly Regex betweenTokensRegex = new Regex("[ _/-]?", RegexOptions.Compiled);
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="devices"></param>
+        /// <exception cref="System.InvalidOperationException">Thrown when unable to find device with id in devices</exception>
+        protected override void AfterOrderingCompleteInit(Dictionary<string, Device> devices)
+        {
+            foreach (String step1Token in orderedRules.Keys)
+            {
+
+                SortElement(step1Token);
+            }
+
+            this.devices = devices;
+            foreach (Object devIdsMapObj in orderedRules.Values)
+            {
+                OrderedDictionary devIdsMap = devIdsMapObj as OrderedDictionary;
+                if (devIdsMap != null)
+                {
+                    foreach (Object devIdObj in devIdsMap.Values)
+                    {
+                        String devId = (String)devIdObj;
+                        if (!devices.ContainsKey(devId))
+                        {
+                            throw new InvalidOperationException("unable to find device with id: " + devId + " in devices");
+                        }
+                    }
+                }
+                else
+                {
+                    //Console.WriteLine(this.GetType().FullName + " can't cast orderedRules' values in OrderedDictionary");
+                }
+            }
+        }
+
+        private void SortElement(String step1Token)
+        {
+            OrderedDictionary currentStep1Map = (OrderedDictionary)orderedRules[step1Token];
+
+            OrderedDictionary tmp = new OrderedDictionary();
+            List<String> keys = new List<string>();
+            foreach (String key in currentStep1Map.Keys)
+            {
+                keys.Add(key);
+            }
+
+            keys.Sort(new OrderedStep1KeyComparer());
+
+            foreach (String str in keys)
+            {
+                tmp.Add(str, currentStep1Map[str]);
+            }
+
+            currentStep1Map = new OrderedDictionary();
+
+            List<String> keysOrdered = orderKeys(keys);
+
+            foreach (String key in keysOrdered)
+            {
+                currentStep1Map.Add(key, tmp[key]);
+                tmp.Remove(key);
+            }
+
+            orderedRules[step1Token] = currentStep1Map;
+        }
+
+        private List<String> orderKeys(List<String> keys)
+        {
+            List<String> keysOrdered = new List<String>();
+
+            while (keys.Count > 0)
+            {
+                if (!findKey(keys, keysOrdered))
+                {
+                    continue;
+                }
+                int max = 0;
+                int idx = -1;
+                for (int i = 0; i < keys.Count; i++)
+                {
+                    String str = keys[i];
+                    if (str.Length > max)
+                    {
+                        max = str.Length;
+                        idx = i;
+                    }
+                }
+                if (idx >= 0)
+                {
+                    keysOrdered.Add(keys[idx]);
+                    keys.Remove(keys[idx]);
+                }
+            }
+
+            return keysOrdered;
+        }
+
+        private bool findKey(List<String> keys, List<String> keysOrdered)
+        {
+            bool found = false;
+            //CompareInfo compareInfo = CultureInfo.InvariantCulture.CompareInfo;
+            //foreach (String k1 in keys)
+            foreach (string k1 in keys)
+            {
+                Regex k1Regex = new Regex(".*" + k1 + ".*");
+                //foreach (String k2 in keys)
+                foreach (string k2 in keys)
+                {
+                    if ((!k1.Equals(k2)) && k1Regex.IsMatch(k2))
+                    //if ((!k1.Equals(k2))/* && k2.Contains(k1)*/ && compareInfo.IndexOf(k2, k1) != -1)
+                    //if ((!k1.Equals(k2)) && k2.Contains(k1))
+                    {
+                        found = true;
+                        break;
+                    }
+                }
+                if (!found)
+                {
+                    keysOrdered.Add(k1);
+                    keys.Remove(k1);
+                    break;
+                }
+            }
+
+            return found;
+        }
+
+        public override void PutDevice(string deviceID, List<string> initProperties)
+        {
+            String step1TokenString = initProperties[0];
+            String step2TokenString = initProperties[1];
+
+            Regex step1TokenStringRegex = new Regex(".*" + step1TokenString + ".*");
+            if (step1TokenStringRegex.IsMatch(step2TokenString))
+            //if (step2TokenString.Contains(step1TokenString))
+            {
+                step2TokenString = Regex.Replace(step2TokenString, step1TokenString + "[^a-zA-Z0-9]?", "");
+            }
+
+            OrderedDictionary step1Token = null;
+            if (orderedRules.Contains(step1TokenString))
+            {
+                step1Token = (OrderedDictionary)orderedRules[step1TokenString];
+            }
+
+            if (step1Token == null)
+            {
+                step1Token = new OrderedDictionary();
+                try
+                {
+                    regexs.Add(step1TokenString + "_icase", new Regex(/*"(?i).*"*/".?>*" + step1TokenString + ".*", RegexOptions.IgnoreCase));
+                    orderedRules.Add(initProperties[0], step1Token);
+                    //Console.WriteLine("initProperties[0] " + initProperties[0] + " step1Token " + step1Token);
+                }
+                catch (Exception ex)
+                {
+                    //Console.WriteLine(this.GetType().FullName + " " + "initProperties[0] " + initProperties[0] + " step1Token " + step1Token + " " + ex.Message);
+                }
+            }
+            try
+            {
+                step1Token.Add(step2TokenString, deviceID);
+                regexs.Add(step2TokenString + "_loose", Regex.Replace(step2TokenString, "[ _/-]", ".?"));
+                regexs.Add(step2TokenString + "_loose_icase", new Regex(/*"(?i).*"*/".?>*" + Regex.Replace(step2TokenString, "[ _/-]", ".?") + ".*", RegexOptions.IgnoreCase));
+                regexs.Add(step2TokenString + "_icase", new Regex(/*"(?i).*"*/".?>*" + step2TokenString + ".*", RegexOptions.IgnoreCase));
+                //Console.WriteLine("step2token " + step2TokenString + " deviceID " + deviceID);
+            }
+            catch (Exception ex)
+            {
+                //Console.WriteLine(this.GetType().FullName + " " + "step2token " + step2TokenString + " deviceID " + deviceID + " " + ex.Message);
+            }
+        }
+
+        public override bool CanBuild(UserAgent userAgent)
+        {
+            foreach (String step1Token in orderedRules.Keys)
+            {
+                Regex step1TokenRegex = (Regex)(regexs[step1Token + "_icase"]);
+                //Regex step1TokenRegex = new Regex(/*"(?i).*"*/".*" + step1Token + ".*", RegexOptions.IgnoreCase);
+                if (step1TokenRegex.IsMatch(userAgent.completeUserAgent))
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public override BuiltObject Build(UserAgent userAgent, int confidenceTreshold)
+        {
+            List<Device> foundDevices = new List<Device>();
+            foreach (String step1Token in orderedRules.Keys)
+            {
+                //Regex step1TokenRegex = new Regex("(?i).*" + step1Token + ".*");
+                //if (step1TokenRegex.IsMatch(userAgent.completeUserAgent))
+                if (Regex.IsMatch(userAgent.completeUserAgent, /*"(?i).*"*/".?>*" + step1Token + ".*", RegexOptions.IgnoreCase))
+                {
+                    OrderedDictionary step1Compliant = (OrderedDictionary)orderedRules[step1Token];
+                    foreach (String step2token in step1Compliant.Keys)
+                    {
+                        Device d = ElaborateTwoStepDeviceWithToken(userAgent, step1Token, step2token);
+                        if (d != null)
+                        {
+                            if (d.confidence > confidenceTreshold)
+                            {
+                                return d;
+
+                            }
+                            else
+                            {
+                                if (d.confidence > 0)
+                                {
+                                    foundDevices.Add(d);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            if (foundDevices.Count > 0)
+            {
+                foundDevices.Sort();
+                foundDevices.Reverse();
+                return foundDevices[0];
+            }
+
+            return null;
+        }
+
+        private Device ElaborateTwoStepDeviceWithToken(UserAgent userAgent, String step1Token, String step2Token)
+        {
+            int maxLittleTokensDistance = 4;
+            int maxBigTokensDistance = 8;
+            int confidence;
+
+            String originalToken = step2Token;
+            String looseToken = (String)(regexs[step2Token + "_loose"]); 
+            //String looseToken = Regex.Replace(step2Token, "[ _/-]", ".?");
+            Regex step2TokenRegex = (Regex)(regexs[step2Token + "_icase"]);  
+            //Regex step2TokenRegex = new Regex(/*"(?i).*"*/".*" + step2Token + ".*", RegexOptions.IgnoreCase);
+            if (step2TokenRegex.IsMatch(userAgent.completeUserAgent))
+            {
+                confidence = 100;
+
+            }
+            else
+            {
+                Regex looseTokenRegex = (Regex)(regexs[step2Token + "_loose_icase"]);
+                //Regex looseTokenRegex = new Regex(/*"(?i).*"*/".*" + looseToken + ".*", RegexOptions.IgnoreCase);
+                if (looseTokenRegex.IsMatch(userAgent.completeUserAgent))
+                {
+                    step2Token = looseToken;
+                    confidence = 90;
+
+                }
+                else
+                {
+                    return null;
+                }
+            }
+
+            Regex step1And2TokenRegex = new Regex(/*"(?i)(?:(?:.*"*/"(?:(?:.*" + step1Token + "(.*?)" + step2Token + ".*)|(?:.*" + step2Token + "(.*?)" + step1Token + ".*))", RegexOptions.IgnoreCase);
+            if (step1And2TokenRegex.IsMatch(userAgent.completeUserAgent))
+            {
+                Match result = step1And2TokenRegex.Match(userAgent.completeUserAgent);
+                //test for case sensitive match
+                Regex step1And2TokenCaseSensitiveRegex = new Regex("(?:(?:.*" + step1Token + "(.*?)" + step2Token + ".*)|(?:.*" + step2Token + "(.*?)" + step1Token + ".*))");
+                if (step1And2TokenCaseSensitiveRegex.IsMatch(userAgent.completeUserAgent))
+                {
+                    Match bestResult = step1And2TokenCaseSensitiveRegex.Match(userAgent.completeUserAgent);
+                    result = bestResult;
+
+                }
+                else
+                {
+                    confidence -= 20;
+                }
+
+                GroupCollection groups = result.Groups;
+                String betweenTokens = groups[1].Value;
+                String s2 = groups[2].Value;
+                if (s2 != null && s2.Length != 0 && (betweenTokens == null || betweenTokens.Length > s2.Length))
+                {
+                    betweenTokens = s2;
+                }
+                int betweenTokensLength = betweenTokens.Length;
+                if (step2Token.Length > 3)
+                {
+                    if (betweenTokensLength > maxBigTokensDistance)
+                    {
+                        confidence -= 10;
+                    }
+
+                    if (orderedRules.Contains(step1Token))
+                    {
+                        OrderedDictionary d = (OrderedDictionary)orderedRules[step1Token];
+                        String deviceId = null;
+                        if (d.Contains(originalToken))
+                        {
+                            deviceId = (string)d[originalToken];
+                            Device retDevice = null;
+                            if (devices.TryGetValue(deviceId, out retDevice))
+                            {
+                                retDevice = (Device)retDevice.Clone();
+                                retDevice.confidence = confidence;
+                                return retDevice;
+                            }
+                        }
+                    }
+                }
+
+                if ((betweenTokensLength < maxLittleTokensDistance) || (betweenTokensLength < maxBigTokensDistance && (step2Token.Length < 6 || !litteralRegex.IsMatch(step2Token))))
+                {
+                    if (betweenTokensLength <= 1)
+                    {
+                        
+                        if (!betweenTokensRegex.IsMatch(betweenTokens))
+                        {
+                            confidence -= 20;
+                        }
+
+                    }
+                    else
+                    {
+                        confidence -= 40;
+                    }
+
+                    confidence -= (betweenTokensLength * 4);
+
+                    if (orderedRules.Contains(step1Token))
+                    {
+                        OrderedDictionary d = (OrderedDictionary)orderedRules[step1Token];
+                        String deviceId = null;
+
+                        if (d.Contains(originalToken))
+                        {
+                            deviceId = (string)d[originalToken];
+                            Device retDevice = null;
+                            if (devices.TryGetValue(deviceId, out retDevice))
+                            {
+                                retDevice = (Device)retDevice.Clone();
+                                retDevice.confidence = confidence;
+                                return retDevice;
+                            }
+                        }
+                    }
+                }
+            }
+
+            return null;
+        }
+    }
+
+    public class OrderedStep1KeyComparer : IComparer<string>
+    {
+        public int Compare(string x, string y)
+        {
+            if (y.Length == x.Length)
+            {
+                return y.CompareTo(x);
+            }
+            else
+            {
+                return y.Length - x.Length;
+            }
+        }
+    }
+}

Added: incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/WinPhoneDeviceBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/WinPhoneDeviceBuilder.cs?rev=1392912&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/WinPhoneDeviceBuilder.cs (added)
+++ incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/Devices/WinPhoneDeviceBuilder.cs Tue Oct  2 13:34:31 2012
@@ -0,0 +1,233 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Oddr.Models.Devices;
+using Oddr.Models;
+using System.Text.RegularExpressions;
+
+namespace Oddr.Builders.Devices
+{
+    public class WinPhoneDeviceBuilder : OrderedTokenDeviceBuilder
+    {
+        private Dictionary<String, Device> devices;
+        private Dictionary<String, Object> regexs = new Dictionary<String, Object>();
+
+        public WinPhoneDeviceBuilder()
+            : base()
+        {
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="devices"></param>
+        /// <exception cref="System.InvalidOperationException">Thrown when unable to find device with id in devices</exception>
+        protected override void AfterOrderingCompleteInit(Dictionary<string, Device> devices)
+        {
+            this.devices = devices;
+            foreach (Object devIdObj in orderedRules.Values) {
+                String devId = (String) devIdObj;
+                if (!devices.ContainsKey(devId)) {
+                    throw new InvalidOperationException("unable to find device with id: " + devId + " in devices");
+                }
+            }
+        }
+
+        public override void PutDevice(string deviceID, List<string> initProperties)
+        {
+            try
+            {
+                orderedRules.Add(initProperties[0], deviceID);
+                regexs.Add(initProperties[0] + "_loose", Regex.Replace(initProperties[0], "[ _/-]", ".?"));
+                regexs.Add(initProperties[0] + "_loose_icase_regex", new Regex(/*"(?i).*"*/".?>*" + Regex.Replace(initProperties[0], "[ _/-]", ".?") + ".*", RegexOptions.IgnoreCase));
+            }
+            catch (Exception ex)
+            {
+                //Console.WriteLine(this.GetType().FullName + " " + initProperties[0] + " " + deviceID + " " + ex.Message);
+            }
+        }
+
+        public override bool CanBuild(UserAgent userAgent)
+        {
+            return userAgent.containsWindowsPhone && (userAgent.mozillaPattern || userAgent.operaPattern);
+        }
+
+        public override BuiltObject Build(UserAgent userAgent, int confidenceTreshold)
+        {
+            List<Device> foundDevices = new List<Device>();
+            foreach (string token in orderedRules.Keys)
+            {
+                Device d = ElaborateWinPhoneDeviceWithToken(userAgent, token);
+                if (d != null)
+                {
+                    if (d.confidence > confidenceTreshold)
+                    {
+                        return d;
+
+                    }
+                    else
+                    {
+                        if (d.confidence > 0)
+                        {
+                            foundDevices.Add(d);
+                        }
+                    }
+                }
+            }
+            if (foundDevices.Count > 0)
+            {
+                foundDevices.Sort();
+                foundDevices.Reverse();
+                return foundDevices[0];
+            }
+            return null;
+        }
+
+        private Device ElaborateWinPhoneDeviceWithToken(UserAgent userAgent, String token)
+        {
+            if (userAgent.mozillaPattern || userAgent.operaPattern)
+            {
+                int subtract = 0;
+                String currentToken = token;
+
+                String looseToken = (String)(regexs[token + "_loose"]); 
+                //String looseToken = Regex.Replace(token, "[ _/-]", ".?");
+
+                Regex looseRegex = (Regex)(regexs[token + "_loose_icase_regex"]);
+                //Regex looseRegex = new Regex(/*"(?i).*"*/".*" + looseToken + ".*", RegexOptions.IgnoreCase);
+
+                if (!looseRegex.IsMatch(userAgent.completeUserAgent))
+                {
+                    return null;
+                }
+
+                Regex currentRegex = null;
+
+                if (userAgent.operaPattern)
+                {
+                    subtract += 10;
+                }
+
+                for (int i = 0; i <= 1; i++)
+                {
+                    if (i == 1)
+                    {
+                        currentToken = looseToken;
+                    }
+
+                    currentRegex = new Regex(/*"(?i).*"*/".?>*" + currentToken, RegexOptions.IgnoreCase);
+                    if (userAgent.GetPatternElementsInside() != null && currentRegex.IsMatch(userAgent.GetPatternElementsInside()))
+                    {
+                        String deviceId = (String)orderedRules[token];
+
+                        Device retDevice = null;
+                        if (devices.TryGetValue(deviceId, out retDevice))
+                        {
+                            retDevice = (Device)retDevice.Clone();
+                            retDevice.confidence = (100 - subtract);
+                            return retDevice;
+                        }
+                    }
+                    if (userAgent.GetPatternElementsPre() != null && currentRegex.IsMatch(userAgent.GetPatternElementsPre()))
+                    {
+                        String deviceId = (String)orderedRules[token];
+
+                        Device retDevice = null;
+                        if (devices.TryGetValue(deviceId, out retDevice))
+                        {
+                            retDevice = (Device)retDevice.Clone();
+                            retDevice.confidence = (95 - subtract);
+                            return retDevice;
+                        }
+                    }
+
+                    currentRegex = new Regex(/*"(?i).*"*/".?>*" + currentToken + ".?;.*", RegexOptions.IgnoreCase);
+                    if (userAgent.GetPatternElementsInside() != null && currentRegex.IsMatch(userAgent.GetPatternElementsInside()))
+                    {
+                        String deviceId = (String)orderedRules[token];
+
+                        Device retDevice = null;
+                        if (devices.TryGetValue(deviceId, out retDevice))
+                        {
+                            retDevice = (Device)retDevice.Clone();
+                            retDevice.confidence = (90 - subtract);
+                            return retDevice;
+                        }
+                    }
+
+                    if (i == 1)
+                    {
+                        currentRegex = looseRegex;
+
+                    }
+                    else
+                    {
+                        currentRegex = new Regex(/*"(?i).*"*/".?>*" + currentToken + ".*", RegexOptions.IgnoreCase);
+                    }
+
+                    if (userAgent.GetPatternElementsInside() != null && currentRegex.IsMatch(userAgent.GetPatternElementsInside()))
+                    {
+                        String deviceId = (String)orderedRules[token];
+
+                        Device retDevice = null;
+                        if (devices.TryGetValue(deviceId, out retDevice))
+                        {
+                            retDevice = (Device)retDevice.Clone();
+                            retDevice.confidence = (80 - subtract);
+                            return retDevice;
+                        }
+                    }
+                    if (userAgent.GetPatternElementsPre() != null && currentRegex.IsMatch(userAgent.GetPatternElementsPre()))
+                    {
+                        String deviceId = (String)orderedRules[token];
+
+                        Device retDevice = null;
+                        if (devices.TryGetValue(deviceId, out retDevice))
+                        {
+                            retDevice = (Device)retDevice.Clone();
+                            retDevice.confidence = (80 - subtract);
+                            return retDevice;
+                        }
+                    }
+                    if (userAgent.GetPatternElementsPost() != null && currentRegex.IsMatch(userAgent.GetPatternElementsPost()))
+                    {
+                        String deviceId = (String)orderedRules[token];
+
+                        Device retDevice = null;
+                        if (devices.TryGetValue(deviceId, out retDevice))
+                        {
+                            retDevice = (Device)retDevice.Clone();
+                            retDevice.confidence = (60 - subtract);
+                            return retDevice;
+                        }
+                    }
+                    subtract += 20;
+                }
+            }
+
+            return null;
+        }
+    }
+}

Added: incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/IBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/IBuilder.cs?rev=1392912&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/IBuilder.cs (added)
+++ incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/IBuilder.cs Tue Oct  2 13:34:31 2012
@@ -0,0 +1,36 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Oddr.Models;
+
+namespace Oddr.Builders
+{
+    public interface IBuilder
+    {
+        bool CanBuild(UserAgent userAgent);
+
+        BuiltObject Build(UserAgent userAgent, int confidenceTreshold);
+    }
+}

Added: incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/BlackBerryOSBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/BlackBerryOSBuilder.cs?rev=1392912&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/BlackBerryOSBuilder.cs (added)
+++ incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/BlackBerryOSBuilder.cs Tue Oct  2 13:34:31 2012
@@ -0,0 +1,88 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using Oddr.Models;
+using OSModel = Oddr.Models.OS;
+
+namespace Oddr.Builders.OS
+{
+    public class BlackBerryOSBuilder : IBuilder
+    {
+        private const String VERSION_REGEXP = "(?:.*?[Bb]lack.?[Bb]erry(?:\\d+)/((\\d+)\\.(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?).*)";
+        private Regex versionRegex = new Regex(VERSION_REGEXP);
+
+        public bool CanBuild(UserAgent userAgent)
+        {
+            return userAgent.containsBlackBerryOrRim;
+        }
+
+        public BuiltObject Build(UserAgent userAgent, int confidenceTreshold)
+        {
+            OSModel.OperatingSystem model = new OSModel.OperatingSystem();
+
+            model.SetVendor("Research In Motion");
+            model.SetModel("Black Berry OS");
+            model.majorRevision = "1";
+
+            if (versionRegex.IsMatch(userAgent.completeUserAgent))
+            {
+                Match versionMatcher = versionRegex.Match(userAgent.completeUserAgent);
+                GroupCollection groups = versionMatcher.Groups;
+
+                if (groups[1] != null && groups[1].Value.Trim().Length > 0)
+                {
+                    model.confidence = 50;
+                    model.SetVersion(groups[1].Value);
+
+                    if (groups[2] != null && groups[2].Value.Trim().Length > 0)
+                    {
+                        model.majorRevision = groups[2].Value;
+                        model.confidence = 60;
+                    }
+
+                    if (groups[3] != null && groups[3].Value.Trim().Length > 0)
+                    {
+                        model.minorRevision = groups[3].Value;
+                        model.confidence = 70;
+                    }
+
+                    if (groups[4] != null && groups[4].Value.Trim().Length > 0)
+                    {
+                        model.microRevision = groups[4].Value;
+                        model.confidence = 80;
+                    }
+
+                    if (groups[5] != null && groups[5].Value.Trim().Length > 0)
+                    {
+                        model.nanoRevision = groups[5].Value;
+                        model.confidence = 90;
+                    }
+                }
+            }
+            return model;
+        }
+    }
+}

Added: incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/DefaultOSBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/DefaultOSBuilder.cs?rev=1392912&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/DefaultOSBuilder.cs (added)
+++ incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/DefaultOSBuilder.cs Tue Oct  2 13:34:31 2012
@@ -0,0 +1,116 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Oddr.Models;
+using OSModel = Oddr.Models.OS;
+
+namespace Oddr.Builders.OS
+{
+    public class DefaultOSBuilder : IBuilder
+    {
+        private IBuilder[] builders;
+        private static volatile DefaultOSBuilder instance;
+        private static object syncRoot = new Object();
+
+        private DefaultOSBuilder()
+        {
+            builders = new IBuilder[]
+            {
+                new MozillaOSModelBuilder(),
+                new OperaOSModelBuilder(),
+                new BlackBerryOSBuilder()
+            };
+        }
+
+        public static DefaultOSBuilder Instance
+        {
+            get
+            {
+                if (instance == null)
+                {
+                    lock (syncRoot)
+                    {
+                        if (instance == null)
+                        {
+                            instance = new DefaultOSBuilder();
+                        }
+                    }
+                }
+
+                return instance;
+            }
+        }
+
+        public bool CanBuild(UserAgent userAgent)
+        {
+            foreach (IBuilder builder in builders)
+            {
+                if (builder.CanBuild(userAgent))
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public BuiltObject Build(UserAgent userAgent, int confidenceTreshold)
+        {
+            List<OSModel.OperatingSystem> founds = new List<OSModel.OperatingSystem>();
+            OSModel.OperatingSystem found = null;
+            foreach (IBuilder builder in builders)
+            {
+                if (builder.CanBuild(userAgent))
+                {
+                    OSModel.OperatingSystem builded = (OSModel.OperatingSystem)builder.Build(userAgent, confidenceTreshold);
+                    if (builded != null)
+                    {
+                        founds.Add(builded);
+                        if (builded.confidence >= confidenceTreshold)
+                        {
+                            found = builded;
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if (found != null)
+            {
+                return found;
+            }
+            else
+            {
+                if (founds.Count > 0)
+                {
+                    founds.Sort();
+                    founds.Reverse();
+                    return founds[0];
+                }
+
+                return null;
+            }
+        }
+    }
+}

Added: incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/Mozilla/AndroidMozillaSubBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/Mozilla/AndroidMozillaSubBuilder.cs?rev=1392912&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/Mozilla/AndroidMozillaSubBuilder.cs (added)
+++ incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/Mozilla/AndroidMozillaSubBuilder.cs Tue Oct  2 13:34:31 2012
@@ -0,0 +1,122 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using Oddr.Models;
+using OSModel = Oddr.Models.OS;
+
+namespace Oddr.Builders.OS.Mozilla
+{
+    public class AndroidMozillaSubBuilder : IBuilder
+    {
+        private const String VERSION_REGEXP = ".*?Android.?((\\d+)\\.(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(.*))";
+        private const String BUILD_HASH_REGEXP = ".*Build/(.*)(?:[ \\)])?";
+        private Regex versionRegex = new Regex(VERSION_REGEXP);
+        private Regex buildHashRegex = new Regex(BUILD_HASH_REGEXP);
+
+
+        public bool CanBuild(UserAgent userAgent)
+        {
+            return userAgent.containsAndroid;
+        }
+
+        public BuiltObject Build(UserAgent userAgent, int confidenceTreshold)
+        {
+            OSModel.OperatingSystem model = new OSModel.OperatingSystem();
+            model.majorRevision = "1";
+            model.SetVendor("Google");
+            model.SetModel("Android");
+            model.confidence = 40;
+
+            string patternElementsInside = userAgent.GetPatternElementsInside();
+            String[] splittedTokens = patternElementsInside.Split(";".ToCharArray());
+            foreach (String tokenElement in splittedTokens)
+            {
+                if (versionRegex.IsMatch(tokenElement))
+                {
+                    Match versionMatcher = versionRegex.Match(tokenElement);
+                    GroupCollection groups = versionMatcher.Groups;
+
+                    if (model.confidence > 40)
+                    {
+                        model.confidence = 100;
+
+                    }
+                    else
+                    {
+                        model.confidence = 90;
+                    }
+
+                    if (groups[1] != null && groups[1].Value.Trim().Length > 0)
+                    {
+                        model.SetVersion(groups[1].Value);
+                    }
+                    if (groups[2] != null && groups[2].Value.Trim().Length > 0)
+                    {
+                        model.majorRevision = groups[2].Value;
+                    }
+                    if (groups[3] != null && groups[3].Value.Trim().Length > 0)
+                    {
+                        model.minorRevision = groups[3].Value;
+                    }
+                    if (groups[4] != null && groups[4].Value.Trim().Length > 0)
+                    {
+                        model.microRevision = (groups[4].Value);
+                    }
+                    if (groups[5] != null && groups[5].Value.Trim().Length > 0)
+                    {
+                        model.nanoRevision = groups[5].Value;
+                    }
+                    if (groups[6] != null && groups[6].Value.Trim().Length > 0)
+                    {
+                        model.SetDescription(groups[6].Value);
+                    }
+                }
+
+                if (buildHashRegex.IsMatch(tokenElement))
+                {
+                    Match buildHashMatcher = buildHashRegex.Match(tokenElement);
+                    GroupCollection groups = buildHashMatcher.Groups;
+
+                    if (model.confidence > 40)
+                    {
+                        model.confidence = 100;
+
+                    }
+                    else
+                    {
+                        model.confidence = 45;
+                    }
+
+                    if (groups[1] != null && groups[1].Value.Trim().Length > 0)
+                    {
+                        model.SetBuild(groups[1].Value);
+                    }
+                }
+            }
+            return model;
+        }
+    }
+}

Added: incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/Mozilla/BadaMozillaSubBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/Mozilla/BadaMozillaSubBuilder.cs?rev=1392912&view=auto
==============================================================================
--- incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/Mozilla/BadaMozillaSubBuilder.cs (added)
+++ incubator/devicemap/trunk/openddr/csharp/OpenDDR-CSharp/Builders/OS/Mozilla/BadaMozillaSubBuilder.cs Tue Oct  2 13:34:31 2012
@@ -0,0 +1,85 @@
+/**
+ * Copyright 2011 OpenDDR LLC
+ * This software is distributed under the terms of the GNU Lesser General Public License.
+ *
+ *
+ * This file is part of OpenDDR Simple APIs.
+ * OpenDDR Simple APIs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OpenDDR Simple APIs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Simple APIs.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using Oddr.Models;
+using OSModel = Oddr.Models.OS;
+
+namespace Oddr.Builders.OS.Mozilla
+{
+    public class BadaMozillaSubBuilder : IBuilder
+    {
+        private const String VERSION_REGEXP = ".*?Bada.?((\\d+)\\.(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(.*))";
+        private Regex versionRegex = new Regex(VERSION_REGEXP);
+
+        public bool CanBuild(UserAgent userAgent)
+        {
+            return (userAgent.GetPatternElementsInside() != null && userAgent.GetPatternElementsInside().Contains("Bada"));
+        }
+
+        public BuiltObject Build(UserAgent userAgent, int confidenceTreshold)
+        {
+            OSModel.OperatingSystem model = new OSModel.OperatingSystem();
+            model.majorRevision = "1";
+            model.SetVendor("Samsung");
+            model.SetModel("Bada");
+            model.confidence = 40;
+
+            string patternElementsInside = userAgent.GetPatternElementsInside();
+            String[] splittedTokens = patternElementsInside.Split(";".ToCharArray());
+            foreach (String tokenElement in splittedTokens)
+            {
+                if (versionRegex.IsMatch(tokenElement))
+                {
+                    Match versionMatcher = versionRegex.Match(tokenElement);
+                    GroupCollection groups = versionMatcher.Groups;
+
+                    model.confidence = 90;
+                    if (groups[1] != null && groups[1].Value.Trim().Length > 0)
+                    {
+                        model.SetVersion(groups[1].Value);
+                    }
+                    if (groups[2] != null && groups[2].Value.Trim().Length > 0)
+                    {
+                        model.majorRevision = groups[2].Value;
+                    }
+                    if (groups[3] != null && groups[3].Value.Trim().Length > 0)
+                    {
+                        model.minorRevision = groups[3].Value;
+                    }
+                    if (groups[4] != null && groups[4].Value.Trim().Length > 0)
+                    {
+                        model.microRevision = groups[4].Value;
+                    }
+                    if (groups[5] != null && groups[5].Value.Trim().Length > 0)
+                    {
+                        model.nanoRevision = groups[5].Value;
+                    }
+                }
+            }
+            return model;
+        }
+    }
+}