Hi,
I was moving a floating window when the below exception occured.
Our application uses multiple top-level windows in different appdomains, and a ribbon with office 2010 style backstage.
Infragistics version is currently 2013.1.
Any insights? Anything we can do to prevent it, since the affected window sometimes hangs afterward and the application must be manually terminated.
App_DispatcherUnhandledExceptionSystem.InvalidOperationException: Cannot set Visibility or call Show, ShowDialog, or WindowInteropHelper.EnsureHandle after a Window has closed. at System.Windows.Window.CoerceVisibility(DependencyObject d, Object value) at System.Windows.DependencyObject.ProcessCoerceValue(DependencyProperty dp, PropertyMetadata metadata, EntryIndex& entryIndex, Int32& targetIndex, EffectiveValueEntry& newEntry, EffectiveValueEntry& oldEntry, Object& oldValue, Object baseValue, Object controlValue, CoerceValueCallback coerceValueCallback, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, Boolean skipBaseValueChecks) at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal) at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value) at System.Windows.Data.BindingOperations.SetBinding(DependencyObject target, DependencyProperty dp, BindingBase binding) at Infragistics.Windows.Controls.ToolWindowHostWindow.DeferShowHelper.Show(Boolean activate) at Infragistics.Windows.Controls.ToolWindow.DeferredShowInfo.ProcessShow(Boolean cancel) at Infragistics.Windows.DockManager.DockManagerUtilities.ShowToolWindow(ToolWindow window, FrameworkElement owner, Boolean activate) at Infragistics.Windows.DockManager.Dragging.DragManager.CreateFloatingPreviewWindow(Point point, Size size) at Infragistics.Windows.DockManager.Dragging.MoveWindowAction.PerformAction(DragManager dragManager, Boolean isPreview) at Infragistics.Windows.DockManager.Dragging.DragManager.ProcessDragMove(IInputDeviceInfo e, Nullable`1 windowRect) at Infragistics.Windows.DockManager.Dragging.DragManager.StartDrag(FrameworkElement element, Point mouseDownPosition, IInputDeviceInfo e, Boolean processMove, Boolean isWindowDragMode) at Infragistics.Windows.DockManager.Dragging.DragManager.OnPendingDragElementMouseMove(Object sender, MouseEventArgs e) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
Hello,
Thank you for your post. I have been looking into it and since this is not a known issue, I am not able to conclude what can cause it, so could you please send an isolated sample project, where the issue is reproduced, so I can investigate it further for you.
Looking forward for your reply.
That would be very hard to accomplish, I'm afraid. So far I've only seen this issue once. And I cannot reproduce it with the full application either.
Given that you have the call stack, you may want to consider catching the exception at this location.
Do as you wish - this was more a notification that you may have an issue here when there are multiple UI threads in play.
Great. I'm glad you were able to get around the issue and hopefully the debugging snippets could help someone else in the future who might encounter this issue (with an older version anyway as we'll make a change to avoid the re-entrant MouseMove message processing during the drag).
Thank you for all your help and the workaround. I wasn't able to get the Capture Mouse workaround to work but BeginInvoke the FitWidth at Application Idle priority seems to be enough to prevent the issue. At this point I consider the issue closed.
Thanks for the input and your patience on this one.
So basically what seems to be happening is that while we are processing the MouseMove we are trying to show the tool window. As part of showing a Window WPF will call UpdateLayout. You have code in your ItemViewerUC that is listening to the SizeChanged and you are calling FitWidth on the OCX. When trying to communicate with the OCX the framework is processing the queued messages which at least in this case includes another MouseMove which results in a re-entrancy (i.e. they invoke the MouseMove while they are already in the middle of processing a MouseMove).
Since we close/remove a toolwindow that doesn't contain any visible panes this causes us to call Close on the toolwindow which in this case is in the middle of a show (from the 1st MouseMove that is still in progress). So one option is for you to asynchronously process the SizeChanged (or perhaps skip it entirely if the window is in the middle of a show). Another might be to try and capture the MouseMove while you are calling FitWidth.
e.g.
var fe = Mouse.Captured as FrameworkElement; MouseEventHandler mouseHandler = (obj, args) => { args.Handled = true; }; if (fe != null) fe.AddHandler(PreviewMouseMoveEvent, mouseHandler); // do your OCX changes if (fe != null) fe.RemoveHandler(PreviewMouseMoveEvent, mouseHandler);
var fe = Mouse.Captured as FrameworkElement; MouseEventHandler mouseHandler = (obj, args) => { args.Handled = true; };
if (fe != null) fe.AddHandler(PreviewMouseMoveEvent, mouseHandler);
// do your OCX changes
if (fe != null) fe.RemoveHandler(PreviewMouseMoveEvent, mouseHandler);
We can add code to ignore a mousemove while we are processing one during a drag but you'll need to do one of the above workarounds or something else since you won't be able to upgrade to 13.2 or later.
This is the last stack trace I got with the provided debug code before the thrown exception.
at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) at System.Environment.get_StackTrace() at ToolWindowDebugger.DebugHelper.OnToolWindowClosing(Object sender, CancelEventArgs e) in c:\_DevEnvs\Syn 32bit Crt\Synergy Client\UI\App.xaml.cs:line 351 at System.Windows.Window.OnClosing(CancelEventArgs e) at Infragistics.Windows.Controls.ToolWindowHostWindow.OnClosing(CancelEventArgs e) at System.Windows.Window.WmClose() at System.Windows.Window.WindowFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at MS.Win32.UnsafeNativeMethods.UnsafeSendMessage(IntPtr hWnd, WindowMessage msg, IntPtr wParam, IntPtr lParam) at System.Windows.Window.InternalClose(Boolean shutdown, Boolean ignoreCancel) at System.Windows.Window.Close() at Infragistics.Windows.Controls.ToolWindowHostWindow.CloseHelperImpl() at Infragistics.Windows.Controls.ToolWindowHostWindow.CloseHelper() at Infragistics.Windows.Controls.ToolWindowHostWindow.Infragistics.Windows.Controls.IToolWindowHost.Close() at Infragistics.Windows.Controls.ToolWindow.CloseOverride() at Infragistics.Windows.DockManager.PaneToolWindow.CloseOverride() at Infragistics.Windows.Controls.ToolWindow.Close() at Infragistics.Windows.DockManager.PaneToolWindow.OnChildVisibilityChanged(Object sender, RoutedEventArgs e) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e) at Infragistics.Windows.DockManager.DockManagerUtilities.RaiseVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) at Infragistics.Windows.DockManager.SplitPane.OnVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) at System.Windows.PropertyChangedCallback.Invoke(DependencyObject d, DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args) at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.DependencyObject.CoerceValue(DependencyProperty dp) at Infragistics.Windows.DockManager.SplitPane.OnChildrenCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at Infragistics.Collections.ObservableCollectionExtended`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at Infragistics.Windows.DockManager.ObservableSplitElementCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e) at Infragistics.Collections.ObservableCollectionExtended`1.RemoveItem(Int32 index) at System.Collections.ObjectModel.Collection`1.RemoveAt(Int32 index) at Infragistics.Windows.DockManager.SplitPane.Infragistics.Windows.DockManager.IContentPaneContainer.RemoveContentPane(ContentPane pane, Boolean replaceWithPlaceholder) at Infragistics.Windows.DockManager.DockManagerUtilities.MovePane(ContentPane pane, IContentPaneContainer newContainer, Nullable`1 newIndex, PaneLocation newLocation, MovePaneHelper moveHelper) at Infragistics.Windows.DockManager.Dragging.DragManager.CloneRootDragElement(PaneLocation newLocation, Action`1 initializeNewSplit) at Infragistics.Windows.DockManager.Dragging.DragManager.CreateWindowBeingDragged(Point location, Size size) at Infragistics.Windows.DockManager.Dragging.FloatPaneAction.PerformAction(DragManager dragManager, Boolean isPreview) at Infragistics.Windows.DockManager.Dragging.DragManager.ProcessDragMove(IInputDeviceInfo e, Nullable`1 windowRect) at Infragistics.Windows.DockManager.Dragging.DragManager.ProcessDragMove(MouseEventArgs e) at Infragistics.Windows.DockManager.Dragging.DragManager.OnDragElementMouseMove(Object sender, MouseEventArgs e) at System.Windows.Input.MouseEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.ContentElement.RaiseTrustedEvent(RoutedEventArgs args) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters) at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams) at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData) at SynDocViewerLib._DSynDocViewer.FitWidth(Int32 lFit) at AxSynDocViewerLib.AxSynDocViewer.FitWidth(Int32 lFit) at SynDocViewerWrapper.SynDocViewerWrap.FitWidth(Boolean bFit) in c:\_DevEnvs\Syn 32bit Crt\Synergy Capture\SynDocViewerWrapper\SynDocViewerWrap.cs:line 1302 at SynergyECM.Controls.ItemViewerUC.fitWidthAndTextWidth() in c:\_DevEnvs\Syn 32bit Crt\Synergy Controls\SynViewerCntrls\ItemViewerUC\ItemViewerUC.xaml.cs:line 4131 at SynergyECM.Controls.ItemViewerUC.docViewerHostGrid_SizeChanged(Object sender, SizeChangedEventArgs e) in c:\_DevEnvs\Syn 32bit Crt\Synergy Controls\SynViewerCntrls\ItemViewerUC\ItemViewerUC.xaml.cs:line 1787 at System.Windows.SizeChangedEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e) at System.Windows.FrameworkElement.OnRenderSizeChanged(SizeChangedInfo sizeInfo) at System.Windows.ContextLayoutManager.fireSizeChangedEvents() at System.Windows.ContextLayoutManager.UpdateLayout() at System.Windows.UIElement.UpdateLayout() at System.Windows.Interop.HwndSource.SetLayoutSize() at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value) at System.Windows.Interop.HwndSource.set_RootVisual(Visual value) at System.Windows.Window.SetRootVisual() at System.Windows.Window.SetRootVisualAndUpdateSTC() at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight) at System.Windows.Window.CreateSourceWindow(Boolean duringShow) at System.Windows.Window.CreateSourceWindowDuringShow() at System.Windows.Window.SafeCreateWindowDuringShow() at System.Windows.Window.ShowHelper(Object booleanBox) at System.Windows.Window.Show() at Infragistics.Windows.Controls.ToolWindowHostWindow.Show(Boolean activate) at Infragistics.Windows.Controls.ToolWindowHostWindow.DeferShowHelper.Show(Boolean activate) at Infragistics.Windows.Controls.ToolWindow.DeferredShowInfo.ProcessShow(Boolean cancel) at Infragistics.Windows.Controls.ToolWindow.DeferredShowInfo.System.IDisposable.Dispose() at Infragistics.Windows.DockManager.PaneToolWindow.ResumeSyncShow() at Infragistics.Windows.DockManager.MovePaneHelper.OnToolWindowChanged(PaneToolWindow oldWindow, PaneToolWindow newWindow) at Infragistics.Windows.DockManager.MovePaneHelper.OnToolWindowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args) at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.DependencyObject.ClearValueCommon(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata) at System.Windows.DependencyObject.ClearValue(DependencyProperty dp) at System.Windows.Data.BindingOperations.ClearBinding(DependencyObject target, DependencyProperty dp) at Infragistics.Windows.DockManager.MovePaneHelper.System.IDisposable.Dispose() at Infragistics.Windows.DockManager.Dragging.DragManager.CloneRootDragElement(PaneLocation newLocation, Action`1 initializeNewSplit) at Infragistics.Windows.DockManager.Dragging.DragManager.CreateWindowBeingDragged(Point location, Size size) at Infragistics.Windows.DockManager.Dragging.FloatPaneAction.PerformAction(DragManager dragManager, Boolean isPreview) at Infragistics.Windows.DockManager.Dragging.DragManager.ProcessDragMove(IInputDeviceInfo e, Nullable`1 windowRect) at Infragistics.Windows.DockManager.Dragging.DragManager.ProcessDragMove(MouseEventArgs e) at Infragistics.Windows.DockManager.Dragging.DragManager.OnDragElementMouseMove(Object sender, MouseEventArgs e) at System.Windows.Input.MouseEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.ContentElement.RaiseTrustedEvent(RoutedEventArgs args) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.Run() at System.Windows.Application.RunDispatcher(Object ignore) at System.Windows.Application.RunInternal(Window window) at System.Windows.Application.Run(Window window) at System.Windows.Application.Run() at SynergyECM.Client.UI.SynergyClientApp.Main() in c:\_DevEnvs\Syn 32bit Crt\Synergy Client\UI\obj\x86\Debug\App.g.cs:line 0 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()
I'll give it try and yes, at this point I haven't been able to isolate the cause into a test application.