OracleConnectionStringBuilder.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / DataOracleClient / System / Data / OracleClient / OracleConnectionStringBuilder.cs / 1 / OracleConnectionStringBuilder.cs

                            //------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
    using System;
    using System.Collections; 
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Data.Common; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.Runtime.Serialization; 
    using System.Security.Permissions;
    using System.Text; 

namespace System.Data.OracleClient {

    [DefaultProperty("DataSource")] 
    [System.ComponentModel.TypeConverterAttribute(typeof(OracleConnectionStringBuilder.OracleConnectionStringBuilderConverter))]
    public sealed class OracleConnectionStringBuilder : DbConnectionStringBuilder { 
 
        private enum Keywords { // specific ordering for ConnectionString output construction
//          NamedConnection, 

            DataSource,
            PersistSecurityInfo,
            IntegratedSecurity, 
            UserID,
            Password, 
 
            Enlist,
            Pooling, 
            MinPoolSize,
            MaxPoolSize,

            Unicode, 

            LoadBalanceTimeout, 
 
            OmitOracleConnectionName,
        } 

        private static readonly string[] _validKeywords;
        private static readonly Dictionary _keywords;
 
//      private string _namedConnection        = DbConnectionStringDefaults.NamedConnection;
 
        private string _dataSource             = DbConnectionStringDefaults.DataSource; 
        private string _password               = DbConnectionStringDefaults.Password;
        private string _userID                 = DbConnectionStringDefaults.UserID; 

        private int _loadBalanceTimeout        = DbConnectionStringDefaults.LoadBalanceTimeout;
        private int _maxPoolSize               = DbConnectionStringDefaults.MaxPoolSize;
        private int _minPoolSize               = DbConnectionStringDefaults.MinPoolSize; 

        private bool _enlist                   = DbConnectionStringDefaults.Enlist; 
        private bool _integratedSecurity       = DbConnectionStringDefaults.IntegratedSecurity; 
        private bool _persistSecurityInfo      = DbConnectionStringDefaults.PersistSecurityInfo;
        private bool _pooling                  = DbConnectionStringDefaults.Pooling; 
        private bool _unicode                  = DbConnectionStringDefaults.Unicode;
        private bool _omitOracleConnectionName = DbConnectionStringDefaults.OmitOracleConnectionName;

        static OracleConnectionStringBuilder() { 
            string[] validKeywords = new string[12];
            validKeywords[(int)Keywords.DataSource]               = DbConnectionStringKeywords.DataSource; 
            validKeywords[(int)Keywords.Enlist]                   = DbConnectionStringKeywords.Enlist; 
            validKeywords[(int)Keywords.IntegratedSecurity]       = DbConnectionStringKeywords.IntegratedSecurity;
            validKeywords[(int)Keywords.LoadBalanceTimeout]       = DbConnectionStringKeywords.LoadBalanceTimeout; 
            validKeywords[(int)Keywords.MaxPoolSize]              = DbConnectionStringKeywords.MaxPoolSize;
            validKeywords[(int)Keywords.MinPoolSize]              = DbConnectionStringKeywords.MinPoolSize;
//          validKeywords[(int)Keywords.NamedConnection]          = DbConnectionStringKeywords.NamedConnection;
            validKeywords[(int)Keywords.Password]                 = DbConnectionStringKeywords.Password; 
            validKeywords[(int)Keywords.PersistSecurityInfo]      = DbConnectionStringKeywords.PersistSecurityInfo;
            validKeywords[(int)Keywords.Pooling]                  = DbConnectionStringKeywords.Pooling; 
            validKeywords[(int)Keywords.Unicode]                  = DbConnectionStringKeywords.Unicode; 
            validKeywords[(int)Keywords.UserID]                   = DbConnectionStringKeywords.UserID;
            validKeywords[(int)Keywords.OmitOracleConnectionName] = DbConnectionStringKeywords.OmitOracleConnectionName; 
            _validKeywords = validKeywords;

            Dictionary hash = new Dictionary(19, StringComparer.OrdinalIgnoreCase);
            hash.Add(DbConnectionStringKeywords.DataSource,                Keywords.DataSource); 
            hash.Add(DbConnectionStringKeywords.Enlist,                    Keywords.Enlist);
            hash.Add(DbConnectionStringKeywords.IntegratedSecurity,        Keywords.IntegratedSecurity); 
            hash.Add(DbConnectionStringKeywords.LoadBalanceTimeout,        Keywords.LoadBalanceTimeout); 
            hash.Add(DbConnectionStringKeywords.MaxPoolSize,               Keywords.MaxPoolSize);
            hash.Add(DbConnectionStringKeywords.MinPoolSize,               Keywords.MinPoolSize); 
//          hash.Add(DbConnectionStringKeywords.NamedConnection,           Keywords.NamedConnection);
            hash.Add(DbConnectionStringKeywords.OmitOracleConnectionName,  Keywords.OmitOracleConnectionName);
            hash.Add(DbConnectionStringKeywords.Password,                  Keywords.Password);
            hash.Add(DbConnectionStringKeywords.PersistSecurityInfo,       Keywords.PersistSecurityInfo); 
            hash.Add(DbConnectionStringKeywords.Pooling,                   Keywords.Pooling);
            hash.Add(DbConnectionStringKeywords.Unicode,                   Keywords.Unicode); 
            hash.Add(DbConnectionStringKeywords.UserID,                    Keywords.UserID); 

            hash.Add(DbConnectionStringSynonyms.SERVER,                    Keywords.DataSource); 
            hash.Add(DbConnectionStringSynonyms.ConnectionLifetime,        Keywords.LoadBalanceTimeout);
            hash.Add(DbConnectionStringSynonyms.Pwd,                       Keywords.Password);
            hash.Add(DbConnectionStringSynonyms.PERSISTSECURITYINFO,       Keywords.PersistSecurityInfo);
            hash.Add(DbConnectionStringSynonyms.UID,                       Keywords.UserID); 
            hash.Add(DbConnectionStringSynonyms.User,                      Keywords.UserID);
            hash.Add(DbConnectionStringSynonyms.WorkaroundOracleBug914652, Keywords.OmitOracleConnectionName); 
            Debug.Assert(19 == hash.Count, "initial expected size is incorrect"); 
            _keywords = hash;
        } 

