﻿/*******************************************************************************
 * You may amend and distribute as you like, but don't remove this header!
 *
 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
 * See http://www.codeplex.com/EPPlus for details.
 *
 * Copyright (C) 2011  Jan Källman
 *
 * This library 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; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library 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.
 *
 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
 *
 * All code and executables are provided "as is" with no warranty either express or implied. 
 * The author accepts no liability for any damage or loss of business that this product may cause.
 *
 * Code change notes:
 * 
 * Author							Change						Date
 * ******************************************************************************
 * Jan Källman		    Initial Release		        2010-01-28
 * Jan Källman		    License changed GPL-->LGPL  2011-12-27
 * Eyal Seagull		    Conditional Formatting      2012-04-03
 *******************************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Data;
using System.Threading;
using OfficeOpenXml.FormulaParsing;
using OfficeOpenXml.Style;
using System.Xml;
using System.Drawing;
using System.Globalization;
using System.Collections;
using OfficeOpenXml.Table;
using System.Text.RegularExpressions;
using System.IO;
using System.Linq;
using OfficeOpenXml.DataValidation;
using OfficeOpenXml.DataValidation.Contracts;
using System.Reflection;
using OfficeOpenXml.Style.XmlAccess;
using System.Security;
using OfficeOpenXml.ConditionalFormatting;
using OfficeOpenXml.ConditionalFormatting.Contracts;
using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
namespace OfficeOpenXml
{	
    /// <summary>
	/// A range of cells 
	/// </summary>
	public class ExcelRangeBase : ExcelAddress, IExcelCell, IDisposable, IEnumerable<ExcelRangeBase>, IEnumerator<ExcelRangeBase>
	{
		/// <summary>
		/// Reference to the worksheet
		/// </summary>
		protected ExcelWorksheet _worksheet;
		internal ExcelWorkbook _workbook = null;
		private delegate void _changeProp(_setValue method, object value);
		private delegate void _setValue(object value, int row, int col);
		private _changeProp _changePropMethod;
		private int _styleID;
        private class CopiedCell
        {
            internal int Row { get; set; }
            internal int Column { get; set; }
            internal object Value { get; set; }
            internal string Type { get; set; }
            internal object Formula { get; set; }
            internal int? StyleID { get; set; }
            internal Uri HyperLink { get; set; }
            internal ExcelComment Comment { get; set; }
            internal Byte Flag { get; set; }
        }
        //private class CopiedFlag
        //{
        //    internal int Row { get; set; }
        //    internal int Column { get; set; }
        //    internal Byte Flag { get; set; }
        //}
        #region Constructors
		internal ExcelRangeBase(ExcelWorksheet xlWorksheet)
		{
			_worksheet = xlWorksheet;
			_ws = _worksheet.Name;
            _workbook = _worksheet.Workbook;
            this.AddressChange += new EventHandler(ExcelRangeBase_AddressChange);
			SetDelegate();
		}

        void ExcelRangeBase_AddressChange(object sender, EventArgs e)
        {
            if (Table != null)
            {
                SetRCFromTable(_workbook._package, null);
            }
            SetDelegate();
        }
		internal ExcelRangeBase(ExcelWorksheet xlWorksheet, string address) :
			base(xlWorksheet == null ? "" : xlWorksheet.Name, address)
		{
			_worksheet = xlWorksheet;
            _workbook = _worksheet.Workbook;
            base.SetRCFromTable(_worksheet._package, null);
			if (string.IsNullOrEmpty(_ws)) _ws = _worksheet == null ? "" : _worksheet.Name;
            this.AddressChange += new EventHandler(ExcelRangeBase_AddressChange);
            SetDelegate();
		}
		internal ExcelRangeBase(ExcelWorkbook wb, ExcelWorksheet xlWorksheet, string address, bool isName) :
			base(xlWorksheet == null ? "" : xlWorksheet.Name, address, isName)
		{
            SetRCFromTable(wb._package, null);
            _worksheet = xlWorksheet;
			_workbook = wb;
			if (string.IsNullOrEmpty(_ws)) _ws = (xlWorksheet == null ? null : xlWorksheet.Name);
            this.AddressChange += new EventHandler(ExcelRangeBase_AddressChange);
            SetDelegate();
		}
        ~ExcelRangeBase()
        {
            //this.AddressChange -= new EventHandler(ExcelRangeBase_AddressChange);
        }
		#endregion
		#region Set Value Delegates
        private void SetDelegate()
		{
			if (_fromRow == -1)
			{
				_changePropMethod = SetUnknown;
			}
			//Single cell
			else if (_fromRow == _toRow && _fromCol == _toCol && Addresses == null)
			{
				_changePropMethod = SetSingle;
			}
			//Range (ex A1:A2)
			else if (Addresses == null)
			{
				_changePropMethod = SetRange;
			}
			//Multi Range (ex A1:A2,C1:C2)
			else
			{
				_changePropMethod = SetMultiRange;
			}
		}
        /// <summary>
		/// We dont know the address yet. Set the delegate first time a property is set.
		/// </summary>
		/// <param name="valueMethod"></param>
		/// <param name="value"></param>
		private void SetUnknown(_setValue valueMethod, object value)
		{
			//Address is not set use, selected range
			if (_fromRow == -1)
			{
				SetToSelectedRange();
			}
			SetDelegate();
			_changePropMethod(valueMethod, value);
		}
		/// <summary>
		/// Set a single cell
		/// </summary>
		/// <param name="valueMethod"></param>
		/// <param name="value"></param>
		private void SetSingle(_setValue valueMethod, object value)
		{
			valueMethod(value, _fromRow, _fromCol);
		}
		/// <summary>
		/// Set a range
		/// </summary>
		/// <param name="valueMethod"></param>
		/// <param name="value"></param>
		private void SetRange(_setValue valueMethod, object value)
		{
			SetValueAddress(this, valueMethod, value);
		}
		/// <summary>
		/// Set a multirange (A1:A2,C1:C2)
		/// </summary>
		/// <param name="valueMethod"></param>
		/// <param name="value"></param>
		private void SetMultiRange(_setValue valueMethod, object value)
		{
			SetValueAddress(this, valueMethod, value);
			foreach (var address in Addresses)
			{
				SetValueAddress(address, valueMethod, value);
			}
		}
		/// <summary>
		/// Set the property for an address
		/// </summary>
		/// <param name="address"></param>
		/// <param name="valueMethod"></param>
		/// <param name="value"></param>
		private void SetValueAddress(ExcelAddress address, _setValue valueMethod, object value)
		{
			IsRangeValid("");
			if (_fromRow == 1 && _fromCol == 1 && _toRow == ExcelPackage.MaxRows && _toCol == ExcelPackage.MaxColumns)  //Full sheet (ex ws.Cells.Value=0). Set value for A1 only to avoid hanging 
			{
				throw (new ArgumentException("Can't reference all cells. Please use the indexer to set the range"));
			}
			else
			{
				for (int col = address.Start.Column; col <= address.End.Column; col++)
				{
					for (int row = address.Start.Row; row <= address.End.Row; row++)
					{
						valueMethod(value, row, col);
					}
				}
			}
		}
		#endregion
		#region Set property methods
		private void Set_StyleID(object value, int row, int col)
		{
            _worksheet._styles.SetValue(row, col, (int)value);
		}
		private void Set_StyleName(object value, int row, int col)
		{
			//_worksheet.Cell(row, col).SetNewStyleName(value.ToString(), _styleID);
            _worksheet._styles.SetValue(row, col, _styleID);
		}
		private void Set_Value(object value, int row, int col)
		{
			//ExcelCell c = _worksheet.Cell(row, col);
            var sfi = _worksheet._formulas.GetValue(row, col);
            if (sfi is int)
            {
                SplitFormulas(_worksheet.Cells[row, col]);                
            }
            if (sfi != null) _worksheet._formulas.SetValue(row, col, string.Empty);
			_worksheet._values.SetValue(row, col, value);
		}
		private void Set_Formula(object value, int row, int col)
		{
			//ExcelCell c = _worksheet.Cell(row, col);
            var f = _worksheet._formulas.GetValue(row, col);
            if (f is int && (int)f >= 0) SplitFormulas(_worksheet.Cells[row, col]);

			string formula = (value == null ? string.Empty : value.ToString());
			if (formula == string.Empty)
			{
                _worksheet._formulas.SetValue(row, col, string.Empty);
			}
			else
			{
				if (formula[0] == '=') value = formula.Substring(1, formula.Length - 1); // remove any starting equalsign.
                _worksheet._formulas.SetValue(row, col, formula);
                _worksheet._values.SetValue(row, col, null);
            }
		}
		/// <summary>
		/// Handles shared formulas
		/// </summary>
		/// <param name="value">The  formula</param>
		/// <param name="address">The address of the formula</param>
		/// <param name="IsArray">If the forumla is an array formula.</param>
		private void Set_SharedFormula(string value, ExcelAddress address, bool IsArray)
		{
			if (_fromRow == 1 && _fromCol == 1 && _toRow == ExcelPackage.MaxRows && _toCol == ExcelPackage.MaxColumns)  //Full sheet (ex ws.Cells.Value=0). Set value for A1 only to avoid hanging 
			{
				throw (new InvalidOperationException("Can't set a formula for the entire worksheet"));
			}
			else if (address.Start.Row == address.End.Row && address.Start.Column == address.End.Column && !IsArray)             //is it really a shared formula? Arrayformulas can be one cell only
			{
				//Nope, single cell. Set the formula
				Set_Formula(value, address.Start.Row, address.Start.Column);
				return;
			}
			//RemoveFormuls(address);
			CheckAndSplitSharedFormula(address);
			ExcelWorksheet.Formulas f = new ExcelWorksheet.Formulas(SourceCodeTokenizer.Default);
			f.Formula = value;
			f.Index = _worksheet.GetMaxShareFunctionIndex(IsArray);
			f.Address = address.FirstAddress;
			f.StartCol = address.Start.Column;
			f.StartRow = address.Start.Row;
			f.IsArray = IsArray;

			_worksheet._sharedFormulas.Add(f.Index, f);
            //_worksheet.Cell(address.Start.Row, address.Start.Column).SharedFormulaID = f.Index;
            //_worksheet.Cell(address.Start.Row, address.Start.Column).Formula = value;

			for (int col = address.Start.Column; col <= address.End.Column; col++)
			{
				for (int row = address.Start.Row; row <= address.End.Row; row++)
				{
					//_worksheet.Cell(row, col).SharedFormulaID = f.Index;
                    _worksheet._formulas.SetValue(row, col, f.Index);
                    _worksheet._values.SetValue(row, col, null);
				}
			}
		}
		private void Set_HyperLink(object value, int row, int col)
		{
			//_worksheet.Cell(row, col).Hyperlink = value as Uri;
            if (value is Uri)
            {
                _worksheet._hyperLinks.SetValue(row, col, (Uri)value);

                if (value is ExcelHyperLink)
                {
                    _worksheet._values.SetValue(row, col, ((ExcelHyperLink)value).Display);
                }
                else
                {
                   _worksheet._values.SetValue(row, col, ((Uri)value).OriginalString);
                }                    
            }
            else
            {
                _worksheet._hyperLinks.SetValue(row, col, (Uri)null);
                _worksheet._values.SetValue(row, col, (Uri)null);
            }
        }
        private void Set_IsArrayFormula(object value, int row, int col)
        {
            _worksheet._flags.SetFlagValue(row, col, (bool)value, CellFlags.ArrayFormula);
        }
        private void Set_IsRichText(object value, int row, int col)
		{
			//_worksheet.Cell(row, col).IsRichText = (bool)value;
            _worksheet._flags.SetFlagValue(row, col, (bool)value, CellFlags.RichText);
		}
		private void Exists_Comment(object value, int row, int col)
		{
			ulong cellID = GetCellID(_worksheet.SheetID, row, col);
			if (_worksheet.Comments._comments.ContainsKey(cellID))
			{
				throw (new InvalidOperationException(string.Format("Cell {0} already contain a comment.", new ExcelCellAddress(row, col).Address)));
			}

		}
		private void Set_Comment(object value, int row, int col)
		{
			string[] v = (string[])value;
			Worksheet.Comments.Add(new ExcelRangeBase(_worksheet, GetAddress(_fromRow, _fromCol)), v[0], v[1]);
			//   _worksheet.Cell(row, col).Comment = comment;
		}
		#endregion
		private void SetToSelectedRange()
		{
			if (_worksheet.View.SelectedRange == "")
			{
				Address = "A1";
			}
			else
			{
				Address = _worksheet.View.SelectedRange;
			}
		}
		private void IsRangeValid(string type)
		{
			if (_fromRow <= 0)
			{
				if (_address == "")
				{
					SetToSelectedRange();
				}
				else
				{
					if (type == "")
					{
						throw (new InvalidOperationException(string.Format("Range is not valid for this operation: {0}", _address)));
					}
					else
					{
						throw (new InvalidOperationException(string.Format("Range is not valid for {0} : {1}", type, _address)));
					}
				}
			}
		}
		#region Public Properties
		/// <summary>
		/// The styleobject for the range.
		/// </summary>
		public ExcelStyle Style
		{
			get
			{
				IsRangeValid("styling");
                int s=0;
                if(!_worksheet._styles.Exists(_fromRow,_fromCol, ref s)) //Cell exists
                {
                    if(!_worksheet._styles.Exists(_fromRow,0, ref s)) //No, check Row style
                    {
                        var c = Worksheet.GetColumn(_fromCol);
                        if (c == null)
                        {
                            s = 0;
                        }
                        else
                        {
                            s = c.StyleID;   
                        }                        
                    }
                }
				return _worksheet.Workbook.Styles.GetStyleObject(s, _worksheet.PositionID, Address);
			}
		}
		/// <summary>
		/// The named style
		/// </summary>
		public string StyleName
		{
			get
			{
				IsRangeValid("styling");
				int  xfId;
                if (_fromRow == 1 && _toRow == ExcelPackage.MaxRows)
                {
                    xfId=GetColumnStyle(_fromCol);
                }
                else if (_fromCol == 1 && _toCol == ExcelPackage.MaxColumns)
                {
                    xfId = 0;
                    if (!_worksheet._styles.Exists(_fromRow, 0, ref xfId))
                    {
                        xfId = GetColumnStyle(_fromCol);
                    }
                }
                else
                {
                    xfId = 0;
                    if(!_worksheet._styles.Exists(_fromRow, _fromCol, ref xfId))
                    {
                        if (!_worksheet._styles.Exists(_fromRow, 0, ref xfId))
                        {
                            xfId = GetColumnStyle(_fromCol);
                        }
                    }
                }
                int nsID;
                if (xfId <= 0)
                {
                    nsID=Style.Styles.CellXfs[0].XfId;
                }
                else
                {
                    nsID=Style.Styles.CellXfs[xfId].XfId;
                }
                foreach (var ns in Style.Styles.NamedStyles)
                {
                    if (ns.StyleXfId == nsID)
                    {
                        return ns.Name;
                    }
                }
                
                return "";
			}
			set
			{
				_styleID = _worksheet.Workbook.Styles.GetStyleIdFromName(value);
                int col = _fromCol;
                if (_fromRow == 1 && _toRow == ExcelPackage.MaxRows)    //Full column
				{
					ExcelColumn column;
					//Get the startcolumn
					//ulong colID = ExcelColumn.GetColumnID(_worksheet.SheetID, column);
                    var c = _worksheet.GetValue(0, _fromCol);
                    if (c==null)
					{
                        column = _worksheet.Column(_fromCol);
                        //if (_worksheet._values.PrevCell(ref row, ref col))
                        //{
                        //    var prevCol = (ExcelColumn)_worksheet._values.GetValue(row, col);
                        //    column = prevCol.Clone(_worksheet, column);
                        //    prevCol.ColumnMax = column - 1;
                        //}
					}
					else
					{
                        column = (ExcelColumn)c;
					}

                    column.StyleName = value;
                    column.StyleID = _styleID;

                    //var index = _worksheet._columns.IndexOf(colID);
                    var cols = new CellsStoreEnumerator<object>(_worksheet._values, 0, _fromCol + 1, 0, _toCol);
                    if (cols.Next())
                    {
                        col = _fromCol;
                        while (column.ColumnMin <= _toCol)
                        {
                            if (column.ColumnMax > _toCol)
                            {
                                var newCol = _worksheet.CopyColumn(column, _toCol + 1, column.ColumnMax);
                                column.ColumnMax = _toCol;
                            }

                            column._styleName = value;
                            column.StyleID = _styleID;

                            if (cols.Value == null)
                            {
                                break;
                            }
                            else
                            {
                                var nextCol = (ExcelColumn)cols.Value;
                                if(column.ColumnMax < nextCol.ColumnMax-1)
                                {
                                    column.ColumnMax = nextCol.ColumnMax - 1;
                                }
                                column = nextCol;
                                cols.Next();
                            }
                        }
                    }
                    if (column.ColumnMax < _toCol)
                    {
                        column.ColumnMax = _toCol;
                    }
                    //if (column.ColumnMin == column)
                    //{
                    //    column.ColumnMax = _toCol;
                    //}
                    //else if (column._columnMax < _toCol)
                    //{
                    //    var newCol = _worksheet.Column(column._columnMax + 1) as ExcelColumn;
                    //    newCol._columnMax = _toCol;

                    //    newCol._styleID = _styleID;
                    //    newCol._styleName = value;
                    //}
                    if (_fromCol == 1 && _toCol == ExcelPackage.MaxColumns) //FullRow
                    {
                        var rows = new CellsStoreEnumerator<object>(_worksheet._values, 1, 0, ExcelPackage.MaxRows, 0);
                        rows.Next();
                        while(rows.Value!=null)
                        {
                            _worksheet._styles.SetValue(rows.Row, 0, _styleID);
                            if (!rows.Next())
                            {
                                break;
                            }
                        }
                    }
				}
                else if (_fromCol == 1 && _toCol == ExcelPackage.MaxColumns) //FullRow
                {
                    for (int r = _fromRow; r <= _toRow; r++)
                    {
                        _worksheet.Row(r)._styleName = value;
                        _worksheet.Row(r).StyleID = _styleID;
                    }
                }

                if (!((_fromRow == 1 && _toRow == ExcelPackage.MaxRows) || (_fromCol == 1 && _toCol == ExcelPackage.MaxColumns))) //Cell specific
                {
                    for (int c = _fromCol; c <= _toCol; c++)
                    {
                        for (int r = _fromRow; r <= _toRow; r++)
                        {
                            _worksheet._styles.SetValue(r, c, _styleID);
                        }
                    }
                }
                else //Only set name on created cells. (uncreated cells is set on full row or full column).
                {
                    var cells = new CellsStoreEnumerator<object>(_worksheet._values, _fromRow, _fromCol, _toRow, _toCol);
                    while (cells.Next())
                    {
                        _worksheet._styles.SetValue(cells.Row, cells.Column, _styleID);
                    }
                }
                //_changePropMethod(Set_StyleName, value);
			}
		}

        private int GetColumnStyle(int col)
        {
            object c=null;
            if (_worksheet._values.Exists(0, col, ref c))
            {
                return (c as ExcelColumn).StyleID;
            }
            else
            {
                int row = 0;
                if (_worksheet._values.PrevCell(ref row, ref col))
                {
                    var column=_worksheet._values.GetValue(row,col) as ExcelColumn;
                    if(column.ColumnMax>=col)
                    {
                        return _worksheet._styles.GetValue(row, col);
                    }
                }
            }
            return 0;
        }
		/// <summary>
		/// The style ID. 
		/// It is not recomended to use this one. Use Named styles as an alternative.
		/// If you do, make sure that you use the Style.UpdateXml() method to update any new styles added to the workbook.
		/// </summary>
		public int StyleID
		{
			get
			{
                int s=0;
                if(!_worksheet._styles.Exists(_fromRow, _fromCol, ref s))
                {
                    if (!_worksheet._styles.Exists(_fromRow, 0, ref s))
                    {
                        s = _worksheet._styles.GetValue(0, _fromCol);
                    }
                }
                return s;
			}
			set
			{
				_changePropMethod(Set_StyleID, value);
			}
		}
		/// <summary>
		/// Set the range to a specific value
		/// </summary>
		public object Value
		{
			get
			{
				if (IsName)
				{
					if (_worksheet == null)
					{
						return _workbook._names[_address].NameValue;
					}
					else
					{
						return _worksheet.Names[_address].NameValue; 
					}
				}
				else
				{
					if (_fromRow == _toRow && _fromCol == _toCol)
					{
						return _worksheet.GetValue(_fromRow, _fromCol);
					}
					else
					{
						return GetValueArray();
					}
				}
			}
			set
			{
				if (IsName)
				{
					if (_worksheet == null)
					{
						_workbook._names[_address].NameValue = value;
					}
					else
					{
						_worksheet.Names[_address].NameValue = value;
					}
				}
				else
				{
					_changePropMethod(Set_Value, value);
				}
			}
		}

        private bool IsInfinityValue(object value)
        {
            double? valueAsDouble = value as double?;

            if(valueAsDouble.HasValue && 
                (double.IsNegativeInfinity(valueAsDouble.Value) || double.IsPositiveInfinity(valueAsDouble.Value)))
            {
                return true;
            }

            return false;
        }

		private object GetValueArray()
		{
			ExcelAddressBase addr;
			if (_fromRow == 1 && _fromCol == 1 && _toRow == ExcelPackage.MaxRows && _toCol == ExcelPackage.MaxColumns)
			{
				addr = _worksheet.Dimension;
				if (addr == null) return null;
			}
			else
			{
				addr = this;
			}
			object[,] v = new object[addr._toRow - addr._fromRow + 1, addr._toCol - addr._fromCol + 1];

			for (int col = addr._fromCol; col <= addr._toCol; col++)
			{
				for (int row = addr._fromRow; row <= addr._toRow; row++)
				{
					if (_worksheet._values.Exists(row,col))
					{
                        if (_worksheet._flags.GetFlagValue(row, col, CellFlags.RichText))
						{
							v[row - addr._fromRow, col - addr._fromCol] = GetRichText(row, col).Text;
						}
						else
						{
							v[row - addr._fromRow, col - addr._fromCol] = _worksheet._values.GetValue(row, col);
						}
					}
				}
			}
			return v;
		}
		private ExcelAddressBase GetAddressDim(ExcelRangeBase addr)
		{
			int fromRow, fromCol, toRow, toCol;
			var d = _worksheet.Dimension;
			fromRow = addr._fromRow < d._fromRow ? d._fromRow : addr._fromRow;
			fromCol = addr._fromCol < d._fromCol ? d._fromCol : addr._fromCol;

			toRow = addr._toRow > d._toRow ? d._toRow : addr._toRow;
			toCol = addr._toCol > d._toCol ? d._toCol : addr._toCol;

			if (addr._fromCol == fromRow && addr._fromCol == addr._fromCol && addr._toRow == toRow && addr._toCol == _toCol)
			{
				return addr;
			}
			else
			{
				if (_fromRow > _toRow || _fromCol > _toCol)
				{
					return null;
				}
				else
				{
					return new ExcelAddressBase(fromRow, fromCol, toRow, toCol);
				}
			}
		}

		private object GetSingleValue()
		{
			if (IsRichText)
			{
				return RichText.Text;
			}
			else
			{
				return _worksheet._values.GetValue(_fromRow, _fromCol);
			}
		}
		/// <summary>
		/// Returns the formatted value.
		/// </summary>
		public string Text
		{
			get
			{
				return GetFormattedText(false);
			}
		}
		/// <summary>
		/// Set the column width from the content of the range. The minimum width is the value of the ExcelWorksheet.defaultColumnWidth property.
		/// Note: Cells containing formulas are ignored since EPPlus don't have a calculation engine.
		/// Wrapped and merged cells are also ignored.
		/// </summary>
		public void AutoFitColumns()
		{
			AutoFitColumns(_worksheet.DefaultColWidth);
		}

		/// <summary>
		/// Set the column width from the content of the range.
		/// Note: Cells containing formulas are ignored if no calculation is made.
		///       Wrapped and merged cells are also ignored.
		/// </summary>
        /// <remarks>This method will not work if you run in an environment that does not support GDI</remarks>
		/// <param name="MinimumWidth">Minimum column width</param>
		public void AutoFitColumns(double MinimumWidth)
		{
		    AutoFitColumns(MinimumWidth, double.MaxValue);
		}

	    /// <summary>
	    /// Set the column width from the content of the range.
        /// Note: Cells containing formulas are ignored if no calculation is made.
        ///       Wrapped and merged cells are also ignored.
	    /// </summary>
	    /// <param name="MinimumWidth">Minimum column width</param>
	    /// <param name="MaximumWidth">Maximum column width</param>
	    public void AutoFitColumns(double MinimumWidth, double MaximumWidth)
		{
            if (_worksheet.Dimension == null)
            {
                return;
            }
            if (_fromCol < 1 || _fromRow < 1)
			{
				SetToSelectedRange();
			}
            var fontCache = new Dictionary<int, Font>();

	        bool doAdjust = _worksheet._package.DoAdjustDrawings;
			_worksheet._package.DoAdjustDrawings = false;
			var drawWidths = _worksheet.Drawings.GetDrawingWidths();

			var fromCol = _fromCol > _worksheet.Dimension._fromCol ? _fromCol : _worksheet.Dimension._fromCol;
			var toCol = _toCol < _worksheet.Dimension._toCol ? _toCol : _worksheet.Dimension._toCol;
			if (Addresses == null)
			{
				SetMinWidth(MinimumWidth, fromCol, toCol);
			}
			else
			{
				foreach (var addr in Addresses)
				{
					fromCol = addr._fromCol > _worksheet.Dimension._fromCol ? addr._fromCol : _worksheet.Dimension._fromCol;
					toCol = addr._toCol < _worksheet.Dimension._toCol ? addr._toCol : _worksheet.Dimension._toCol;
                    SetMinWidth(MinimumWidth, fromCol, toCol);
                }
			}

			//Get any autofilter to widen these columns
			var afAddr = new List<ExcelAddressBase>();
			if (_worksheet.AutoFilterAddress != null)
			{
				afAddr.Add(new ExcelAddressBase(    _worksheet.AutoFilterAddress._fromRow,
													_worksheet.AutoFilterAddress._fromCol,
													_worksheet.AutoFilterAddress._fromRow,
													_worksheet.AutoFilterAddress._toCol));
				afAddr[afAddr.Count - 1]._ws = WorkSheet;
			}
			foreach (var tbl in _worksheet.Tables)
			{
				if (tbl.AutoFilterAddress != null)
				{
					afAddr.Add(new ExcelAddressBase(tbl.AutoFilterAddress._fromRow,
																			tbl.AutoFilterAddress._fromCol,
																			tbl.AutoFilterAddress._fromRow,
																			tbl.AutoFilterAddress._toCol));
					afAddr[afAddr.Count - 1]._ws = WorkSheet;
				}
			}

			var styles = _worksheet.Workbook.Styles;
			var nf = styles.Fonts[styles.CellXfs[0].FontId];
			var fs = FontStyle.Regular;
			if (nf.Bold) fs |= FontStyle.Bold;
			if (nf.UnderLine) fs |= FontStyle.Underline;
			if (nf.Italic) fs |= FontStyle.Italic;
			if (nf.Strike) fs |= FontStyle.Strikeout;
			var nfont = new Font(nf.Name, nf.Size, fs);
            
			using (var b = new Bitmap(1, 1))
			{
				using (var g = Graphics.FromImage(b))
				{
                    g.PageUnit = GraphicsUnit.Pixel;
                    var normalSize = (float)Math.Truncate(g.MeasureString("00", nfont, 10000, StringFormat.GenericTypographic).Width - g.MeasureString("0", nfont, 10000, StringFormat.GenericTypographic).Width);
					foreach (var cell in this)
					{
						if (cell.Merge == true || cell.Style.WrapText) continue;
						var fntID = styles.CellXfs[cell.StyleID].FontId;
					    Font f;
					    if (fontCache.ContainsKey(fntID))
						{
							f = fontCache[fntID];
						}
						else
						{
							var fnt = styles.Fonts[fntID];
							fs = FontStyle.Regular;
							if (fnt.Bold) fs |= FontStyle.Bold;
							if (fnt.UnderLine) fs |= FontStyle.Underline;
							if (fnt.Italic) fs |= FontStyle.Italic;
							if (fnt.Strike) fs |= FontStyle.Strikeout;
							f = new Font(fnt.Name, fnt.Size, fs);
							fontCache.Add(fntID, f);
						}

						//Truncate(({pixels}-5)/{Maximum Digit Width} * 100+0.5)/100

                        var size = g.MeasureString(cell.TextForWidth, f, 10000, StringFormat.GenericTypographic);
                        double width;
                        double r = styles.CellXfs[cell.StyleID].TextRotation;
                        if (r <= 0 )
                        {
                            width = (size.Width + 5) / normalSize;
                        }
                        else
                        {
                            r = (r <= 90 ? r : r - 90);
                            width = (((size.Width - size.Height) * Math.Abs(System.Math.Cos(System.Math.PI * r / 180.0)) + size.Height) + 5) / normalSize;
                        }

						foreach (var a in afAddr)
						{
							if (a.Collide(cell) != eAddressCollition.No)
							{
								width += 2.25;
								break;
							}
						}

						if (width > _worksheet.Column(cell._fromCol).Width)
						{
							_worksheet.Column(cell._fromCol).Width = width > MaximumWidth ? MaximumWidth : width;
						}
					}
				}
			}
			_worksheet.Drawings.AdjustWidth(drawWidths);
			_worksheet._package.DoAdjustDrawings = doAdjust;
		}

        private void SetMinWidth(double minimumWidth, int fromCol, int toCol)
        {
            var iterator = new CellsStoreEnumerator<object>(_worksheet._values, 0, fromCol, 0, toCol);
            var prevCol = fromCol;
            foreach (ExcelColumn col in iterator)
            {
                col.Width = minimumWidth;
                if (_worksheet.DefaultColWidth > minimumWidth && col.ColumnMin > prevCol)
                {
                    var newCol = _worksheet.Column(prevCol);
                    newCol.ColumnMax = col.ColumnMin - 1;
                    newCol.Width = minimumWidth;
                }
                prevCol = col.ColumnMax + 1;
            }
            if (_worksheet.DefaultColWidth > minimumWidth && prevCol<toCol)
            {
                var newCol = _worksheet.Column(prevCol);
                newCol.ColumnMax = toCol;
                newCol.Width = minimumWidth;
            }
        }

        internal string TextForWidth
		{
			get
			{
				return GetFormattedText(true);
			}
		}
		private string GetFormattedText(bool forWidthCalc)
		{
			object v = Value;
			if (v == null) return "";
			var styles = Worksheet.Workbook.Styles;
			var nfID = styles.CellXfs[StyleID].NumberFormatId;
			ExcelNumberFormatXml.ExcelFormatTranslator nf = null;
			for (int i = 0; i < styles.NumberFormats.Count; i++)
			{
				if (nfID == styles.NumberFormats[i].NumFmtId)
				{
					nf = styles.NumberFormats[i].FormatTranslator;
					break;
				}
			}

			string format, textFormat;
			if (forWidthCalc)
			{
				format = nf.NetFormatForWidth;
				textFormat = nf.NetTextFormatForWidth;
			}
			else
			{
				format = nf.NetFormat;
				textFormat = nf.NetTextFormat;
			}

            return FormatValue(v, nf, format, textFormat);
		}

        internal static string FormatValue(object v, ExcelNumberFormatXml.ExcelFormatTranslator nf, string format, string textFormat)
        {
			if (v is decimal || v.GetType().IsPrimitive)
			{
				double d;
				try
				{
					d = Convert.ToDouble(v);
				}
				catch
				{
					return "";
				}

				if (nf.DataType == ExcelNumberFormatXml.eFormatType.Number)
				{
					if (string.IsNullOrEmpty(nf.FractionFormat))
					{
						return d.ToString(format, nf.Culture);
					}
					else
					{
						return nf.FormatFraction(d);
					}
				}
				else if (nf.DataType == ExcelNumberFormatXml.eFormatType.DateTime)
				{
					var date = DateTime.FromOADate(d);
					return date.ToString(format, nf.Culture);
				}
			}
			else if (v is DateTime)
			{
				if (nf.DataType == ExcelNumberFormatXml.eFormatType.DateTime)
				{
					return ((DateTime)v).ToString(format, nf.Culture);
				}
				else
				{
					double d = ((DateTime)v).ToOADate();
					if (string.IsNullOrEmpty(nf.FractionFormat))
					{
						return d.ToString(format, nf.Culture);
					}
					else
					{
						return nf.FormatFraction(d);
					}
				}
			}
			else if (v is TimeSpan)
			{
				if (nf.DataType == ExcelNumberFormatXml.eFormatType.DateTime)
				{
					return new DateTime(((TimeSpan)v).Ticks).ToString(format, nf.Culture);
				}
				else
				{
					double d = (new DateTime(((TimeSpan)v).Ticks)).ToOADate();
					if (string.IsNullOrEmpty(nf.FractionFormat))
					{
						return d.ToString(format, nf.Culture);
					}
					else
					{
						return nf.FormatFraction(d);
					}
				}
			}
			else
			{
				if (textFormat == "")
				{
					return v.ToString();
				}
				else
				{
					return string.Format(textFormat, v);
				}
			}
			return v.ToString();
}
		/// <summary>
		/// Gets or sets a formula for a range.
		/// </summary>
		public string Formula
		{
			get
			{
				if (IsName)
				{
					if (_worksheet == null)
					{
						return _workbook._names[_address].NameFormula;
					}
					else
					{
						return _worksheet.Names[_address].NameFormula;
					}
				}
				else
				{
					return _worksheet.GetFormula(_fromRow, _fromCol);                    
				}
			}
			set
			{
				if (IsName)
				{
					if (_worksheet == null)
					{
						_workbook._names[_address].NameFormula = value;
					}
					else
					{
						_worksheet.Names[_address].NameFormula = value;
					}
				}
				else
				{
					if(value==null || value.Trim()=="")
                    {
                        //Set the cells to null
                        Value = null;
                    }                    
                    else if (_fromRow == _toRow && _fromCol == _toCol)
					{
						Set_Formula(value, _fromRow, _fromCol);
					}
					else
					{
						Set_SharedFormula(value, this, false);
						if (Addresses != null)
						{
							foreach (var address in Addresses)
							{
								Set_SharedFormula(value, address, false);
							}
						}
					}
				}
			}
		}
		/// <summary>
		/// Gets or Set a formula in R1C1 format.
		/// </summary>
		public string FormulaR1C1
		{
			get
			{
				IsRangeValid("FormulaR1C1");
				return _worksheet.GetFormulaR1C1(_fromRow, _fromCol);
			}
			set
			{
				IsRangeValid("FormulaR1C1");
                if (value.Length > 0 && value[0] == '=') value = value.Substring(1, value.Length - 1); // remove any starting equalsign.

                if (value == null || value.Trim() == "")
                {
                    //Set the cells to null
                    _worksheet.Cells[ExcelCellBase.TranslateFromR1C1(value, _fromRow, _fromCol)].Value = null;    
                }
				else if (Addresses == null)
				{
					Set_SharedFormula(ExcelCellBase.TranslateFromR1C1(value, _fromRow, _fromCol), this, false);
				}
				else
				{
					Set_SharedFormula(ExcelCellBase.TranslateFromR1C1(value, _fromRow, _fromCol), new ExcelAddress(WorkSheet, FirstAddress), false);
					foreach (var address in Addresses)
					{
						Set_SharedFormula(ExcelCellBase.TranslateFromR1C1(value, address.Start.Row, address.Start.Column), address, false);
					}
				}
			}
		}
        public string ArrayFormulaAddress
        {
            get
            {
                IsRangeValid("FormulaR1C1");
                return _worksheet.GetArrayFormulaAddress(_fromRow, _fromCol);
            }
        }
        /// <summary>
        /// Set the hyperlink property for a range of cells
        /// </summary>
        public Uri Hyperlink
		{
			get
			{
				IsRangeValid("formulaR1C1");
				return _worksheet._hyperLinks.GetValue(_fromRow, _fromCol);
			}
			set
			{
				_changePropMethod(Set_HyperLink, value);
			}
		}
		/// <summary>
		/// If the cells in the range are merged.
		/// </summary>
		public bool Merge
		{
			get
			{
				IsRangeValid("merging");
				for (int col = _fromCol; col <= _toCol; col++)
				{
					for (int row = _fromRow; row <= _toRow; row++)
					{
                        if(_worksheet.MergedCells[row, col]==null)
                        {
                            return false;
                        }
                        //if (!_worksheet._flags.GetFlagValue(row, col, CellFlags.Merged))
                        //{
                        //    return false;
                        //}
					}
				}
				return true;
			}
			set
			{
				IsRangeValid("merging");
				//SetMerge(value, FirstAddress);
			    if (value)
			    {
			        _worksheet.MergedCells.Add(new ExcelAddressBase(FirstAddress), true);
			        if (Addresses != null)
			        {
			            foreach (var address in Addresses)
			            {
			                _worksheet.MergedCells.Add(address, true);
			                //SetMerge(value, address._address);
			            }
			        }
			    }
			    else
			    {
			        _worksheet.MergedCells.Clear(this);
                    if (Addresses != null)
			        {
			            foreach (var address in Addresses)
			            {
                            _worksheet.MergedCells.Clear(address); ;
			            }
			        }
			        
			    }
			}
		}

        //private void SetMerge(bool value, string address)
        //{
        //    if (!value)
        //    {
        //        if (_worksheet.MergedCells.List.Contains(address))
        //        {
        //            SetCellMerge(false, address);
        //            _worksheet.MergedCells.List.Remove(address);
        //        }
        //        else if (!CheckMergeDiff(false, address))
        //        {
        //            throw (new Exception("Range is not fully merged.Specify the exact range"));
        //        }
        //    }
        //    else
        //    {
        //        if (CheckMergeDiff(false, address))
        //        {
        //            SetCellMerge(true, address);
        //            _worksheet.MergedCells.List.Add(address);
        //        }
        //        else
        //        {
        //            if (!_worksheet.MergedCells.List.Contains(address))
        //            {
        //                throw (new Exception("Cells are already merged"));
        //            }
        //        }
        //    }
        //}
		/// <summary>
		/// Set an autofilter for the range
		/// </summary>
		public bool AutoFilter
		{
			get
			{
				IsRangeValid("autofilter");
				ExcelAddressBase address = _worksheet.AutoFilterAddress;
				if (address == null) return false;
				if (_fromRow >= address.Start.Row
						&&
						_toRow <= address.End.Row
						&&
						_fromCol >= address.Start.Column
						&&
						_toCol <= address.End.Column)
				{
					return true;
				}
				return false;
			}
			set
			{
				IsRangeValid("autofilter");
				_worksheet.AutoFilterAddress = this;
				if (_worksheet.Names.ContainsKey("_xlnm._FilterDatabase"))
				{
					_worksheet.Names.Remove("_xlnm._FilterDatabase");
				}
				var result = _worksheet.Names.Add("_xlnm._FilterDatabase", this);
				result.IsNameHidden = true;
			}
		}
		/// <summary>
		/// If the value is in richtext format.
		/// </summary>
		public bool IsRichText
		{
			get
			{
				IsRangeValid("richtext");
				return _worksheet._flags.GetFlagValue(_fromRow, _fromCol,CellFlags.RichText);
			}
			set
			{
				_changePropMethod(Set_IsRichText, value);
			}
		}
		/// <summary>
		/// Is the range a part of an Arrayformula
		/// </summary>
		public bool IsArrayFormula
		{
			get
			{
				IsRangeValid("arrayformulas");
                return _worksheet._flags.GetFlagValue(_fromRow, _fromCol, CellFlags.ArrayFormula);
			}
            set
            {
                _changePropMethod(Set_IsArrayFormula, value);
            }
        }
		ExcelRichTextCollection _rtc = null;
		/// <summary>
		/// Cell value is richtext formatted. 
		/// Richtext-property only apply to the left-top cell of the range.
		/// </summary>
		public ExcelRichTextCollection RichText
		{
			get
			{
				IsRangeValid("richtext");
				if (_rtc == null)
				{
					_rtc = GetRichText(_fromRow, _fromCol);
				}
				return _rtc;
			}
		}

		private ExcelRichTextCollection GetRichText(int row, int col)
		{
			XmlDocument xml = new XmlDocument();
            var v = _worksheet._values.GetValue(row, col);
            var isRt = _worksheet._flags.GetFlagValue(row, col, CellFlags.RichText);
            if (v != null)
			{
				if (isRt)
				{
                    XmlHelper.LoadXmlSafe(xml, "<d:si xmlns:d=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" >" + v.ToString() + "</d:si>", Encoding.UTF8);
				}
				else
				{
					xml.LoadXml("<d:si xmlns:d=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ><d:r><d:t>" + SecurityElement.Escape(v.ToString()) + "</d:t></d:r></d:si>");
				}
			}
			else
			{
				xml.LoadXml("<d:si xmlns:d=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" />");
			}
			var rtc = new ExcelRichTextCollection(_worksheet.NameSpaceManager, xml.SelectSingleNode("d:si", _worksheet.NameSpaceManager), this);
			return rtc;
		}
		/// <summary>
		/// returns the comment object of the first cell in the range
		/// </summary>
		public ExcelComment Comment
		{
			get
			{
				IsRangeValid("comments");
				ulong cellID = GetCellID(_worksheet.SheetID, _fromRow, _fromCol);
				if (_worksheet.Comments._comments.ContainsKey(cellID))
				{
					return _worksheet._comments._comments[cellID] as ExcelComment;
				}
				return null;
			}
		}
		/// <summary>
		/// WorkSheet object 
		/// </summary>
		public ExcelWorksheet Worksheet
		{
			get
			{
				return _worksheet;
			}
		}
		/// <summary>
		/// Address including sheetname
		/// </summary>
		public string FullAddress
		{
			get
			{
				string fullAddress = GetFullAddress(_worksheet.Name, _address);
				if (Addresses != null)
				{
					foreach (var a in Addresses)
					{
						fullAddress += "," + GetFullAddress(_worksheet.Name, a.Address); ;
					}
				}
				return fullAddress;
			}
		}
		/// <summary>
		/// Address including sheetname
		/// </summary>
		public string FullAddressAbsolute
		{
			get
			{
				string wbwsRef = string.IsNullOrEmpty(base._wb) ? base._ws : "[" + base._wb.Replace("'", "''") + "]" + _ws;
				string fullAddress = GetFullAddress(wbwsRef, GetAddress(_fromRow, _fromCol, _toRow, _toCol, true));
				if (Addresses != null)
				{
					foreach (var a in Addresses)
					{
						fullAddress += "," + GetFullAddress(wbwsRef, GetAddress(a.Start.Row, a.Start.Column, a.End.Row, a.End.Column, true)); ;
					}
				}
				return fullAddress;
			}
		}
        /// <summary>
        /// Address including sheetname
        /// </summary>
        internal string FullAddressAbsoluteNoFullRowCol
        {
            get
            {
                string wbwsRef = string.IsNullOrEmpty(base._wb) ? base._ws : "[" + base._wb.Replace("'", "''") + "]" + _ws;
                string fullAddress = GetFullAddress(wbwsRef, GetAddress(_fromRow, _fromCol, _toRow, _toCol, true), false);
                if (Addresses != null)
                {
                    foreach (var a in Addresses)
                    {
                        fullAddress += "," + GetFullAddress(wbwsRef, GetAddress(a.Start.Row, a.Start.Column, a.End.Row, a.End.Column, true),false); ;
                    }
                }
                return fullAddress;
            }
        }
		#endregion
		#region Private Methods
        ///// <summary>
        ///// Check if the range is partly merged
        ///// </summary>
        ///// <param name="startValue">the starting value</param>
        ///// <param name="address">the address</param>
        ///// <returns></returns>
        //private bool CheckMergeDiff(bool startValue, string address)
        //{
        //    ExcelAddress a = new ExcelAddress(address);
        //    for (int col = a.column; col <= a._toCol; col++)
        //    {
        //        for (int row = a._fromRow; row <= a._toRow; row++)
        //        {
        //            if (_worksheet._flags.GetFlagValue(row, col, CellFlags.Merged) != startValue)
        //            {
        //                return false;
        //            }
        //        }
        //    }
        //    return true;
        //}
        ///// <summary>
        ///// Set the merge flag for the range
        ///// </summary>
        ///// <param name="value"></param>
        ///// <param name="address"></param>
        //internal void SetCellMerge(bool value, string address)
        //{
        //    ExcelAddress a = new ExcelAddress(address);
        //    for (int col = a.column; col <= a._toCol; col++)
        //    {
        //        for (int row = a._fromRow; row <= a._toRow; row++)
        //        {
        //            _worksheet._flags.SetFlagValue(row, col,value,CellFlags.Merged);
        //        }
        //    }
        //}
		/// <summary>
		/// Set the value without altering the richtext property
		/// </summary>
		/// <param name="value">the value</param>
		internal void SetValueRichText(object value)
		{
			if (_fromRow == 1 && _fromCol == 1 && _toRow == ExcelPackage.MaxRows && _toCol == ExcelPackage.MaxColumns)  //Full sheet (ex ws.Cells.Value=0). Set value for A1 only to avoid hanging 
			{
				//_worksheet.Cell(1, 1).SetValueRichText(value);
                SetValue(value, 1, 1);
			}
			else
			{
                //for (int col = _fromCol; col <= _toCol; col++)
                //{
                //    for (int row = _fromRow; row <= _toRow; row++)
                //    {
						//_worksheet.Cell(row, col).SetValueRichText(value);
                        SetValue(value, _fromRow,_fromCol);
                    //}
				//}
			}
		}

        private void SetValue(object value, int row, int col)
        {
            _worksheet.SetValue(row, col, value);
           // if (value is string) _worksheet._types.SetValue(row, col, "S"); else _worksheet._types.SetValue(row, col, "");
            _worksheet._formulas.SetValue(row, col, "");
        }
		/// <summary>
		/// Removes a shared formula
		/// </summary>
        //private void RemoveFormuls(ExcelAddress address)
        //{
        //    List<int> removed = new List<int>();
        //    int fFromRow, fFromCol, fToRow, fToCol;
        //    foreach (int index in _worksheet._sharedFormulas.Keys)
        //    {
        //        ExcelWorksheet.Formulas f = _worksheet._sharedFormulas[index];
        //        ExcelCellBase.GetRowColFromAddress(f.Address, out fFromRow, out fFromCol, out fToRow, out fToCol);
        //        if (((fFromCol >= address.Start.Column && fFromCol <= address.End.Column) ||
        //             (fToCol >= address.Start.Column && fToCol <= address.End.Column)) &&
        //             ((fFromRow >= address.Start.Row && fFromRow <= address.End.Row) ||
        //             (fToRow >= address.Start.Row && fToRow <= address.End.Row)))
        //        {
        //            for (int col = fFromCol; col <= fToCol; col++)
        //            {
        //                for (int row = fFromRow; row <= fToRow; row++)
        //                {
        //                    _worksheet._formulas.SetValue(row, col, int.MinValue);
        //                }
        //            }
        //            removed.Add(index);
        //        }
        //    }
        //    foreach (int index in removed)
        //    {
        //        _worksheet._sharedFormulas.Remove(index);
        //    }
        //}
		internal void SetSharedFormulaID(int id)
		{
			for (int col = _fromCol; col <= _toCol; col++)
			{
				for (int row = _fromRow; row <= _toRow; row++)
				{
                    _worksheet._formulas.SetValue(row, col, id);
				}
			}
		}
		private void CheckAndSplitSharedFormula(ExcelAddressBase address)
		{
            for (int col = address._fromCol; col <= address._toCol; col++)
			{
                for (int row = address._fromRow; row <= address._toRow; row++)
				{
                    var f = _worksheet._formulas.GetValue(row, col);
                    if (f is int && (int)f >= 0)
					{
						SplitFormulas(address);
						return;
					}
				}
			}
		}

		private void SplitFormulas(ExcelAddressBase address)
		{
			List<int> formulas = new List<int>();
            for (int col = address._fromCol; col <= address._toCol; col++)
			{
                for (int row = address._fromRow; row <= address._toRow; row++)
				{
					var f = _worksheet._formulas.GetValue(row, col);
                    if (f is int)
                    {
                        int id = (int)f;
                        if (id >= 0 && !formulas.Contains(id))
                        {
                            if (_worksheet._sharedFormulas[id].IsArray &&
                                    Collide(_worksheet.Cells[_worksheet._sharedFormulas[id].Address]) == eAddressCollition.Partly) // If the formula is an array formula and its on the inside the overwriting range throw an exception
                            {
                                throw (new InvalidOperationException("Can not overwrite a part of an array-formula"));
                            }
                            formulas.Add(id);
                        }
                    }                    
				}
			}

			foreach (int ix in formulas)
			{
                SplitFormula(address, ix);
			}
        
            ////Clear any formula references inside the refered range
            //_worksheet._formulas.Clear(address._fromRow, address._toRow, address._toRow - address._fromRow + 1, address._toCol - address.column + 1);
        }

		private void SplitFormula(ExcelAddressBase address, int ix)
		{
			var f = _worksheet._sharedFormulas[ix];
			var fRange = _worksheet.Cells[f.Address];
            var collide = address.Collide(fRange);

            //The formula is inside the currenct range, remove it
			if (collide == eAddressCollition.Equal || collide == eAddressCollition.Inside)
			{
				_worksheet._sharedFormulas.Remove(ix);
                return;
				//fRange.SetSharedFormulaID(int.MinValue); 
			}
            var firstCellCollide = address.Collide(new ExcelAddressBase(fRange._fromRow, fRange._fromCol, fRange._fromRow, fRange._fromCol));
            if (collide == eAddressCollition.Partly && (firstCellCollide == eAddressCollition.Inside || firstCellCollide == eAddressCollition.Equal)) //Do we need to split? Only if the functions first row is inside the new range.
            {
                //The formula partly collides with the current range
                bool fIsSet = false;
                string formulaR1C1 = fRange.FormulaR1C1;
                //Top Range
                if (fRange._fromRow < _fromRow)
                {
                    f.Address = ExcelCellBase.GetAddress(fRange._fromRow, fRange._fromCol, _fromRow - 1, fRange._toCol);
                    fIsSet = true;
                }
                //Left Range
                if (fRange._fromCol < address._fromCol)
                {
                    if (fIsSet)
                    {
                        f = new ExcelWorksheet.Formulas(SourceCodeTokenizer.Default);
                        f.Index = _worksheet.GetMaxShareFunctionIndex(false);
                        f.StartCol = fRange._fromCol;
                        f.IsArray = false;
                        _worksheet._sharedFormulas.Add(f.Index, f);
                    }
                    else
                    {
                        fIsSet = true;
                    }
                    if (fRange._fromRow < address._fromRow)
                        f.StartRow = address._fromRow;
                    else
                    {
                        f.StartRow = fRange._fromRow;
                    }
                    if (fRange._toRow < address._toRow)
                    {
                        f.Address = ExcelCellBase.GetAddress(f.StartRow, f.StartCol,
                                fRange._toRow, address._fromCol - 1);
                    }
                    else
                    {
                        f.Address = ExcelCellBase.GetAddress(f.StartRow, f.StartCol,
                             address._toRow, address._fromCol - 1);
                    }
                    f.Formula = TranslateFromR1C1(formulaR1C1, f.StartRow, f.StartCol);
                    _worksheet.Cells[f.Address].SetSharedFormulaID(f.Index);
                }
                //Right Range
                if (fRange._toCol > address._toCol)
                {
                    if (fIsSet)
                    {
                        f = new ExcelWorksheet.Formulas(SourceCodeTokenizer.Default);
                        f.Index = _worksheet.GetMaxShareFunctionIndex(false);
                        f.IsArray = false;
                        _worksheet._sharedFormulas.Add(f.Index, f);
                    }
                    else
                    {
                        fIsSet = true;
                    }
                    f.StartCol = address._toCol + 1;
                    if (address._fromRow < fRange._fromRow)
                        f.StartRow = fRange._fromRow;
                    else
                    {
                        f.StartRow = address._fromRow;
                    }

                    if (fRange._toRow < address._toRow)
                    {
                        f.Address = ExcelCellBase.GetAddress(f.StartRow, f.StartCol,
                                fRange._toRow, fRange._toCol);
                    }
                    else
                    {
                        f.Address = ExcelCellBase.GetAddress(f.StartRow, f.StartCol,
                                address._toRow, fRange._toCol);
                    }
                    f.Formula = TranslateFromR1C1(formulaR1C1, f.StartRow, f.StartCol);
                    _worksheet.Cells[f.Address].SetSharedFormulaID(f.Index);
                }
                //Bottom Range
                if (fRange._toRow > address._toRow)
                {
                    if (fIsSet)
                    {
                        f = new ExcelWorksheet.Formulas(SourceCodeTokenizer.Default);
                        f.Index = _worksheet.GetMaxShareFunctionIndex(false);
                        f.IsArray = false;
                        _worksheet._sharedFormulas.Add(f.Index, f);
                    }

                    f.StartCol = fRange._fromCol;
                    f.StartRow = _toRow + 1;

                    f.Formula = TranslateFromR1C1(formulaR1C1, f.StartRow, f.StartCol);

                    f.Address = ExcelCellBase.GetAddress(f.StartRow, f.StartCol,
                            fRange._toRow, fRange._toCol);
                    _worksheet.Cells[f.Address].SetSharedFormulaID(f.Index);

                }
            }
		}
		private object ConvertData(ExcelTextFormat Format, string v, int col, bool isText)
		{
			if (isText && (Format.DataTypes == null || Format.DataTypes.Length < col)) return v;

			double d;
			DateTime dt;
			if (Format.DataTypes == null || Format.DataTypes.Length <= col || Format.DataTypes[col] == eDataTypes.Unknown)
			{
				string v2 = v.EndsWith("%") ? v.Substring(0, v.Length - 1) : v;
				if (double.TryParse(v2, NumberStyles.Any, Format.Culture, out d))
				{
					if (v2 == v)
					{
						return d;
					}
					else
					{
						return d / 100;
					}
				}
				if (DateTime.TryParse(v, Format.Culture, DateTimeStyles.None, out dt))
				{
					return dt;
				}
				else
				{
					return v;
				}
			}
			else
			{
				switch (Format.DataTypes[col])
				{
					case eDataTypes.Number:
						if (double.TryParse(v, NumberStyles.Any, Format.Culture, out d))
						{
							return d;
						}
						else
						{
							return v;
						}
					case eDataTypes.DateTime:
						if (DateTime.TryParse(v, Format.Culture, DateTimeStyles.None, out dt))
						{
							return dt;
						}
						else
						{
							return v;
						}
					case eDataTypes.Percent:
						string v2 = v.EndsWith("%") ? v.Substring(0, v.Length - 1) : v;
						if (double.TryParse(v2, NumberStyles.Any, Format.Culture, out d))
						{
							return d / 100;
						}
						else
						{
							return v;
						}

					default:
						return v;

				}
			}
		}
		#endregion
		#region Public Methods
		#region ConditionalFormatting
		/// <summary>
		/// Conditional Formatting for this range.
		/// </summary>
		public IRangeConditionalFormatting ConditionalFormatting
		{
			get
			{
				return new RangeConditionalFormatting(_worksheet, new ExcelAddress(Address));
			}
		}
		#endregion
		#region DataValidation
		/// <summary>
		/// Data validation for this range.
		/// </summary>
		public IRangeDataValidation DataValidation
		{
			get
			{
                return new RangeDataValidation(_worksheet, Address);
			}
		}
		#endregion
        #region LoadFromDataReader
	    /// <summary>
	    /// Load the data from the datareader starting from the top left cell of the range
	    /// </summary>
	    /// <param name="Reader">The datareader to loadfrom</param>
	    /// <param name="PrintHeaders">Print the column caption property (if set) or the columnname property if not, on first row</param>
	    /// <param name="TableName">The name of the table</param>
	    /// <param name="TableStyle">The table style to apply to the data</param>
	    /// <returns>The filled range</returns>
	    public ExcelRangeBase LoadFromDataReader(IDataReader Reader, bool PrintHeaders, string TableName, TableStyles TableStyle = TableStyles.None)
	    {
	        var r = LoadFromDataReader(Reader, PrintHeaders);

            int rows = r.Rows - 1;
	        if (rows >= 0 && r.Columns > 0)
	        {
	            var tbl = _worksheet.Tables.Add(new ExcelAddressBase(_fromRow, _fromCol, _fromRow + (rows <= 0 ? 1 : rows), _fromCol + r.Columns - 1), TableName);
	            tbl.ShowHeader = PrintHeaders;
	            tbl.TableStyle = TableStyle;
	        }
	        return r;
	    }

	    /// <summary>
	    /// Load the data from the datareader starting from the top left cell of the range
	    /// </summary>
	    /// <param name="Reader">The datareader to load from</param>
	    /// <param name="PrintHeaders">Print the caption property (if set) or the columnname property if not, on first row</param>
	    /// <returns>The filled range</returns>
	    public ExcelRangeBase LoadFromDataReader(IDataReader Reader, bool PrintHeaders)
	    {
	        if (Reader == null)
	        {
	            throw (new ArgumentNullException("Reader", "Reader can't be null"));
	        }
	        int fieldCount = Reader.FieldCount;
	  
	        int col = _fromCol, row = _fromRow;
	        if (PrintHeaders)
	        {
	            for (int i = 0; i < fieldCount; i++)
	            {
	                // If no caption is set, the ColumnName property is called implicitly.
	                _worksheet._values.SetValue(row, col++, Reader.GetName(i));
	            }
	            row++;
	            col = _fromCol;
	        }
	        while(Reader.Read())
	        {
	            for (int i = 0; i < fieldCount; i++)
	            {
	                _worksheet._values.SetValue(row, col++, Reader.GetValue(i));
	            }
	            row++;
	            col = _fromCol;
	        }
	        return _worksheet.Cells[_fromRow, _fromCol, row - 1, _fromCol + fieldCount - 1];
	    }
	    #endregion
		#region LoadFromDataTable
		/// <summary>
		/// Load the data from the datatable starting from the top left cell of the range
		/// </summary>
		/// <param name="Table">The datatable to load</param>
		/// <param name="PrintHeaders">Print the column caption property (if set) or the columnname property if not, on first row</param>
		/// <param name="TableStyle">The table style to apply to the data</param>
		/// <returns>The filled range</returns>
		public ExcelRangeBase LoadFromDataTable(DataTable Table, bool PrintHeaders, TableStyles TableStyle)
		{
			var r = LoadFromDataTable(Table, PrintHeaders);

            int rows = (Table.Rows.Count == 0 ? 1 : Table.Rows.Count) + (PrintHeaders ? 1 : 0);
            if (rows >= 0 && Table.Columns.Count>0)
			{
                var tbl = _worksheet.Tables.Add(new ExcelAddressBase(_fromRow, _fromCol, _fromRow + rows - 1, _fromCol + Table.Columns.Count-1), Table.TableName);
				tbl.ShowHeader = PrintHeaders;
				tbl.TableStyle = TableStyle;
			}
		    return r;
		}
		/// <summary>
		/// Load the data from the datatable starting from the top left cell of the range
		/// </summary>
		/// <param name="Table">The datatable to load</param>
		/// <param name="PrintHeaders">Print the caption property (if set) or the columnname property if not, on first row</param>
		/// <returns>The filled range</returns>
		public ExcelRangeBase LoadFromDataTable(DataTable Table, bool PrintHeaders)
		{
			if (Table == null)
			{
				throw (new ArgumentNullException("Table can't be null"));
			}

			int col = _fromCol, row = _fromRow;
			if (PrintHeaders)
			{
				foreach (DataColumn dc in Table.Columns)
				{
                    // If no caption is set, the ColumnName property is called implicitly.
					_worksheet._values.SetValue(row, col++, dc.Caption);
				}
				row++;
				col = _fromCol;
			}
            else if (Table.Rows.Count == 0)
            {
                return null;
            }
			foreach (DataRow dr in Table.Rows)
			{
				foreach (object value in dr.ItemArray)
				{
                    if (value != null && value != DBNull.Value && !string.IsNullOrEmpty(value.ToString()))
                    {
                        _worksheet._values.SetValue(row, col++, value);
                    }
                    else
                    {
                        col++;
                    }
                }
				row++;
				col = _fromCol;
			}
            return _worksheet.Cells[_fromRow, _fromCol, (row == _fromRow ? _fromRow : row - 1), _fromCol + Table.Columns.Count - 1];
		}
		#endregion
		#region LoadFromArrays
		/// <summary>
		/// Loads data from the collection of arrays of objects into the range, starting from
		/// the top-left cell.
		/// </summary>
		/// <param name="Data">The data.</param>
		public ExcelRangeBase LoadFromArrays(IEnumerable<object[]> Data)
		{
			//thanx to Abdullin for the code contribution
			if (Data == null) throw new ArgumentNullException("data");

			int column = _fromCol, row = _fromRow;

			foreach (var rowData in Data)
			{
				column = _fromCol;
				foreach (var cellData in rowData)
				{
					_worksheet._values.SetValue(row, column, cellData);
					column += 1;
				}
				row += 1;
			}
			return _worksheet.Cells[_fromRow, _fromCol, row - 1, column - 1];
		}
		#endregion
		#region LoadFromCollection
		/// <summary>
		/// Load a collection into a the worksheet starting from the top left row of the range.
		/// </summary>
		/// <typeparam name="T">The datatype in the collection</typeparam>
		/// <param name="Collection">The collection to load</param>
		/// <returns>The filled range</returns>
		public ExcelRangeBase LoadFromCollection<T>(IEnumerable<T> Collection)
		{
			return LoadFromCollection<T>(Collection, false, TableStyles.None, BindingFlags.Public | BindingFlags.Instance, null);
		}
		/// <summary>
		/// Load a collection of T into the worksheet starting from the top left row of the range.
		/// Default option will load all public instance properties of T
		/// </summary>
		/// <typeparam name="T">The datatype in the collection</typeparam>
		/// <param name="Collection">The collection to load</param>
        /// <param name="PrintHeaders">Print the property names on the first row. If the property is decorated with a <see cref="DisplayNameAttribute"/> or a <see cref="DescriptionAttribute"/> that attribute will be used instead of the reflected member name.</param>
		/// <returns>The filled range</returns>
		public ExcelRangeBase LoadFromCollection<T>(IEnumerable<T> Collection, bool PrintHeaders)
		{
			return LoadFromCollection<T>(Collection, PrintHeaders, TableStyles.None, BindingFlags.Public | BindingFlags.Instance, null);
		}
		/// <summary>
		/// Load a collection of T into the worksheet starting from the top left row of the range.
		/// Default option will load all public instance properties of T
		/// </summary>
		/// <typeparam name="T">The datatype in the collection</typeparam>
		/// <param name="Collection">The collection to load</param>
        /// <param name="PrintHeaders">Print the property names on the first row. If the property is decorated with a <see cref="DisplayNameAttribute"/> or a <see cref="DescriptionAttribute"/> that attribute will be used instead of the reflected member name.</param>
		/// <param name="TableStyle">Will create a table with this style. If set to TableStyles.None no table will be created</param>
		/// <returns>The filled range</returns>
		public ExcelRangeBase LoadFromCollection<T>(IEnumerable<T> Collection, bool PrintHeaders, TableStyles TableStyle)
		{
			return LoadFromCollection<T>(Collection, PrintHeaders, TableStyle, BindingFlags.Public | BindingFlags.Instance, null);
		}
		/// <summary>
		/// Load a collection into the worksheet starting from the top left row of the range.
		/// </summary>
		/// <typeparam name="T">The datatype in the collection</typeparam>
		/// <param name="Collection">The collection to load</param>
		/// <param name="PrintHeaders">Print the property names on the first row. Any underscore in the property name will be converted to a space. If the property is decorated with a <see cref="DisplayNameAttribute"/> or a <see cref="DescriptionAttribute"/> that attribute will be used instead of the reflected member name.</param>
		/// <param name="TableStyle">Will create a table with this style. If set to TableStyles.None no table will be created</param>
		/// <param name="memberFlags">Property flags to use</param>
		/// <param name="Members">The properties to output. Must be of type T</param>
		/// <returns>The filled range</returns>
		public ExcelRangeBase LoadFromCollection<T>(IEnumerable<T> Collection, bool PrintHeaders, TableStyles TableStyle, BindingFlags memberFlags, MemberInfo[] Members)
		{
			var type = typeof(T);
			if (Members == null)
			{
				Members = type.GetProperties(memberFlags);
			}
			else
			{
				foreach (var t in Members)
				{
                    if (t.DeclaringType!=null && t.DeclaringType != type && !t.DeclaringType.IsSubclassOf(type))
					{
						throw new InvalidCastException("Supplied properties in parameter Properties must be of the same type as T (or an assignable type from T");
					}
				}
			}

			int col = _fromCol, row = _fromRow;
			if (Members.Length > 0 && PrintHeaders)
			{
				foreach (var t in Members)
				{
                    var descriptionAttribute = t.GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault() as DescriptionAttribute;
				    var header = string.Empty;
                    if (descriptionAttribute != null)
                    {
                        header = descriptionAttribute.Description;
                    }
                    else
                    {
                        var displayNameAttribute =
                            t.GetCustomAttributes(typeof (DisplayNameAttribute), false).FirstOrDefault() as
                            DisplayNameAttribute;
                        if (displayNameAttribute != null)
                        {
                            header = displayNameAttribute.DisplayName;
                        }
                        else
                        {
                            header = t.Name.Replace('_', ' ');
                        }
                    }
                    _worksheet._values.SetValue(row, col++, header);
				}
				row++;
			}

		    if (!Collection.Any() && (Members.Length == 0 || PrintHeaders == false))
		    {
		        return null;
		    }

			if (Members.Length == 0)
			{
				foreach (var item in Collection)
				{
					_worksheet.Cells[row++, col].Value = item;
				}
			}
			else
			{
				foreach (var item in Collection)
				{
					col = _fromCol;
                    if (item is string || item is decimal || item is DateTime || item.GetType().IsPrimitive)
                    {
                        _worksheet.Cells[row, col++].Value = item;
                    }
                    else
                    {
                        foreach (var t in Members)
                        {
                            if (t is PropertyInfo)
                            {
                                _worksheet.Cells[row, col++].Value = ((PropertyInfo)t).GetValue(item, null);
                            }
                            else if (t is FieldInfo)
                            {
                                _worksheet.Cells[row, col++].Value = ((FieldInfo)t).GetValue(item);
                            }
                            else if (t is MethodInfo)
                            {
                                _worksheet.Cells[row, col++].Value = ((MethodInfo)t).Invoke(item, null);
                            }
                        }
                    }
					row++;
				}
			}

            if (_fromRow == row-1 && PrintHeaders)
            {
                row++;
            }

            var r = _worksheet.Cells[_fromRow, _fromCol, row - 1, Members.Length==0 ? col : col - 1];

			if (TableStyle != TableStyles.None)
			{
				var tbl = _worksheet.Tables.Add(r, "");
				tbl.ShowHeader = PrintHeaders;
				tbl.TableStyle = TableStyle;
			}
			return r;
		}
		#endregion
		#region LoadFromText
		/// <summary>
		/// Loads a CSV text into a range starting from the top left cell.
		/// Default settings is Comma separation
		/// </summary>
		/// <param name="Text">The Text</param>
		/// <returns>The range containing the data</returns>
		public ExcelRangeBase LoadFromText(string Text)
		{
			return LoadFromText(Text, new ExcelTextFormat());
		}
		/// <summary>
		/// Loads a CSV text into a range starting from the top left cell.
		/// </summary>
		/// <param name="Text">The Text</param>
		/// <param name="Format">Information how to load the text</param>
		/// <returns>The range containing the data</returns>
        public ExcelRangeBase LoadFromText(string Text, ExcelTextFormat Format)
        {
            if (string.IsNullOrEmpty(Text))
            {
                var r = _worksheet.Cells[_fromRow, _fromCol];
                r.Value = "";
                return r;
            }

            if (Format == null) Format = new ExcelTextFormat();

            string splitRegex = String.Format("{0}(?=(?:[^{1}]*{1}[^{1}]*{1})*[^{1}]*$)", Format.EOL, Format.TextQualifier);
            string[] lines = Regex.Split(Text, splitRegex);
            int row = _fromRow;
            int col = _fromCol;
            int maxCol = col;
            int lineNo = 1;
            foreach (string line in lines)
            {
                if (lineNo > Format.SkipLinesBeginning && lineNo <= lines.Length - Format.SkipLinesEnd)
                {
                    col = _fromCol;
                    string v = "";
                    bool isText = false, isQualifier = false;
                    int QCount = 0;
                    int lineQCount = 0;
                    foreach (char c in line)
                    {
                        if (Format.TextQualifier != 0 && c == Format.TextQualifier)
                        {
                            if (!isText && v != "")
                            {
                                throw (new Exception(string.Format("Invalid Text Qualifier in line : {0}", line)));
                            }
                            isQualifier = !isQualifier;
                            QCount += 1;
                            lineQCount++;
                            isText = true;
                        }
                        else
                        {
                            if (QCount > 1 && !string.IsNullOrEmpty(v))
                            {
                                v += new string(Format.TextQualifier, QCount / 2);
                            }
                            else if (QCount > 2 && string.IsNullOrEmpty(v))
                            {
                                v += new string(Format.TextQualifier, (QCount - 1) / 2);
                            }

                            if (isQualifier)
                            {
                                v += c;
                            }
                            else
                            {
                                if (c == Format.Delimiter)
                                {
                                    _worksheet.SetValue(row, col, ConvertData(Format, v, col - _fromCol, isText));
                                    v = "";
                                    isText = false;
                                    col++;
                                }
                                else
                                {
                                    if (QCount % 2 == 1)
                                    {
                                        throw (new Exception(string.Format("Text delimiter is not closed in line : {0}", line)));
                                    }
                                    v += c;
                                }
                            }
                            QCount = 0;
                        }
                    }
                    if (QCount > 1)
                    {
                        v += new string(Format.TextQualifier, QCount / 2);
                    }
                    if (lineQCount % 2 == 1)
                        throw (new Exception(string.Format("Text delimiter is not closed in line : {0}", line)));

                    _worksheet._values.SetValue(row, col, ConvertData(Format, v, col - _fromCol, isText));
                    if (col > maxCol) maxCol = col;
                    row++;
                }
                lineNo++;
            }
            return _worksheet.Cells[_fromRow, _fromCol, row - 1, maxCol];
        }
		/// <summary>
		/// Loads a CSV text into a range starting from the top left cell.
		/// </summary>
		/// <param name="Text">The Text</param>
		/// <param name="Format">Information how to load the text</param>
		/// <param name="TableStyle">Create a table with this style</param>
		/// <param name="FirstRowIsHeader">Use the first row as header</param>
		/// <returns></returns>
		public ExcelRangeBase LoadFromText(string Text, ExcelTextFormat Format, TableStyles TableStyle, bool FirstRowIsHeader)
		{
			var r = LoadFromText(Text, Format);

			var tbl = _worksheet.Tables.Add(r, "");
			tbl.ShowHeader = FirstRowIsHeader;
			tbl.TableStyle = TableStyle;

			return r;
		}
		/// <summary>
		/// Loads a CSV file into a range starting from the top left cell.
		/// </summary>
		/// <param name="TextFile">The Textfile</param>
		/// <returns></returns>
		public ExcelRangeBase LoadFromText(FileInfo TextFile)
		{
			return LoadFromText(File.ReadAllText(TextFile.FullName, Encoding.ASCII));
		}
		/// <summary>
		/// Loads a CSV file into a range starting from the top left cell.
		/// </summary>
		/// <param name="TextFile">The Textfile</param>
		/// <param name="Format">Information how to load the text</param>
		/// <returns></returns>
		public ExcelRangeBase LoadFromText(FileInfo TextFile, ExcelTextFormat Format)
		{
			return LoadFromText(File.ReadAllText(TextFile.FullName, Format.Encoding), Format);
		}
		/// <summary>
		/// Loads a CSV file into a range starting from the top left cell.
		/// </summary>
		/// <param name="TextFile">The Textfile</param>
		/// <param name="Format">Information how to load the text</param>
		/// <param name="TableStyle">Create a table with this style</param>
		/// <param name="FirstRowIsHeader">Use the first row as header</param>
		/// <returns></returns>
		public ExcelRangeBase LoadFromText(FileInfo TextFile, ExcelTextFormat Format, TableStyles TableStyle, bool FirstRowIsHeader)
		{
			return LoadFromText(File.ReadAllText(TextFile.FullName, Format.Encoding), Format, TableStyle, FirstRowIsHeader);
		}
		#endregion
		#region GetValue
		/// <summary>
		/// Get the strongly typed value of the cell.
		/// </summary>
		/// <typeparam name="T">The type</typeparam>
		/// <returns>The value. If the value can't be converted to the specified type, the default value will be returned</returns>
		public T GetValue<T>()
		{
			return _worksheet.GetTypedValue<T>(Value);
		}
		#endregion
		/// <summary>
		/// Get a range with an offset from the top left cell.
		/// The new range has the same dimensions as the current range
		/// </summary>
		/// <param name="RowOffset">Row Offset</param>
		/// <param name="ColumnOffset">Column Offset</param>
		/// <returns></returns>
		public ExcelRangeBase Offset(int RowOffset, int ColumnOffset)
		{
			if (_fromRow + RowOffset < 1 || _fromCol + ColumnOffset < 1 || _fromRow + RowOffset > ExcelPackage.MaxRows || _fromCol + ColumnOffset > ExcelPackage.MaxColumns)
			{
				throw (new ArgumentOutOfRangeException("Offset value out of range"));
			}
			string address = GetAddress(_fromRow + RowOffset, _fromCol + ColumnOffset, _toRow + RowOffset, _toCol + ColumnOffset);
			return new ExcelRangeBase(_worksheet, address);
		}
		/// <summary>
		/// Get a range with an offset from the top left cell.
		/// </summary>
		/// <param name="RowOffset">Row Offset</param>
		/// <param name="ColumnOffset">Column Offset</param>
		/// <param name="NumberOfRows">Number of rows. Minimum 1</param>
		/// <param name="NumberOfColumns">Number of colums. Minimum 1</param>
		/// <returns></returns>
		public ExcelRangeBase Offset(int RowOffset, int ColumnOffset, int NumberOfRows, int NumberOfColumns)
		{
			if (NumberOfRows < 1 || NumberOfColumns < 1)
			{
				throw (new Exception("Number of rows/columns must be greater than 0"));
			}
			NumberOfRows--;
			NumberOfColumns--;
			if (_fromRow + RowOffset < 1 || _fromCol + ColumnOffset < 1 || _fromRow + RowOffset > ExcelPackage.MaxRows || _fromCol + ColumnOffset > ExcelPackage.MaxColumns ||
				 _fromRow + RowOffset + NumberOfRows < 1 || _fromCol + ColumnOffset + NumberOfColumns < 1 || _fromRow + RowOffset + NumberOfRows > ExcelPackage.MaxRows || _fromCol + ColumnOffset + NumberOfColumns > ExcelPackage.MaxColumns)
			{
				throw (new ArgumentOutOfRangeException("Offset value out of range"));
			}
			string address = GetAddress(_fromRow + RowOffset, _fromCol + ColumnOffset, _fromRow + RowOffset + NumberOfRows, _fromCol + ColumnOffset + NumberOfColumns);
			return new ExcelRangeBase(_worksheet, address);
		}
		/// <summary>
		/// Adds a new comment for the range.
		/// If this range contains more than one cell, the top left comment is returned by the method.
		/// </summary>
		/// <param name="Text"></param>
		/// <param name="Author"></param>
		/// <returns>A reference comment of the top left cell</returns>
		public ExcelComment AddComment(string Text, string Author)
		{
		    if (string.IsNullOrEmpty(Author))
		    {
		        Author = Thread.CurrentPrincipal.Identity.Name;
		    }
            //Check if any comments exists in the range and throw an exception
			_changePropMethod(Exists_Comment, null);
			//Create the comments
			_changePropMethod(Set_Comment, new string[] { Text, Author });

			return _worksheet.Comments[new ExcelCellAddress(_fromRow, _fromCol)];
		}

        ///// <summary>
        ///// Copies the range of cells to an other range
        ///// </summary>
        ///// <param name="Destination">The start cell where the range will be copied.</param>
        public void Copy(ExcelRangeBase Destination)
        {
            bool sameWorkbook = Destination._worksheet.Workbook == _worksheet.Workbook;
            ExcelStyles sourceStyles = _worksheet.Workbook.Styles,
                        styles = Destination._worksheet.Workbook.Styles;
            Dictionary<int, int> styleCashe = new Dictionary<int, int>();

            //Clear all existing cells; 
            int toRow = _toRow - _fromRow + 1,
                toCol = _toCol - _fromCol + 1;

            string s = "";
            int i=0;
            object o = null;
            byte flag=0;
            Uri hl = null;
            ExcelComment comment=null;

            var cse = new CellsStoreEnumerator<object>(_worksheet._values, _fromRow, _fromCol, _toRow, _toCol);
            var copiedValue = new List<CopiedCell>();
            while (cse.Next())
            {
                var row=cse.Row;
                var col = cse.Column;       //Issue 15070
                var cell = new CopiedCell
                {
                    Row = Destination._fromRow + (row - _fromRow),
                    Column = Destination._fromCol + (col - _fromCol),
                    Value=cse.Value
                };

                //Destination._worksheet._values.SetValue(row, col, cse.Value);

                if (_worksheet._types.Exists(row, col, ref s))
                {
                    //Destination._worksheet._types.SetValue(row, col,s);
                    cell.Type=s;
                }

                if (_worksheet._formulas.Exists(row, col, ref o))
                {
                    if (o is int)
                    {
                       // Destination._worksheet._formulas.SetValue(row, col, _worksheet.GetFormula(cse.Row, cse.Column));    //Shared formulas, set the formula per cell to simplify
                        cell.Formula=_worksheet.GetFormula(cse.Row, cse.Column);
                    }
                    else
                    {
                        //Destination._worksheet._formulas.SetValue(row, col, o);
                        cell.Formula=o;
                    }
                }
                if(_worksheet._styles.Exists(row, col, ref i))
                {
                    if (sameWorkbook)
                    {
                        //Destination._worksheet._styles.SetValue(row, col, i);
                        cell.StyleID=i;
                    }
                    else
                    {
                        if (styleCashe.ContainsKey(i))
                        {
                            i = styleCashe[i];
                        }
                        else
                        {
                            var oldStyleID = i;
                            i = styles.CloneStyle(sourceStyles, i);
                            styleCashe.Add(oldStyleID, i);
                        }
                        //Destination._worksheet._styles.SetValue(row, col, i);
                        cell.StyleID=i;
                    }
                }
                
                if (_worksheet._hyperLinks.Exists(row, col, ref hl))
                {
                    //Destination._worksheet._hyperLinks.SetValue(row, col, hl);
                    cell.HyperLink=hl;
                }

                if(_worksheet._commentsStore.Exists(row, col, ref comment))
                {
                    cell.Comment=comment;
                }

                if (_worksheet._flags.Exists(row, col, ref flag))
                {
                    cell.Flag = flag;
                }
                copiedValue.Add(cell);
            }

            //Copy styles with no cell value
            var cses = new CellsStoreEnumerator<int>(_worksheet._styles, _fromRow, _fromCol, _toRow, _toCol);
            while (cses.Next())
            {
                if (!_worksheet._values.Exists(cses.Row, cses.Column))
                {
                    var row = Destination._fromRow + (cses.Row - _fromRow);
                    var col = Destination._fromCol + (cses.Column - _fromCol);
                    var cell = new CopiedCell
                    {
                        Row = row,
                        Column = col,
                        Value = null
                    };

                    i = cses.Value;
                    if (sameWorkbook)
                    {
                        cell.StyleID = i;
                    }
                    else
                    {
                        if (styleCashe.ContainsKey(i))
                        {
                            i = styleCashe[i];
                        }
                        else
                        {
                            var oldStyleID = i;
                            i = styles.CloneStyle(sourceStyles, i);
                            styleCashe.Add(oldStyleID, i);
                        }
                        //Destination._worksheet._styles.SetValue(row, col, i);
                        cell.StyleID = i;
                    }
                    copiedValue.Add(cell);
                }
            }
            var copiedMergedCells = new Dictionary<int, ExcelAddress>();
            //Merged cells
            var csem = new CellsStoreEnumerator<int>(_worksheet.MergedCells._cells, _fromRow, _fromCol, _toRow, _toCol);
            while (csem.Next())
            {
                if(!copiedMergedCells.ContainsKey(csem.Value))
                {
                    var adr = new ExcelAddress(_worksheet.Name, _worksheet.MergedCells.List[csem.Value]);
                    if(this.Collide(adr)==eAddressCollition.Inside)
                    {                        
                        copiedMergedCells.Add(csem.Value, new ExcelAddress(
                            Destination._fromRow + (adr.Start.Row - _fromRow),
                            Destination._fromCol + (adr.Start.Column - _fromCol),
                            Destination._fromRow + (adr.End.Row - _fromRow),
                            Destination._fromCol + (adr.End.Column - _fromCol)));
                    }
                    else
                    {
                        //Partial merge of the address ignore.
                        copiedMergedCells.Add(csem.Value, null);
                    }
                }
            }

            Destination._worksheet.MergedCells.Clear(new ExcelAddressBase(Destination._fromRow, Destination._fromCol, Destination._fromRow+toRow-1, Destination._fromCol+toCol-1));

            Destination._worksheet._values.Clear(Destination._fromRow, Destination._fromCol, toRow, toCol);
            Destination._worksheet._formulas.Clear(Destination._fromRow, Destination._fromCol, toRow, toCol);
            Destination._worksheet._styles.Clear(Destination._fromRow, Destination._fromCol, toRow, toCol);
            Destination._worksheet._types.Clear(Destination._fromRow, Destination._fromCol, toRow, toCol);
            Destination._worksheet._hyperLinks.Clear(Destination._fromRow, Destination._fromCol, toRow, toCol);
            Destination._worksheet._flags.Clear(Destination._fromRow, Destination._fromCol, toRow, toCol);
            Destination._worksheet._commentsStore.Clear(Destination._fromRow, Destination._fromCol, toRow, toCol);
           
            foreach(var cell in copiedValue)
            {
                Destination._worksheet._values.SetValue(cell.Row, cell.Column, cell.Value);

                if(cell.Type!=null)
                {
                    Destination._worksheet._types.SetValue(cell.Row, cell.Column, cell.Type);
                }

                if(cell.StyleID!=null)
                {
                    Destination._worksheet._styles.SetValue(cell.Row, cell.Column, cell.StyleID.Value);
                }

                if(cell.Formula!=null)
                {
                    cell.Formula = UpdateFormulaReferences(cell.Formula.ToString(), Destination._fromRow - _fromRow, Destination._fromCol - _fromCol, 0, 0, true);
                    Destination._worksheet._formulas.SetValue(cell.Row, cell.Column, cell.Formula);
                }
                if(cell.HyperLink!=null)
                {
                    Destination._worksheet._hyperLinks.SetValue(cell.Row, cell.Column, cell.HyperLink);
                }

                if (cell.Comment != null)
                {
                    //Destination._worksheet._commentsStore.SetValue(cell.Row, cell.Column, cell.Comment);
                }
                if (cell.Flag != 0)
                {
                    Destination._worksheet._flags.SetValue(cell.Row, cell.Column, cell.Flag);
                }
            }

            //Add merged cells
            foreach(var m in copiedMergedCells.Values)
            {
                if(m!=null)
                {
                    Destination._worksheet.MergedCells.Add(m, true);
                }
            }


            //Clone the cell
                //var copiedCell = (_worksheet._cells[GetCellID(_worksheet.SheetID, cell._fromRow, cell.column)] as ExcelCell);

                //var newCell = copiedCell.Clone(Destination._worksheet,
                //        Destination._fromRow + (copiedCell.Row - _fromRow),
                //        Destination.column + (copiedCell.Column - column));

        //        newCell.MergeId = _worksheet.GetMergeCellId(copiedCell.Row, copiedCell.Column);


        //        if (!string.IsNullOrEmpty(newCell.Formula))
        //        {
        //            newCell.Formula = ExcelCell.UpdateFormulaReferences(newCell.Formula, newCell.Row - copiedCell.Row, (newCell.Column - copiedCell.Column), 1, 1);
        //        }

        //        //If its not the same workbook we must copy the styles to the new workbook.
        //        if (!sameWorkbook)
        //        {
        //            if (styleCashe.ContainsKey(cell.StyleID))
        //            {
        //                newCell.StyleID = styleCashe[cell.StyleID];
        //            }
        //            else
        //            {
        //                newCell.StyleID = styles.CloneStyle(sourceStyles, cell.StyleID);
        //                styleCashe.Add(cell.StyleID, newCell.StyleID);
        //            }
        //        }
        //        newCells.Add(newCell);
        //        if (newCell.Merge) mergedCells.Add(newCell.CellID, newCell);
        //    }

        //    //Now clear the destination.
        //    Destination.Offset(0, 0, (_toRow - _fromRow) + 1, (_toCol - column) + 1).Clear();

        //    //And last add the new cells to the worksheet
        //    foreach (var cell in newCells)
        //    {
        //        Destination.Worksheet._cells.Add(cell);
        //    }
        //    //Add merged cells
        //    if (mergedCells.Count > 0)
        //    {
        //        List<ExcelAddressBase> mergedAddresses = new List<ExcelAddressBase>();
        //        foreach (var cell in mergedCells.Values)
        //        {
        //            if (!IsAdded(cell, mergedAddresses))
        //            {
        //                int startRow = cell.Row, startCol = cell.Column, endRow = cell.Row, endCol = cell.Column + 1;
        //                while (mergedCells.ContainsKey(ExcelCell.GetCellID(Destination.Worksheet.SheetID, endRow, endCol)))
        //                {
        //                    ExcelCell next = mergedCells[ExcelCell.GetCellID(Destination.Worksheet.SheetID, endRow, endCol)];
        //                    if (cell.MergeId != next.MergeId)
        //                    {
        //                        break;
        //                    }
        //                    endCol++;
        //                }

        //                while (IsMerged(mergedCells, Destination.Worksheet, endRow, startCol, endCol - 1, cell))
        //                {
        //                    endRow++;
        //                }

        //                mergedAddresses.Add(new ExcelAddressBase(startRow, startCol, endRow - 1, endCol - 1));
        //            }
        //        }
        //        Destination.Worksheet.MergedCells.List.AddRange((from r in mergedAddresses select r.Address));
        //    }
        //}

        //private bool IsAdded(ExcelCell cell, List<ExcelAddressBase> mergedAddresses)
        //{
        //    foreach (var address in mergedAddresses)
        //    {
        //        if (address.Collide(new ExcelAddressBase(cell.CellAddress)) == eAddressCollition.Inside)
        //        {
        //            return true;
        //        }
        //    }
        //    return false;
        //}

        //private bool IsMerged(Dictionary<ulong, ExcelCell> mergedCells, ExcelWorksheet worksheet, int row, int startCol, int endCol, ExcelCell cell)
        //{
        //    for (int col = startCol; col <= endCol; col++)
        //    {
        //        if (!mergedCells.ContainsKey(ExcelCell.GetCellID(worksheet.SheetID, row, col)))
        //        {
        //            return false;
        //        }
        //        else
        //        {
        //            ExcelCell next = mergedCells[ExcelCell.GetCellID(worksheet.SheetID, row, col)];
        //            if (cell.MergeId != next.MergeId)
        //            {
        //                return false;
        //            }
        //        }
        //    }
        //    return true;
        }

		/// <summary>
		/// Clear all cells
		/// </summary>
		public void Clear()
		{
			Delete(this, false);
		}
		/// <summary>
		/// Creates an array-formula.
		/// </summary>
		/// <param name="ArrayFormula">The formula</param>
		public void CreateArrayFormula(string ArrayFormula)
		{
			if (Addresses != null)
			{
				throw (new Exception("An Arrayformula can not have more than one address"));
			}
			Set_SharedFormula(ArrayFormula, this, true);
		}
        //private void Clear(ExcelAddressBase Range)
        //{
        //    Clear(Range, true);
        //}
        internal void Delete(ExcelAddressBase Range, bool shift)
		{
            //DeleteCheckMergedCells(Range);
            _worksheet.MergedCells.Clear(Range);
			//First find the start cell
            int fromRow, fromCol;
            var d = Worksheet.Dimension;
            if (d != null && Range._fromRow <= d._fromRow && Range._toRow >= d._toRow) //EntireRow?
            {
                fromRow = 0;
            }
            else
            {
                fromRow = Range._fromRow;                
            }
            if (d != null && Range._fromCol <= d._fromCol && Range._toCol >= d._toCol) //EntireRow?
            {
                fromCol = 0;
            }
            else
            {
                fromCol = Range._fromCol;
            }

            var rows = Range._toRow - fromRow + 1;
            var cols = Range._toCol - fromCol + 1;
            
            _worksheet._values.Delete(fromRow, fromCol, rows, cols, shift);
            _worksheet._types.Delete(fromRow, fromCol, rows, cols, shift);
            _worksheet._styles.Delete(fromRow, fromCol, rows, cols, shift);
            _worksheet._formulas.Delete(fromRow, fromCol, rows, cols, shift);
            _worksheet._hyperLinks.Delete(fromRow, fromCol, rows, cols, shift);
            _worksheet._flags.Delete(fromRow, fromCol, rows, cols, shift);
            _worksheet._commentsStore.Delete(fromRow, fromCol, rows, cols, shift);

            //if(shift)
            //{
            //    _worksheet.AdjustFormulasRow(fromRow, rows);
            //}

			//Clear multi addresses as well
			if (Addresses != null)
			{
				foreach (var sub in Addresses)
				{
					Delete(sub, shift);
				}
            }
        }

        private void DeleteCheckMergedCells(ExcelAddressBase Range)
        {
            var removeItems = new List<string>();
            foreach (var addr in Worksheet.MergedCells)
            {
                var addrCol = Range.Collide(new ExcelAddress(Range.WorkSheet, addr));
                if (addrCol != eAddressCollition.No)
                {
                    if (addrCol == eAddressCollition.Inside)
                    {
                        removeItems.Add(addr);
                    }
                    else
                    {
                        throw (new InvalidOperationException("Can't remove/overwrite a part of cells that are merged"));
                    }
                }
            }
            foreach (var item in removeItems)
            {
                Worksheet.MergedCells.Remove(item);
			}
		}
		#endregion
		#region IDisposable Members

		public void Dispose()
		{
			//_worksheet = null;            
		}

		#endregion
		#region "Enumerator"
        //int _index;
        //ulong _toCellId;
        //int _enumAddressIx;
        CellsStoreEnumerator<object> cellEnum;
		public IEnumerator<ExcelRangeBase> GetEnumerator()
		{
			Reset();
			return this;
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			Reset();
			return this;
		}

		/// <summary>
		/// The current range when enumerating
		/// </summary>
		public ExcelRangeBase Current
		{
			get
			{
				return new ExcelRangeBase(_worksheet, ExcelAddressBase.GetAddress(cellEnum.Row, cellEnum.Column));
			}
		}

		/// <summary>
		/// The current range when enumerating
		/// </summary>
		object IEnumerator.Current
		{
			get
			{
				return ((object)(new ExcelRangeBase(_worksheet, ExcelAddressBase.GetAddress(cellEnum.Row, cellEnum.Column))));
			}
		}

		int _enumAddressIx = -1;
        public bool MoveNext()
		{
            if (cellEnum.Next())
            {
                return true;
            }
            else if (_addresses!=null)
            {
                _enumAddressIx++;
                if (_enumAddressIx < _addresses.Count)
                {
                    cellEnum = new CellsStoreEnumerator<object>(_worksheet._values, 
                        _addresses[_enumAddressIx]._fromRow, 
                        _addresses[_enumAddressIx]._fromCol, 
                        _addresses[_enumAddressIx]._toRow, 
                        _addresses[_enumAddressIx]._toCol);
                    return MoveNext();
                }
                else
                {
                    return false;
                }
            }
            return false;
		}

		public void Reset()
		{
            _enumAddressIx = -1;
            cellEnum = new CellsStoreEnumerator<object>(_worksheet._values, _fromRow, _fromCol, _toRow, _toCol);
        }

        //private void GetNextIndexEnum(int fromRow, int fromCol, int toRow, int toCol)
        //{
        //    if (_index >= _worksheet._cells.Count) return;
        //    ExcelCell cell = _worksheet._cells[_index] as ExcelCell;
        //    while (cell.Column > toCol || cell.Column < fromCol)
        //    {
        //        if (cell.Column < fromCol)
        //        {
        //            _index = _worksheet._cells.IndexOf(ExcelAddress.GetCellID(_worksheet.SheetID, cell.Row, fromCol));
        //        }
        //        else
        //        {
        //            _index = _worksheet._cells.IndexOf(ExcelAddress.GetCellID(_worksheet.SheetID, cell.Row + 1, fromCol));
        //        }

        //        if (_index < 0)
        //        {
        //            _index = ~_index;
        //        }
        //        if (_index >= _worksheet._cells.Count || _worksheet._cells[_index].RangeID > _toCellId)
        //        {
        //            break;
        //        }
        //        cell = _worksheet._cells[_index] as ExcelCell;
        //    }
        //}

        //private void GetStartIndexEnum(int fromRow, int fromCol, int toRow, int toCol)
        //{
        //    _index = _worksheet._cells.IndexOf(ExcelCellBase.GetCellID(_worksheet.SheetID, fromRow, fromCol));
        //    _toCellId = ExcelCellBase.GetCellID(_worksheet.SheetID, toRow, toCol);
        //    if (_index < 0)
        //    {
        //        _index = ~_index;
        //    }
        //    _index--;
        //}
    #endregion
    }
}
