private static Caller VerifyAsyncUsedProperly(Caller res)
        {
            if (res == null)
            {
                return null;
            }

            var attribute = Type.GetType(AsyncAttributeName, false);
            if (attribute == null)
            {
                return res;
            }

            var asyncFrame = res.GetFirstFrameForAttribute(attribute);
            MethodBase method = res.Method;
            var mi = method as MethodInfo;
            if (asyncFrame != null && mi != null && mi.ReturnType == typeof(void))
            {
                var msg =
                    @"WARNING: You are using xUnit async incorrectly.
The method {0} has a return type of void instead of Task.
In this form this test can never fail, it will always pass.
".FormatWith(method.ToStandardString());
                msg = StringUtils.FormatFrame('*', msg);
                FailLoudly(msg);
            }
            return res;
        }
		public virtual bool Parse(StackTrace trace)
		{
			caller = new Caller(trace, 0);
			approvalFrame = FindApprovalFrame();
			Logger.Variable("approvalFrame",approvalFrame);
			return approvalFrame != null;
		}
		private string GetFileNameForStack(Caller frame)
		{
		
			Logger.Variable("frame",  frame);
			return 
				frame.Parents.Select(c => c.StackFrame.GetFileName()).FirstOrDefault(f => f != null);
		}
		public static Caller GetFirstFrameForAttribute(Caller caller, string attributeName)
		{
			var firstFrameForAttribute =
				caller.Callers.FirstOrDefault(c => ContainsAttribute(c.Method.GetCustomAttributes(false), attributeName));
			if (firstFrameForAttribute == null) return null;
			var all = caller.Callers.Where(c => ContainsAttribute(c.Method.GetCustomAttributes(false), attributeName));
			return firstFrameForAttribute;
		}
		public override bool Parse(StackTrace stackTrace)
		{
			 caller = new Caller(stackTrace, 0);
			approvalFrame = FindApprovalFrame(caller);
			if (approvalFrame == null)
			{
				return false;
			}
      return true;
		}
		public static void VerifyNoAbandonedFiles()
		{
			var path = PathUtilities.GetDirectoryForCaller(1);
			var assembly = new Caller().Methods.First().Module.Assembly;
			var files = FindAbandonedFiles(path, assembly);
			if (files.Any())
			{
				throw new Exception("The folling files have been abandoned:\r\n" + files.ToReadableString().Replace(",","\r\n"));
			}
		}
		private static IEnumerable<FileInfo> CleanUpAbandonedFiles()
		{
			var assembly = new Caller().Methods.First().Module.Assembly; 
			var path = PathUtilities.GetDirectoryForCaller(1);
			var list = ApprovalMaintenance.FindAbandonedFiles(path,assembly);
			foreach (var fileInfo in list)
			{
				fileInfo.Delete();
			}
			return list;
		}
		private Caller FindApprovalFrame(Caller caller)
		{
			var mspecInvocationFrame = caller.Callers.NonLambda().FirstOrDefault(
				c => c.Class.FullName == "Machine.Specifications.Model.Specification"
				     && c.Method.Name == "InvokeSpecificationField");

			if (mspecInvocationFrame == null)
			{
				return null;
			}

			return mspecInvocationFrame.Parents.NonLambda().Skip(1)
				.FirstOrDefault(c => !c.Class.FullName.StartsWith("System."));
		}
        public bool Parse(StackTrace stackTrace)
        {
            _caller = new Caller(stackTrace, 0);
            var approvalFrame = FindApprovalFrame();
            if (approvalFrame == null) return false;
 
            var type = approvalFrame.Class;
            object x = Activator.CreateInstance(type);
            var y = type.GetMembers()
                        .Where(m => m.ReflectedType.Name == "It");
            var g = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            var h = g.Where(fi => fi.FieldType.FullName == "Machine.Specifications.It").ToList();
            var i = h.Where(mi => 
                {
                    var theDelegate = mi.GetValue(x) as Delegate;
                    return theDelegate != null && theDelegate.Method == approvalFrame.Method;
                });
            FieldInfo j = i.FirstOrDefault();
 
            approverMethodName = j.Name;
 
            return true;
        }
		public string GetCallingMethod()
		{
			var outsideCallingMethod = new Caller().Methods.First(m => m.DeclaringType.Namespace != this.GetType().Namespace);
			return outsideCallingMethod.ToStandardString();
		}
 private static Caller GetFirstFrameForAttribute(Caller caller,string attributeName)
 {
     return caller.Callers.FirstOrDefault(c => ContainsAttribute(c.Method.GetCustomAttributes(false), attributeName));
 }
 public bool Parse(StackTrace trace)
 {
     caller = new Caller(trace, 0);
     return FindApprovalFrame() != null;
 }
 private string GetFileNameForStack(Caller frame)
 {
     return frame.Parents.Select(c => c.StackFrame.GetFileName()).FirstOrDefault(f => f != null);
 }
		public virtual bool Parse(StackTrace trace)
		{
			caller = new Caller(trace, 0);
			approvalFrame = FindApprovalFrame();
			return approvalFrame != null;
		}
		public static IEnumerable<FileInfo> FindAbandonedFiles(string path)
		{
			var assembly = new Caller().Methods.First().Module.Assembly;
			return FindAbandonedFiles(path, assembly);
		}