        public OracleConnectionStringBuilder() : this((string)null) {
        }
 
        public OracleConnectionStringBuilder(string connectionString) : base() {
            if (!ADP.IsEmpty(connectionString)) { 
                ConnectionString = connectionString; 
            }
        } 

        public override object this[string keyword] {
            get {
                Keywords index = GetIndex(keyword); 
                return GetAt(index);
            } 
            set { 
                Bid.Trace(" keyword='%ls'\n", keyword);
                if (null != value) { 
                    Keywords index = GetIndex(keyword);
                    switch(index) {
                    case Keywords.DataSource:                DataSource = ConvertToString(value); break;
//                  case Keywords.NamedConnection:           NamedConnection = ConvertToString(value); break; 
                    case Keywords.Password:                  Password = ConvertToString(value); break;
                    case Keywords.UserID:                    UserID = ConvertToString(value); break; 
 
                    case Keywords.LoadBalanceTimeout:        LoadBalanceTimeout = ConvertToInt32(value); break;
                    case Keywords.MaxPoolSize:               MaxPoolSize = ConvertToInt32(value); break; 
                    case Keywords.MinPoolSize:               MinPoolSize = ConvertToInt32(value); break;

                    case Keywords.IntegratedSecurity:        IntegratedSecurity = ConvertToIntegratedSecurity(value); break;
 
                    case Keywords.Enlist:                    Enlist = ConvertToBoolean(value); break;
                    case Keywords.PersistSecurityInfo:       PersistSecurityInfo = ConvertToBoolean(value); break; 
                    case Keywords.Pooling:                   Pooling = ConvertToBoolean(value); break; 
                    case Keywords.Unicode:                   Unicode = ConvertToBoolean(value); break;
                    case Keywords.OmitOracleConnectionName:  OmitOracleConnectionName = ConvertToBoolean(value); break; 

                    default:
                        Debug.Assert(false, "unexpected keyword");
                        throw ADP.KeywordNotSupported(keyword); 
                    }
                } 
                else { 
                    Remove(keyword);
                } 
            }
        }

        [DisplayName(DbConnectionStringKeywords.DataSource)] 
        [ResCategoryAttribute(Res.DataCategory_Source)]
        [ResDescriptionAttribute(Res.DbConnectionString_DataSource)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)] 
        public string DataSource {
            get { return _dataSource; } 
            set {
                if ((null != value) && (128 < value.Length)) {
                    throw ADP.InvalidConnectionOptionLength(DbConnectionStringKeywords.DataSource, 128);
                } 
                SetValue(DbConnectionStringKeywords.DataSource, value);
                _dataSource = value; 
            } 
        }
 
        [DisplayName(DbConnectionStringKeywords.Enlist)]
        [ResCategoryAttribute(Res.DataCategory_Pooling)]
        [ResDescriptionAttribute(Res.DbConnectionString_Enlist)]
        [RefreshPropertiesAttribute(RefreshProperties.All)] 
        public bool Enlist {
            get { return _enlist; } 
            set { 
                SetValue(DbConnectionStringKeywords.Enlist, value);
                _enlist = value; 
            }
        }

        [DisplayName(DbConnectionStringKeywords.IntegratedSecurity)] 
        [ResCategoryAttribute(Res.DataCategory_Security)]
        [ResDescriptionAttribute(Res.DbConnectionString_IntegratedSecurity)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)] 
        public bool IntegratedSecurity {
            get { return _integratedSecurity; } 
            set {
                SetValue(DbConnectionStringKeywords.IntegratedSecurity, value);
                _integratedSecurity = value;
            } 
        }
 
        [DisplayName(DbConnectionStringKeywords.LoadBalanceTimeout)] 
        [ResCategoryAttribute(Res.DataCategory_Pooling)]
        [ResDescriptionAttribute(Res.DbConnectionString_LoadBalanceTimeout)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        public int LoadBalanceTimeout {
            get { return _loadBalanceTimeout; }
            set { 
                if (value < 0) {
                    throw ADP.InvalidConnectionOptionValue(DbConnectionStringKeywords.LoadBalanceTimeout); 
                } 
                SetValue(DbConnectionStringKeywords.LoadBalanceTimeout, value);
                _loadBalanceTimeout = value; 
            }
        }

        [DisplayName(DbConnectionStringKeywords.MaxPoolSize)] 
        [ResCategoryAttribute(Res.DataCategory_Pooling)]
        [ResDescriptionAttribute(Res.DbConnectionString_MaxPoolSize)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)] 
        public int MaxPoolSize {
            get { return _maxPoolSize; } 
            set {
                if (value < 1) {
                    throw ADP.InvalidConnectionOptionValue(DbConnectionStringKeywords.MaxPoolSize);
                } 
                SetValue(DbConnectionStringKeywords.MaxPoolSize, value);
                _maxPoolSize = value; 
            } 
        }
 
        [DisplayName(DbConnectionStringKeywords.MinPoolSize)]
        [ResCategoryAttribute(Res.DataCategory_Pooling)]
        [ResDescriptionAttribute(Res.DbConnectionString_MinPoolSize)]
        [RefreshPropertiesAttribute(RefreshProperties.All)] 
        public int MinPoolSize {
            get { return _minPoolSize; } 
            set { 
                if (value < 0) {
                    throw ADP.InvalidConnectionOptionValue(DbConnectionStringKeywords.MinPoolSize); 
                }
                SetValue(DbConnectionStringKeywords.MinPoolSize, value);
                _minPoolSize = value;
            } 
        }
