]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java
Merge "Trying to wait for procedures"
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / adapter / GraphToDiagramSynchronizer.java
index dd6c9b7d10f7e7e916264a30bc3f24af71180627..e2c1521ee45b21c6e63dc166535d645b60e0354e 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 Association for Decentralized Information Management
  * in Industry THTH ry.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -49,6 +49,7 @@ import org.simantics.db.common.procedure.adapter.AsyncProcedureAdapter;
 import org.simantics.db.common.procedure.adapter.CacheListener;
 import org.simantics.db.common.procedure.adapter.ListenerSupport;
 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
+import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
 import org.simantics.db.common.request.AsyncReadRequest;
 import org.simantics.db.common.request.ReadRequest;
 import org.simantics.db.common.session.SessionEventListenerAdapter;
@@ -762,7 +763,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                 else
                     result.add(eh);
             }
-            return ElementClass.compile(result).setId(ec.getId());
+            return ElementClass.compile(result, false).setId(ec.getId());
         }
     }
 
@@ -1301,7 +1302,8 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     task4.finish();
                     // ITask task5 = ThreadLogger.getInstance().begin("DiagramContentRequest2");
                     ITask task42 = ThreadLogger.getInstance().begin("DiagramContentRequest2");
-                    DiagramContents contents = g.syncRequest(query);
+                    DiagramContents contents = g.syncRequest(query, TransientCacheAsyncListener.instance());
+                    //System.err.println("contents: " + contents);
                     task42.finish();
                     // task5.finish();
                     monitor.worked(10);
@@ -1338,7 +1340,12 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                             ArrayMap.keys(ProfileKeys.DIAGRAM, ProfileKeys.CANVAS, ProfileKeys.NODE_MAP).values(GraphToDiagramSynchronizer.this.diagram, canvas, dn),
                             new CanvasNotification(canvas));
 
-                    profileObserver.listen(g, GraphToDiagramSynchronizer.this);
+                    g.getSession().asyncRequest(new AsyncReadRequest() {
+                        @Override
+                        public void run(AsyncReadGraph graph) {
+                            profileObserver.listen(graph, GraphToDiagramSynchronizer.this);
+                        }
+                    });
 
                     return d;
 
@@ -1603,11 +1610,11 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
         }
 
         public void clear() {
-               // Prevent DiagramContents leakage through DisposableListeners.
-               lastContent = null;
-               content = null;
-               changes = null;
-               
+            // Prevent DiagramContents leakage through DisposableListeners.
+            lastContent = null;
+            content = null;
+            changes = null;
+
             this.addedElements.clear();
             this.removedElements.clear();
             this.addedConnectionSegments.clear();
@@ -1623,7 +1630,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             this.removedRouteGraphConnections.clear();
         }
 
