public static object TypeToObject(
     CBORObject objThis,
     Type t,
     CBORTypeMapper mapper,
     PODOptions options,
     int depth)
 {
     if (t.Equals(typeof(int)))
     {
         return(objThis.AsInt32());
     }
     if (t.Equals(typeof(short)))
     {
         return(objThis.AsNumber().ToInt16Checked());
     }
     if (t.Equals(typeof(ushort)))
     {
         return(objThis.AsUInt16Legacy());
     }
     if (t.Equals(typeof(byte)))
     {
         return(objThis.AsByteLegacy());
     }
     if (t.Equals(typeof(sbyte)))
     {
         return(objThis.AsSByteLegacy());
     }
     if (t.Equals(typeof(long)))
     {
         return(objThis.AsNumber().ToInt64Checked());
     }
     if (t.Equals(typeof(uint)))
     {
         return(objThis.AsUInt32Legacy());
     }
     if (t.Equals(typeof(ulong)))
     {
         return(objThis.AsUInt64Legacy());
     }
     if (t.Equals(typeof(double)))
     {
         return(objThis.AsDouble());
     }
     if (t.Equals(typeof(decimal)))
     {
         return(objThis.AsDecimal());
     }
     if (t.Equals(typeof(float)))
     {
         return(objThis.AsSingle());
     }
     if (t.Equals(typeof(bool)))
     {
         return(objThis.AsBoolean());
     }
     if (t.Equals(typeof(char)))
     {
         if (objThis.Type == CBORType.TextString)
         {
             string s = objThis.AsString();
             if (s.Length != 1)
             {
                 throw new CBORException("Can't convert to char");
             }
             return(s[0]);
         }
         if (objThis.IsNumber && objThis.AsNumber().CanFitInInt32())
         {
             int c = objThis.AsNumber().ToInt32IfExact();
             if (c < 0 || c >= 0x10000)
             {
                 throw new CBORException("Can't convert to char");
             }
             return((char)c);
         }
         throw new CBORException("Can't convert to char");
     }
     if (t.Equals(typeof(DateTime)))
     {
         return(new CBORDateConverter().FromCBORObject(objThis));
     }
     if (t.Equals(typeof(Guid)))
     {
         return(new CBORUuidConverter().FromCBORObject(objThis));
     }
     if (t.Equals(typeof(Uri)))
     {
         return(new CBORUriConverter().FromCBORObject(objThis));
     }
     if (IsAssignableFrom(typeof(Enum), t))
     {
         return(ObjectToEnum(objThis, t));
     }
     if (IsGenericType(t))
     {
         Type td = t.GetGenericTypeDefinition();
         // Nullable types
         if (td.Equals(typeof(Nullable <>)))
         {
             Type nullableType = Nullable.GetUnderlyingType(t);
             if (objThis.IsNull)
             {
                 return(Activator.CreateInstance(t));
             }
             else
             {
                 object wrappedObj = objThis.ToObject(
                     nullableType,
                     mapper,
                     options,
                     depth + 1);
                 return(Activator.CreateInstance(
                            t,
                            wrappedObj));
             }
         }
     }
     if (objThis.Type == CBORType.ByteString)
     {
         if (t.Equals(typeof(byte[])))
         {
             byte[] bytes   = objThis.GetByteString();
             var    byteret = new byte[bytes.Length];
             Array.Copy(bytes, 0, byteret, 0, byteret.Length);
             return(byteret);
         }
     }
     if (objThis.Type == CBORType.Array)
     {
         Type   objectType        = typeof(object);
         var    isList            = false;
         object listObject        = null;
         object genericListObject = null;
 #if NET40 || NET20
         if (IsAssignableFrom(typeof(Array), t))
         {
             Type  elementType = t.GetElementType();
             Array array       = Array.CreateInstance(
                 elementType,
                 GetDimensions(objThis));
             return(FillArray(
                        array,
                        elementType,
                        objThis,
                        mapper,
                        options,
                        depth));
         }
         if (t.IsGenericType)
         {
             Type td = t.GetGenericTypeDefinition();
             isList = td.Equals(typeof(List <>)) || td.Equals(typeof(IList <>)) ||
                      td.Equals(typeof(ICollection <>)) ||
                      td.Equals(typeof(IEnumerable <>));
         }
         isList = isList && t.GetGenericArguments().Length == 1;
         if (isList)
         {
             objectType = t.GetGenericArguments()[0];
             Type listType = typeof(List <>).MakeGenericType(objectType);
             listObject = Activator.CreateInstance(listType);
         }
 #else
         if (IsAssignableFrom(typeof(Array), t))
         {
             Type  elementType = t.GetElementType();
             Array array       = Array.CreateInstance(
                 elementType,
                 GetDimensions(objThis));
             return(FillArray(
                        array,
                        elementType,
                        objThis,
                        mapper,
                        options,
                        depth));
         }
         if (t.GetTypeInfo().IsGenericType)
         {
             Type td = t.GetGenericTypeDefinition();
             isList = td.Equals(typeof(List <>)) || td.Equals(typeof(IList <>)) ||
                      td.Equals(typeof(ICollection <>)) ||
                      td.Equals(typeof(IEnumerable <>));
         }
         isList = isList && t.GenericTypeArguments.Length == 1;
         if (isList)
         {
             objectType = t.GenericTypeArguments[0];
             Type listType = typeof(List <>).MakeGenericType(objectType);
             listObject = Activator.CreateInstance(listType);
         }
 #endif
         if (listObject == null)
         {
             if (t.Equals(typeof(IList)) ||
                 t.Equals(typeof(ICollection)) || t.Equals(typeof(IEnumerable)))
             {
                 listObject = new List <object>();
                 objectType = typeof(object);
             }
             else if (IsClassOrValueType(t))
             {
                 // TODO: write Java equivalent
                 var implementsList = false;
                 foreach (var interf in GetTypeInterfaces(t))
                 {
                     if (IsGenericType(interf) &&
                         interf.GetGenericTypeDefinition().Equals(typeof(IList <>)))
                     {
                         if (implementsList)
                         {
                             { implementsList = false; }
                             break;
                         }
                         else
                         {
                             implementsList = true;
                             objectType     =
                                 FirstGenericArgument(interf);
                         }
                     }
                 }
                 if (implementsList)
                 {
                     // DebugUtility.Log("assignable from list<>");
                     genericListObject = Activator.CreateInstance(t);
                 }
                 else
                 {
                     // DebugUtility.Log("not assignable from list<> " + t);
                 }
             }
         }
         if (genericListObject != null)
         {
             object addMethod = FindOneArgumentMethod(
                 genericListObject,
                 "Add",
                 objectType);
             if (addMethod == null)
             {
                 throw new CBORException();
             }
             foreach (CBORObject value in objThis.Values)
             {
                 PropertyMap.InvokeOneArgumentMethod(
                     addMethod,
                     genericListObject,
                     value.ToObject(objectType, mapper, options, depth + 1));
             }
             return(genericListObject);
         }
         if (listObject != null)
         {
             System.Collections.IList ie = (System.Collections.IList)listObject;
             foreach (CBORObject value in objThis.Values)
             {
                 ie.Add(value.ToObject(objectType, mapper, options, depth + 1));
             }
             return(listObject);
         }
     }
     if (objThis.Type == CBORType.Map)
     {
         var    isDict     = false;
         Type   keyType    = null;
         Type   valueType  = null;
         object dictObject = null;
 #if NET40 || NET20
         isDict = t.IsGenericType;
         if (t.IsGenericType)
         {
             Type td = t.GetGenericTypeDefinition();
             isDict = td.Equals(typeof(Dictionary <,>)) ||
                      td.Equals(typeof(IDictionary <,>));
         }
         // DebugUtility.Log("list=" + isDict);
         isDict = isDict && t.GetGenericArguments().Length == 2;
         // DebugUtility.Log("list=" + isDict);
         if (isDict)
         {
             keyType   = t.GetGenericArguments()[0];
             valueType = t.GetGenericArguments()[1];
             Type listType = typeof(Dictionary <,>).MakeGenericType(
                 keyType,
                 valueType);
             dictObject = Activator.CreateInstance(listType);
         }
 #else
         isDict = t.GetTypeInfo().IsGenericType;
         if (t.GetTypeInfo().IsGenericType)
         {
             Type td = t.GetGenericTypeDefinition();
             isDict = td.Equals(typeof(Dictionary <,>)) ||
                      td.Equals(typeof(IDictionary <,>));
         }
         // DebugUtility.Log("list=" + isDict);
         isDict = isDict && t.GenericTypeArguments.Length == 2;
         // DebugUtility.Log("list=" + isDict);
         if (isDict)
         {
             keyType   = t.GenericTypeArguments[0];
             valueType = t.GenericTypeArguments[1];
             Type listType = typeof(Dictionary <,>).MakeGenericType(
                 keyType,
                 valueType);
             dictObject = Activator.CreateInstance(listType);
         }
 #endif
         if (dictObject == null)
         {
             if (t.Equals(typeof(IDictionary)))
             {
                 dictObject = new Dictionary <object, object>();
                 keyType    = typeof(object);
                 valueType  = typeof(object);
             }
         }
         if (dictObject != null)
         {
             System.Collections.IDictionary idic =
                 (System.Collections.IDictionary)dictObject;
             foreach (CBORObject key in objThis.Keys)
             {
                 CBORObject value = objThis[key];
                 idic.Add(
                     key.ToObject(keyType, mapper, options, depth + 1),
                     value.ToObject(valueType, mapper, options, depth + 1));
             }
             return(dictObject);
         }
         if (mapper != null)
         {
             if (!mapper.FilterTypeName(t.FullName))
             {
                 throw new CBORException("Type " + t.FullName +
                                         " not supported");
             }
         }
         else
         {
             if (t.FullName != null && (
                     StartsWith(t.FullName, "Microsoft.Win32.") ||
                     StartsWith(t.FullName, "System.IO.")))
             {
                 throw new CBORException("Type " + t.FullName +
                                         " not supported");
             }
             if (StartsWith(t.FullName, "System.") &&
                 !HasCustomAttribute(t, "System.SerializableAttribute"))
             {
                 throw new CBORException("Type " + t.FullName +
                                         " not supported");
             }
         }
         var values    = new List <KeyValuePair <string, CBORObject> >();
         var propNames = PropertyMap.GetPropertyNames(
             t,
             options != null ? options.UseCamelCase : true);
         foreach (string key in propNames)
         {
             if (objThis.ContainsKey(key))
             {
                 CBORObject cborValue = objThis[key];
                 var        dict      = new KeyValuePair <string, CBORObject>(
                     key,
                     cborValue);
                 values.Add(dict);
             }
         }
         return(PropertyMap.ObjectWithProperties(
                    t,
                    values,
                    mapper,
                    options,
                    depth));
     }
     else
     {
         throw new CBORException();
     }
 }