/* 
        [DisplayName(DbConnectionStringKeywords.NamedConnection)] 
        [ResCategoryAttribute(Res.DataCategory_NamedConnectionString)]
        [ResDescriptionAttribute(Res.DbConnectionString_NamedConnection)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        [TypeConverter(typeof(NamedConnectionStringConverter))]
        public string NamedConnection {
            get { 
                return _namedConnection;
            } 
            set { 
                SetValue(DbConnectionStringKeywords.NamedConnection, value);
                _namedConnection = value; 
            }
        }
*/
        [DisplayName(DbConnectionStringKeywords.OmitOracleConnectionName)] 
        [ResCategoryAttribute(Res.DataCategory_Initialization)]
        [ResDescriptionAttribute(Res.DbConnectionString_OmitOracleConnectionName)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)] 
        public bool OmitOracleConnectionName {
            get { return _omitOracleConnectionName; } 
            set {
                SetValue(DbConnectionStringKeywords.OmitOracleConnectionName, value);
                _omitOracleConnectionName = value;
            } 
        }
 
        [DisplayName(DbConnectionStringKeywords.Password)] 
        [PasswordPropertyTextAttribute(true)]
        [ResCategoryAttribute(Res.DataCategory_Security)] 
        [ResDescriptionAttribute(Res.DbConnectionString_Password)]
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        public string Password {
            get { return _password; } 
            set {
                if ((null != value) && (30 < value.Length)) { 
                    throw ADP.InvalidConnectionOptionLength(DbConnectionStringKeywords.Password, 30); 
                }
                SetValue(DbConnectionStringKeywords.Password, value); 
                _password = value;
            }
        }
 
        [DisplayName(DbConnectionStringKeywords.PersistSecurityInfo)]
        [ResCategoryAttribute(Res.DataCategory_Security)] 
        [ResDescriptionAttribute(Res.DbConnectionString_PersistSecurityInfo)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        public bool PersistSecurityInfo { 
            get { return _persistSecurityInfo; }
            set {
                SetValue(DbConnectionStringKeywords.PersistSecurityInfo, value);
                _persistSecurityInfo = value; 
            }
        } 
 
        [DisplayName(DbConnectionStringKeywords.Pooling)]
        [ResCategoryAttribute(Res.DataCategory_Pooling)] 
        [ResDescriptionAttribute(Res.DbConnectionString_Pooling)]
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        public bool Pooling {
            get { return _pooling; } 
            set {
                SetValue(DbConnectionStringKeywords.Pooling, value); 
                _pooling = value; 
            }
        } 

        [DisplayName(DbConnectionStringKeywords.Unicode)]
        [ResCategoryAttribute(Res.DataCategory_Initialization)]
        [ResDescriptionAttribute(Res.DbConnectionString_Unicode)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        public bool Unicode { 
            get { return _unicode; } 
            set {
                SetValue(DbConnectionStringKeywords.Unicode, value); 
                _unicode = value;
            }
        }
 
        [DisplayName(DbConnectionStringKeywords.UserID)]
        [ResCategoryAttribute(Res.DataCategory_Security)] 
        [ResDescriptionAttribute(Res.DbConnectionString_UserID)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        public string UserID { 
            get { return _userID; }
            set {
                if ((null != value) && (30 < value.Length)) {
                    throw ADP.InvalidConnectionOptionLength(DbConnectionStringKeywords.UserID, 30); 
                }
                SetValue(DbConnectionStringKeywords.UserID, value); 
                _userID = value; 
            }
        } 

        public override bool IsFixedSize {
            get {
                return true; 
            }
        } 
 
        public override ICollection Keys {
            get { 
                return new System.Data.Common.ReadOnlyCollection(_validKeywords);
            }
        }
 
        public override ICollection Values {
            get { 
                // written this way so if the ordering of Keywords & _validKeywords changes 
                // this is one less place to maintain
                object[] values = new object[_validKeywords.Length]; 
                for(int i = 0; i < _validKeywords.Length; ++i) {
                    values[i] = GetAt((Keywords)i);
                }
                return new System.Data.Common.ReadOnlyCollection(values); 
            }
        } 
 
        public override void Clear() {
            base.Clear(); 
            for(int i = 0; i < _validKeywords.Length; ++i) {
                Reset((Keywords)i);
            }
        } 

        new internal void ClearPropertyDescriptors() { 
            base.ClearPropertyDescriptors(); 
        }
 
        public override bool ContainsKey(string keyword) {
            ADP.CheckArgumentNull(keyword, "keyword");
            return _keywords.ContainsKey(keyword);
        } 

        private static bool ConvertToBoolean(object value) { 
            return DbConnectionStringBuilderUtil.ConvertToBoolean(value); 
        }
        private static int ConvertToInt32(object value) { 
            return DbConnectionStringBuilderUtil.ConvertToInt32(value);
        }
        private static bool ConvertToIntegratedSecurity(object value) {
            return DbConnectionStringBuilderUtil.ConvertToIntegratedSecurity(value); 
        }
        private static string ConvertToString(object value) { 
            return DbConnectionStringBuilderUtil.ConvertToString(value); 
        }
 
        private object GetAt(Keywords index) {
            switch(index) {
            case Keywords.DataSource:                return DataSource;
            case Keywords.Enlist:                    return Enlist; 
            case Keywords.IntegratedSecurity:        return IntegratedSecurity;
            case Keywords.LoadBalanceTimeout:        return LoadBalanceTimeout; 
            case Keywords.MaxPoolSize:               return MaxPoolSize; 
            case Keywords.MinPoolSize:               return MinPoolSize;
//          case Keywords.NamedConnection:           return NamedConnection; 
            case Keywords.OmitOracleConnectionName:  return OmitOracleConnectionName;
            case Keywords.Password:                  return Password;
            case Keywords.PersistSecurityInfo:       return PersistSecurityInfo;
            case Keywords.Pooling:                   return Pooling; 
            case Keywords.Unicode:                   return Unicode;
            case Keywords.UserID:                    return UserID; 
            default: 
                Debug.Assert(false, "unexpected keyword");
                throw ADP.KeywordNotSupported(_validKeywords[(int)index]); 
            }
        }

        private Keywords GetIndex(string keyword) { 
            ADP.CheckArgumentNull(keyword, "keyword");
            Keywords index; 
            if (_keywords.TryGetValue(keyword, out index)) { 
                return index;
            } 
            throw ADP.KeywordNotSupported(keyword);
        }

        private Attribute[] GetAttributesFromCollection(AttributeCollection collection) { 
            Attribute[] attributes = new Attribute[collection.Count];
            collection.CopyTo(attributes, 0); 
            return attributes; 
        }
 
        protected override void GetProperties(Hashtable propertyDescriptors) {
            foreach(PropertyDescriptor reflected in TypeDescriptor.GetProperties(this, true)) {
                bool refreshOnChange = false;
                bool isReadonly = false; 
                string displayName = reflected.DisplayName;
 
                // 'Password' & 'User ID' will be readonly if 'Integrated Security' is true 
                if (DbConnectionStringKeywords.IntegratedSecurity == displayName) {
                    refreshOnChange = true; 
                    isReadonly = reflected.IsReadOnly;
                }
                else if ((DbConnectionStringKeywords.Password == displayName) ||
                         (DbConnectionStringKeywords.UserID == displayName)) { 
                     isReadonly = IntegratedSecurity;
                } 
                else { 
                    continue;
                } 
                Attribute[] attributes = GetAttributesFromCollection(reflected.Attributes);
                DbConnectionStringBuilderDescriptor descriptor = new DbConnectionStringBuilderDescriptor(reflected.Name,
                        reflected.ComponentType, reflected.PropertyType, isReadonly, attributes);
                descriptor.RefreshOnChange = refreshOnChange; 
                propertyDescriptors[displayName] = descriptor;
            } 
            base.GetProperties(propertyDescriptors); 
        }
 
        public override bool Remove(string keyword) {
            ADP.CheckArgumentNull(keyword, "keyword");
            Keywords index;
            if (_keywords.TryGetValue(keyword, out index)) { 
                base.Remove(_validKeywords[(int)index]);
                Reset(index); 
                return true; 
            }
            return false; 
        }

        private void Reset(Keywords index) {
            switch(index) { 
            case Keywords.DataSource:
                _dataSource = DbConnectionStringDefaults.DataSource; 
                break; 
            case Keywords.Enlist:
                _enlist = DbConnectionStringDefaults.Enlist; 
                break;
            case Keywords.IntegratedSecurity:
                _integratedSecurity = DbConnectionStringDefaults.IntegratedSecurity;
                break; 
            case Keywords.LoadBalanceTimeout:
                _loadBalanceTimeout = DbConnectionStringDefaults.LoadBalanceTimeout; 
                break; 
            case Keywords.MaxPoolSize:
                _maxPoolSize = DbConnectionStringDefaults.MaxPoolSize; 
                break;
            case Keywords.MinPoolSize:
                _minPoolSize = DbConnectionStringDefaults.MinPoolSize;
                break; 
//          case Keywords.NamedConnection:
//              _namedConnection = DbConnectionStringDefaults.NamedConnection; 
//              break; 
            case Keywords.OmitOracleConnectionName:
                _omitOracleConnectionName = DbConnectionStringDefaults.OmitOracleConnectionName; 
                break;
            case Keywords.Password:
                _password = DbConnectionStringDefaults.Password;
                break; 
            case Keywords.PersistSecurityInfo:
                _persistSecurityInfo = DbConnectionStringDefaults.PersistSecurityInfo; 
                break; 
            case Keywords.Pooling:
                _pooling = DbConnectionStringDefaults.Pooling; 
                break;
            case Keywords.Unicode:
                _unicode = DbConnectionStringDefaults.Unicode;
                break; 
            case Keywords.UserID:
                _userID = DbConnectionStringDefaults.UserID; 
                break; 
            default:
                Debug.Assert(false, "unexpected keyword"); 
                throw ADP.KeywordNotSupported(_validKeywords[(int)index]);
            }
        }
 
        private void SetValue(string keyword, bool value) {
            base[keyword] = value.ToString((System.IFormatProvider)null); 
        } 
        private void SetValue(string keyword, int value) {
            base[keyword] = value.ToString((System.IFormatProvider)null); 
        }
        private void SetValue(string keyword, string value) {
            ADP.CheckArgumentNull(value, keyword);
            base[keyword] = value; 
        }
 
        public override bool ShouldSerialize(string keyword) { 
            ADP.CheckArgumentNull(keyword, "keyword");
            Keywords index; 
            return _keywords.TryGetValue(keyword, out index) && base.ShouldSerialize(_validKeywords[(int)index]);
        }

        public override bool TryGetValue(string keyword, out object value) { 
            Keywords index;
            if (_keywords.TryGetValue(keyword, out index)) { 
                value = GetAt(index); 
                return true;
            } 
            value = null;
            return false;
        }
 
        sealed internal class OracleConnectionStringBuilderConverter : ExpandableObjectConverter {
 
            // converter classes should have public ctor 
            public OracleConnectionStringBuilderConverter() {
            } 

            override public bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
                if (typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType) {
                    return true; 
                }
                return base.CanConvertTo(context, destinationType); 
            } 

            override public object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { 
                if (destinationType == null) {
                    throw ADP.ArgumentNull("destinationType");
                }
                if (typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType) { 
                    OracleConnectionStringBuilder obj = (value as OracleConnectionStringBuilder);
                    if (null != obj) { 
                        return ConvertToInstanceDescriptor(obj); 
                    }
                } 
                return base.ConvertTo(context, culture, value, destinationType);
            }

            private System.ComponentModel.Design.Serialization.InstanceDescriptor ConvertToInstanceDescriptor(OracleConnectionStringBuilder options) { 
                Type[] ctorParams = new Type[] { typeof(string) };
                object[] ctorValues = new object[] { options.ConnectionString }; 
                System.Reflection.ConstructorInfo ctor = typeof(OracleConnectionStringBuilder).GetConstructor(ctorParams); 
                return new System.ComponentModel.Design.Serialization.InstanceDescriptor(ctor, ctorValues);
            } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
    using System;
    using System.Collections; 
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Data.Common; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.Runtime.Serialization; 
    using System.Security.Permissions;
    using System.Text; 

namespace System.Data.OracleClient {

    [DefaultProperty("DataSource")] 
    [System.ComponentModel.TypeConverterAttribute(typeof(OracleConnectionStringBuilder.OracleConnectionStringBuilderConverter))]
    public sealed class OracleConnectionStringBuilder : DbConnectionStringBuilder { 
 
        private enum Keywords { // specific ordering for ConnectionString output construction
//          NamedConnection, 

            DataSource,
            PersistSecurityInfo,
            IntegratedSecurity, 
            UserID,
            Password, 
 
            Enlist,
            Pooling, 
            MinPoolSize,
            MaxPoolSize,

            Unicode, 

            LoadBalanceTimeout, 
 
            OmitOracleConnectionName,
        } 

        private static readonly string[] _validKeywords;
        private static readonly Dictionary _keywords;
 
//      private string _namedConnection        = DbConnectionStringDefaults.NamedConnection;
 
        private string _dataSource             = DbConnectionStringDefaults.DataSource; 
        private string _password               = DbConnectionStringDefaults.Password;
        private string _userID                 = DbConnectionStringDefaults.UserID; 

        private int _loadBalanceTimeout        = DbConnectionStringDefaults.LoadBalanceTimeout;
        private int _maxPoolSize               = DbConnectionStringDefaults.MaxPoolSize;
        private int _minPoolSize               = DbConnectionStringDefaults.MinPoolSize; 

        private bool _enlist                   = DbConnectionStringDefaults.Enlist; 
        private bool _integratedSecurity       = DbConnectionStringDefaults.IntegratedSecurity; 
        private bool _persistSecurityInfo      = DbConnectionStringDefaults.PersistSecurityInfo;
        private bool _pooling                  = DbConnectionStringDefaults.Pooling; 
        private bool _unicode                  = DbConnectionStringDefaults.Unicode;
        private bool _omitOracleConnectionName = DbConnectionStringDefaults.OmitOracleConnectionName;

        static OracleConnectionStringBuilder() { 
            string[] validKeywords = new string[12];
            validKeywords[(int)Keywords.DataSource]               = DbConnectionStringKeywords.DataSource; 
            validKeywords[(int)Keywords.Enlist]                   = DbConnectionStringKeywords.Enlist; 
            validKeywords[(int)Keywords.IntegratedSecurity]       = DbConnectionStringKeywords.IntegratedSecurity;
            validKeywords[(int)Keywords.LoadBalanceTimeout]       = DbConnectionStringKeywords.LoadBalanceTimeout; 
            validKeywords[(int)Keywords.MaxPoolSize]              = DbConnectionStringKeywords.MaxPoolSize;
            validKeywords[(int)Keywords.MinPoolSize]              = DbConnectionStringKeywords.MinPoolSize;
//          validKeywords[(int)Keywords.NamedConnection]          = DbConnectionStringKeywords.NamedConnection;
            validKeywords[(int)Keywords.Password]                 = DbConnectionStringKeywords.Password; 
            validKeywords[(int)Keywords.PersistSecurityInfo]      = DbConnectionStringKeywords.PersistSecurityInfo;
            validKeywords[(int)Keywords.Pooling]                  = DbConnectionStringKeywords.Pooling; 
            validKeywords[(int)Keywords.Unicode]                  = DbConnectionStringKeywords.Unicode; 
            validKeywords[(int)Keywords.UserID]                   = DbConnectionStringKeywords.UserID;
            validKeywords[(int)Keywords.OmitOracleConnectionName] = DbConnectionStringKeywords.OmitOracleConnectionName; 
            _validKeywords = validKeywords;

            Dictionary hash = new Dictionary(19, StringComparer.OrdinalIgnoreCase);
            hash.Add(DbConnectionStringKeywords.DataSource,                Keywords.DataSource); 
            hash.Add(DbConnectionStringKeywords.Enlist,                    Keywords.Enlist);
            hash.Add(DbConnectionStringKeywords.IntegratedSecurity,        Keywords.IntegratedSecurity); 
            hash.Add(DbConnectionStringKeywords.LoadBalanceTimeout,        Keywords.LoadBalanceTimeout); 
            hash.Add(DbConnectionStringKeywords.MaxPoolSize,               Keywords.MaxPoolSize);
            hash.Add(DbConnectionStringKeywords.MinPoolSize,               Keywords.MinPoolSize); 
//          hash.Add(DbConnectionStringKeywords.NamedConnection,           Keywords.NamedConnection);
            hash.Add(DbConnectionStringKeywords.OmitOracleConnectionName,  Keywords.OmitOracleConnectionName);
            hash.Add(DbConnectionStringKeywords.Password,                  Keywords.Password);
            hash.Add(DbConnectionStringKeywords.PersistSecurityInfo,       Keywords.PersistSecurityInfo); 
            hash.Add(DbConnectionStringKeywords.Pooling,                   Keywords.Pooling);
            hash.Add(DbConnectionStringKeywords.Unicode,                   Keywords.Unicode); 
            hash.Add(DbConnectionStringKeywords.UserID,                    Keywords.UserID); 

            hash.Add(DbConnectionStringSynonyms.SERVER,                    Keywords.DataSource); 
            hash.Add(DbConnectionStringSynonyms.ConnectionLifetime,        Keywords.LoadBalanceTimeout);
            hash.Add(DbConnectionStringSynonyms.Pwd,                       Keywords.Password);
            hash.Add(DbConnectionStringSynonyms.PERSISTSECURITYINFO,       Keywords.PersistSecurityInfo);
            hash.Add(DbConnectionStringSynonyms.UID,                       Keywords.UserID); 
            hash.Add(DbConnectionStringSynonyms.User,                      Keywords.UserID);
            hash.Add(DbConnectionStringSynonyms.WorkaroundOracleBug914652, Keywords.OmitOracleConnectionName); 
            Debug.Assert(19 == hash.Count, "initial expected size is incorrect"); 
            _keywords = hash;
        } 

        public OracleConnectionStringBuilder() : this((string)null) {
        }
 
        public OracleConnectionStringBuilder(string connectionString) : base() {
            if (!ADP.IsEmpty(connectionString)) { 
                ConnectionString = connectionString; 
            }
        } 

        public override object this[string keyword] {
            get {
                Keywords index = GetIndex(keyword); 
                return GetAt(index);
            } 
            set { 
                Bid.Trace(" keyword='%ls'\n", keyword);
                if (null != value) { 
                    Keywords index = GetIndex(keyword);
                    switch(index) {
                    case Keywords.DataSource:                DataSource = ConvertToString(value); break;
//                  case Keywords.NamedConnection:           NamedConnection = ConvertToString(value); break; 
                    case Keywords.Password:                  Password = ConvertToString(value); break;
                    case Keywords.UserID:                    UserID = ConvertToString(value); break; 
 
                    case Keywords.LoadBalanceTimeout:        LoadBalanceTimeout = ConvertToInt32(value); break;
                    case Keywords.MaxPoolSize:               MaxPoolSize = ConvertToInt32(value); break; 
                    case Keywords.MinPoolSize:               MinPoolSize = ConvertToInt32(value); break;

                    case Keywords.IntegratedSecurity:        IntegratedSecurity = ConvertToIntegratedSecurity(value); break;
 
                    case Keywords.Enlist:                    Enlist = ConvertToBoolean(value); break;
                    case Keywords.PersistSecurityInfo:       PersistSecurityInfo = ConvertToBoolean(value); break; 
                    case Keywords.Pooling:                   Pooling = ConvertToBoolean(value); break; 
                    case Keywords.Unicode:                   Unicode = ConvertToBoolean(value); break;
                    case Keywords.OmitOracleConnectionName:  OmitOracleConnectionName = ConvertToBoolean(value); break; 

                    default:
                        Debug.Assert(false, "unexpected keyword");
                        throw ADP.KeywordNotSupported(keyword); 
                    }
                } 
                else { 
                    Remove(keyword);
                } 
            }
        }

        [DisplayName(DbConnectionStringKeywords.DataSource)] 
        [ResCategoryAttribute(Res.DataCategory_Source)]
        [ResDescriptionAttribute(Res.DbConnectionString_DataSource)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)] 
        public string DataSource {
            get { return _dataSource; } 
            set {
                if ((null != value) && (128 < value.Length)) {
                    throw ADP.InvalidConnectionOptionLength(DbConnectionStringKeywords.DataSource, 128);
                } 
                SetValue(DbConnectionStringKeywords.DataSource, value);
                _dataSource = value; 
            } 
        }
 
        [DisplayName(DbConnectionStringKeywords.Enlist)]
        [ResCategoryAttribute(Res.DataCategory_Pooling)]
        [ResDescriptionAttribute(Res.DbConnectionString_Enlist)]
        [RefreshPropertiesAttribute(RefreshProperties.All)] 
        public bool Enlist {
            get { return _enlist; } 
            set { 
                SetValue(DbConnectionStringKeywords.Enlist, value);
                _enlist = value; 
            }
        }

        [DisplayName(DbConnectionStringKeywords.IntegratedSecurity)] 
        [ResCategoryAttribute(Res.DataCategory_Security)]
        [ResDescriptionAttribute(Res.DbConnectionString_IntegratedSecurity)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)] 
        public bool IntegratedSecurity {
            get { return _integratedSecurity; } 
            set {
                SetValue(DbConnectionStringKeywords.IntegratedSecurity, value);
                _integratedSecurity = value;
            } 
        }
 
        [DisplayName(DbConnectionStringKeywords.LoadBalanceTimeout)] 
        [ResCategoryAttribute(Res.DataCategory_Pooling)]
        [ResDescriptionAttribute(Res.DbConnectionString_LoadBalanceTimeout)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        public int LoadBalanceTimeout {
            get { return _loadBalanceTimeout; }
            set { 
                if (value < 0) {
                    throw ADP.InvalidConnectionOptionValue(DbConnectionStringKeywords.LoadBalanceTimeout); 
                } 
                SetValue(DbConnectionStringKeywords.LoadBalanceTimeout, value);
                _loadBalanceTimeout = value; 
            }
        }

        [DisplayName(DbConnectionStringKeywords.MaxPoolSize)] 
        [ResCategoryAttribute(Res.DataCategory_Pooling)]
        [ResDescriptionAttribute(Res.DbConnectionString_MaxPoolSize)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)] 
        public int MaxPoolSize {
            get { return _maxPoolSize; } 
            set {
                if (value < 1) {
                    throw ADP.InvalidConnectionOptionValue(DbConnectionStringKeywords.MaxPoolSize);
                } 
                SetValue(DbConnectionStringKeywords.MaxPoolSize, value);
                _maxPoolSize = value; 
            } 
        }
 
        [DisplayName(DbConnectionStringKeywords.MinPoolSize)]
        [ResCategoryAttribute(Res.DataCategory_Pooling)]
        [ResDescriptionAttribute(Res.DbConnectionString_MinPoolSize)]
        [RefreshPropertiesAttribute(RefreshProperties.All)] 
        public int MinPoolSize {
            get { return _minPoolSize; } 
            set { 
                if (value < 0) {
                    throw ADP.InvalidConnectionOptionValue(DbConnectionStringKeywords.MinPoolSize); 
                }
                SetValue(DbConnectionStringKeywords.MinPoolSize, value);
                _minPoolSize = value;
            } 
        }
/* 
        [DisplayName(DbConnectionStringKeywords.NamedConnection)] 
        [ResCategoryAttribute(Res.DataCategory_NamedConnectionString)]
        [ResDescriptionAttribute(Res.DbConnectionString_NamedConnection)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        [TypeConverter(typeof(NamedConnectionStringConverter))]
        public string NamedConnection {
            get { 
                return _namedConnection;
            } 
            set { 
                SetValue(DbConnectionStringKeywords.NamedConnection, value);
                _namedConnection = value; 
            }
        }
*/
        [DisplayName(DbConnectionStringKeywords.OmitOracleConnectionName)] 
        [ResCategoryAttribute(Res.DataCategory_Initialization)]
        [ResDescriptionAttribute(Res.DbConnectionString_OmitOracleConnectionName)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)] 
        public bool OmitOracleConnectionName {
            get { return _omitOracleConnectionName; } 
            set {
                SetValue(DbConnectionStringKeywords.OmitOracleConnectionName, value);
                _omitOracleConnectionName = value;
            } 
        }
 
        [DisplayName(DbConnectionStringKeywords.Password)] 
        [PasswordPropertyTextAttribute(true)]
        [ResCategoryAttribute(Res.DataCategory_Security)] 
        [ResDescriptionAttribute(Res.DbConnectionString_Password)]
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        public string Password {
            get { return _password; } 
            set {
                if ((null != value) && (30 < value.Length)) { 
                    throw ADP.InvalidConnectionOptionLength(DbConnectionStringKeywords.Password, 30); 
                }
                SetValue(DbConnectionStringKeywords.Password, value); 
                _password = value;
            }
        }
 
        [DisplayName(DbConnectionStringKeywords.PersistSecurityInfo)]
        [ResCategoryAttribute(Res.DataCategory_Security)] 
        [ResDescriptionAttribute(Res.DbConnectionString_PersistSecurityInfo)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        public bool PersistSecurityInfo { 
            get { return _persistSecurityInfo; }
            set {
                SetValue(DbConnectionStringKeywords.PersistSecurityInfo, value);
                _persistSecurityInfo = value; 
            }
        } 
 
        [DisplayName(DbConnectionStringKeywords.Pooling)]
        [ResCategoryAttribute(Res.DataCategory_Pooling)] 
        [ResDescriptionAttribute(Res.DbConnectionString_Pooling)]
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        public bool Pooling {
            get { return _pooling; } 
            set {
                SetValue(DbConnectionStringKeywords.Pooling, value); 
                _pooling = value; 
            }
        } 

        [DisplayName(DbConnectionStringKeywords.Unicode)]
        [ResCategoryAttribute(Res.DataCategory_Initialization)]
        [ResDescriptionAttribute(Res.DbConnectionString_Unicode)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        public bool Unicode { 
            get { return _unicode; } 
            set {
                SetValue(DbConnectionStringKeywords.Unicode, value); 
                _unicode = value;
            }
        }
 
        [DisplayName(DbConnectionStringKeywords.UserID)]
        [ResCategoryAttribute(Res.DataCategory_Security)] 
        [ResDescriptionAttribute(Res.DbConnectionString_UserID)] 
        [RefreshPropertiesAttribute(RefreshProperties.All)]
        public string UserID { 
            get { return _userID; }
            set {
                if ((null != value) && (30 < value.Length)) {
                    throw ADP.InvalidConnectionOptionLength(DbConnectionStringKeywords.UserID, 30); 
                }
                SetValue(DbConnectionStringKeywords.UserID, value); 
                _userID = value; 
            }
        } 

        public override bool IsFixedSize {
            get {
                return true; 
            }
        } 
 
        public override ICollection Keys {
            get { 
                return new System.Data.Common.ReadOnlyCollection(_validKeywords);
            }
        }
 
        public override ICollection Values {
            get { 
                // written this way so if the ordering of Keywords & _validKeywords changes 
                // this is one less place to maintain
                object[] values = new object[_validKeywords.Length]; 
                for(int i = 0; i < _validKeywords.Length; ++i) {
                    values[i] = GetAt((Keywords)i);
                }
                return new System.Data.Common.ReadOnlyCollection(values); 
            }
        } 
 
        public override void Clear() {
            base.Clear(); 
            for(int i = 0; i < _validKeywords.Length; ++i) {
                Reset((Keywords)i);
            }
        } 

        new internal void ClearPropertyDescriptors() { 
            base.ClearPropertyDescriptors(); 
        }
 
        public override bool ContainsKey(string keyword) {
            ADP.CheckArgumentNull(keyword, "keyword");
            return _keywords.ContainsKey(keyword);
        } 

        private static bool ConvertToBoolean(object value) { 
            return DbConnectionStringBuilderUtil.ConvertToBoolean(value); 
        }
        private static int ConvertToInt32(object value) { 
            return DbConnectionStringBuilderUtil.ConvertToInt32(value);
        }
        private static bool ConvertToIntegratedSecurity(object value) {
            return DbConnectionStringBuilderUtil.ConvertToIntegratedSecurity(value); 
        }
        private static string ConvertToString(object value) { 
            return DbConnectionStringBuilderUtil.ConvertToString(value); 
        }
 
        private object GetAt(Keywords index) {
            switch(index) {
            case Keywords.DataSource:                return DataSource;
            case Keywords.Enlist:                    return Enlist; 
            case Keywords.IntegratedSecurity:        return IntegratedSecurity;
            case Keywords.LoadBalanceTimeout:        return LoadBalanceTimeout; 
            case Keywords.MaxPoolSize:               return MaxPoolSize; 
            case Keywords.MinPoolSize:               return MinPoolSize;
//          case Keywords.NamedConnection:           return NamedConnection; 
            case Keywords.OmitOracleConnectionName:  return OmitOracleConnectionName;
            case Keywords.Password:                  return Password;
            case Keywords.PersistSecurityInfo:       return PersistSecurityInfo;
            case Keywords.Pooling:                   return Pooling; 
            case Keywords.Unicode:                   return Unicode;
            case Keywords.UserID:                    return UserID; 
            default: 
                Debug.Assert(false, "unexpected keyword");
                throw ADP.KeywordNotSupported(_validKeywords[(int)index]); 
            }
        }

        private Keywords GetIndex(string keyword) { 
            ADP.CheckArgumentNull(keyword, "keyword");
            Keywords index; 
            if (_keywords.TryGetValue(keyword, out index)) { 
                return index;
            } 
            throw ADP.KeywordNotSupported(keyword);
        }

        private Attribute[] GetAttributesFromCollection(AttributeCollection collection) { 
            Attribute[] attributes = new Attribute[collection.Count];
            collection.CopyTo(attributes, 0); 
            return attributes; 
        }
 
        protected override void GetProperties(Hashtable propertyDescriptors) {
            foreach(PropertyDescriptor reflected in TypeDescriptor.GetProperties(this, true)) {
                bool refreshOnChange = false;
                bool isReadonly = false; 
                string displayName = reflected.DisplayName;
 
                // 'Password' & 'User ID' will be readonly if 'Integrated Security' is true 
                if (DbConnectionStringKeywords.IntegratedSecurity == displayName) {
                    refreshOnChange = true; 
                    isReadonly = reflected.IsReadOnly;
                }
                else if ((DbConnectionStringKeywords.Password == displayName) ||
                         (DbConnectionStringKeywords.UserID == displayName)) { 
                     isReadonly = IntegratedSecurity;
                } 
                else { 
                    continue;
                } 
                Attribute[] attributes = GetAttributesFromCollection(reflected.Attributes);
                DbConnectionStringBuilderDescriptor descriptor = new DbConnectionStringBuilderDescriptor(reflected.Name,
                        reflected.ComponentType, reflected.PropertyType, isReadonly, attributes);
                descriptor.RefreshOnChange = refreshOnChange; 
                propertyDescriptors[displayName] = descriptor;
            } 
            base.GetProperties(propertyDescriptors); 
        }
 
        public override bool Remove(string keyword) {
            ADP.CheckArgumentNull(keyword, "keyword");
            Keywords index;
            if (_keywords.TryGetValue(keyword, out index)) { 
                base.Remove(_validKeywords[(int)index]);
                Reset(index); 
                return true; 
            }
            return false; 
        }

        private void Reset(Keywords index) {
            switch(index) { 
            case Keywords.DataSource:
                _dataSource = DbConnectionStringDefaults.DataSource; 
                break; 
            case Keywords.Enlist:
                _enlist = DbConnectionStringDefaults.Enlist; 
                break;
            case Keywords.IntegratedSecurity:
                _integratedSecurity = DbConnectionStringDefaults.IntegratedSecurity;
                break; 
            case Keywords.LoadBalanceTimeout:
                _loadBalanceTimeout = DbConnectionStringDefaults.LoadBalanceTimeout; 
                break; 
            case Keywords.MaxPoolSize:
                _maxPoolSize = DbConnectionStringDefaults.MaxPoolSize; 
                break;
            case Keywords.MinPoolSize:
                _minPoolSize = DbConnectionStringDefaults.MinPoolSize;
                break; 
//          case Keywords.NamedConnection:
//              _namedConnection = DbConnectionStringDefaults.NamedConnection; 
//              break; 
            case Keywords.OmitOracleConnectionName:
                _omitOracleConnectionName = DbConnectionStringDefaults.OmitOracleConnectionName; 
                break;
            case Keywords.Password:
                _password = DbConnectionStringDefaults.Password;
                break; 
            case Keywords.PersistSecurityInfo:
                _persistSecurityInfo = DbConnectionStringDefaults.PersistSecurityInfo; 
                break; 
            case Keywords.Pooling:
                _pooling = DbConnectionStringDefaults.Pooling; 
                break;
            case Keywords.Unicode:
                _unicode = DbConnectionStringDefaults.Unicode;
                break; 
            case Keywords.UserID:
                _userID = DbConnectionStringDefaults.UserID; 
                break; 
            default:
                Debug.Assert(false, "unexpected keyword"); 
                throw ADP.KeywordNotSupported(_validKeywords[(int)index]);
            }
        }
 
        private void SetValue(string keyword, bool value) {
            base[keyword] = value.ToString((System.IFormatProvider)null); 
        } 
        private void SetValue(string keyword, int value) {
            base[keyword] = value.ToString((System.IFormatProvider)null); 
        }
        private void SetValue(string keyword, string value) {
            ADP.CheckArgumentNull(value, keyword);
            base[keyword] = value; 
        }
 
        public override bool ShouldSerialize(string keyword) { 
            ADP.CheckArgumentNull(keyword, "keyword");
            Keywords index; 
            return _keywords.TryGetValue(keyword, out index) && base.ShouldSerialize(_validKeywords[(int)index]);
        }

        public override bool TryGetValue(string keyword, out object value) { 
            Keywords index;
            if (_keywords.TryGetValue(keyword, out index)) { 
                value = GetAt(index); 
                return true;
            } 
            value = null;
            return false;
        }
 
        sealed internal class OracleConnectionStringBuilderConverter : ExpandableObjectConverter {
 
            // converter classes should have public ctor 
            public OracleConnectionStringBuilderConverter() {
            } 

            override public bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
                if (typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType) {
                    return true; 
                }
                return base.CanConvertTo(context, destinationType); 
            } 

            override public object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { 
                if (destinationType == null) {
                    throw ADP.ArgumentNull("destinationType");
                }
                if (typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType) { 
                    OracleConnectionStringBuilder obj = (value as OracleConnectionStringBuilder);
                    if (null != obj) { 
                        return ConvertToInstanceDescriptor(obj); 
                    }
                } 
                return base.ConvertTo(context, culture, value, destinationType);
            }

            private System.ComponentModel.Design.Serialization.InstanceDescriptor ConvertToInstanceDescriptor(OracleConnectionStringBuilder options) { 
                Type[] ctorParams = new Type[] { typeof(string) };
                object[] ctorValues = new object[] { options.ConnectionString }; 
                System.Reflection.ConstructorInfo ctor = typeof(OracleConnectionStringBuilder).GetConstructor(ctorParams); 
                return new System.ComponentModel.Design.Serialization.InstanceDescriptor(ctor, ctorValues);
            } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK