/// <summary>Read the cache file into memory.</summary>
 /// <remarks>Read the cache file into memory.</remarks>
 /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
 public virtual void Read()
 {
     changed   = false;
     statDirty = false;
     if (!cacheFile.Exists())
     {
         header = null;
         entries.Clear();
         lastCacheTime = 0;
         return;
     }
     cache = new RandomAccessFile(cacheFile, "r");
     try
     {
         FileChannel channel = cache.GetChannel();
         ByteBuffer  buffer  = ByteBuffer.AllocateDirect((int)cacheFile.Length());
         buffer.Order(ByteOrder.BIG_ENDIAN);
         int j = channel.Read(buffer);
         if (j != buffer.Capacity())
         {
             throw new IOException(MessageFormat.Format(JGitText.Get().couldNotReadIndexInOneGo
                                                        , j, buffer.Capacity()));
         }
         buffer.Flip();
         header = new GitIndex.Header(buffer);
         entries.Clear();
         for (int i = 0; i < header.entries; ++i)
         {
             GitIndex.Entry entry    = new GitIndex.Entry(this, buffer);
             GitIndex.Entry existing = entries.Get(entry.name);
             entries.Put(entry.name, entry);
             if (existing != null)
             {
                 entry.stages |= existing.stages;
             }
         }
         lastCacheTime = cacheFile.LastModified();
     }
     finally
     {
         cache.Close();
     }
 }
        /// <summary>Write content of index to disk.</summary>
        /// <remarks>Write content of index to disk.</remarks>
        /// <exception cref="System.IO.IOException">System.IO.IOException</exception>
        public virtual void Write()
        {
            CheckWriteOk();
            FilePath tmpIndex = new FilePath(cacheFile.GetAbsoluteFile() + ".tmp");
            FilePath Lock     = new FilePath(cacheFile.GetAbsoluteFile() + ".lock");

            if (!Lock.CreateNewFile())
            {
                throw new IOException(JGitText.Get().indexFileIsInUse);
            }
            try
            {
                FileOutputStream fileOutputStream = new FileOutputStream(tmpIndex);
                FileChannel      fc  = fileOutputStream.GetChannel();
                ByteBuffer       buf = ByteBuffer.Allocate(4096);
                MessageDigest    newMessageDigest = Constants.NewMessageDigest();
                header = new GitIndex.Header(entries);
                header.Write(buf);
                buf.Flip();
                newMessageDigest.Update(((byte[])buf.Array()), buf.ArrayOffset(), buf.Limit());
                fc.Write(buf);
                buf.Flip();
                buf.Clear();
                for (Iterator i = entries.Values.Iterator(); i.HasNext();)
                {
                    GitIndex.Entry e = (GitIndex.Entry)i.Next();
                    e.Write(buf);
                    buf.Flip();
                    newMessageDigest.Update(((byte[])buf.Array()), buf.ArrayOffset(), buf.Limit());
                    fc.Write(buf);
                    buf.Flip();
                    buf.Clear();
                }
                buf.Put(newMessageDigest.Digest());
                buf.Flip();
                fc.Write(buf);
                fc.Close();
                fileOutputStream.Close();
                if (cacheFile.Exists())
                {
                    if (db.FileSystem.RetryFailedLockFileCommit())
                    {
                        // file deletion fails on windows if another
                        // thread is reading the file concurrently
                        // So let's try 10 times...
                        bool deleted = false;
                        for (int i_1 = 0; i_1 < 10; i_1++)
                        {
                            if (cacheFile.Delete())
                            {
                                deleted = true;
                                break;
                            }
                            try
                            {
                                Sharpen.Thread.Sleep(100);
                            }
                            catch (Exception)
                            {
                            }
                        }
                        // ignore
                        if (!deleted)
                        {
                            throw new IOException(JGitText.Get().couldNotRenameDeleteOldIndex);
                        }
                    }
                    else
                    {
                        if (!cacheFile.Delete())
                        {
                            throw new IOException(JGitText.Get().couldNotRenameDeleteOldIndex);
                        }
                    }
                }
                if (!tmpIndex.RenameTo(cacheFile))
                {
                    throw new IOException(JGitText.Get().couldNotRenameTemporaryIndexFileToIndex);
                }
                changed       = false;
                statDirty     = false;
                lastCacheTime = cacheFile.LastModified();
                db.FireEvent(new IndexChangedEvent());
            }
            finally
            {
                if (!Lock.Delete())
                {
                    throw new IOException(JGitText.Get().couldNotDeleteLockFileShouldNotHappen);
                }
                if (tmpIndex.Exists() && !tmpIndex.Delete())
                {
                    throw new IOException(JGitText.Get().couldNotDeleteTemporaryIndexFileShouldNotHappen
                                          );
                }
            }
        }