OutputLog          slog_outs;
        Kind               next_kind;
        Topology           topo;
        CategoryMap        objdefs;   // Drawable def'n
        Map                shadefs;   // Shadow   def'n
        Category           objdef;
        LineIDMapList      lineIDmaps;
        LineIDMap          lineIDmap;
        Primitive          prime_obj;
        Composite          cmplx_obj;
        long               Nobjs;
        TreeTrunk          treetrunk;
        double             prev_dobj_endtime;
        double             curr_dobj_endtime;
        long               offended_Nobjs;
        Drawable           offended_dobj;
        //  Initialize prev_dobj_endtime to avoid complaint by compiler
        prev_dobj_endtime = Double.NEGATIVE_INFINITY;
        offended_Nobjs    = Integer.MIN_VALUE;
        offended_dobj     = null;
        out_filename      = null;
        del_iobjdefs      = null;
        parseCmdLineArgs( args );
        if ( out_filename == null )
            out_filename  = TraceName.getDefaultSLOG2Name( in_filename );
        objdefs       = new CategoryMap();
        shadefs       = new HashMap();
        lineIDmaps    = new LineIDMapList();
        Nobjs         = 0;
        // Initialize the SLOG-2 file for piped-input, output for this program.
        dobj_ins   = new PipedInputLog( in_filename );
        if ( dobj_ins == null ) {
            System.err.println( "Null input logfile!" );
            System.exit( 1 );
        }
        if ( ! dobj_ins.isSLOG2() ) {
            System.err.println( in_filename + " is NOT SLOG-2 file!." );
            System.exit( 1 );
        }
        String err_msg;
        if ( (err_msg = dobj_ins.getCompatibleHeader()) != null ) {
            System.err.print( err_msg );
            PipedInputLog.stdoutConfirmation();
        }
        dobj_ins.initialize();
        /* */    Date time1 = new Date();
        slog_outs  = new OutputLog( out_filename );
        //  Set Tree properties, !optional!
        //  TreeNode's minimum size, without any drawable/shadow, is 38 bytes.
        //  Drawable;s minimum size is 32 bytes, whether it is state/arrow.
        //  Arrow( with 2 integer infovalues ) is 40 bytes long.
        //  So, for 1 state primitive leaf, the size is 38 + 40 = 78 .
        if ( leaf_bytesize > 0 )
            slog_outs.setTreeLeafByteSize( leaf_bytesize );
        else
            slog_outs.setTreeLeafByteSize( dobj_ins.getTreeLeafByteSize() );
        if ( num_children_per_node > 0 )
            slog_outs.setNumChildrenPerNode( num_children_per_node );
        else
            slog_outs.setNumChildrenPerNode( dobj_ins.getNumChildrenPerNode() );
        treetrunk = new TreeTrunk( slog_outs, shadefs );
        /* */    Date time2 = new Date();
        while ( ( next_kind = dobj_ins.peekNextKind() ) != Kind.EOF ) {
            if ( next_kind == Kind.TOPOLOGY ) {
                topo = dobj_ins.getNextTopology();
                // Put in the default Shadow categories in case the original
                // does not have any shadow categories, i.e no shadows.
                objdef = Category.getShadowCategory( topo );
                objdefs.put( new Integer( objdef.getIndex() ), objdef );
                shadefs.put( topo, objdef );
            }
            else if ( next_kind == Kind.YCOORDMAP ) {
                lineIDmap = new LineIDMap( dobj_ins.getNextYCoordMap() );
                lineIDmaps.add( lineIDmap );
            }
            else if ( next_kind == Kind.CATEGORY ) {
                objdef = dobj_ins.getNextCategory();
                if ( objdef.isShadowCategory() ) {
                    objdefs.put( new Integer( objdef.getIndex() ), objdef );
                    shadefs.put( objdef.getTopology(), objdef );
                }
                // Category can be removed here for efficiency reason.
                // Instead let CategoryMap.removeUnusedCategories() do the work.
                // if ( isCategoryToBeRemoved( objdef.getIndex() ) )
                //     continue;
                objdefs.put( new Integer( objdef.getIndex() ), objdef );
                objdef.setUsed( false );
            } 
            else if ( next_kind == Kind.PRIMITIVE ) {
                prime_obj = dobj_ins.getNextPrimitive();
                // Undo InfoBox.resolveCategory() when the Drawable is read.
                prime_obj.releaseCategory();