-        void processNodes(AsyncReadGraph graph) {
+        void processNodes(ReadGraph graph) throws DatabaseException {
 
             for (Map.Entry<Resource, Change> entry : changes.elements.entrySet()) {
 
@@ -1635,7 +1642,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         IElement mappedElement = getMappedElement(element);
                         if (mappedElement == null) {
                             if (DebugPolicy.DEBUG_NODE_LOAD)
-                                graph.asyncRequest(new ReadRequest() {
+                                graph.syncRequest(new ReadRequest() {
                                     @Override
                                     public void run(ReadGraph graph) throws DatabaseException {
                                         System.out.println("    EXTERNALLY ADDED ELEMENT: "
@@ -1648,10 +1655,13 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
 
                                 // TODO: Connection loading has no listening, changes :Connection will not be noticed by this code!
                                 Listener<IElement> loadListener = new DisposableListener<IElement>(canvasListenerSupport) {
-                                       @Override
-                                       public String toString() {
-                                               return "Connection load listener for " + element;
-                                       }
+
+                                    boolean firstTime = true;
+
+                                    @Override
+                                    public String toString() {
+                                        return "Connection load listener for " + element;
+                                    }
                                     @Override
                                     public void execute(IElement loaded) {
                                         // Invoked when the element has been loaded.
@@ -1663,6 +1673,19 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                             return;
                                         }
 
+                                        if (firstTime) {
+
+                                            mapElement(element, loaded);
+                                            synchronized (GraphToDiagramUpdater.this) {
+                                                addedElements.add(loaded);
+                                                addedElementMap.put(element, loaded);
+                                                addedConnectionMap.put(element, loaded);
+                                            }
+
+                                            firstTime = false;
+
+                                        }
+
                                         Object data = loaded.getHint(ElementHints.KEY_OBJECT);
 
                                         // Logic for disposing listener
@@ -1699,19 +1722,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                     }
                                 };
 
-                                graph.asyncRequest(new ConnectionRequest(canvas, diagram, element, errorHandler, loadListener), new AsyncProcedure<IElement>() {
+                                graph.syncRequest(new ConnectionRequest(canvas, diagram, element, errorHandler, loadListener), new AsyncProcedure<IElement>() {
                                     @Override
                                     public void execute(AsyncReadGraph graph, final IElement e) {
-                                        if (e == null)
-                                            return;
-
-                                        //System.out.println("ConnectionRequestProcedure " + e);
-                                        mapElement(element, e);
-                                        synchronized (GraphToDiagramUpdater.this) {
-                                            addedElements.add(e);
-                                            addedElementMap.put(element, e);
-                                            addedConnectionMap.put(element, e);
-                                        }
 
                                         // Read connection type
                                         graph.forSingleType(element, br.DIA.Connection, new Procedure<Resource>() {
@@ -1730,6 +1743,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                                 }
                                             }
                                         });
+
                                     }
 
                                     @Override
@@ -1740,10 +1754,13 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                             } else if (content.nodeSet.contains(element)) {
 
                                 Listener<IElement> loadListener = new DisposableListener<IElement>(canvasListenerSupport) {
-                                       @Override
-                                       public String toString() {
-                                               return "Node load listener for " + element;
-                                       }
+
+                                    boolean firstTime = true;
+
+                                    @Override
+                                    public String toString() {
+                                        return "Node load listener for " + element;
+                                    }
                                     @Override
                                     public void execute(IElement loaded) {
                                         // Invoked when the element has been loaded.
@@ -1755,6 +1772,22 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                             return;
                                         }
 
+                                        if (firstTime) {
+
+                                            // This is invoked before the element is actually loaded.
+                                            //System.out.println("NodeRequestProcedure " + e);
+                                            if (DebugPolicy.DEBUG_NODE_LOAD)
+                                                System.out.println("MAPPING ADDED NODE: " + element + " -> " + loaded);
+                                            mapElement(element, loaded);
+                                            synchronized (GraphToDiagramUpdater.this) {
+                                                addedElements.add(loaded);
+                                                addedElementMap.put(element, loaded);
+                                            }
+
+                                            firstTime = false;
+
+                                        }
+
                                         Object data = loaded.getHint(ElementHints.KEY_OBJECT);
 
                                         // Logic for disposing listener
@@ -1792,21 +1825,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                 };
 
                                 //System.out.println("NODE REQUEST: " + element);
-                                graph.asyncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
+                                graph.syncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
                                     @Override
                                     public void execute(AsyncReadGraph graph, IElement e) {
-                                        if (e == null)
-                                            return;
-
-                                        // This is invoked before the element is actually loaded.
-                                        //System.out.println("NodeRequestProcedure " + e);
-                                        if (DebugPolicy.DEBUG_NODE_LOAD)
-                                            System.out.println("MAPPING ADDED NODE: " + element + " -> " + e);
-                                        mapElement(element, e);
-                                        synchronized (GraphToDiagramUpdater.this) {
-                                            addedElements.add(e);
-                                            addedElementMap.put(element, e);
-                                        }
                                     }
 
                                     @Override
@@ -1826,7 +1847,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     case REMOVED: {
                         IElement e = getMappedElement(element);
                         if (DebugPolicy.DEBUG_NODE_LOAD)
-                            graph.asyncRequest(new ReadRequest() {
+                            graph.syncRequest(new ReadRequest() {
                                 @Override
                                 public void run(ReadGraph graph) throws DatabaseException {
                                     System.out.println("    EXTERNALLY REMOVED ELEMENT: "
@@ -1839,6 +1860,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         }
                         break;
                     }
+                    default:
                 }
             }
         }
@@ -1872,6 +1894,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         }
                         break;
                     }
+                    default:
                 }
             }
         }
@@ -1915,6 +1938,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     case REMOVED: {
                         removedConnectionEntities.add(ce);
                     }
+                    default:
                 }
             }
 
@@ -1932,7 +1956,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             }
         }
 
-        void processRouteGraphConnections(AsyncReadGraph graph) {
+        void processRouteGraphConnections(ReadGraph graph) throws DatabaseException {
             for (Map.Entry<Resource, Change> entry : changes.routeGraphConnections.entrySet()) {
                 final Resource connection = entry.getKey();
 
@@ -1944,10 +1968,13 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                             continue;
 
                         Listener<IElement> loadListener = new DisposableListener<IElement>(canvasListenerSupport) {
-                               @Override
-                               public String toString() {
-                                       return "processRouteGraphConnections " + connection;
-                               }
+
+                            boolean firstTime = true;
+
+                            @Override
+                            public String toString() {
+                                return "processRouteGraphConnections " + connection;
+                            }
                             @Override
                             public void execute(IElement loaded) {
                                 // Invoked when the element has been loaded.
@@ -1959,6 +1986,18 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                     return;
                                 }
 
+                                if(firstTime) {
+                                    if (DebugPolicy.DEBUG_NODE_LOAD)
+                                        System.out.println("MAPPING ADDED ROUTE GRAPH CONNECTION: " + connection + " -> " + loaded);
+                                    mapElement(connection, loaded);
+                                    synchronized (GraphToDiagramUpdater.this) {
+                                        addedElements.add(loaded);
+                                        addedElementMap.put(connection, loaded);
+                                        addedRouteGraphConnectionMap.put(connection, loaded);
+                                    }
+                                    firstTime = false;
+                                }
+
                                 Object data = loaded.getHint(ElementHints.KEY_OBJECT);
 
                                 // Logic for disposing listener
@@ -2010,21 +2049,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                             }
                         };
 
-                        graph.asyncRequest(new ConnectionRequest(canvas, diagram, connection, errorHandler, loadListener), new Procedure<IElement>() {
+                        graph.syncRequest(new ConnectionRequest(canvas, diagram, connection, errorHandler, loadListener), new Procedure<IElement>() {
                             @Override
                             public void execute(final IElement e) {
-                                if (e == null)
-                                    return;
-
-                                //System.out.println("ConnectionRequestProcedure " + e);
-                                if (DebugPolicy.DEBUG_NODE_LOAD)
-                                    System.out.println("MAPPING ADDED ROUTE GRAPH CONNECTION: " + connection + " -> " + e);
-                                mapElement(connection, e);
-                                synchronized (GraphToDiagramUpdater.this) {
-                                    addedElements.add(e);
-                                    addedElementMap.put(connection, e);
-                                    addedRouteGraphConnectionMap.put(connection, e);
-                                }
                             }
                             @Override
                             public void exception(Throwable throwable) {
@@ -2039,6 +2066,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                             removedRouteGraphConnections.add(e);
                         break;
                     }
+                    default:
                 }
             }
         }
@@ -2052,7 +2080,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             return assertMappedConnection(connection);
         }
 
-        void processBranchPoints(AsyncReadGraph graph) {
+        void processBranchPoints(ReadGraph graph) throws DatabaseException {
             for (Map.Entry<Resource, Change> entry : changes.branchPoints.entrySet()) {
 
                 final Resource element = entry.getKey();
@@ -2063,7 +2091,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         IElement mappedElement = getMappedElement(element);
                         if (mappedElement == null) {
                             if (DebugPolicy.DEBUG_NODE_LOAD)
-                                graph.asyncRequest(new ReadRequest() {
+                                graph.syncRequest(new ReadRequest() {
                                     @Override
                                     public void run(ReadGraph graph) throws DatabaseException {
                                         System.out.println("    EXTERNALLY ADDED BRANCH POINT: "
@@ -2073,10 +2101,13 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                 });
 
                             Listener<IElement> loadListener = new DisposableListener<IElement>(canvasListenerSupport) {
-                               @Override
-                               public String toString() {
-                                       return "processBranchPoints for " + element;
-                               }
+
+                                boolean firstTime = true;
+
+                                @Override
+                                public String toString() {
+                                    return "processBranchPoints for " + element;
+                                }
                                 @Override
                                 public void execute(IElement loaded) {
                                     // Invoked when the element has been loaded.
@@ -2088,6 +2119,21 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                         return;
                                     }
 
+                                    if (firstTime) {
+
+                                        mapElement(element, loaded);
+                                        synchronized (GraphToDiagramUpdater.this) {
+                                            addedBranchPoints.add(loaded);
+                                            addedElementMap.put(element, loaded);
+                                            ConnectionEntityImpl ce = getConnectionEntity(element);
+                                            loaded.setHint(ElementHints.KEY_CONNECTION_ENTITY, ce);
+                                            loaded.setHint(ElementHints.KEY_PARENT_ELEMENT, ce.getConnectionElement());
+                                        }
+
+                                        firstTime = false;
+
+                                    }
+
                                     Object data = loaded.getHint(ElementHints.KEY_OBJECT);
                                     if (addedElementMap.containsKey(data)) {
                                         // This element was just loaded, in
@@ -2115,19 +2161,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                 }
                             };
 
-                            graph.asyncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
+                            graph.syncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
                                 @Override
                                 public void execute(AsyncReadGraph graph, IElement e) {
-                                    if (e != null) {
-                                        mapElement(element, e);
-                                        synchronized (GraphToDiagramUpdater.this) {
-                                            addedBranchPoints.add(e);
-                                            addedElementMap.put(element, e);
-                                            ConnectionEntityImpl ce = getConnectionEntity(element);
-                                            e.setHint(ElementHints.KEY_CONNECTION_ENTITY, ce);
-                                            e.setHint(ElementHints.KEY_PARENT_ELEMENT, ce.getConnectionElement());
-                                        }
-                                    }
                                 }
 
                                 @Override
@@ -2141,7 +2177,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     case REMOVED: {
                         IElement e = getMappedElement(element);
                         if (DebugPolicy.DEBUG_NODE_LOAD)
-                            graph.asyncRequest(new ReadRequest() {
+                            graph.syncRequest(new ReadRequest() {
                                 @Override
                                 public void run(ReadGraph graph) throws DatabaseException {
                                     System.out.println("    EXTERNALLY REMOVED BRANCH POINT: "
@@ -2154,11 +2190,12 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         }
                         break;
                     }
+                    default:
                 }
             }
         }
 
-        void processConnectionSegments(AsyncReadGraph graph) {
+        void processConnectionSegments(ReadGraph graph) throws DatabaseException {
             ConnectionSegmentAdapter adapter = connectionSegmentAdapter;
 
             for (Map.Entry<EdgeResource, Change> entry : changes.connectionSegments.entrySet()) {
@@ -2170,7 +2207,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         IElement mappedElement = getMappedElement(seg);
                         if (mappedElement == null) {
                             if (DebugPolicy.DEBUG_EDGE_LOAD)
-                                graph.asyncRequest(new ReadRequest() {
+                                graph.syncRequest(new ReadRequest() {
                                     @Override
                                     public void run(ReadGraph graph) throws DatabaseException {
                                         System.out.println("    EXTERNALLY ADDED CONNECTION SEGMENT: " + seg.toString()
@@ -2178,7 +2215,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                     }
                                 });
 
-                            graph.asyncRequest(new EdgeRequest(canvas, errorHandler, canvasListenerSupport, diagram, adapter, seg), new AsyncProcedure<IElement>() {
+                            graph.syncRequest(new EdgeRequest(canvas, errorHandler, canvasListenerSupport, diagram, adapter, seg), new AsyncProcedure<IElement>() {
                                 @Override
                                 public void execute(AsyncReadGraph graph, IElement e) {
                                     if (DebugPolicy.DEBUG_EDGE_LOAD)
@@ -2206,7 +2243,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     case REMOVED: {
                         final IElement e = getMappedElement(seg);
                         if (DebugPolicy.DEBUG_EDGE_LOAD)
-                            graph.asyncRequest(new ReadRequest() {
+                            graph.syncRequest(new ReadRequest() {
                                 @Override
                                 public void run(ReadGraph graph) throws DatabaseException {
                                     System.out.println("    EXTERNALLY REMOVED CONNECTION SEGMENT: " + seg.toString() + " - "
@@ -2218,6 +2255,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         }
                         break;
                     }
+                    default:
                 }
             }
         }
@@ -2260,9 +2298,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             Object task = Timing.BEGIN("processNodesConnections");
             //System.out.println("---- PROCESS NODES & CONNECTIONS BEGIN");
             if (!changes.elements.isEmpty()) {
-                graph.syncRequest(new AsyncReadRequest() {
+                graph.syncRequest(new ReadRequest() {
                     @Override
-                    public void run(AsyncReadGraph graph) {
+                    public void run(ReadGraph graph) throws DatabaseException {
                         processNodes(graph);
                     }
                     @Override
@@ -2277,9 +2315,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
 
             //System.out.println("---- PROCESS BRANCH POINTS BEGIN");
             if (!changes.branchPoints.isEmpty()) {
-                graph.syncRequest(new AsyncReadRequest() {
+                graph.syncRequest(new ReadRequest() {
                     @Override
-                    public void run(AsyncReadGraph graph) {
+                    public void run(ReadGraph graph) throws DatabaseException {
                         processBranchPoints(graph);
                     }
                     @Override
@@ -2295,9 +2333,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
 
             //System.out.println("---- PROCESS CONNECTION SEGMENTS BEGIN");
             if (!changes.connectionSegments.isEmpty()) {
-                graph.syncRequest(new AsyncReadRequest() {
+                graph.syncRequest(new ReadRequest() {
                     @Override
-                    public void run(AsyncReadGraph graph) {
+                    public void run(ReadGraph graph) throws DatabaseException {
                         processConnectionSegments(graph);
                     }
                     @Override
@@ -2312,9 +2350,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
 
             task = Timing.BEGIN("processRouteGraphConnections");
             if (!changes.routeGraphConnections.isEmpty()) {
-                graph.syncRequest(new AsyncReadRequest() {
+                graph.syncRequest(new ReadRequest() {
                     @Override
-                    public void run(AsyncReadGraph graph) {
+                    public void run(ReadGraph graph) throws DatabaseException {
                         processRouteGraphConnections(graph);
                     }
                     @Override
@@ -2373,12 +2411,12 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         return "defaultConnectionSegmentAdapter";
                     }
                 }, new DisposableListener<IElement>(listenerSupport) {
-                       
-                       @Override
-                       public String toString() {
-                               return "DefaultConnectionSegmentAdapter listener for " + edge;
-                       }
-                       
+                    
+                    @Override
+                    public String toString() {
+                        return "DefaultConnectionSegmentAdapter listener for " + edge;
+                    }
+                    
                     @Override
                     public void execute(IElement loaded) {
                         // Invoked when the element has been loaded.
@@ -2474,13 +2512,18 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     return;
                 }
 
-                // NOTICE: Layer information is loaded from the connection entity resource
-                // that is shared by all segments of the same connection.
-                ElementFactoryUtil.loadLayersForElement(graph, layerManager, diagram, edge, info.connection,
-                        new AsyncProcedureAdapter<IElement>() {
+                graph.syncRequest(new AsyncReadRequest() {
                     @Override
-                    public void exception(AsyncReadGraph graph, Throwable t) {
-                        error("failed to load layers for connection segment", t);
+                    public void run(AsyncReadGraph graph) {
+                        // NOTICE: Layer information is loaded from the connection entity resource
+                        // that is shared by all segments of the same connection.
+                        ElementFactoryUtil.loadLayersForElement(graph, layerManager, diagram, edge, info.connection,
+                                new AsyncProcedureAdapter<IElement>() {
+                            @Override
+                            public void exception(AsyncReadGraph graph, Throwable t) {
+                                error("failed to load layers for connection segment", t);
+                            }
+                        });
                     }
                 });
 
@@ -2650,9 +2693,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     GraphToDiagramUpdater updater = new GraphToDiagramUpdater(lastContent, content, changes);
                     GraphToDiagramSynchronizer.this.currentUpdater = updater;
                     try {
-                       updater.process(graph);
+                        updater.process(graph);
                     } finally {
-                       GraphToDiagramSynchronizer.this.currentUpdater = null;
+                        GraphToDiagramSynchronizer.this.currentUpdater = null;
                     }
                     Timing.END(task);