private Expression FixCaseLiteralValue(LiteralExpression literalCondition)
		{
			TypeReference conditionType = theSwitch.Condition.ExpressionType;
			int integerRepresentation = Convert.ToInt32(literalCondition.Value) + this.conditionOffset;
			literalCondition.Value = integerRepresentation;
			var theTypeSystem = context.MethodContext.Method.Module.TypeSystem;

			if (conditionType.Name == "System.Nullable`1" && conditionType.HasGenericParameters)
			{
				conditionType = conditionType.GenericParameters[0];
			}
			if (conditionType.FullName == theTypeSystem.Char.FullName)
			{
				//switch cases should have char labels;
				return new LiteralExpression(Convert.ToChar(integerRepresentation),theTypeSystem, null);
			}
			else if (conditionType.FullName == theTypeSystem.Boolean.FullName)
			{
				return new LiteralExpression(Convert.ToBoolean(integerRepresentation),theTypeSystem,null);
			}
			else
			{
				TypeDefinition resolvedConditionType = conditionType.Resolve();
				if (resolvedConditionType != null && resolvedConditionType.IsEnum)
				{
					Expression result = EnumHelper.GetEnumExpression(resolvedConditionType,literalCondition,theTypeSystem);
					if (result is LiteralExpression)
					{
						result = new CastExpression(result, resolvedConditionType, null);
					}
					return result;
				}
			}
			return literalCondition;
		}
        private Expression GetMethodHandleExpression(MethodReference methodReference, IEnumerable<Instruction> instructions)
        {
            TypeDefinition corlibTypeTypeDefinition = GetSystemTypeTypeDefinition();

            string[] parametersNames = methodReference.HasParameters ? new string[] { "System.String", "System.Type[]" } : new string[] { "System.String" };
            MethodReference getMethodReference = GetSystemTypeMethodReference(corlibTypeTypeDefinition, "GetMethod", parametersNames);

            MethodReference getMethodHandleReference = GetHandlePropertyGetterReference(typeof(System.Reflection.MethodBase), "get_MethodHandle");

            TypeOfExpression typeOfExpression = new TypeOfExpression(methodReference.DeclaringType, null);
            MethodReferenceExpression getMethodMethodReferenceExpression = new MethodReferenceExpression(typeOfExpression, getMethodReference, null);
            MethodInvocationExpression getMethodMethodInvocationExpression = new MethodInvocationExpression(getMethodMethodReferenceExpression, null);
            LiteralExpression argument = new LiteralExpression(methodReference.Name, this.typeSystem, null);
            getMethodMethodInvocationExpression.Arguments.Add(argument);

            if (methodReference.HasParameters)
            {
                BlockExpression blockExpression = new BlockExpression(null);
                foreach (ParameterDefinition parameter in methodReference.Parameters)
                {
                    blockExpression.Expressions.Add(new TypeOfExpression(parameter.ParameterType, null));
                }

				InitializerExpression initializer = new InitializerExpression(blockExpression, InitializerType.ArrayInitializer);
				ArrayCreationExpression getMethodTypeParametersArray = new ArrayCreationExpression(corlibTypeTypeDefinition, initializer, null);
                getMethodTypeParametersArray.Dimensions.Add(new LiteralExpression(blockExpression.Expressions.Count, this.typeSystem, null));

                getMethodMethodInvocationExpression.Arguments.Add(getMethodTypeParametersArray);
            }

            MethodReferenceExpression getMethodHandleMethodReferenceExpression = new MethodReferenceExpression(getMethodMethodInvocationExpression, getMethodHandleReference, null);
            MethodInvocationExpression getMethodHandleMethodInvocationExpression = new MethodInvocationExpression(getMethodHandleMethodReferenceExpression, instructions);
            PropertyReferenceExpression methodHandlePropertyReferenceExpression = new PropertyReferenceExpression(getMethodHandleMethodInvocationExpression, null);

            return methodHandlePropertyReferenceExpression;
        }
		protected virtual void WriteFieldDeclaration(FieldDefinition field)
		{
			if (!this.TypeContext.BackingFieldToNameMap.ContainsKey(field) && this.ModuleContext.RenamedMembers.Contains(field.MetadataToken.ToUInt32()))
			{
				string originalFieldName = GetOriginalFieldName(field);
				WriteComment(originalFieldName);
				WriteLine();
			}

			WriteMemberVisibility(field);
			WriteSpace();
			if (field.IsInitOnly)
			{
				WriteKeyword(KeyWordWriter.ReadOnly);
				WriteSpace();
			}
			if (field.IsLiteral)
			{
				WriteKeyword(KeyWordWriter.Const);
				WriteSpace();
			}
			else if (field.IsStatic)
			{
				WriteKeyword(KeyWordWriter.Static);
				WriteSpace();
			}

			WriteFieldTypeAndName(field);

			if (field.HasConstant)
			{
				WriteSpace();
				WriteToken("=");
				WriteSpace();
				TypeDefinition fieldType = field.FieldType.Resolve();
				if (fieldType != null && fieldType.IsEnum)
				{
					LiteralExpression fieldConstant = new LiteralExpression(field.Constant.Value, field.DeclaringType.Module.TypeSystem, null);
					Expression constant = EnumHelper.GetEnumExpression(fieldType, fieldConstant, field.DeclaringType.Module.TypeSystem);
					Write(constant);
				}
				else
				{
					WriteLiteralInLanguageSyntax(field.Constant.Value);
				}
			}
		}
		public override void VisitLiteralExpression(LiteralExpression node)
		{
			WriteLiteralInLanguageSyntax(node.Value);
		}
 private int GetIntegerValue(LiteralExpression size)
 {
     if (size != null)
     {
         try
         {
             return Convert.ToInt32(size.Value);
         }
         catch (InvalidCastException)
         {
             return -1;
         }
     }
     return -1;
 }
		public static Expression GetEnumExpression(TypeDefinition enumDefinition, LiteralExpression targetedValue, TypeSystem typeSystem)
		{
			int enumDefinitionUnderlyingTypeSize = GetEnumBitSize(enumDefinition);

			/// This depends on the unchecked context, which is default for C#
			ulong value = 0;
            switch (targetedValue.Value.GetType().FullName)
            {
                case "System.Int32":
                    /// This is done, so that the same size extension is used when casting the literal's value to ulong 
                    /// and when casting anum's contstants to ulong.
                    /// Otherwise, casting int -1 and long -1 to ulong will yield different results.
                    if (enumDefinitionUnderlyingTypeSize == 32)
                    {
                        value = (uint)(int)targetedValue.Value;
                    }
                    else
                    {
                        value = (ulong)(int)targetedValue.Value;
                    }
                    break;
                case "System.Int64":
                    value = (ulong)(long)targetedValue.Value;
                    break;
                case "System.UInt32":
                    value = (uint)targetedValue.Value;
                    break;
                case "System.UInt64":
                    value = (ulong)targetedValue.Value;
                    break;
                // The types below should not be present at any point, but are added just to complete all the possible cases.
                case "System.Byte":
                    value = (byte)targetedValue.Value;
                    break;
                case "System.SByte":
                    value = (ulong)(sbyte)targetedValue.Value;
                    break;
                case "System.Int16":
                    value = (ulong)(short)targetedValue.Value;
                    break;
                case "System.UInt16":
                    value = (ushort)targetedValue.Value;
                    break;
            }

			Collection<FieldDefinition> fields = enumDefinition.Fields;
			List<FieldDefinition> enumFields = new List<FieldDefinition>();
			foreach (FieldDefinition currentField in fields)
			{
				if (currentField.Constant != null && currentField.Constant.Value != null)
				{
					ulong fieldValue = 0;

                    switch (currentField.Constant.Value.GetType().FullName)
                    {
                        case "System.Int32": // most common case
						    fieldValue = (uint)(int)(currentField.Constant.Value);
                            break;
                        case "System.UInt32":
						    fieldValue = (uint)(currentField.Constant.Value);
                            break;
                        case "System.Byte":
						    fieldValue = (byte)(currentField.Constant.Value);
                            break;
                        case "System.SByte":
						    fieldValue = (byte)(sbyte)(currentField.Constant.Value);
                            break;
                        case "System.Int16":
						    fieldValue = (ushort)(short)(currentField.Constant.Value);
                            break;
                        case "System.UInt16":
						    fieldValue = (ushort)(currentField.Constant.Value);
                            break;
                        case "System.Int64":
						    fieldValue = (ulong)(long)(currentField.Constant.Value);
                            break;
                        case "System.UInt64":
						    fieldValue = (ulong)(currentField.Constant.Value);
                            break;
                    }
					if (fieldValue == value)
					{
						return new EnumExpression(currentField, targetedValue.UnderlyingSameMethodInstructions);
					}
					if (fieldValue != 0 && (fieldValue | value) == value)
					//if (IsPartOfValue(fieldValue, value))
					{
						///Then this one of the flags, used to generate the value.
						enumFields.Add(currentField);
					}
				}
			}

			///Generate the expression of the flags.
			if (enumFields.Count < 2)
			{
				return targetedValue;
			}
			Expression result = new BinaryExpression(BinaryOperator.BitwiseOr, new EnumExpression(enumFields[0], null), new EnumExpression(enumFields[1], null), typeSystem, null);
			result.ExpressionType = enumDefinition;
			for (int i = 2; i < enumFields.Count; i++)
			{
				result = new BinaryExpression(BinaryOperator.BitwiseOr, result, new EnumExpression(enumFields[i], null), typeSystem, null);
				result.ExpressionType = enumDefinition;
			}

			return result.CloneAndAttachInstructions(targetedValue.UnderlyingSameMethodInstructions);
		}
 private object GetDecrementedValue(LiteralExpression expression)
 {
     switch (expression.ExpressionType.Name)
     {
         case "Byte":
             byte byteValue = (byte)expression.Value;
             byteValue--;
             return byteValue;
         case "SByte":
             sbyte sbyteValue = (sbyte)expression.Value;
             sbyteValue--;
             return sbyteValue;
         case "Int16":
             short shortValue = (short)expression.Value;
             shortValue--;
             return shortValue;
         case "UInt16":
             ushort ushortValue = (ushort)expression.Value;
             ushortValue--;
             return ushortValue;
         case "Int32":
             int intValue = (int)expression.Value;
             intValue--;
             return intValue;
         case "UInt32":
             uint uintValue = (uint)expression.Value;
             uintValue--;
             return uintValue;
         case "Int64":
             long longValue = (long)expression.Value;
             longValue--;
             return longValue;
         case "UInt64":
             ulong ulongValue = (ulong)expression.Value;
             ulongValue--;
             return ulongValue;
         case "Char":
             char charValue = (char)expression.Value;
             charValue--;
             return charValue;
         default:
             throw new ArgumentException("Invalid data type for dimension of an array.");
     }
 }
 private string GetExpressionType(LiteralExpression literalExpression)
 {
     if (literalExpression.Value is decimal)
         return "Decimal";
     if (literalExpression.Value is Single)
         return "Float";
     if (literalExpression.Value is byte)
         return "Byte";
     if (literalExpression.Value is sbyte)
         return "SByte";
     if (literalExpression.Value is char)
         return "Char";
     if (literalExpression.Value is double)
         return "Double";
     if (literalExpression.Value is bool)
         return "Boolean";
     if (literalExpression.Value is short)
         return "Short";
     if (literalExpression.Value is int)
         return "Integer";
     if (literalExpression.Value is long)
         return "Long";
     if (literalExpression.Value is ushort)
         return "UShort";
     if (literalExpression.Value is uint)
         return "UInteger";
     if (literalExpression.Value is ulong)
         return "ULong";
     if (literalExpression.Value is string)
         return "String";
     return "Object";
 }
 private void FixCharLiteral(LiteralExpression literal)
 {
     literal.Value = Convert.ToChar(literal.Value);
 }
 private void FixBooleanLiteral(LiteralExpression literal)
 {
     literal.Value = Convert.ToBoolean(literal.Value);
 }
		private void HandleLiteralArgument(TypeReference parameterType, LiteralExpression literalArgument)
		{
			if (parameterType.FullName == currentTypeSystem.Boolean.FullName)
			{
				FixBooleanLiteral(literalArgument);
			}
			else if (parameterType.FullName == currentTypeSystem.Char.FullName)
			{
				FixCharLiteral(literalArgument);
			}
		}
 public override Expression CloneExpressionOnly()
 {
     LiteralExpression result = new LiteralExpression(value, typeSystem, null);
     return result;
 }
        public override Expression Clone()
        {
            LiteralExpression result = new LiteralExpression(value, typeSystem, this.instructions);
			return result;
        }
		private uint GetIndexFromLiteralExpression(LiteralExpression dimention)
		{
			object boxedValue = dimention.Value;

			if (dimention.ExpressionType.FullName == "System.Int32")
			{
				int value = (int)boxedValue;
				if (value < 0)
				{
					throw new IndexOutOfRangeException();
				}
				return (uint)value;
			}
			if (dimention.ExpressionType.FullName == "System.UInt32")
			{
				return (uint)boxedValue;
			}

			if (dimention.ExpressionType.FullName == "System.Int16")
			{
				short value = (short)boxedValue;
				if (value < 0)
				{
					throw new IndexOutOfRangeException();
				}
				return (uint)value;
			}

			if (dimention.ExpressionType.FullName == "System.UInt16")
			{
				return (ushort)boxedValue;
			}

			if (dimention.ExpressionType.FullName == "System.Int8")
			{
				sbyte value = (sbyte)boxedValue;
				if (value < 0)
				{
					throw new IndexOutOfRangeException();
				}
				return (uint)value;
			}

			if (dimention.ExpressionType.FullName == "System.UInt8")
			{
				return (byte)boxedValue;
			}

			if (dimention.ExpressionType.FullName == "System.Int64")
			{
				long value = (long)boxedValue;
				if (value < 0 || value > uint.MaxValue)
				{
					throw new IndexOutOfRangeException();
				}
				return (uint)value;
			}

			if (dimention.ExpressionType.FullName == "System.UInt64")
			{
				ulong value = (ulong)boxedValue;
				if (value < 0 || value > uint.MaxValue)
				{
					throw new IndexOutOfRangeException();
				}
				return (uint)value;
			}
			throw new IndexOutOfRangeException();
		}
 public virtual void VisitLiteralExpression(LiteralExpression node)
 {
 }