/// <summary>
        /// create shifted physical subarray of ILArray specified by range and shift
        /// </summary>
        /// <param name="range">must be valid range</param>
        /// <param name="shift">may be any integer - will be handled modulus ranges dimensions</param>
        /// <returns>physical array specified by range / shift</returns>
        private ILArray <BaseT> CreatePhysicalSubarrayFromPhysicalShifted(int shift, ILRange range)
        {
            if (range == null)
            {
                throw new ILArgumentException("ILArray (construct): Range specified must not be null!");
            }
            int rangeDimLen = range.NumberOfDimensions, higherDimSum = 0;
            int intshift = shift % rangeDimLen;

            shift = shift % ((rangeDimLen > 1)? rangeDimLen : 2);
            int curPosOut = 0, d;

            BaseT[] retArr = ILMemoryPool.Pool.New <BaseT> (range.NumberOfElements);
            int     leadDimNr = intshift, leadDimLenRange = range[intshift].Length, leadDimLen = m_dimensions[intshift];
            int     leadDimInc = m_dimensions.SequentialIndexDistance(intshift), tmpI = 0;
            int     outElemCount = range.NumberOfElements, curPosIn;

            int[]   idxArr       = new int[rangeDimLen]; // used to store current position inside higher dims
            bool[]  isFullDim    = new bool[rangeDimLen];
            int[][] r            = range.RangeArray;
            int[]   rleadDim     = r[leadDimNr]; // faster access
            int[]   seqDistances = m_dimensions.GetSequentialIndexDistances(range.NumberOfDimensions);
            if (rleadDim[0] < 0)
            {
                #region LeadDim is full (specified as ':')
                // leading dimension is a "full" dimension: only its largest
                // index is (negative) given in range[d]
                leadDimLenRange = -rleadDim[0] + 1;
                for (int i = 1; i < idxArr.Length; i++)
                {
                    tmpI = (leadDimNr + i) % rangeDimLen;
                    if (r[tmpI][0] < 0)
                    {
                        // full dimension
                        //higherDimSum += m_dimensions.SequentialIndexDistance(tmpI) * idxArr[i];  // always 0!
                        isFullDim[tmpI] = true;
                    }
                    else
                    {
                        higherDimSum += seqDistances[tmpI] * (r[tmpI][0]);
                    }
                }
                curPosIn = higherDimSum; // todo: might be implemented more efficient...
                for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++, curPosIn += leadDimInc)
                {
                    retArr[curPosOut++] = m_data[curPosIn];
                }
                while (curPosOut < outElemCount)
                {
                    // increase higher dims
                    d = (leadDimNr + 1) % rangeDimLen;
                    while (d != leadDimNr)
                    {
                        if (!isFullDim[d])
                        {
                            if (idxArr[d] >= range[d].Length - 1)
                            {
                                idxArr[d] = 0;
                                d         = (d + 1) % rangeDimLen;
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            if (idxArr[d] >= -r[d][0])
                            {
                                idxArr[d] = 0;
                                d         = (d + 1) % rangeDimLen;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    System.Diagnostics.Debug.Assert(d != leadDimNr);
                    idxArr[d]   += 1;
                    higherDimSum = 0;
                    for (int i = 1; i < idxArr.Length; i++)
                    {
                        tmpI = (i + leadDimNr) % rangeDimLen;
                        if (isFullDim[tmpI])
                        {
                            higherDimSum += seqDistances[tmpI] * idxArr[tmpI];
                        }
                        else
                        {
                            higherDimSum += seqDistances[tmpI] * (r[tmpI][idxArr[tmpI]]);
                        }
                    }
                    // do the copy!
                    curPosIn = higherDimSum; // todo: might be implemented more efficient...
                    tmpI     = leadDimLenRange;
                    while (tmpI-- > 0)
                    {
                        retArr[curPosOut++] = m_data[curPosIn];
                        curPosIn           += leadDimInc;
                    }
                }
                #endregion
            }
            else
            {
                #region LeadDim is explicitly declared
                for (int i = 1; i < idxArr.Length; i++)
                {
                    tmpI = (leadDimNr + i) % rangeDimLen;
                    if (r[tmpI][0] < 0)
                    {
                        // full dimension
                        //higherDimSum += m_dimensions.SequentialIndexDistance(tmpI) * idxArr[i];  // always 0!
                        isFullDim[tmpI] = true;
                    }
                    else
                    {
                        higherDimSum += seqDistances[tmpI] * (r[tmpI][0]);
                    }
                }
                curPosIn = higherDimSum; // todo: might be implemented more efficient...
                for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++)
                {
                    curPosIn            = higherDimSum + rleadDim[lIdx] * leadDimInc;
                    retArr[curPosOut++] = m_data[curPosIn];
                }
                while (curPosOut < outElemCount)
                {
                    // increase higher dims
                    d = (leadDimNr + 1) % rangeDimLen;
                    while (d != leadDimNr)
                    {
                        if (!isFullDim[d])
                        {
                            if (idxArr[d] >= range[d].Length - 1)
                            {
                                idxArr[d] = 0;
                                d         = (d + 1) % rangeDimLen;
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            if (idxArr[d] >= -r[d][0])
                            {
                                idxArr[d] = 0;
                                d         = (d + 1) % rangeDimLen;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    System.Diagnostics.Debug.Assert(d != leadDimNr);   // reached the end
                    idxArr[d]   += 1;
                    higherDimSum = 0;
                    for (int i = 1; i < idxArr.Length; i++)
                    {
                        tmpI = (i + leadDimNr) % rangeDimLen;
                        if (isFullDim[tmpI])
                        {
                            higherDimSum += seqDistances[tmpI] * idxArr[tmpI];
                        }
                        else
                        {
                            higherDimSum += seqDistances[tmpI] * (r[tmpI][idxArr[tmpI]]);
                        }
                    }
                    // do the copy!
                    curPosIn = higherDimSum; // todo: might be implemented more efficient...
                    for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++)
                    {
                        curPosIn            = higherDimSum + rleadDim[lIdx] * leadDimInc;
                        retArr[curPosOut++] = m_data[curPosIn];
                    }
                }
                #endregion
            }
            return(new ILArray <BaseT> (retArr, range.GetDimensions().GetShifted(shift)));
        }
        /// <summary>
        /// create physical subarray from physical ILArray
        /// </summary>
        /// <param name="range"></param>
        /// <returns></returns>
        private ILArray <BaseT> CreatePhysicalSubarrayFromPhysical(ILRange range)
        {
            if (range == null)
            {
                throw new ILArgumentException("range specified must not be null!");
            }
            int rangeDimLen = range.NumberOfDimensions, higherDimSum = 0;
            int leadDimLenRange = range[0].Length, leadDimLen = m_dimensions[0];
            int curPosOut = 0, d, outElemCount = range.NumberOfElements;

            BaseT[] retArr       = ILMemoryPool.Pool.New <BaseT>(outElemCount);
            int[]   idxArr       = new int[rangeDimLen]; // used to store current position inside higher dims
            bool[]  isFullDim    = new bool[rangeDimLen];
            int[][] r            = range.RangeArray;
            int[]   seqDistances = m_dimensions.GetSequentialIndexDistances(range.NumberOfDimensions);
            int[]   rleadDim     = range[0];
            if (rleadDim[0] < 0)
            {
                #region LeadDim is full (specified as ':')
                // leading dimension is a "full" dimension: only its largest index is (negative) given in range[d]
                for (int i = 1; i < idxArr.Length; i++)
                {
                    if (r[i][0] < 0)
                    {
                        // full dimension
                        //higherDimSum += m_dimensions.SequentialIndexDistance(i) * idxArr[i];
                        isFullDim[i] = true;
                    }
                    else
                    {
                        higherDimSum += seqDistances[i] * (r[i][idxArr[i]]);
                    }
                }
                leadDimLenRange = -rleadDim[0] + 1;
                for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++)
                {
                    retArr[curPosOut++] = m_data[higherDimSum + lIdx];
                }
                while (curPosOut < outElemCount)
                {
                    // increase higher dims
                    d = 1;
                    while (d < rangeDimLen)
                    {
                        if (!isFullDim[d])
                        {
                            if (idxArr[d] >= r[d].Length - 1)
                            {
                                idxArr[d] = 0;
                                d++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            if (idxArr[d] >= -r[d][0])
                            {
                                idxArr[d] = 0;
                                d++;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    System.Diagnostics.Debug.Assert(d != idxArr.Length);
                    idxArr[d]   += 1;
                    higherDimSum = 0;
                    for (int i = 1; i < idxArr.Length; i++)
                    {
                        if (isFullDim[i])
                        {
                            higherDimSum += seqDistances[i] * idxArr[i];
                        }
                        else
                        {
                            higherDimSum += seqDistances[i] * (r[i][idxArr[i]]);
                        }
                    }
                    // do the copy!
                    for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++)
                    {
                        retArr[curPosOut++] = m_data[higherDimSum++];
                    }
                }
                #endregion
            }
            else
            {
                #region LeadDim is explicitly declared
                for (int i = 1; i < idxArr.Length; i++)
                {
                    // ... not sure for higher dimensions...
                    if (r[i][0] < 0)
                    {
                        // full dimension
                        // higherDimSum += m_dimensions.SequentialIndexDistance(i) * idxArr[i];
                        isFullDim[i] = true;
                    }
                    else
                    {
                        higherDimSum += seqDistances[i] * (r[i][0]);
                    }
                }
                for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++)
                {
                    retArr[curPosOut++] = m_data[higherDimSum + rleadDim[lIdx]];
                }
                while (curPosOut < outElemCount)
                {
                    // increase higher dims
                    d = 1;
                    while (d < idxArr.Length)
                    {
                        if (!isFullDim[d])
                        {
                            if (idxArr[d] >= r[d].Length - 1)
                            {
                                idxArr[d] = 0;
                                d++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            if (idxArr[d] >= -r[d][0])
                            {
                                idxArr[d] = 0;
                                d++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        System.Diagnostics.Debug.Assert(d < idxArr.Length);
                    }
                    System.Diagnostics.Debug.Assert(d != idxArr.Length);
                    idxArr[d]   += 1;
                    higherDimSum = 0;
                    for (int i = 1; i < idxArr.Length; i++)
                    {
                        if (isFullDim[i])
                        {
                            higherDimSum += seqDistances[i] * idxArr[i];
                        }
                        else
                        {
                            higherDimSum += seqDistances[i] * (r[i][idxArr[i]]);
                        }
                    }
                    // do the copy!
                    for (int lIdx = 0; lIdx < leadDimLenRange; lIdx++)
                    {
                        retArr[curPosOut++] = m_data[higherDimSum + rleadDim[lIdx]];
                    }
                }
                #endregion
            }
            return(new ILArray <BaseT>(retArr, range.GetDimensions()));
        }