Updated the DebuggerManager.GetLocalPath function to cache failing results too.

In order to improve the debugging experience for the very large project that I work on, I was investigating which functions were being called a lot when debugging. The GetLocalPath function was one of those functions.

I noticed that it was doing a lot of work to determine if a SourceFile had a local path. In the cases it found a path it would cache the results, however, it was not caching the result in cases that a local path could not be determined. For my large project this means that most of the SourceFiles would have to run through all the logic time and time again. By updating the code to cache a null result the performance was improved tremendously.

I also changed code that was repeatedly requesting the same property values from the SourceFile, since I am not sure what overhead is involved and since they were used so often.

The final change I made was to convert soem of the string concatenation to use a StringBuilder. I believe the compiler may internally changes `string1 + string2` into `String.Concat(new String[] {string1, string2})`, so this change may be of little value.